1. 程式人生 > >Java中sleep()與wait()區別

Java中sleep()與wait()區別

學習時正好碰到這兩個方法,就查閱相關資料,並通過程式實現,進行區別一下:

1、每個物件都有一個鎖來控制同步訪問,Synchronized關鍵字可以和物件的鎖互動,來實現同步方法或同步塊。sleep()方法正在執行的執行緒主動讓出CPU(然後CPU就可以去執行其他任務),在sleep指定時間後CPU再回到該執行緒繼續往下執行(注意:sleep方法只讓出了CPU,而並不會釋放同步資源鎖!!!);wait()方法則是指當前執行緒讓自己暫時退讓出同步資源鎖,以便其他正在等待該資源的執行緒得到該資源進而執行,只有呼叫了notify()方法,之前呼叫wait()的執行緒才會解除wait狀態,可以去參與競爭同步資源鎖,進而得到執行。(注意:notify的作用相當於叫醒睡著的人,而並不會給他分配任務,就是說notify只是讓之前呼叫wait的執行緒有權利重新參與執行緒的排程

);

2、sleep()方法可以在任何地方使用;wait()方法則只能在同步方法或同步塊中使用;

3、sleep()是執行緒執行緒類(Thread)的方法,呼叫會暫停此執行緒指定的時間,但監控依然保持,不會釋放物件鎖,到時間自動恢復;wait()是Object的方法,呼叫會放棄物件鎖,進入等待佇列,待呼叫notify()/notifyAll()喚醒指定的執行緒或者所有執行緒,才會進入鎖池,不再次獲得物件鎖才會進入執行狀態;

以程式說明:

  1. publicclass MultiThread {  
  2.     privatestaticclass Thread1 implements Runnable{         
  3.         @Override
  4.         publicvoid run() {  
  5.             //由於 Thread1和下面Thread2內部run方法要用同一物件作為監視器,如果用this則Thread1和Threa2的this不是同一物件
  6.             //所以用MultiThread.class這個位元組碼物件,當前虛擬機器裡引用這個變數時指向的都是同一個物件
  7.             synchronized(MultiThread.class){  
  8.                 System.out.println("enter thread1 ...");  
  9.                 System.out.println("thread1 is waiting"
    );  
  10.                 try{  
  11.                     //釋放鎖有兩種方式:(1)程式自然離開監視器的範圍,即離開synchronized關鍵字管轄的程式碼範圍
  12.                     //(2)在synchronized關鍵字管轄的程式碼內部呼叫監視器物件的wait()方法。這裡使用wait方法
  13.                     MultiThread.class.wait();  
  14.                 }catch(InterruptedException e){  
  15.                     e.printStackTrace();  
  16.                 }  
  17.                 System.out.println("thread1 is going on ...");  
  18.                 System.out.println("thread1 is being over!");  
  19.             }  
  20.         }  
  21.     }  
  22.     privatestaticclass Thread2 implements Runnable{  
  23.         @Override
  24.         publicvoid run() {   
  25.             //notify方法並不釋放鎖,即使thread2呼叫了下面的sleep方法休息10ms,但thread1仍然不會執行
  26.             //因為thread2沒有釋放鎖,所以Thread1得不到鎖而無法執行
  27.             synchronized(MultiThread.class){  
  28.                 System.out.println("enter thread2 ...");  
  29.                 System.out.println("thread2 notify other thread can release wait status ...");  
  30.                 MultiThread.class.notify();  
  31.                 System.out.println("thread2 is sleeping ten millisecond ...");  
  32.                 try{  
  33.                     Thread.sleep(10);  
  34.                 }catch(InterruptedException e){  
  35.                     e.printStackTrace();  
  36.                 }  
  37.                 System.out.println("thread2 is going on ...");  
  38.                 System.out.println("thread2 is being over!");  
  39.             }  
  40.         }         
  41.     }  
  42.     publicstaticvoid main(String[] args) {  
  43.         new Thread(new Thread1()).start();  
  44.         try{  
  45.             Thread.sleep(10);  
  46.         }catch(InterruptedException e){  
  47.             e.printStackTrace();  
  48.         }  
  49.         new Thread(new Thread2()).start();  
  50.     }  
  51. }  

程式執行結果如下圖所示