wait()和notify()
package concurrent._wait_notify; public class Demo1 { public static void main(String[] args) throws InterruptedException { ThreadA a = new ThreadA("A"); synchronized (a){ System.out.println("开始主线程睡眠3000ms"); Thread.sleep(3000); System.out.println("启动a"); a.start(); System.out.println("开始主线程睡眠5000ms"); Thread.sleep(5000); System.out.println("主线程wait"); a.wait(); System.out.println("主线程刚从阻塞队列出来,马上结束了"); } } } class ThreadA extends Thread{ public ThreadA(String name){ super(name); } @Override public void run() { System.out.println("尝试获得this锁"); synchronized (this){ System.out.println("获得了this锁,准备notify"); this.notify(); System.out.println("notify()成功"); } } }
结果:
开始主线程睡眠3000ms
启动a
开始主线程睡眠5000ms
尝试获得this锁
主线程wait
获得了this锁,准备notify
notify()成功
主线程马上结束了
修改代码:
package concurrent._wait_notify; public class Demo2 { public static void main(String[] args) throws InterruptedException { Object obj = new Object(); ThreadB b1 = new ThreadB("b1",obj); ThreadB b2 = new ThreadB("b2",obj); ThreadB b3 = new ThreadB("b3",obj); b1.start(); b2.start(); b3.start(); Thread.sleep(1000); synchronized (obj){ obj.notifyAll(); } } } class ThreadB extends Thread{ private Object obj; public ThreadB(String name,Object obj){ super(name); this.obj = obj; } @Override public void run() { String threadName = this.getName(); System.out.println(threadName +"尝试获得obj锁"); synchronized (obj){ try { System.out.println(threadName+"获得了obj锁,进入wait"); obj.wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(threadName+"从wait出来了"); } } }
结果:
b2尝试获得obj锁
b2获得了obj锁,进入wait
b3尝试获得obj锁
b3获得了obj锁,进入wait
b1尝试获得obj锁
b1获得了obj锁,进入wait
b1从wait出来了
b3从wait出来了
b2从wait出来了
再次修改代码将Thread.sleep(1000)注释掉
结果显示:
b1尝试获得obj锁
b1获得了obj锁,进入wait
b2尝试获得obj锁
b3尝试获得obj锁
Main函数获得了锁,进行notifyAll操作
b1从wait出来了
b3获得了obj锁,进入wait
b2获得了obj锁,进入wait
这个结果就是,获得锁的顺序是,b1,main,b2,b3。(打印顺序,不能反映cpu获得锁的顺序,只能说明打印的顺序)
当main函数执行完成notifyAll()之后,b1从阻塞队列出来,结束运行,这时候b2,b3再次进入阻塞状态,但是却没有别的进程将他们唤醒,就会一直阻塞。
notify操作,实际上是释放基于某个锁上面的wait的线程,是根据锁来释放的。
wait操作是让当前在cpu运行的线程,基于某个锁上wait,便于基于某个锁上唤醒。
文章参考博客:
http://www.cnblogs.com/xingele0917/p/3979494.html