博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一 java线程的等待/通知模型
阅读量:5346 次
发布时间:2019-06-15

本文共 3164 字,大约阅读时间需要 10 分钟。

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

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

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

1 /** 2  * 买小米5手机 3  * @author zhanghongjun 4  * 5  */ 6 public class BuyXiaoMi5 { 7     static boolean hasXiaoMi5 = false; 8     static Object lock = new Object(); 9     10     public static void main(String[] args) throws InterruptedException {11         //消费者12         Thread miFansThread = new Thread(new MiFans(),"MiFans");13         14         //生产者15         Thread leiBS = new Thread(new LeiBuShi(),"LeiBuShi");16         17         miFansThread.start();18         leiBS.start();19         20     }21     22     /**23      * 雷布斯,生产者24      * @author zhanghongjun25      *26      */27     static class LeiBuShi implements Runnable{28         @Override29         public void run() {30             synchronized (lock) {31                 System.out.println("Are you ok ? 我们开始生产小米5了,大家等一等啊");32                 try {33                     System.out.println("Are you ok ? 小米5手机生产ing中,大家等一等啊");34                     Thread.sleep(3000); //6个月后,小米5终于上市了35                 } catch (InterruptedException e) {36                     e.printStackTrace();37                 }38                 39                 System.out.println("Are you ok? 小米5上市啦,大家可以哄抢啦");40                 lock.notifyAll();    //通知所有的人,可以抢手机了41                 hasXiaoMi5 = true;    //终于有小米5手机了    42             }43         }44         45     }46     47     48     /**49      * 米粉,消费者50      * @author zhanghongjun51      *52      */53     static class MiFans implements Runnable{54         @Override55         public void run() {56             synchronized (lock) {57                 //没有小米5手机,只有等待了58                 while(!hasXiaoMi5){59                     System.out.println("雷军耍猴,不知道要等多久,才能买到小米5...");60                     try {61                         lock.wait();62                     } catch (InterruptedException e) {63                         e.printStackTrace();64                     }65                 }66             }67             68             System.out.println("我是米粉,终于买到一台发烧的小米5了,开森中。。。");69         }70     }71     72 }

上面代码可以看到,开始的时候,米粉线程要买小米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()

}

 

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

 

posted on
2016-09-12 22:10  阅读(
...) 评论(
...) 收藏

转载于:https://www.cnblogs.com/start1225/p/5866575.html

你可能感兴趣的文章
Java变量类型,实例变量 与局部变量 静态变量
查看>>
mysql操作命令梳理(4)-中文乱码问题
查看>>
Python环境搭建(安装、验证与卸载)
查看>>
一个.NET通用JSON解析/构建类的实现(c#)
查看>>
关于这次软件以及pda终端的培训
查看>>
如何辨别一个程序员的水平高低?是靠发量吗?
查看>>
新手村之循环!循环!循环!
查看>>
线程安全问题
查看>>
linux的子进程调用exec( )系列函数
查看>>
MySQLdb & pymsql
查看>>
zju 2744 回文字符 hdu 1544
查看>>
【luogu P2298 Mzc和男家丁的游戏】 题解
查看>>
前端笔记-bom
查看>>
上海淮海中路上苹果旗舰店门口欲砸一台IMAC电脑维权
查看>>
Google透露Android Market恶意程序扫描服务
查看>>
给mysql数据库字段值拼接前缀或后缀。 concat()函数
查看>>
迷宫问题
查看>>
【FZSZ2017暑假提高组Day9】猜数游戏(number)
查看>>
泛型子类_属性类型_重写方法类型
查看>>
对闭包的理解
查看>>