1. 程式人生 > >Java中什麼方法導致執行緒阻塞

Java中什麼方法導致執行緒阻塞

一、為什麼引入執行緒阻塞機制?

為了解決對共享儲存區的訪問衝突,Java 引入了同步機制,現在讓我們來考察多個執行緒對共享資源的訪問,顯然同步機制已經不夠了,因為在任意時刻所要求的資源不一定已經準備好了被訪問,反過來,同一時刻準備好了的資源也可能不止一個。為了解決這種情況下的訪問控制問題,Java 引入了對阻塞機制的支援

阻塞指的是暫停一個執行緒的執行以等待某個條件發生(如某資源就緒),學過作業系統的同學對它一定已經很熟悉了。Java 提供了大量方法來支援阻塞,下面讓我們逐一分析。

二、Java中實現執行緒阻塞的方法:

1)執行緒睡眠:Thread.sleep (long millis)方法,使執行緒轉到阻塞狀態。

millis引數設定睡眠的時間,以毫秒為單位。當睡眠結束後,就轉為就緒(Runnable)狀態。sleep()平臺移植性好。

2)執行緒等待:Object類中的wait()方法,導致當前的執行緒等待,直到其他執行緒呼叫此物件的 notify() 喚醒方法。這個兩個喚醒方法也是Object類中的方法,行為等價於呼叫 wait() 一樣。wait() notify() 方法:兩個方法配套使用wait() 使得執行緒進入阻塞狀態,它有兩種形式,一種允許 指定以毫秒為單位的一段時間作為引數,另一種沒有引數,前者當對應的 notify() 被呼叫或者超出指定時間時執行緒重新進入可執行狀態,後者則必須對應的

notify() 被呼叫.

3)執行緒禮讓,Thread.yield() 方法,暫停當前正在執行的執行緒物件,把執行機會讓給相同或者更高優先順序的執行緒。yield() 使得執行緒放棄當前分得的 CPU 時間,但是不使執行緒阻塞,即執行緒仍處於可執行狀態,隨時可能再次分得 CPU 時間。呼叫 yield() 的效果等價於排程程式認為該執行緒已執行了足夠的時間從而轉到另一個執行緒.

4)執行緒自閉,join()方法,等待其他執行緒終止。在當前執行緒中呼叫另一個執行緒的join()方法,則當前執行緒轉入阻塞狀態,直到另一個程序執行結束,當前執行緒再由阻塞轉為就緒狀態。

5suspend()

resume() 方法:兩個方法配套使用,suspend()使得執行緒進入阻塞狀態,並且不會自動恢復,必須其對應的resume() 被呼叫,才能使得執行緒重新進入可執行狀態。典型地,suspend() resume() 被用在等待另一個執行緒產生的結果的情形:測試發現結果還沒有產生後,讓執行緒阻塞,另一個執行緒產生了結果後,呼叫 resume() 使其恢復。Threadsuspend()resume()兩個方法在JDK1.5中已經廢除,不再介紹。因為有死鎖傾向

這裡,筆者放入一張執行緒生命週期的經典圖片,來幫助讀者理解,裡面展示了一個執行緒從建立->執行->阻塞->執行->死亡的全過程:


三、常用執行緒名詞解釋

主執行緒JVM呼叫程式main()所產生的執行緒。

當前執行緒:這個是容易混淆的概念。一般指通過Thread.currentThread()來獲取的程序。

後臺執行緒:指為其他執行緒提供服務的執行緒,也稱為守護執行緒。JVM的垃圾回收執行緒就是一個後臺執行緒。使用者執行緒和守護執行緒的區別在於,是否等待主執行緒依賴於主執行緒結束而結束

前臺執行緒:是指接受後臺執行緒服務的執行緒,其實前臺後臺執行緒是聯絡在一起,就像傀儡和幕後操縱者一樣的關係。傀儡是前臺執行緒、幕後操縱者是後臺執行緒。由前臺執行緒建立的執行緒預設也是前臺執行緒。可以通過isDaemon()和setDaemon()方法來判斷和設定一個執行緒是否為後臺執行緒。

可見程序:可見程序是指一些不在前臺,但使用者依然可見的程序,舉例來說:各種widget、輸入法等,都屬於visibe。這部分程序雖然不在前臺,但與我們的使用也是密切相關,我們並不希望它被系統終止。

“前臺可見程序服務於後臺空程序”——這是記錄執行緒重要性的口訣,

重要性一次遞減即,前臺程序>可見程序>服務程序>後臺程序>空程序。

執行緒類的一些常用方法

sleep(): 強迫一個執行緒睡眠N毫秒。

isAlive(): 判斷一個執行緒是否存活。

join(): 等待執行緒終止。

activeCount(): 程式中活躍的執行緒數。

enumerate(): 列舉程式中的執行緒。

currentThread(): 得到當前執行緒。

isDaemon(): 一個執行緒是否為守護執行緒。

setDaemon(): 設定一個執行緒為守護執行緒。(使用者執行緒和守護執行緒的區別在於,是否等待主執行緒依賴於主執行緒結束而結束)

setName(): 為執行緒設定一個名稱。

wait(): 強迫一個執行緒等待。

notify(): 通知一個執行緒繼續執行。

setPriority(): 設定一個執行緒的優先順序。

感興趣的讀者可以參考下筆者的另外一篇文章: