Java每日一題之Thread的yield和join方法區別

  • 2020 年 2 月 13 日
  • 筆記

Java每日一題之Thread的yield和join方法區別

  • 1.Java執行緒調度的一點背景
  • 2.理解執行緒的優先權
  • 3.yield()方法
  • 4.join()方法

1.Java執行緒調度的一點背景

在各種各樣的執行緒中,Java虛擬機必須實現一個有優先權的、基於優先順序的調度程式。這意味著Java程式中的每一個執行緒被分配到一個優先權,使用定義好的範圍內的一個正整數表示。優先順序可以被開發者改變。即使執行緒已經運行了一定時間,Java虛擬機也不會改變其優先順序。 優先順序的值很重要,因為Java虛擬機和下層的作業系統之間的約定是作業系統必須選擇有最高優先權的Java執行緒運行。所以我們說Java實現了一個基於優先權的調度程式。該調度程式使用一種有優先權的方式實現,這意味著當一個有更高優先權的執行緒到來時,無論低優先順序的執行緒是否在運行,都會中斷(搶佔)它。這個約定對於作業系統來說並不總是這樣,這意味著作業系統有時可能會選擇運行一個更低優先順序的執行緒。 注意 : Java並不限定執行緒是以時間片運行,但是大多數作業系統卻有這樣的要求。在術語中經常引起混淆 :搶佔經常與時間片混淆。事實上,搶佔意味著只有擁有高優先順序的執行緒可以優先於低優先順序的執行緒執行,但是當執行緒擁有相同優先順序的時候,他們不能相互搶佔。它們通常受時間片管制,但這並不是Java的要求。

2.理解執行緒的優先權

接下來,理解執行緒優先順序是多執行緒學習很重要的一步,尤其是了解yieid()函數的工作過程。

  1. 記住當執行緒的優先順序沒有指定時,所有執行緒都攜帶普通優先順序。
  2. 優先順序可以用從1到10的範圍指定。10表示最高優先順序,1表示最低優先順序,5是普通優先順序。
  3. 記住優先順序最高的執行緒在執行時被給予優先。但是不能保證執行緒在啟動時就進入運行狀態。
  4. 與在執行緒池中等待運行機會的執行緒相比,當前正在運行的執行緒可能總是擁有更高的優先順序。
  5. 由調度程式決定哪一個執行緒被執行。
  6. t.setPriority()用來設定執行緒的優先順序。
  7. 記住在執行緒開始方法被調用之前,執行緒的優先順序應該被設定。
  8. 你可以使用常量,如MIN_PRIORITY、MAX_PRIORITY、NORM_PRIORITY來設定優先順序

3.yield()方法

理論上,yield意味著放手,放棄,投降。一個調用yield()方法的執行緒告訴虛擬機它樂意讓其他執行緒佔用自己的位置。這表明該執行緒沒有在做一些緊急的事情。注意,這僅是一個暗示,並不能保證不會產生任何影響。 在Thread.java中yield()定義重要的幾點 :

  1. Yield是一個靜態的原生(native)方法。
  2. Yield告訴當前正在執行的執行緒把運行機會交給執行緒池中擁有相同優先順序的執行緒。
  3. Yield不能保證使得當前正在運行的執行緒迅速轉換到可運行的狀態。
  4. 它僅能使一個執行緒從運行狀態轉到可運行狀態,而不是等待或阻塞狀態。

4.join()方法

把指定的執行緒加入到當前執行緒,可以將兩個交替執行的執行緒合併為順序執行的執行緒。 比如在B執行緒中執行執行緒A的join方法,a.join(),那麼B執行緒就會暫停執行,先等A執行緒執行完畢,B執行緒再重新進入可運行狀態。join方法中還可以設置時間a.join(1000),這樣就讓A執行規定時間。在A執行緒執行過程中,如果還有其他執行緒,其他執行緒不受影響,會和A執行緒一起進行,知道A執行緒執行結束,B執行緒重新加入。