wait和notify在鎖競爭中的執行順序

峻峰飛陽發表於2015-12-28

sleep就是正在執行的執行緒主動讓出cpu,cpu去執行其他執行緒,在sleep指定的時間過後,cpu才會回到這個執行緒上繼續往下執行,如果當前執行緒進入了同步鎖,sleep方法並不會釋放鎖,即使當前執行緒使用sleep方法讓出了cpu,但其他被同步鎖擋住了的執行緒也無法得到執行。wait是指在一個已經進入了同步鎖的執行緒內,讓自己暫時讓出同步鎖,以便其他正在等待此鎖的執行緒可以得到同步鎖並執行,只有其他執行緒呼叫了notify方法(notify並不釋放鎖,只是告訴呼叫過wait方法的執行緒可以去參與獲得鎖的競爭了,但不是馬上得到鎖,因為鎖還在別人手裡,別人還沒釋放。如果notify方法後面的程式碼還有很多,需要這些程式碼執行完後才會釋放鎖,可以在notfiy方法後增加一個等待和一些程式碼,看看效果),呼叫wait方法的執行緒就會解除wait狀態和程式可以再次得到鎖後繼續向下執行。

[java] view plaincopy
  1. public class MultiThread {  
  2.     /** 
  3.      * @param args 
  4.      */  
  5.     public static void main(String[] args) {  
  6.         new Thread(new Thread1()).start();  
  7.         try {  
  8.             Thread.sleep(10);  
  9.         } catch (InterruptedException e) {  
  10.             e.printStackTrace();  
  11.         }  
  12.         new Thread(new Thread2()).start();  
  13.     }  
  14.   
  15.     private static class Thread1 implements Runnable {  
  16.   
  17.         @Override  
  18.         public void run() {  
  19.             // 由於這裡的Thread1和下面的Thread2內部run方法要用同一物件作為監視器,我們這裡不能用this,因為在Thread2裡面的this和這個Thread1的this不是同一個物件。我們用MultiThread.class這個位元組碼物件,當前虛擬機器裡引用這個變數時,指向的都是同一個物件。  
  20.             synchronized (MultiThread.class) {  
  21.   
  22.                 System.out.println("enter thread1...");  
  23.                 System.out.println("thread1 is waiting");  
  24.                 try {  
  25.                     // 釋放鎖有兩種方式,第一種方式是程式自然離開監視器的範圍,也就是離開了synchronized關鍵字管轄的程式碼範圍,另一種方式就是在synchronized關鍵字管轄的程式碼內部呼叫監視器物件的wait方法。這裡,使用wait方法釋放鎖。  
  26.                     MultiThread.class.wait();  
  27.                 } catch (InterruptedException e) {  
  28.                     e.printStackTrace();  
  29.                 }  
  30.   
  31.                 System.out.println("thread1 is going on...");  
  32.                 System.out.println("thread1 is being over!");  
  33.             }  
  34.         }  
  35.   
  36.     }  
  37.   
  38.     private static class Thread2 implements Runnable {  
  39.   
  40.         @Override  
  41.         public void run() {  
  42.             synchronized (MultiThread.class) {  
  43.   
  44.                 System.out.println("enter thread2...");  
  45.                 System.out.println("thread2 notify other thread can release wait status..");  
  46.                 // 由於notify方法並不釋放鎖,  
  47.                 // 即使thread2呼叫下面的sleep方法休息了10毫秒,但thread1仍然不會執行,因為thread2沒有釋放鎖,所以Thread1無法得不到鎖。  
  48.                 //notify並不釋放鎖,只是告訴呼叫過wait方法的執行緒可以去參與獲得鎖的競爭了,但不是馬上得到鎖,因為鎖還在別人手裡,別人還沒釋放。如果notify方法後面的程式碼還有很多,需要這些程式碼執行完後才會釋放鎖  
  49.                 MultiThread.class.notify();  
  50.                 System.out.println("thread2 is sleeping ten millisecond...");  
  51.                 try {  
  52.                     Thread.sleep(10);  
  53.                 } catch (InterruptedException e) {  
  54.                     e.printStackTrace();  
  55.                 }  
  56.                 System.out.println("thread2 is going on...");  
  57.                 System.out.println("thread2 is being over!");  
  58.             }  
  59.         }  
  60.   
  61.     }  
  62.     /** 
  63.      * 執行結果: 
  64.      *  enter thread1... 
  65.         thread1 is waiting 
  66.         enter thread2... 
  67.         thread2 notify other thread can release wait status.. 
  68.         thread2 is sleeping ten millisecond... 
  69.         thread2 is going on... 
  70.         thread2 is being over! 
  71.         thread1 is going on... 
  72.         thread1 is being over! 
  73.      */  
  74. }  


相關文章