`
xiaoZ5919
  • 浏览: 400416 次
  • 性别: Icon_minigender_1
  • 来自: 安平人@北京
博客专栏
Group-logo
Netty学习笔记
浏览量:72762
社区版块
存档分类
最新评论

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方法


 
当Thread-0执行完毕释放锁,Thread-1开始执行。此时Thread-0消亡


 
 
场景二 两个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!");
            }


 
场景三,回到开始描述的场景,首先notify的线程先进入,wait的后进入。就会导致看似notify不生效。


 


 
看第二张堆栈图,一切就都明白了,注意看waiting on 和waiting to。synchronized和wait()虽然是监控的同一对象,但不是一回事儿。synchronized只有其他线程释放了锁,其他线程才能获得锁,而wait只能由notify唤醒。还原一下整个过程,notify先进入同步语句块,这时wait的wait to lock等待进入。
后来再到执行notify的时候其实是没用的,wait还被阻塞在synchronized之外。再后来退出同步块,带有 wait的语句块进入执行wait操作,就一直waiting on了,此时貌似notify没起到作用。
  • 大小: 11.2 KB
  • 大小: 5.9 KB
  • 大小: 14.7 KB
  • 大小: 10.1 KB
  • 大小: 7.6 KB
0
4
分享到:
评论
2 楼 xiaoZ5919 2013-06-19  
shenzhang722 写道
你说的很对,这个就是wait和notify的一个特性,也就是说如果notify比wait先调用,后面的wait很有可能就不会被唤醒

因此,最好加上一个条件变量,比如boolean shouldWait = true;

synchronized(object) {
    shouldWait = false;
    object.notify();
}


synchronized(object) {
     while (shouldWait) {
         object.wait();
     }
}

好主意
1 楼 shenzhang722 2013-06-19  
你说的很对,这个就是wait和notify的一个特性,也就是说如果notify比wait先调用,后面的wait很有可能就不会被唤醒

因此,最好加上一个条件变量,比如boolean shouldWait = true;

synchronized(object) {
    shouldWait = false;
    object.notify();
}


synchronized(object) {
     while (shouldWait) {
         object.wait();
     }
}

相关推荐

    java笔试题大集合及答案(另附各大公司笔试题)

    例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取。 当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望...

    JAVA面试题集合面试技能大全

    另一种情况就是JAVA允许程序员扩展这种语义检查,程序员可以创建自己的异常,并自由选择在何时用throw关键字引发异常。所有的异常都是java.lang.Thowable的子类。 2. Java的接口和C++的虚类的相同和不同处。 ...

    java 面试题 总结

    error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。 exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。 16、...

    超级有影响力霸气的Java面试题大全文档

     error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。 exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。 19、...

    2009 达内Unix学习笔记

    感觉是同一文件,删除一个,对另一个没有影响;须两个都删除才算删除。 ln -s file1 file1.sln 创建软链接。可跨系统操作,冲破操作权限;也是快捷方式。 八、时间显示 date 显示时间,精确到秒 用法 date [-u]...

    TCPIP详解--共三卷

    6.4.2 另一种方法 55 6.5 ICMP端口不可达差错 56 6.6 ICMP报文的4.4BSD处理 59 6.7 小结 60 第7章 Ping程序 61 7.1 引言 61 7.2 Ping程序 61 7.2.1 LAN输出 62 7.2.2 WAN输出 63 7.2.3 线路SLIP链接 64 7.2.4 拨号...

    进销存系统文档作业例子

    error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。 exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。 16、...

    java面试题

    答:委托就是将方法作为一个参数带入另一个方法叫做委托,事件是一种特殊的委托。 应用程序域? 答:应用程序域可以理解为一种轻量级的进程,起到安全的作用,占用资源小。 Class.forName作用? 答:调用该访问返回...

    外文翻译 stus MVC

    This stateless behavior made it difficult for the model to notify the view of changes. On the Web, the browser has to re-query the server to discover modification to the state of the application. ...

    jsp内置对象的用法

    19 void forward(String relativeUrlPath) 使当前页面重导到另一页面 20 void include(String relativeUrlPath) 在当前位置包含另一文件 9.config对象 config对象是在一个Servlet初始化时,JSP引擎向它传递...

    Java高级程序设计测试含答案.docx

    update() 在线程同步中,为了唤醒另一个等待的线程,使用下列方法 () [单选题] * A.sleep() B.wait() C.notify()(正确答案) D. join() Java高级程序设计测试含答案全文共40页,当前为第4页。Java提供以下哪个...

    TCPIP详解卷[1].part04

    6.4.2 另一种方法 55 6.5 ICMP端口不可达差错 56 6.6 ICMP报文的4.4BSD处理 59 6.7 小结 60 第7章 Ping程序 61 7.1 引言 61 7.2 Ping程序 61 7.2.1 LAN输出 62 7.2.2 WAN输出 63 7.2.3 线路SLIP链接 64 7.2.4 拨号...

    TCPIP详解卷[1].part09

    6.4.2 另一种方法 55 6.5 ICMP端口不可达差错 56 6.6 ICMP报文的4.4BSD处理 59 6.7 小结 60 第7章 Ping程序 61 7.1 引言 61 7.2 Ping程序 61 7.2.1 LAN输出 62 7.2.2 WAN输出 63 7.2.3 线路SLIP链接 64 7.2.4 拨号...

    TCP_IP详解卷1

    6.4.2 另一种方法 55 6.5 ICMP端口不可达差错 56 6.6 ICMP报文的4.4BSD处理 59 6.7 小结 60 第7章 Ping程序 61 7.1 引言 61 7.2 Ping程序 61 7.2.1 LAN输出 62 7.2.2 WAN输出 63 7.2.3 线路SLIP链接 64 7.2.4 拨号...

    TCPIP详解卷[1].part05

    6.4.2 另一种方法 55 6.5 ICMP端口不可达差错 56 6.6 ICMP报文的4.4BSD处理 59 6.7 小结 60 第7章 Ping程序 61 7.1 引言 61 7.2 Ping程序 61 7.2.1 LAN输出 62 7.2.2 WAN输出 63 7.2.3 线路SLIP链接 64 7.2.4 拨号...

    TCPIP详解卷[1].part06

    6.4.2 另一种方法 55 6.5 ICMP端口不可达差错 56 6.6 ICMP报文的4.4BSD处理 59 6.7 小结 60 第7章 Ping程序 61 7.1 引言 61 7.2 Ping程序 61 7.2.1 LAN输出 62 7.2.2 WAN输出 63 7.2.3 线路SLIP链接 64 7.2.4 拨号...

    TCP/IP详解part_2

    6.4.2 另一种方法 55 6.5 ICMP端口不可达差错 56 6.6 ICMP报文的4.4BSD处理 59 6.7 小结 60 第7章 Ping程序 61 7.1 引言 61 7.2 Ping程序 61 7.2.1 LAN输出 62 7.2.2 WAN输出 63 7.2.3 线路SLIP链接 64 7.2.4 拨号...

    TCPIP详解卷[1].part08

    6.4.2 另一种方法 55 6.5 ICMP端口不可达差错 56 6.6 ICMP报文的4.4BSD处理 59 6.7 小结 60 第7章 Ping程序 61 7.1 引言 61 7.2 Ping程序 61 7.2.1 LAN输出 62 7.2.2 WAN输出 63 7.2.3 线路SLIP链接 64 7.2.4 拨号...

    TCPIP详解卷[1].part11

    6.4.2 另一种方法 55 6.5 ICMP端口不可达差错 56 6.6 ICMP报文的4.4BSD处理 59 6.7 小结 60 第7章 Ping程序 61 7.1 引言 61 7.2 Ping程序 61 7.2.1 LAN输出 62 7.2.2 WAN输出 63 7.2.3 线路SLIP链接 64 7.2.4 拨号...

    TCPIP详解卷[1].part12

    6.4.2 另一种方法 55 6.5 ICMP端口不可达差错 56 6.6 ICMP报文的4.4BSD处理 59 6.7 小结 60 第7章 Ping程序 61 7.1 引言 61 7.2 Ping程序 61 7.2.1 LAN输出 62 7.2.2 WAN输出 63 7.2.3 线路SLIP链接 64 7.2.4 拨号...

Global site tag (gtag.js) - Google Analytics