java 中线程之间的通信问题,有这么一个模型:一个线程修改了一个对象的值,而另一个线程感知到了变化,然后进行相应的操作,整个过程开始于一个线程,而最终执行又是另一个线程。前者是生产者,后者就是消费者,也可以叫做生产者-消费者问题

生产者生产了产品,如何通知消费者?下面就介绍下java线程中的等待-通知机制。其它语言类似,自行研究。代码附上

下面是以买小米5手机为例子,来说明等待通知机制

 /**
* 买小米5手机
* @author zhanghongjun
*
*/
public class BuyXiaoMi5 {
static boolean hasXiaoMi5 = false;
static Object lock = new Object(); public static void main(String[] args) throws InterruptedException {
//消费者
Thread miFansThread = new Thread(new MiFans(),"MiFans"); //生产者
Thread leiBS = new Thread(new LeiBuShi(),"LeiBuShi"); miFansThread.start();
leiBS.start(); } /**
* 雷布斯,生产者
* @author zhanghongjun
*
*/
static class LeiBuShi implements Runnable{
@Override
public void run() {
synchronized (lock) {
System.out.println("Are you ok ? 我们开始生产小米5了,大家等一等啊");
try {
System.out.println("Are you ok ? 小米5手机生产ing中,大家等一等啊");
Thread.sleep(3000); //6个月后,小米5终于上市了
} catch (InterruptedException e) {
e.printStackTrace();
} System.out.println("Are you ok? 小米5上市啦,大家可以哄抢啦");
lock.notifyAll(); //通知所有的人,可以抢手机了
hasXiaoMi5 = true; //终于有小米5手机了
}
} } /**
* 米粉,消费者
* @author zhanghongjun
*
*/
static class MiFans implements Runnable{
@Override
public void run() {
synchronized (lock) {
//没有小米5手机,只有等待了
while(!hasXiaoMi5){
System.out.println("雷军耍猴,不知道要等多久,才能买到小米5...");
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} System.out.println("我是米粉,终于买到一台发烧的小米5了,开森中。。。");
}
} }

上面代码可以看到,开始的时候,米粉线程要买小米5手机,结果条件不满足,hasXiaoMi5 = false; 当条件不满足的时候,就需要等待, lock.wait();

此时线程进入等待队列中,线程会阻塞,需要注意   lock.wait() ,是会释放锁的,进而进入到线程的等待队列中,这时候,因为wait()已经释放了锁,所以,LeiBuShi 线程就可以

获得锁,进而去生产手机,等到手机生产出来以后,既 hasXiaoMi5 = true了,这时候就通知在此锁上等待的线程,lock.notify()或者lock.notifyAll,之后,离开同步块,进而释放锁,这时候 61行,lock.wait() 函数返回,条件成立,进而继续向下运行,买到手机。

这里需要注意的几点如下:

1  使用wait(),notify(),notifyAll()时需要先对调用对象加锁

2  调用wait()方法后,线程状态由Running状态变为 waiting状态,并将当前线程放置到线程的等待队列中

3 notify()或者notifyAll()方法调用后,等待线程依旧不会从wait()返回,需要调用notify()或者nofityAll()的线程释放锁之后,等待线程才有机会从wait()返回

4 从wait()方法返回的前提是获得了调用对象的锁.

等待/通知的经典范式

等待方步骤如下:

1 获取对象的锁

2 如果条件满足,那么调用对象的wait()方法,被通知后仍要检查条件。

3 条件满足则执行相应的业务逻辑

对应的伪代码如下:

synchronized(对象){

  while(条件不满足时){

        对象.wait()

  }

对应的逻辑

}

通知方步骤如下:

1 获得对象的锁

2 改变条件

3 通知所有等待对象上的线程

对应的伪代码如下:

synchronized(对象){

  改变条件

  对象.notifyAll()

}

以上就是典型的通知等待机制。能力有限,希望对大家有所帮助

一 java线程的等待/通知模型的更多相关文章

  1. 第23章 java线程通信——生产者/消费者模型案例

    第23章 java线程通信--生产者/消费者模型案例 1.案例: package com.rocco; /** * 生产者消费者问题,涉及到几个类 * 第一,这个问题本身就是一个类,即主类 * 第二, ...

  2. java线程的等待、通知机制【读书笔记】

    代码示例: package com.baidu.nuomi.concurrent; import java.text.SimpleDateFormat; import java.util.Date; ...

  3. java 多线程:线程通信-等待通知机制wait和notify方法;(同步代码块synchronized和while循环相互嵌套的差异);管道通信:PipedInputStream;PipedOutputStream;PipedWriter; PipedReader

    1.等待通知机制: 等待通知机制的原理和厨师与服务员的关系很相似: 1,厨师做完一道菜的时间不确定,所以厨师将菜品放到"菜品传递台"上的时间不确定 2,服务员什么时候可以取到菜,必 ...

  4. Java并发之等待/通知机制

    目录 1 前言 1.1 先来段代码放松一下 2 Object wait()/notify() 2.1 一段入门代码 2.2 问题三连击 a.为什么官方说wait() 要放在while里面? b.为什么 ...

  5. Java线程的等待与唤醒完整示例代码

    项目结构: 资源类: 输入线程:  输出线程: 测试: 人妖问题发生: 线程安全问题的解决方法: 调用Object的wait()和notify()方法时需注意:必须是锁对象方可调用,否则将抛出无效的监 ...

  6. 二 Java利用等待/通知机制实现一个线程池

    接着上一篇博客的 一Java线程的等待/通知模型 ,没有看过的建议先看一下.下面我们用等待通知机制来实现一个线程池 线程的任务就以打印一行文本来模拟耗时的任务.主要代码如下: 1  定义一个任务的接口 ...

  7. ReentrantLock等待通知机制Condition介绍

    Object类中的wait(),notify()和notifyAll()可以实现线程的等待通知模型,同样在ReentrantLock中可以借助Condition来完成这种机制.本篇就简要介绍Condi ...

  8. Java并发编程(04):线程间通信,等待/通知机制

    本文源码:GitHub·点这里 || GitEE·点这里 一.概念简介 1.线程通信 在操作系统中,线程是个独立的个体,但是在线程执行过程中,如果处理同一个业务逻辑,可能会产生资源争抢,导致并发问题, ...

  9. java多线程系列(三)---等待通知机制

    等待通知机制 前言:本系列将从零开始讲解java多线程相关的技术,内容参考于<java多线程核心技术>与<java并发编程实战>等相关资料,希望站在巨人的肩膀上,再通过我的理解 ...

随机推荐

  1. ASP.NET Misconfiguration: Missing Error Handling

    Abstract: An ASP .NET application must enable custom error pages in order to prevent attackers from ...

  2. Oracle数据库根据时间查询

    ' and trans_dt between to_date('2010-12-01 00:00:00','YYYY-MM-DD HH24:MI:SS') and to_date('2011-12-3 ...

  3. 第十二课:Sizzle引擎详解

    这篇博客难度太大,跟前端开发其实没什么关系,如果你想成为大牛,那就去了解下吧.如果你还不想,那可以忽略,毕竟面试官也不会问到这里来,因为他也不太懂.呵呵. Sizzle引擎是jQuery的选择器,它大 ...

  4. Beat版本分工

    柯晓鸿031302613:负责服务器的搭建,struts2框架的配置,后台与页面的连整合,部分后台接口,数据库连接查询接口,以及页面js的书写 比例:40% 洪腾飞031302608:负责主要界面的书 ...

  5. Elasticsearch相关资源

    安装介绍 http://www.doc88.com/p-171165797348.html 入门教程 http://www.iteye.com/blogs/subjects/elasticsearch ...

  6. Linux驱动学习之驱动开发准备工作

    一.开启驱动开发之路 1.驱动开发的准备工作 (1)正常运行linux系统的开发板.要求开发板中的linux的zImage必须是自己编译的,不能是别人编译的.原因在于在安装模块的时候会进行安全性校验 ...

  7. VS 2008 快捷键

    注释代码:<Ctrl+K,C>取消注释:<Ctrl+K,U> 封装字段(生成get.set方法): <Ctrl+R,E> 定位大括号范围:光标放在其中一个括号的位置 ...

  8. 深入理解 NodeList

    在web前端编程中,我们通常会通过document.getElementsByTagName的方法取出一组相同标签的dom元素,比如: var list = document.getElementsB ...

  9. 史上最全的Python电子书教程资源下载(转)

    网上搜集的,点击即可下载,希望提供给有需要的人^_^   O'Reilly.Python.And.XML.pdf 2.02 MB   OReilly - Programming Python 2nd. ...

  10. 如何在xml文件中加注释或取消注释

    1)加注释:Ctrl+Shift+/ 2)取消注释:Ctrl+Shift+\ 本文欢迎转载,但请注明作者与出处: 作者:Sophia 出处:http://www.cnblogs.com/Sophia- ...