java執行緒

朱智文發表於2015-10-26

呼叫thread.start()方法,是讓執行緒處於可執行狀態

讓執行緒暫時離開執行狀態的三中方法:

1、呼叫執行緒的sleep()方法,使執行緒睡眠一段時間

2、呼叫執行緒的yield()方法,使執行緒暫時回到可執行狀態,來使其他執行緒有機會執行。

3、呼叫執行緒的join()方法,使當前執行緒停止執行,知道當前執行緒中加入的執行緒執行完畢後,當前執行緒才可以執行。


理解 執行緒的yield()方法:讓一個執行的執行緒,執行緒鎖,處於可執行狀態

1:執行緒讓出處理器資源,讓處理器執行其他執行緒(也包括再次執行當前執行緒,jvm是隨機選擇可執行執行緒的)

2:讓執行緒由執行狀態轉到可執行狀態

3:JVM的排程程式隨機選擇處於可執行狀態的執行緒來執行,此時可能有兩種執行過程:(1)選擇一個執行緒執行,直到此執行緒阻塞或者執行到死亡。(2)時間分片機制,為執行緒池中的每個執行緒都提供均勻的執行機會。

理解 執行緒的 sleep()方法:讓當前執行的執行緒,處於睡眠,時間過後處於可執行狀態,在此期間不釋放執行緒鎖

、1執行緒處於睡眠狀態時,JVM排程程式會暫停此執行緒的執行並來執行其他的處於可執行狀態的執行緒。

2:Thread .sleep() 的作用是使當前執行的執行緒處於睡眠狀態,而不是Thread物件(sleep,是Thread類的靜態方法)


理解:執行緒的join()(非靜態方法):讓一個執行緒b 加入到執行緒A的尾部,等執行緒A,執行完畢後再繼續執行,

1:相當於:一個B方法裡在執行A方法,A方法結束後,繼續執行B未執行完的程式碼

2:main執行緒只等1000毫秒,不管T什麼時候結束.


  1. public class JoinTest implements Runnable{  
  2.       
  3.     public static int a = 0;  
  4.   
  5.     public void run() {  
  6.         for (int k = 0; k < 5; k++) {  
  7.             a = a + 1;  
  8.         }  
  9.     }  
  10.   
  11.     public static void main(String[] args) throws Exception {  
  12.         Runnable r = new JoinTest();  
  13.         Thread t = new Thread(r);  
  14.         t.start();        
  15.         System.out.println(a);  
  16.     }         
  17. }  
 請問程式的輸出結果是5嗎?答案是:有可能。其實你很難遇到輸出5的時候,通常情況下都不是5。當然這也和機器有嚴重的關係。為什麼呢?我的解釋是當主執行緒main方法執行System.out.println(a);這條語句時,執行緒還沒有真正開始執行,或許正在為它分配資源準備執行。因為為執行緒分配資源需要時間,而main方法執行完t.start()方法後繼續往下執行System.out.println(a);,這個時候得到的結果是a還沒有被改變的值0,怎樣才能讓輸出結果為5!其實很簡單,join() 方法提供了這種功能。join() 方法,它能夠使呼叫該方法的執行緒在此之前執行完畢。
Java程式碼  收藏程式碼
  1. public static void main(String[] args) throws Exception {  
  2.         Runnable r = new JoinTest();  
  3.         Thread t = new Thread(r);  
  4.         t.start();        
  5.         t.join(); //加入join()  
  6.         System.out.println(a);  
  7.     }     

 這個時候,程式輸入結果始終為5。

為了證明如果不使用t.join()方法,主執行緒main方法的System.out.println(a);語句將搶先執行,我們可以在main方法中加入一個迴圈,這個迴圈用來延長main方法執行的時間,迴圈次數將嚴重取決於機器效能。如果迴圈次數得當,我們也可以看到a的輸出結果是5。

Java程式碼  收藏程式碼
  1. public static void main(String[] args) throws Exception {  
  2.         Runnable r = new JoinTest();  
  3.         Thread t = new Thread(r);  
  4.         t.start();        
  5.         //t.join(); //加入join()  
  6.             /* 
  7.              注意迴圈體內一定要有實際執行語句,否則編譯器或JVM可能優化掉你的這段程式碼,視這段代 
  8.              碼為無效。             
  9.             */  
  10.             for (int i=0; i<300; i++) {                
  11.                 System.out.print(i);  
  12.             }  
  13.             System.out.println();  
  14.         System.out.println(a);  
  15.     }         

 經自己測試,最後a一直是5.

synchronized (thread),獲取執行緒物件t的鎖,並Sleep(9000)後釋放,這就意味著,即使
main方法t.join(1000),等待一秒鐘,它必須等待ThreadTest 執行緒釋放t鎖後才能進入wait方法中,它實際等待時間是9000+1000 MS

其實Join方法實現是通過wait(小提示:Object 提供的方法)。 當main執行緒呼叫t.join時候,main執行緒會獲得執行緒物件t的鎖(wait 意味著拿到該物件的鎖),呼叫該物件的wait(等待時間),直到該物件喚醒main執行緒,比如退出後。




每個執行緒都有一個執行緒棧


相關文章