Java 多執行緒基礎(一)基本概念
一、併發與並行
1、併發:
2、並行:
在作業系統中,安裝了多個程式,併發指的是在一段時間內巨集觀上有多個程式同時執行,這在單 CPU 系統中,每一時刻只能有一道程式執行,即微觀上這些程式是分時的交替執行,只不過是給人的感覺是同時執行,那是因為分時交替執行的時間是非常短的。
而在多個 CPU 系統中,則這些可以併發執行的程式便可以分配到多個處理器上(CPU),實現多工並行執行,即利用每個處理器來處理一個可以併發執行的程式,這樣多個程式便可以同時執行。目前電腦市場上說的多核 CPU,便是多核處理器,核 越多,並行處理的程式越多,能大大的提高電腦執行的效率。
3、注意點
單核處理器的計算機肯定是不能並行的處理多個任務的,只能是多個任務在單個CPU上併發執行。同理,執行緒也是一樣的,從巨集觀角度上理解執行緒是並行執行的,但是從微觀角度上分析卻是序列執行的,即一個執行緒一個執行緒的去執行,當系統只有一個CPU時,執行緒會以某種順序執行多個執行緒,我們把這種情況稱之為執行緒排程。
二、執行緒與程式
1、程式:是指一個記憶體中執行的應用程式,每個程式都有一個獨立的記憶體空間,一個應用程式可以同時執行多個程式;程式也是程式的一次執行過程,是系統執行程式的基本單位;系統執行一個程式即是一個程式從建立、執行到消亡的過程。
2、執行緒:執行緒是程式中的一個執行單元,負責當前程式中程式的執行,一個程式中至少有一個執行緒。一個程式中是可以有多個執行緒的,這個應用程式也可以稱之為多執行緒程式。
作業系統排程的最小任務單位是執行緒。常用的Windows、Linux等作業系統都採用搶佔式多工,如何排程執行緒完全由作業系統決定,程式自己不能決定什麼時候執行,以及執行多長時間。
(一)、執行緒的產生
每個程式都有自己的地址空間,即程式空間,在網路或多使用者換機下,一個伺服器通常需要接收大量不確定數量使用者的併發請求,為每一個請求都建立一個程式顯然行不通(系統開銷大響應使用者請求效率低),因此作業系統中執行緒概念被引進。執行緒的改變只代表CPU的執行過程的改變,而沒有發生程式所擁有的資源的變化。
- 執行緒的執行過程是線性的,儘管中間會發生中斷或者暫停,但是程式所擁有的資源只為改線狀執行過程服務,一旦發生執行緒切換,這些資源需要被保護起來。
- 程式分為單執行緒程式和多執行緒程式,單執行緒程式巨集觀來看也是線性執行過程,微觀上只有單一的執行過程。多執行緒程式巨集觀是線性的,微觀上多個執行操作。
(二)、程式與執行緒的區別
- 地址空間。同一執行緒共享該程式的地址空間;程式之間是獨立的地址空間,
- 用於資源。同一程式內的執行緒共享本程式的資源如記憶體、I/O、cpu等,但是程式之間的資源是獨立的。
- 執行過程。每個獨立的程式程有一個程式執行的入口、順序執行序列和程式入口。但是執行緒不能獨立執行,必須依存在應用程式中,由應用程式提供多個執行緒執行控制。
(三)、優缺點
執行緒執行開銷小,但是不利於資源的管理和保護。執行緒適合在SMP機器(雙CPU系統)上執行。程式執行開銷大,但是能夠很好的進行資源管理和保護。程式可以跨機器前移。
(四)、使用場景
對資源的管理和保護要求高,不限制開銷和效率時,使用多程式。
要求效率高,頻繁切換時,資源的保護管理要求不是很高時,使用多執行緒。
三、執行緒的狀態
執行緒共包括以下5種狀態,也叫生命週期。
1. 新建狀態(New) :執行緒物件被建立後,就進入了新建狀態。例如,Thread thread = new Thread()。
2. 就緒狀態(Runnable):也被稱為“可執行狀態”。執行緒物件被建立後,其它執行緒呼叫了該物件的start()方法,從而來啟動該執行緒。例如,thread.start()。處於就緒狀態的執行緒,隨時可能被CPU排程執行。
3. 執行狀態(Running) :執行緒獲取CPU許可權進行執行。需要注意的是,執行緒只能從就緒狀態進入到執行狀態。
4. 阻塞狀態(Blocked) :阻塞狀態是執行緒因為某種原因放棄CPU使用權,暫時停止執行。直到執行緒進入就緒狀態,才有機會轉到執行狀態。阻塞的情況分三種:
① 等待阻塞 -- 通過呼叫執行緒的wait()方法,讓執行緒等待某工作的完成。
② 同步阻塞 -- 執行緒在獲取 synchronized 同步鎖失敗(因為鎖被其它執行緒所佔用),它會進入同步阻塞狀態。
③ 其他阻塞 -- 通過呼叫執行緒的sleep()或join()或發出了I/O請求時,執行緒會進入到阻塞狀態。當sleep()狀態超時、join()等待執行緒終止或者超時、或者I/O處理完畢時,執行緒重新轉入就緒狀態。
5. 死亡狀態(Dead) :執行緒執行完了或者因異常退出了run()方法,該執行緒結束生命週期。