1. 程式人生 > >java執行緒基礎

java執行緒基礎

(1)    建立:繼承Thread類與實現Runnable介面

(2)    stop()不安全,會解除由執行緒獲取的所有鎖定

(3)    suspend()易發生死鎖,目標執行緒會停止,卻仍持有在這之前獲得的鎖定。

不應該使用suspend(),而應在自己的Thread類中置入一個標誌,指出執行緒應該活動還是掛起。若標誌指出執行緒應該掛起,便用wait()命其進入等待狀態。若標誌指出執行緒應當恢復,則用一個notify()重新啟動執行緒。

(4)  sleep():正在執行的執行緒主動讓出cpucpu去執行其他執行緒,在sleep指定的時間過後,cpu才會回到這個執行緒上繼續往下執行,如果當前執行緒進入了同步鎖,

sleep方法並不會釋放鎖,即使當前執行緒使用sleep方法讓出了cpu,但其他被同步鎖擋住了的執行緒也無法得到執行。

sleep是執行緒類(Thread)的方法,呼叫sleep不會釋放物件鎖。

(5)  wait():指在一個已經進入了同步鎖的執行緒內,讓自己暫時讓出同步鎖,以便其他正在等待此鎖的執行緒可以得到同步鎖並執行,只有其他執行緒呼叫了notify方法,呼叫wait方法的執行緒就會解除wait狀態和程式可以再次得到鎖後繼續向下執行。waitObject類的方法,對此物件呼叫wait方法導致本執行緒放棄物件鎖,進入等待此物件的等待鎖定池,只有針對此物件發出notify方法(或notifyAll

)後本執行緒才進入物件鎖定池準備獲得物件鎖進入執行狀態。

(6) 使用執行緒是如何防止出現大的波峰。
意思是如何防止同時產生大量的執行緒,方法是使用執行緒池,執行緒池具有可以同時提高排程效率和限制資源使用的好處,執行緒池中的執行緒達到最大數時,其他執行緒就會排隊等候。

(7) 程式什麼時候應該使用執行緒,什麼時候單執行緒效率高。

耗時的操作使用執行緒,提高應用程式響應
並行操作時使用執行緒,如C/S架構的伺服器端併發執行緒響應使用者的請求。

多CPU系統中,使用執行緒提高CPU利用率
改善程式結構。一個既長又複雜的程序可以考慮分為多個執行緒,成為幾個獨立或半獨立的執行部分,這樣的程式會利於理解和修改。
其他情況都使用單執行緒。

(8) 執行緒同步,併發操作

在方法名前加關鍵字syschronized來處理多個執行緒同時訪問共享資源。syschronized相當於一把鎖,當有申請者申請該資源時,如果該資源沒有被佔用,那麼將資源交付給這個申請者使用,在此期間,其他申請者只能申請而不能使用該資源,當該資源被使用完成後將釋放該資源的鎖,其他申請者可申請使用。

併發控制主要是為了多執行緒操作時帶來的資源讀寫問題。如果不加以空間可能會出現死鎖,讀髒資料、不可重複讀、丟失更新等異常。

併發操作可以通過加鎖的方式進行控制,鎖又可分為樂觀鎖和悲觀鎖。

悲觀鎖:併發模式假定系統中存在足夠多的資料修改操作,以致於任何確定的讀操作都可能會受到由個別的使用者所製造的資料修改的影響。也就是說悲觀鎖假定衝突總會發生,通過獨佔正在被讀取的資料來避免衝突。但是獨佔資料會導致其他程序無法修改該資料,進而產生阻塞,讀資料和寫資料會相互阻塞。

樂觀鎖:假定系統的資料修改只會產生非常少的衝突,也就是說任何程序都不大可能修改別的程序正在訪問的資料。樂觀併發模式下,讀資料和寫資料之間不會發生衝突,只有寫資料與寫資料之間會發生衝突。即讀資料不會產生阻塞,只有寫資料才會產生阻塞。

(9)  執行緒安全定義:

當多個執行緒訪問一個類時,如果不用考慮這些執行緒在執行時環境下的排程和交替執行,並且不需要額外的同步及在呼叫方程式碼不必做其他的協調,這個類的行為仍然是正確的,那麼這個類就被稱之為是執行緒安全的。簡言之對於執行緒安全類的例項進行順序或併發的一系列操作,都不會導致例項處於無效狀態。

只有物件狀態可變,且存在物件共享,才需要考慮執行緒安全。

可以通過下面的方法來確保執行緒安全:

l 無狀態物件:

無狀態物件不包含域也沒有引用其他類的域,一次特定計算的瞬時狀態只會唯一存在本地變數中,這些本地變數儲存線上程的棧中,只有執行執行緒才能訪問,因此無狀態物件永遠是執行緒安全的。

l 不可變物件:

不可變物件需要滿足下面條件:

A.物件本身是final的(避免被子類化),所有域都是final型別。

B.不可變物件的狀態在建立後就不能再改變,每次對他們的改變都是產生了新的不可變物件的物件。

C.不可變物件能被正確地建立(在建立過程中沒有發生this引用逸出)。

不可變物件是執行緒安全的,不需要任何同步或鎖的機制就可以保證安全地在多執行緒之間共享。

l 原子變數:

介紹原子變數前首先介紹原子操作,假設有操作A和B,如果從執行A的角度看,當其他執行緒執行B時,要麼全部執行完成,要麼一點都沒有執行,這樣A和B互為原子操作,不滿足原子操作要求的操作被稱為複合操作,原子操作是執行緒安全的。

JDK的java.util.concurrent.atomic包中包括了原子變數類,這些類用來實現數字和物件引用的原子狀態轉換。

原子變數自身是執行緒安全的,但是如果一個不變約束涉及多個變數時,變數間不是彼此獨立的,無論這些變數是否是原子變數都不能確保執行緒安全,而需要在同一個原子操作中更新這些相互關聯的狀態變數才能確保執行緒安全。

l 正確使用執行緒同步:

通過使用synchronized關鍵字獨佔鎖、顯式鎖、volatile等同步機制實現的相對執行緒安全。

(10) 執行緒的四種狀態

A.新狀態:執行緒已被建立但尚未執行(start() 尚未被呼叫)。

B.可執行狀態:執行緒可以執行,雖然不一定正在執行。CPU 時間隨時可能被分配給該執行緒,從而使得它執行。

C.死亡狀態:正常情況下 run() 返回使得執行緒死亡。呼叫 stop()或 destroy() 亦有同樣效果,但是不被推薦,前者會產生異常,後者是強制終止,不會釋放鎖。

D.阻塞狀態:執行緒不會被分配 CPU 時間,無法執行。

(11) 執行緒的優先順序

  執行緒的優先順序代表該執行緒的重要程度,當有多個執行緒同時處於可執行狀態並等待獲得CPU 時間時,執行緒排程系統根據各個執行緒的優先順序來決定給誰分配 CPU 時間,優先順序高的執行緒有更大的機會獲得 CPU 時間,優先順序低的執行緒也不是沒有機會,只是機會小一些。

可以呼叫 Thread 類的方法 getPriority() 和 setPriority()來存取執行緒的優先順序,執行緒的優先順序界於1(MIN_PRIORITY)和10(MAX_PRIORITY)之間,預設是5(NORM_PRIORITY)