1. 程式人生 > >史上最全的多執行緒概述

史上最全的多執行緒概述

程序:資源的分配和排程的一個獨立單元

執行緒:CPU排程的基本單元,存在於程序中,比如微信要接受訊息,傳送訊息,這些子任務就是執行緒。

聯絡:同一個程序中可以包括多個執行緒,並且執行緒共享整個程序的資源(暫存器、堆疊、上下文),一個進行至少包括一個執行緒。

Http請求的執行緒形式:

http請求,到業務處理,再到響應的過程,是在一個執行緒裡面的。一個執行緒由一個方法啟動,但是一個執行緒裡面可以有多個執行緒,並不是每個方法都是一個執行緒,只有當啟動執行緒結束時,該執行緒才終止。 對tomcat來說,每一個進來的請求(request)都需要一個執行緒,直到該請求結束。tomcat會維護一個執行緒池,每一個http請求,會從執行緒池中取出一個空閒執行緒。預設初始化75個執行緒,可以進行修改。

java執行緒排程:

執行緒排程是指系統為執行緒分配處理器使用權的過程,主要排程方式分兩種,分別是協同式執行緒排程和搶佔式執行緒排程。 

協同式執行緒排程:執行緒執行時間由執行緒本身來控制,執行緒把自己的工作執行完之後,要主動通知系統切換到另外一個執行緒上。最大好處是實現簡單,且切換操作對執行緒自己是可知的,沒啥執行緒同步問題。壞處是執行緒執行時間不可控制,如果一個執行緒有問題,可能一直阻塞在那裡。 

搶佔式排程:每個執行緒將由系統來分配執行時間,執行緒的切換不由執行緒本身來決定(Java中,Thread.yield()可以讓出執行時間,但無法獲取執行時間)。執行緒執行時間系統可控,也不會有一個執行緒導致整個程序阻塞。 

Java執行緒排程就是搶佔式排程。 

希望系統能給某些執行緒多分配一些時間,給一些執行緒少分配一些時間,可以通過設定執行緒優先順序來完成。Java語言一共10個級別的執行緒優先順序,在兩執行緒同時處於ready狀態時,優先順序越高的執行緒越容易被系統選擇執行。但優先順序並不是很靠譜,因為Java執行緒是通過對映到系統的原生執行緒上來實現的,所以執行緒排程最終還是取決於作業系統。

補充:

1. 中央處理器,是一塊超大規模的積體電路,是一臺計算機的運算核心和控制核心。 它的工作,主要是解釋計算機中的指令,和處理計算機軟體中的數

據。它在計算機中起著最重要的作用,構成了系統的控制中心,對各個應用程式進行統一協調和控制。

2. java執行緒只能搶佔cpu的執行權,但是無法控制執行時間,即當一個執行緒在執行某一方式時,即使該方法沒有執行完,也即該執行緒沒有執行完,但是系統分配給該執行緒的執行時間已經到了,這時該執行緒獨立的程式計數器,會儲存虛擬機器位元組碼指令地址,當該執行緒重新獲取cpu執行權時,將不會重新開始執行執行緒的所有方法,而是會從該執行緒中的程式計數器中獲取位元組碼指定地址,然後從這裡開始繼續執行。

3. 執行緒在執行I/O時,只有在開始或者結束時需要cpu做一定處理,在執行I/O程式期間,是不需要cpu干預的,換言在,即程式在進行I/O操作時,JVM會將該執行緒設定為阻塞狀態,當I/O處理完畢時,執行緒會重新轉入就緒狀態。

 

單核cpu和多核cpu:

  • 都是一個cpu,不同的是每個cpu上的核心數
  • 多核cpu是多個單核cpu的替代方案,多核cpu減小了體積,同時也減少了功耗
  • 一個核心只能同時執行一個執行緒
  • 所謂的4核8執行緒,4核指的是物理核心。通過超執行緒技術,用一個物理核模擬兩個虛擬核,每個核兩個執行緒,總數為8執行緒。在作業系統看來是8個

核,但是實際上是4個物理核。通過超執行緒技術可以實現單個物理核實現執行緒級別的平行計算,但是比不上效能兩個物理核。

 

執行緒切換:

  • cpu給執行緒分配時間片(也就是分配給執行緒的時間),執行完時間片後會切換都另一個執行緒。
  • 切換之前會儲存執行緒的狀態,下次時間片再給這個執行緒時才能知道當前狀態。
  • 從儲存執行緒A的狀態再到切換到執行緒B時,重新載入執行緒B的狀態的這個過程就叫上下文切換。
  • 而上下切換時會消耗大量的cpu時間。

 

執行緒開銷:

  • 上下文切換消耗
  • 執行緒建立和消亡的開銷
  • 執行緒需要儲存維持執行緒本地棧,會消耗記憶體

 

多執行緒的優點:

1. 使用執行緒可以把佔據時間長的程式中的任務放到後臺去處理

2. 使用者介面更加吸引人,這樣比如使用者點選了一個按鈕去觸發某件事件的處

理,可以彈出一個進度條來顯示處理的進度

3. 程式的執行效率可能會提高

4. 在一些等待的任務實現上如使用者輸入,檔案讀取和網路收發資料等,執行緒就

比較有用了.

 

多執行緒的缺點:

1. 如果有大量的執行緒,會影響效能,因為作業系統需要在它們之間切換.

2. 更多的執行緒需要更多的記憶體空間

3. 執行緒中止需要考慮對程式執行的影響.

4. 通常塊模型資料是在多個執行緒間共享的,需要防止執行緒死鎖情況的發生

 

執行緒的生命週期:

1、新建狀態(New):新建立了一個執行緒物件。

2、就緒狀態(Runnable):執行緒物件建立後,其他執行緒呼叫了該物件的start()方

法。該狀態的執行緒位於可執行執行緒池中,變得可執行,等待獲取CPU的使用

權。

3、執行狀態(Running):就緒狀態的執行緒獲取了CPU,執行程式程式碼。

4、阻塞狀態(Blocked):阻塞狀態是執行緒因為某種原因放棄CPU使用權,暫時

停止執行。直到執行緒進入就緒狀態,才有機會轉到執行狀態。阻塞的情況分

三種:

(一)等待阻塞:執行的執行緒執行wait()方法,JVM會把該執行緒放入等待中。

(二)同步阻塞:執行的執行緒在獲取物件的同步鎖時,若該同步鎖被別的執行緒

佔用,則JVM會把該執行緒放入鎖池中。

(三)其他阻塞:執行的執行緒執行sleep()或join()方法,或者發出了I/O請求

時,JVM會把該執行緒置為阻塞狀態。當sleep()狀態超時、join()等待執行緒

終止或者超時、或者I/O處理完畢時,執行緒重新轉入就緒狀態。

5、死亡狀態(Dead):執行緒執行完了或者因異常退出了run()方法,該執行緒結束生命週期。

resume(),suspend(),stop()方法已經過時了,捨棄不用