java object wait notify notifyAll 的探究
阿新 • • 發佈:2020-11-04
先列出我的測試程式碼:
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=newSimpleDateFormat("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等待的執行緒啟用繼續執行