首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

线程通信:wait和notify

*应用场景:生产者和消费者问题

*假如仓库中只能存放一件商品,生产者将生产出来的产品放入仓库,消费者将仓库中产品取走消费。

*如果仓库中没有产品,则生产者将产品放入仓库,否则停止生产并等待,直到仓库中的产品被消费者取走为止。

*如果仓库中放有产品,则消费者可以将产品取走消费,否则停止消费并等待,直到仓库中再次放入产品为止。

*

*场景分析:这是一个线程同步问题,生产者和消费者共享同一个资源,并且生产者和消费者之间相互依赖,互为条件。

*对于生产者,没有生产产品之前,要通知消费者等待。而生产了产品之后,又需要马上通知消费者消费。

*对于消费者,在消费之后,要通知生产者已经结束消费,需要生产新的产品以供消费。

*在生产者消费者问题中,没生产出产品之前,消费者是不能消费的,反之,消费者没消费完之前,生产者是不能生产的。

*这就需要锁来实现线程之间的同步。仅有同步还不行,还要实现线程之间的消息传递,即通信。

*

* Java提供了解决线程之间通信问题的方法:

*方法名 作用

* wait () 表示线程一直等待,直到其他线程通知,与sleep不同会释放锁

* wait (long timeOut) 指定等待的毫秒数

* notify () 唤醒一个处于等待状态的线程

* notifyAll() 唤醒同一个对象所有的调用wait()方法的线程,优先级高的优先调度

*注意:均是Object的方法,均只能在同步方法或者同步代码块中使用,否则会抛出异常IIIegalMonitorStageException。

*

*解决线程之间通信的方式:管程法和信号灯法。本例为管程法。

*

*/

public class MyWait {

public static void main(String[] args) {

SynContainer container = new SynContainer();

new Productor(container).start();

new Consumer(container).start();

}

}

//产品

class Chicken {

int id;

public Chicken (int id) {

this.id = id;

}

}

//生产者

class Productor extends Thread {

SynContainer synContainer;

public Productor(SynContainer synContainer) {

this.synContainer = synContainer;

}

@Override

public void run() {

for (int i = 0; i < 20; i++) {

synContainer.pushTo(new Chicken(i));

}

}

}

//消费者

class Consumer extends Thread {

SynContainer synContainer;

public Consumer(SynContainer synContainer) {

this.synContainer = synContainer;

}

@Override

public void run() {

for (int i = 0; i < 20; i++) {

synContainer.popTo();

}

}

}

//容器

class SynContainer {

//定义一个大小为10的容器

Chicken[] chickens = new Chicken[10];

//容器计数器

int count;

//生产者生产产品方法

public synchronized void pushTo(Chicken chicken) {

//如果容器满了,就停止生产

if (chickens.length == count) {

try {

this.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

//如果容器没满,就往容器中放入产品

chickens[count] = chicken;

count ++;

//通知消费者消费

this.notifyAll();

}

//消费者消费产品方法

public synchronized Chicken popTo() {

//如果容器中没有产品了,就停止消费

if (count == 0) {

try {

this.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

//如果容器有产品,就可以消费

count --;

Chicken chicken = chickens[count];

//只要消费了,就通知生产者生产

this.notifyAll();

return chicken;

}

}

  • 发表于:
  • 原文链接https://page.om.qq.com/page/O_hSNuID-g-IlqzqujDp80Nw0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券