Java線程中yield與join方法的區別

Java線程調度的一點背景

在各類各樣的線程中,Java虛擬機必須實現一個有優先權的、基於優先級的調度程序。這意味着Java程序中的每個線程被分配到必定的優先權,使用定義好的範圍內的一個正整數表示。優先級能夠被開發者改變。即便線程已經運行了必定時間,Java虛擬機也不會改變其優先級java

優先級的值很重要,由於Java虛擬機和下層的操做系統之間的約定是操做系統必須選擇有最高優先權的Java線程運行。因此咱們說Java實現了一個基於優先權的調度程序。該調度程序使用一種有優先權的方式實現,這意味着當一個有更高優先權的線程到來時,不管低優先級的線程是否在運行,都會中斷(搶佔)它。這個約定對於操做系統來講並不老是這樣,這意味着操做系統有時可能會選擇運行一個更低優先級的線程。(我憎恨多線程的這一點,由於這不能保證任何事情)多線程

 

理解線程的優先權

接下來,理解線程優先級是多線程學習很重要的一步,尤爲是瞭解yield()函數的工做過程。函數

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

如今,當咱們對線程調度和線程優先級有必定理解後,讓咱們進入主題。學習

yield()方法

理論上,yield意味着放手,放棄,投降。一個調用yield()方法的線程告訴虛擬機它樂意讓其餘線程佔用本身的位置。這代表該線程沒有在作一些緊急的事情。注意,這僅是一個暗示,並不能保證不會產生任何影響。this

讓咱們列舉一下關於以上定義重要的幾點:spa

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

yield()方法使用示例

在下面的示例程序中,我隨意的建立了名爲生產者和消費者的兩個線程。生產者設定爲最小優先級,消費者設定爲最高優先級。在Thread.yield()註釋和非註釋的狀況下我將分別運行該程序。沒有調用yield()方法時,雖然輸出有時改變,可是一般消費者行先打印出來,而後事生產者。操作系統

調用yield()方法時,兩個線程依次打印,而後將執行機會交給對方,一直這樣進行下去。線程

join()方法

線程實例的方法join()方法可使得一個線程在另外一個線程結束後再執行。若是join()方法在一個線程實例上調用,當前運行着的線程將阻塞直到這個線程實例完成了執行。code

1
2
3
//Waits for this thread to die.
 
public final void join() throws InterruptedException

在join()方法內設定超時,使得join()方法的影響在特定超時後無效。當超時時,主方法和任務線程申請運行的時候是平等的。然而,當涉及sleep時,join()方法依靠操做系統計時,因此你不該該假定join()方法將會等待你指定的時間。blog

像sleep,join經過拋出InterruptedException對中斷作出迴應。

 

 1 package test.core.threads;
 2  
 3 public class JoinExample
 4 {
 5    public static void main(String[] args) throws InterruptedException
 6    {
 7       Thread t = new Thread(new Runnable()
 8          {
 9             public void run()
10             {
11                System.out.println("First task started");
12                System.out.println("Sleeping for 2 seconds");
13                try
14                {
15                   Thread.sleep(2000);
16                } catch (InterruptedException e)
17                {
18                   e.printStackTrace();
19                }
20                System.out.println("First task completed");
21             }
22          });
23       Thread t1 = new Thread(new Runnable()
24          {
25             public void run()
26             {
27                System.out.println("Second task completed");
28             }
29          });
30       t.start(); // Line 15
31       t.join(); // Line 16
32       t1.start();
33    }
34 }
35  
36 Output:
37  
38 First task started
39 Sleeping for 2 seconds
40 First task completed
41 Second task completed
相關文章
相關標籤/搜索