Java如何通过线程解决生产者/消费者问题
作者:知优码 时间:2023-09-27 00:31:08
生产者和消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一个存储空间,如下图所示
生产者向空间里存放数据,而消费者取用数据,如果不加以协调可能会出现以下情况:
存储空间已满,而生产者占用着它,消费者等着生产者让出空间从而去除产品,生产者等着消费者消费产品,从而向空间中添加产品。互相等待,从而发生死锁。
以下实例演示了如何通过线程解决生产者/消费者问题:
/*
author by javaidea.com
ProducerConsumerTest.java
*/
public class ProducerConsumerTest {
public static void main(String[] args) {
CubbyHole c = new CubbyHole();
Producer p1 = new Producer(c, 1);
Consumer c1 = new Consumer(c, 1);
p1.start();
c1.start();
}
}
class CubbyHole {
private int contents;
private boolean available = false;
public synchronized int get() {
while (available == false) {
try {
wait();
}
catch (InterruptedException e) {
}
}
available = false;
notifyAll();
return contents;
}
public synchronized void put(int value) {
while (available == true) {
try {
wait();
}
catch (InterruptedException e) {
}
}
contents = value;
available = true;
notifyAll();
}
}
class Consumer extends Thread {
private CubbyHole cubbyhole;
private int number;
public Consumer(CubbyHole c, int number) {
cubbyhole = c;
this.number = number;
}
public void run() {
int value = 0;
for (int i = 0; i < 10; i++) {
value = cubbyhole.get();
System.out.println("消费者 #" + this.number+ " got: " + value);
}
}
}
class Producer extends Thread {
private CubbyHole cubbyhole;
private int number;
public Producer(CubbyHole c, int number) {
cubbyhole = c;
this.number = number;
}
public void run() {
for (int i = 0; i < 10; i++) {
cubbyhole.put(i);
System.out.println("生产者 #" + this.number + " put: " + i);
try {
sleep((int)(Math.random() * 100));
} catch (InterruptedException e) { }
}
}
}
以上代码运行输出结果为:
消费者 #1 got: 0
生产者 #1 put: 0
生产者 #1 put: 1
消费者 #1 got: 1
生产者 #1 put: 2
消费者 #1 got: 2
生产者 #1 put: 3
消费者 #1 got: 3
生产者 #1 put: 4
消费者 #1 got: 4
生产者 #1 put: 5
消费者 #1 got: 5
生产者 #1 put: 6
消费者 #1 got: 6
生产者 #1 put: 7
消费者 #1 got: 7
生产者 #1 put: 8
消费者 #1 got: 8
生产者 #1 put: 9
消费者 #1 got: 9
来源:https://www.javaidea.cn/topic/602.html
标签:Java,线程,生产者,消费者
0
投稿
猜你喜欢
浅谈java中的重载和重写的区别
2023-03-31 04:45:57
Java执行cmd命令两种实现方法解析
2022-09-24 02:43:49
解析C++哈夫曼树编码和译码的实现
2021-11-19 05:26:25
解决eclipse上传svn忽略target文件夹的坑
2023-09-12 04:04:23
springboot使用GuavaCache做简单缓存处理的方法
2022-12-04 22:43:02
WPF实现自带触控键盘的文本框
2023-08-25 15:23:20
SpringCloud实战之Feign声明式服务调用
2022-07-02 08:25:30
SpringBoot Scheduling定时任务的示例代码
2023-08-12 17:55:05
Flutter开发Mac桌面应用实现自动提取生成视频字幕文件
2023-05-11 05:25:58
Java动态线程池插件dynamic-tp集成zookeeper
2023-11-25 03:41:38
Spring常用注解汇总
2022-12-19 16:26:03
java根据不同的参数调用不同的实现类操作
2021-11-08 17:05:16
java递归设置层级菜单的实现
2023-03-05 14:14:57
C#监控文件夹变化的方法
2023-03-26 09:39:38
如何用C#创建用户自定义异常浅析
2023-06-10 20:06:16
WPF+SkiaSharp实现自绘弹幕效果
2022-09-30 09:52:38
Android多媒体之VideoView视频播放器
2023-11-12 14:38:35
Android 屏幕截屏方法汇总
2022-01-23 05:48:18
c++指针使用形参改变实参的方法
2023-03-11 22:40:21
Spring通过<import>标签导入外部配置文件
2023-03-04 06:43:58