java多线程wait notify,实现线程交互的wait()和notify()方法在类中定义
00-1010一、为什么需要线程通信二。等待和通知方法1。wait()方法2。notify()方法3。notifyAll()方法3。利用等待和通知实现面包店业务。阻塞队列1。生产者-消费者模型2。标准库3中的阻塞队列。阻塞队列5的模拟实现。等待和睡眠的区别(面试问题
00-1010线程并行执行,显示线程随机执行。但是我们在实际应用中对线程的执行顺序是有要求的,这就需要线程通信。
线程为什么不用优先级来解决线程的运行顺序?
的总优先级是由线程pcb中的优先级信息和线程的等待时间决定的,所以在一般的开发中,不会依赖优先级来指示线程的执行顺序。
看下面的场景:面包店的例子被用来描述生产者-消费者模型。
有面包店有面包师和顾客,对应我们的生产者和消费者。面包店有储存面包的库存,库存满了就不生产了。与此同时,消费者也在购买面包。当库存面包卖光后,消费者必须等待新的面包生产出来,才能继续购买。
解析:什么时候停止生产,什么时候停止消费,需要应用到线程通信中,准确传达生产和消费信息。
00-1010WAIT():释放当前线程持有的对象锁并等待。
Wait(长超时):对应的参数是线程等待的时间。
Notify():唤醒使用同一个对象调用wait的线程进入等待,重新竞争对象锁。
NotifyAll():如果有多个线程在等待,notifyAll会唤醒,notify会随机唤醒一个。
注意:
这些方法都属于Object类中的方法。
必须在同步的同步代码块/同步方法中使用。
哪个对象被锁定就用哪个对象等等,通知。
调用notify后,不会立即唤醒,而是等到同步完成。
目录
调用wait方法后:
让执行当前代码的线程等待(线程被放在等待队列中)
释放当前锁定
满足一定条件时唤醒,再次尝试获取锁。
wait等待结束的条件:
其他线程调用该对象的notify方法。
等待时间已超时(超时参数指定等待时间)
其他线程调用interrupted方法,导致wait引发InterruptedException异常。
00-1010使用不带参数的wait方法时,需要notify方法唤醒线程等待。
此方法唤醒等待对象的对象锁的线程,以便它们可以重新获取对象的对象锁。
如果有多个线程在等待,线程调度器会随机选择一个处于等待状态的线程(没有先到先服务)。
在notify()方法之后,当前线程不会立即释放对象锁,但是直到执行notify()方法的线程执行完程序,也就是退出同步代码块,才会释放对象锁。
00-1010该方法与notify()方法的功能相同,只是当它唤醒时,会唤醒所有等待的线程。
notify()方法只是随机唤醒一个线程。
一. 为什么需要线程通信
前提说明:
有两个面包师。面包师一次可以做两个面包。
这个仓库能储存100条面包
有10个消费者,每个消费者一次买一个面包。
注意:
并且消费和生产同时并行进行,而不是一个生产一个消费。
实现代码:
公共类面包店{私人静态int total//Inventory公共静态void main(string[]args){ producer producer=new producer();for(int I=0;I 2;I ){新线(制作人,贝克- (i-1))。start();}公司
nsumer consumer = new Consumer(); for(int i = 0;i < 10;i++){ new Thread(consumer,"消费者-"+(i-1)).start(); } } private static class Producer implements Runnable{ private int num = 3; //生产者每次生产三个面包 @Override public void run() { try { while(true){ //一直生产 synchronized (Bakery.class){ while((total+num)>100){ //仓库满了,生产者等待 Bakery.class.wait(); } //等待解除 total += num; System.out.println(Thread.currentThread().getName()+"生产面包,库存:"+total); Thread.sleep(500); Bakery.class.notifyAll(); //唤醒生产 } Thread.sleep(500); } } catch (InterruptedException e) { e.printStackTrace(); } } } private static class Consumer implements Runnable{ private int num = 1; //消费者每次消费1个面包 @Override public void run() { try { while(true){ //一直消费 synchronized (Bakery.class){ while((total-num)<0){ //仓库空了,消费者等待 Bakery.class.wait(); } //解除消费者等待 total -= num; System.out.println(Thread.currentThread().getName()+"消费面包,库存:"+total); Thread.sleep(500); Bakery.class.notifyAll(); //唤醒消费 } Thread.sleep(500); } } catch (InterruptedException e) { e.printStackTrace(); } } }}部分打印结果:
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。