ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java线程间通讯——等待通知机制及其经典范式

2021-10-31 23:33:00  阅读:179  来源: 互联网

标签:范式 对象 通知 线程 Java 多线程 等待 wait


  等待/通知的相关方法是任意Java对象都具备的,因为这些方法被定义在所有对象的超类java.lang.Object上:
    

  等待/通知机制,是指一个线程A调用了对象O的wait()方法进入等待状态,而另一个线程B调用了对象O的notify()或者notifyAll()方法,线程A收到通知后从对象O的wait()方法返回,进而执行后续操作。上述两个线程通过对象O来完成交互,而对象上的wait()和notify/notifyAll()的关系就如同开关信号一样,用来完成等待方和通知方之间的交互工作。

  先看单线程使用该机制:

  

  通过实践结果看,生成一个消费一个。

  再看多线程:

    

   再执行一次:

    

   多线程每次执行的结果似乎都不一样,也不是先生产后消费。wait和notify在此多线程应用不失效了?!从通知等待机制来分析,多线程的案例中6个线程分两组分别调用了对象myQueue中的wait()和notify(),相互交互。不应该出现失效的情况,为什么还是会出现消费者线程没有等到生产者的通知已生产完毕再进行消费的情况?

  分析源代码,通知等待机制哪里失控了?首先分析消费者线程:

    

  从源码看:消费者线程根据随机数获取消息队列中的数据。同时消息队列长度为0时wait(),除此以外都是根据随机数取数据。失控的点就在此处:如果消息队列长度不为0,比如说其长度为2,同时随机数为3,那么消费者线程取队列中的第4个数据——可想而知是没有任何元素在此处的。

  综合上述,多线程并发如果只是有关键字synchronized,wait(),notify()等方法并不能完全保证业务逻辑的正确性即有效同步。怎么解决这个问题呢?还需要合理的业务逻辑:

    

 

   以上可以得出一个小经验:提炼出等待/通知的经典范式,该范式分为两部分,分别针对等待方(消费者)和通知方(生产者)。

    等待方遵循如下原则:

      1)获取对象的锁。
      2)如果条件不满足,那么调用对象的wait()方法,被通知后仍要检查条件。
      3)条件满足则执行对应的逻辑。
      对应的伪代码如下:
        synchronized(对象) {
          while(条件不满足) {
            对象.wait();
          }

          对应的处理逻辑

        }

    通知方遵循如下原则:

      1)获得对象的锁。
      2)改变条件。
      3)通知所有等待在对象上的线程。
      对应的伪代码如下:
        synchronized(对象) {
          改变条件
          对象.notifyAll();
        }

   

 

标签:范式,对象,通知,线程,Java,多线程,等待,wait
来源: https://www.cnblogs.com/ilovebath/p/15490349.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有