1.首先 sleep 方法是Thread類中的靜態方法,他的作用是使當前線程暫時睡眠指定的時間,可以不用放在synchronized方法或者代碼塊中,但是 wait 方法是Object類的方法,它是使當前線程暫時放棄監視對象的使用權進行等待,必須要放在synchronized方法或者代碼塊中
2.調用線程的sleep 方法當前線程會讓出CPU給其他線程執行,但不會釋放鎖,依然占用鎖的使用權,但是 wait方法會釋放鎖。
3.sleep方法到睡眠指定時間后會自動回復到可運行狀態,但是wait方法需要另外一個擁有鎖的對象調用 notify 方法進行喚醒,否則將一直掛起。
驗證代碼如下:
1 package test.main.com; 2 3 public class SleepAndWait { 4 5 6 private static class Thread1 implements Runnable{ 7 @Override 8 public void run() { 9 synchronized (SleepAndWait.class) { 10 System.out.println("thread 1 enter run method..."); 11 System.out.println("thread 1 start waiting..."); 12 try { 13 SleepAndWait.class.wait(); 14 } catch (Exception e) { 15 e.printStackTrace(); 16 } 17 System.out.println("thread 1 ending waiting..."); 18 System.out.println("thread 1 is over..."); 19 } 20 } 21 } 22 23 24 private static class Thread2 implements Runnable{ 25 26 @Override 27 public void run() { 28 synchronized (SleepAndWait.class) { 29 System.out.println("thread 2 enter run method..."); 30 System.out.println("thread 2 sleeping..."); 31 SleepAndWait.class.notifyAll(); 32 33 try { 34 Thread.sleep(10000); 35 } catch (InterruptedException e) { 36 e.printStackTrace(); 37 } 38 39 System.out.println("thread2 is going on...."); 40 System.out.println("thread2 is over!!!"); 41 } 42 } 43 44 } 45 46 public static void main(String[] args) { 47 new Thread(new Thread1()).start(); 48 new Thread(new Thread1()).start(); 49 new Thread(new Thread1()).start(); 50 51 try { 52 System.out.println("main Thread begin sleeping...."); 53 Thread.sleep(8000); 54 System.out.println("main Thread end sleeping...."); 55 } catch (InterruptedException e) { 56 e.printStackTrace(); 57 } 58 59 new Thread(new Thread2()).start(); 60 } 61 62 63 }
說明:雖然Thread2調用了notify,但是由於Thread2調用的是sleep,所以Thread2實際上還是沒有釋放鎖,因此Thread1的Run方法一直拿不到鎖,只有等待Thread2執行完畢以后,Thread1拿到鎖,然后才能繼續執行。