wait-notify的另一种情况

阅读更多
wait-notify用在经典的生产者-消费者模型。一般代码都是先初始化consumer,然后再初始化producer,程序正常运行。这是带有wait()先进入同步语句块,带有notifyAll()的后进入同步语句块。现在反过来带有notifyAll()先进入同步语句块,儿带有wait()的后进入语句块,这时候程序会一直阻塞,觉得很蹊跷,带着这个对synchronized,wait,notify又深入研究了一番。有一些结论和大家分享一下,首先来看synchronized,这个大家都很清楚,相当于排他锁谁先持有,其他线程必须得等待直到释放。依据这样的结论,
场景一 两个线程同时执行synchronized语句块,肯定只有一个线程成功,而另外一个阻塞。
下面的代码验证了结论:
            synchronized (lock) {
//                    for(int i = 0; i < 1000000;i++);
//                lock.notify();
                try {
                    Thread.sleep(50000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "notify other!");
            }
Thread-1被synchronized阻塞,Thread-0进入语句块执行sleep方法

wait-notify的另一种情况_第1张图片
 
当Thread-0执行完毕释放锁,Thread-1开始执行。此时Thread-0消亡

wait-notify的另一种情况_第2张图片
 
 
场景二 两个synchronized块中执行wait()的线程,会先后进入语句块,而不是其中一个等待另外一个执行完毕以后再进入。为什么会这样呢?我又重新看了一下jdk的comment发现,The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another thread
 notifies threads waiting on this object's monitor to wake up。wait首先释放同步语句块的锁,再执行wait,此时其他线程就能进入了。
  synchronized (lock) {
//                    for(int i = 0; i < 1000000;i++);
//                lock.notify();
                try {
                    Thread.sleep(50000);
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "notify other!");
            }

wait-notify的另一种情况_第3张图片
 
场景三,回到开始描述的场景,首先notify的线程先进入,wait的后进入。就会导致看似notify不生效。

wait-notify的另一种情况_第4张图片
 

wait-notify的另一种情况_第5张图片
 
看第二张堆栈图,一切就都明白了,注意看waiting on 和waiting to。 synchronized和wait()虽然是监控的同一对象,但不是一回事儿。 synchronized只有其他线程释放了锁,其他线程才能获得锁,而wait只能由notify唤醒。还原一下整个过程,notify先进入同步语句块,这时wait的wait to lock等待进入。
后来再到执行notify的时候其实是没用的,wait还被阻塞在 synchronized之外。再后来退出同步块,带有 wait的语句块进入执行wait操作,就一直waiting on了,此时貌似notify没起到作用。
  • wait-notify的另一种情况_第6张图片
  • 大小: 11.2 KB
  • wait-notify的另一种情况_第7张图片
  • 大小: 5.9 KB
  • wait-notify的另一种情况_第8张图片
  • 大小: 14.7 KB
  • wait-notify的另一种情况_第9张图片
  • 大小: 10.1 KB
  • wait-notify的另一种情况_第10张图片
  • 大小: 7.6 KB
  • 查看图片附件

你可能感兴趣的:(wait-notify的另一种情况)