1. 程式人生 > 實用技巧 >java object wait notify notifyAll 的探究

java object wait notify notifyAll 的探究

先列出我的測試程式碼:

 1 public static Object loc=new Object();
 2 
 3     public static void main(String[] args)  throws Exception{
 4 
 5         Thread t1=new Thread(new Runnable() {
 6             @Override
 7             public void run() {
 8                 try {
 9                     java.text.SimpleDateFormat sdf=new
SimpleDateFormat("HH:mm:ss SSS"); 10 System.out.println("["+sdf.format(new Date())+"] t1___等待鎖..."); 11 synchronized (loc) { 12 System.out.println("["+sdf.format(new Date())+"] t1___獲得鎖 ..."); 13 Thread.sleep(5000);
14 System.out.println("["+sdf.format(new Date())+"] t1___loc..開始執行wait..."); 15 loc.wait(); 16 System.out.println("["+sdf.format(new Date())+"] t1___loc..執行wait後續..."); 17 Thread.sleep(1000); 18 }
19 System.out.println("["+sdf.format(new Date())+"] t1___loc..離開鎖..."); 20 }catch (Exception e){ 21 e.printStackTrace(); 22 } 23 } 24 }); 25 Thread t3=new Thread(new Runnable() { 26 @Override 27 public void run() { 28 try { 29 java.text.SimpleDateFormat sdf=new SimpleDateFormat("HH:mm:ss SSS"); 30 System.out.println("["+sdf.format(new Date())+"] t3___等待鎖..."); 31 synchronized (loc) { 32 System.out.println("["+sdf.format(new Date())+"] t3___進入鎖..."); 33 Thread.sleep(5000); 34 System.out.println("["+sdf.format(new Date())+"] t3___loc..開始 wait..."); 35 loc.wait(); 36 System.out.println("["+sdf.format(new Date())+"] t3___loc..執行 wait後續..."); 37 Thread.sleep(1000); 38 } 39 System.out.println("["+sdf.format(new Date())+"] t3___離開鎖..."); 40 }catch (Exception e){ 41 e.printStackTrace(); 42 } 43 } 44 }); 45 46 Thread t2=new Thread(new Runnable() { 47 @Override 48 public void run() { 49 try { 50 java.text.SimpleDateFormat sdf=new SimpleDateFormat("HH:mm:ss SSS"); 51 System.out.println("["+sdf.format(new Date())+"] t2___等待鎖..."); 52 synchronized (loc) { 53 System.out.println("["+sdf.format(new Date())+"] t2___獲得鎖..."); 54 Thread.sleep(5000); 55 System.out.println("["+sdf.format(new Date())+"] t2___loc..開始執行 notify..."); 56 loc.notify(); 57 System.out.println("["+sdf.format(new Date())+"] t2___loc..執行 notify後續..."); 58 Thread.sleep(1000); 59 } 60 System.out.println("["+sdf.format(new Date())+"] t2___loc 離開鎖...."); 61 }catch (Exception e){ 62 e.printStackTrace(); 63 } 64 } 65 }); 66 t1.start(); 67 t3.start(); 68 Thread.sleep(500); 69 t2.start(); 70 71 72 System.out.println("t1___before join ...."); 73 t1.join(); 74 System.out.println("t2___before join ...."); 75 t2.join(); 76 System.out.println("t3____before join ...."); 77 t3.join(); 78 System.out.println("main exit...."); 79 }

執行結果:

[16:55:59 384] t1___等待鎖...
[16:55:59 384] t1___獲得鎖 ...
[16:55:59 384] t3___等待鎖...
t1___before join ....
[16:55:59 836] t2___等待鎖...
[16:56:04 392] t1___loc..開始執行wait...

[16:56:04 392] t2___獲得鎖...
[16:56:09 392] t2___loc..開始執行 notify...
[16:56:09 392] t2___loc..執行 notify後續...
[16:56:10 392] t2___loc 離開鎖....


[16:56:10 392] t3___進入鎖...
[16:56:15 392] t3___loc..開始 wait...
[16:56:15 392] t1___loc..執行wait後續...
[16:56:16 392] t1___loc..離開鎖...
t2___before join ....
t3____before join ....

總結:

1.執行wait後‘’暫時‘ 釋放當前物件鎖給其他執行緒,當前執行緒處於等待狀態

2.syn塊中的wait收到notify通知後 喚醒cpu 然後繼續判斷物件鎖狀態

2.執行notify且當前的物件鎖釋放後 wait等待的執行緒啟用繼續執行