当前位置: 首页>后端>正文

线程通信:wait和notify

线程通信:wait和notify,第1张

/**

*线程协作

*线程之间需要进行通信,通信有数据共享(1、文件共享;2、网络共享;3、变量共享)和线程协作两种方式。

*线程协作指不同线程驱动的任务相互依赖,依赖一般就是对共享资源的依赖。(有共享就有竞争,有竞争就会有线程安全问题(即并发),解决并发问题就用线程同步)。

?*

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

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

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

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

?*

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

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

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

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

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

?*

* 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;

System.out.println("生产了" + chicken.id + "个鸡腿");

????????count ++;

//通知消费者消费

????????this.notifyAll();

????}

//消费者消费产品方法

????public synchronized Chicken popTo() {

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

????????if (count == 0) {

????????????try {

????????????????this.wait();

????????????} catch (InterruptedException e) {

????????????????e.printStackTrace();

????????????}

????????}

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

????????count --;

????????Chicken chicken = chickens[count];

System.out.println("消费了第" + chicken.id + "个鸡退");

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

????????this.notifyAll();

????????return chicken;

????}

}


https://www.xamrdz.com/backend/39t1941363.html

相关文章: