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 继续判断锁状态
3. 执行notify且当前的对象锁释放后 wait等待的线程激活
4. notifyAll 是一次唤醒所有的wait