多线程 wait-notify 写一段代码来解决生产者-消费者问题

本文深入探讨生产者-消费者模式在多线程环境下的应用,通过农夫与小孩的生动案例,展示如何利用线程间的同步与等待机制实现资源的有效分配与利用。此模式广泛应用于解决线程间通信问题,确保数据的正确读写。

                                                                  生产者-消费者

      该模式在现实生活中很常见,在项目开发中也广泛应用,它是线程间通信的经典应用。  生产者是一堆线程,消费者是另一堆线程,内存缓冲区可以使用 List 集合存储数据。该模式的关键之处是如何处理多线程之间的协调通信,内存缓冲区为空的时候,消费者必须等待,   而内存缓冲区满的时候,生产者必须等待,其他时候可以是个动态平衡。

下面的案例模拟实现农夫采摘水果放到筐里,小孩从筐里拿水果吃,农夫是一个线程,  小孩是一个线程,水果筐放满了,农夫停;水果筐空了,小孩停。

public class Kuang {
//这个集合就是水果筐 假设最多存 10 个水果
public static ArrayList<String> kuang=new ArrayList<String>();
}

上述代码定义一个静态集合作为内存缓冲区用来存储数据,同时这个集合也可以作为锁去被   多个线程使用。

public class Farmer extends Thread { public void run() {
while (true) {
synchronized (Kuang.kuang) {
//1.筐放满了就让农夫休息
if (Kuang.kuang.size() == 10) {
try {
Kuang.kuang.wait();
} catch (InterruptedException e) {
}
}
//2.往筐里放水果
Kuang.kuang.add("apple");
System.out.println("农夫放了一个水果,目前筐里有" + Kuang.kuang.size()
+ "个水果");
//3.唤醒小孩继续吃
Kuang.kuang.notify();
}
//4.模拟控制速度
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}

上述代码就是农夫线程,不断的往集合(筐)里放水果,当筐满了就停,同时释放锁。

public class Child extends Thread { public void run() {
while (true) {
synchronized (Kuang.kuang) {
//1.筐里没水果了就让小孩休息
if (Kuang.kuang.size() == 0) {
try {
Kuang.kuang.wait();
} catch (InterruptedException e) {
}
}
//2.小孩吃水果
Kuang.kuang.remove("apple");
System.out.println("小孩吃了一个水果,目前筐里有" + Kuang.kuang.size() + "个水果");
//3.唤醒农夫继续放水果
Kuang.kuang.notify();
}
//4.模拟控制速度try {
Thread.sleep(400);
} catch (InterruptedException e) { e.printStackTrace();
}
}
}
}

上述代码是小孩线程,不断的从集合(筐)里拿水果吃,当筐空了就停,同时释放锁。

public class TestFarmerChild {
public static void main(String[] args) { new Farmer().start();
new Child().start();
}
}

我们创建两个线程同时运行,可以通过双方线程里的 sleep 方法模拟控制速度,当农夫往框里放水果的速度快于小孩吃水果的速度时,运行效果如下图所示:

当小孩吃水果的速度快于农夫往框里放水管的速度时,运行效果如下图所示:

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_无往而不胜_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值