-
什麼是線程?
作業系統是包含多個程序的容器,而每個程序又是容納了多個線程的容器。
從圖中可以看出 一個作業系統同時可以有多個子程序,一個程序可以有多個子線程但一個子線程隻能有一個父程序。
建立你的第一個java多線程程式:
public class Creat100Threads {
/**
* 建立一百個線程
* @param args
*/
public static void main(String[] args) throws InterruptedException {
for(int i=0;i<100;i++){
new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
}
運作代碼後 多了100個線程 可以看到 程式确實實作了線程。
線程和程序的不同
- .程序和線程的定義不同
- 程序:是執行中一段程式,即一旦程式被載入到記憶體中并準備執行,它就是一個程序。程序是表示資源配置設定的的基本概念,又是排程運作的基本機關,是系統中的并發執行的機關。
- 線程:單個程序中執行中每個任務就是一個線程。線程是程序中執行運算的最小機關,是cpu排程的基本機關。
- 記憶體共享方式不同:
- 程序是互相獨立的:不同程序會被作業系統配置設定一定記憶體空間,但通常不同程序之間記憶體是獨立的無法互相通路。如果要實作程序間通訊需要用到"程序間通信(IPC)"。
- 線程之間特定資源是共享的:線程共享資源包括:
- 程序代碼段
- 程序的公有資料(利用這些共享資料,線程很容易實作互相通訊)
- 程序打開檔案掃描符
- 信号處理器
- 程序的目前目錄
- 程序使用者ID與程序組ID
- 線程獨有内容:
- 線程ID
- 寄存器組的值
- 線程的堆棧
- 錯誤傳回碼
- 線程的屏蔽新号碼
- 數量不同
- 一個程序至少有一個或以上線程, 一個線程隻能有一個父程序。
- 開銷不同
- 線程的建立、終止時間比程序段
- 同一程序内的線程切換時間比程序短
- 同 一程序的各個線程間共享記憶體和檔案資源,可不通過核心進行通信。
Java語言和多線程的淵源和關系
- Java設計之初–支援多線程(受限于硬體當時很多語言并不支援多線程)
- Java語言在服務端開發語言中的地位–常年居榜前三(阿裡 騰訊 百度 美團。。。)
- 一對一映射到作業系統的核心線程(java中的多線程會在作業系統核心 中一一對應建立多線程)
- jvm自動啟動線程
啟動一個隻有main方法的java程式可以看到除了main線程還jvm還幫我們啟動了其他線程,這裡面啟動的線程有
Finalizer:負責對象的Finalizer()方法
Signal Dispatcher 負責把作業系統發來的信号分發給适當的程式處理
Reference Handler GC、引用相關線程(java的垃圾回收)
main 主線程,使用者程式的入口。
多線程
什麼是多線程?
多線程的概念:如果一個程式允許兩個或以上的線程,那麼它就是多線程程式。多線程市值在單個程序中運作多個線程。
生活中的多線程:
比喻你和室友同住一間房
- 客廳(程序的記憶體空間)
- 廁所(隻能有一個人上廁所 上廁所時其他人不能上 鎖的概念)
- 獨立房間(每個線程 有自己的ID 堆棧)
- 打掃(一個人打掃效率比較慢 在公共區域可能會一起協作打掃 )
- 吃火鍋
- 大火鍋一人吃(相當于 單程序單線程)
- 大火鍋一起吃 (單程序 多線程)
- 一個人吃多個小火鍋(多程序)
- 吃火鍋底料(有人霸占了這些火鍋(鎖) 那你就吃不到了)
什麼是多線程?
多線程實際例子:搶火車票
如果各個任務互相獨立 互不影響 則不需要多線程。
但絕大多數場景不同的任務 是互相耦合影響的,這時候就需要多線程。
為什麼需要多線程?
-
最主要是提高cpu利用效率
-cpu一個時鐘周期 是非常快的 相對于記憶體 和 硬碟來說 是跟不上 cpu這個速度的 如果 為了響應 cpu 記憶體 的處理的資料 那會大大拖累cpu的性能。那cpu在這個等到記憶體 等外部裝置處理的、過程中就會浪費資源。而多線程就是提高cpu的資源使用率。
- 提高使用者體驗:避免卡頓、縮短等待時間
- 并行處理,提高性能,通常是服務領域(例如timcat),用多個線程去接收進來的Http請求,而不是排隊等待單一的線程處理。
- 在Android開發中,主線程的重要任務之一是繪制螢幕界面,該線程中不允許進行IO操作或網絡請求,目的是避免卡頓,影響使用者互動。
- 便于程式員設計程式設計模型(将一個功能分割成若幹不同子線程)
-
阿姆達定律
-處理器越多,程式就執行越快,但有上限,取決于程式中串行部分的比例,并行比例越高多處理器性能優勢越明顯。
由于摩爾定律的逐漸失效 單主頻提升越來越不明顯,要想提升程式速度 需要靠程式提高并行處理的能力。
什麼場景會用到多線程?
- 同時處理不同的事:1. 聽音樂 2. 背景定時任務,execel
- 同時提高工作效率:1. tomecat 2. 并行下載下傳 3. NIO
- 需要很大并發量的時候
多線程的局限
- 性能問題:上下文切換帶來的問題
- 異構化任務: (任務結構不一樣)很難高效并行
- 帶來線程安全問題:包括資料安全問題(例如i++ 總數不一緻) 以及線程帶來的活躍性問題(線程饑餓、死鎖)
串行、并行、并發
- 串行和并行 打個比方 串行就是你數羊毛一次數1根1根的 而并行 是十根十根一起數。
- 并行、并發
在隻有一個cpu的情況下 但是 你的音樂 QQ 都能 同時運作 互相切換 就是cpu處于并行運算 将cpu的片段是在不同程序中切換配置設定的。這時cpu相當于在邏輯上并行處理多個應用。
而當有多個cpu時 程式跑在真實的不同實體cpu上這時就是并發了。
-
真正的"同時"運作-在同一時刻,有多個任務同時執行。
例如,在多核處理器上,有兩個線程同時執行一段代碼。
相反的,單核cpu是無法處理并發任務的。
并發的2種概念
- 形容多個任務的執行狀态
- 兩個或多個任務可以再重疊的時間段内啟動,運作和完成
-
并發(兩個線程同時執行)一定是并發
p a r a l l e l i s m ∈ C o n c u r r e n c y parallelism \in Concurrency parallelism∈Concurrency
可以說:并發是并行的充分條件,并行是并發的必要條件。
- 對"并發性"的簡稱
- 不同部分可以無序或同時執行,且并不會影響最終的執行結果。
- 在不同核心數的計算機上的不同表現
串并行和并發的實際例子
-
打遊戲時,女朋友來電話
假設 大腦是單核cpu
并行:此時 如果你選擇繼續打遊戲并且 接電話 但受限于你的大腦是單核的 你的思維就隻能在這之間不同切換,此時就是并行。
串行:此時你選擇暫時不接電話,等遊戲結束後 再打電話給女朋友 ,此時就是串行,每次隻處理一件事。
一個程式能并行運作一定具有并發性。
是什麼讓并發和并行成為可能?
- CPU更新
- 作業系統更新
- 程式設計語言更新
高并發
- 什麼是高并發(雙十一 春晚 12306)
- 是系統 同時能夠處理大量的不求請求的能力。
- 高并發和多線程的聯系和不同?
- 多線程是高并發的一種重要的解決方案,多線程并不意味着高并發,如Redis 是單線程的同時也是能處理大量的請求。
-
高并發有哪些名額
-QPS(Queries Per Second) 每秒的查詢數
- 帶寬
- PV(Page View)
- UV(Unique Visitor)
- IP 和 UV 的差別
- 并發連接配接數(The number of concurrency)
- 伺服器平均請求等待時間 (Time per request:across all concurrent requests)
同步與異步、阻塞與非阻塞
- 同步與異步:被調用者主動告訴調用者結果
- 阻塞與非阻塞:我是調用者,我調用一個東西以後,結果傳回前,是否還能處理其他事情。
如上圖 在EVENT調用後 有一段等待時間 電腦是不會做其他事情的 直到結果傳回前,此時電腦資源被白白的耗費着。
異步就不同了在發送一個請求後在伺服器響應前 電腦又去處理其他請求了。 就相當于你燒白開水 同步的話你就守在水壺面前什麼也不幹 直到水壺燒開 開關跳掉 但我相信平時你坑定不會這麼做 更多的是異步 燒開水時你去幹别的事等 燒開 等電源跳掉 你聽到了 再去取。
同步:同步異步這裡指的是被調用者(也就是伺服器)的行為,而不是請求方的行為。在沒有得到結果這錢,服務端就不傳回任何結果。
異步:調用在發出之後,服務端立刻傳回,告訴調用方”我收到你的請求了,我會處理的“。
再打個比方 你去借書 問老闆有沒有這本書老闆說 我幫你找找 然後過了一小時你就去問老闆 書有沒有找到 這時同步的一種思想 與此相對的是 當你去問老闆的時候老闆說 我先幫你找找 你留個電話找到了我再打電話給你這就相當于異步 回調了你的電話。
阻塞和非阻塞
- 站線上程狀态的角度
- 站線上程送出請求(通常是HTTP請求)的角度
-
阻塞非阻塞的栗子:燒水壺、買書
還是借書的栗子 如果在你問了老闆之後 你如果去幹了别的事情那這就是非阻塞。當然如果你一直等着老闆 那就是阻塞。
燒開水 同樣也是 你可以在燒毀的同時去看電視 等到 水壺發出 嗚嗚嗚的聲音你再處理。這樣就是異步非阻塞。如果你一直等着 但是等聽到水壺發出嗚嗚嗚 的聲音 你再去處理 這就是 異步阻塞 所謂的異步就是讓被調用者 主動觸發 調用者 來實作而同步與此相反 就是水壺不會發出 嗚嗚嗚 的聲音你必須時不時的去看 這水壺燒開沒有 。