生产者与消费者问题可以被描述为:一个有限缓冲区和两类线程,它们是生产者和消费者,生产者把产品放入缓冲区,相反消费者便是从缓冲区中拿走产品。
生产者在缓冲区满时必须等待,直到缓冲区有空间才继续生产。消费者在缓冲区空时必须等待,直到缓冲区中有产品才能继续读取。
下面用三个实例描述这个问题在线程级别上的Java实现。
1.单生产者-单消费者-单个资源
单个生产者,单个消费者以及缓冲区大小为1(单个资源)的情况,类似于停等协议的实现。
生产者(SingleProducer):
[1]生产一个资源(Resource);
[2]notify潜在的等待着的消费者(SingleCostumer);
[3]wait直到资源被消费。
消费者(SingleCostumer):
[1]消费一个资源(Resource);
[2]notify潜在的等待着的生产者;
[3]wait直到资源被产生。
资源Resource.java
package com.zj.one;
public class Resource {
private final int resNum;
public Resource(int resNum) {
this.resNum = resNum;
}
public String toString() {
return "Resource " + resNum;
}
}
|
生产者SingleProducer.java
package com.zj.one;
import java.util.concurrent.TimeUnit;
public class SingleProducer implements Runnable {
private SinglePlatform platform;
private int count = 0;
public SingleProducer(SinglePlatform platform) {
this.platform = platform;
}
public void run() {
try {
while (!Thread.interrupted()) {
synchronized (this) {
while (platform.res != null)
wait(); // for the resource to be consumed
}
System.out.println("Producer add resource " + ++count);
synchronized (platform.customer) {
platform.res = new Resource(count);
platform.customer.notify();
}
TimeUnit.MILLISECONDS.sleep(100);
}
} catch (InterruptedException e) {
System.out.println("Producer interrupted");
}
}
}
|
消费者SingleCustomer.java
package com.zj.one;
public class SingleCustomer implements Runnable {
private SinglePlatform platform;
public SingleCustomer(SinglePlatform platform) {
this.platform = platform;
}
public void run() {
try {
while (!Thread.interrupted()) {
synchronized (this) {
while (platform.res == null)
wait(); // ... for the productor to produce
}
System.out.println("Customer got " + platform.res);
synchronized (platform.productor) {
platform.res = null;
platform.productor.notify(); // Ready for another
}
}
} catch (InterruptedException e) {
System.out.println("Customer interrupted");
}
}
}
|
单个资源缓冲区SinglePlatform.java
package com.zj.one;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
public class SinglePlatform {
Resource res;
ExecutorService exec = Executors.newCachedThreadPool();
SingleProducer productor = new SingleProducer(this);
SingleCustomer customer = new SingleCustomer(this);
public void runPlatform() throws InterruptedException{
Future<?> f1=exec.submit(productor);
Future<?> f2=exec.submit(customer);
TimeUnit.SECONDS.sleep(3);
f1.cancel(true);
f2.cancel(true);
exec.shutdown();
}
public static void main(String[] args) throws InterruptedException {
new SinglePlatform().runPlatform();
}
}
|
每次启动程序后,在3秒钟后中断所有的线程,结束程序。
2.单生产者-单消费者-多个资源
当缓冲区长度大于1时,类似于滑动窗口协议。资源类Resource.java不变。缓冲区BufferPlatform.java中使用一个队列来实现滑动窗口。
这里设计两种策略来模拟生产速度快于和慢于消费速度两种情形。策略实现自一个策略接口RunnerStrategy。
生产者与消费者分别持有一个标志位来判断是否需要等待。在队列满时,生产者等待;在队列空时,消费者等待。
缓冲区BufferPlatform.java
package com.zj.two;
import java.util.AbstractQueue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import com.zj.three.Resource;
public class BufferPlatform {
AbstractQueue<Resource> res = new ConcurrentLinkedQueue<Resource>();
private int queueSize = 3;//窗口大小
ExecutorService exec = Executors.newCachedThreadPool();
RunnerStrategy runnerStrategy;
SingleProducer producer |
分享到:
相关推荐
线程同步中的典型事例生产者消费者问题 方便理解线程的各方面内容
Linux的生产者与消费者问题,有具体的案例,有详细的例题和解析,操作系统必考题
这是一个在Linux下实现的生产者-消费者进程同步经典问题。编译是使用“gcc -pthread synchro.c -o main"。运行时使用./main后 输入两个参数,第一个是生产者数目,第二个是消费者数目。程序运行30秒结束。
主要介绍了Java实现简易生产者消费者模型过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
主要介绍了Java多线程生产者消费者模式实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
Qt实现串口通信(利用windows API实现串口枚举,多线程、生产者消费者模型实现数据解析); 自定义事件,向UI界面提供数据交互接口; 自定义队列,支持线程安全。
主要介绍了Java实现Kafka生产者消费者代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
主要介绍了Python semaphore evevt生产者消费者模型原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
教育精品资料
主要介绍了Java多线程并发生产者消费者设计模式实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
2.1、编写MonkeyRunner自动脚本 2.2、抓取应用流量信息 2.3、数据解析实现 2.3.1、数据处理流程 2.3.2、使用生产者消费者模式处理数据
runtimeqs-适用于AWS SQS的预打包运行时助手->概述该项目是一个工具包,用于运行与用go编写的AWS SQS进行交互的服务。 它附带记录器,指标客户端和配置解析的自选选项。 好处是围绕aws-sdk api的一个简单抽象,用于...
主要介绍了Java多线程Queue、BlockingQueue和使用BlockingQueue实现生产消费者模型方法解析,涉及queue,BlockingQueue等有关内容,具有一定参考价值,需要的朋友可以参考。
10. 生产者-消费者问题:在9个生产者、6个消费者共享容量为8的缓冲器的生产者-消费者问题中,互斥使用缓冲器的信号量的初值应设为1。 11. 有序分配策略:资源的有序分配策略可以破坏导致死锁的四个必要条件中的互斥...
常用的解析工具有正则表达式、XPath、Beautiful Soup等。这些工具帮助爬虫定位和提取目标数据,如文本、图片、链接等。 数据存储: 爬虫将提取的数据存储到数据库、文件或其他存储介质中,以备后续分析或展示。常用...
Producer: 生产者,负责生产消息并发送到消息引擎。测评开始时,测评程序会启动10~20个Producer,每个Producer在一条线程中,然后每个Producer随机生产某个Topic或者附属于Queue的消息并发送到消息引擎; Topic: ...
通过生产者消费者模型理解等待唤醒机制.mp4 Condition的使用及原理解析.mp4 使用Condition重写waitnotify案例并实现一个有界队列.mp4 深入解析Condition源码.mp4 实战:简易数据连接池.mp4 线程之间通信之join应用与...
计算机操作系统常见题型解析及模拟题 读者-写者问题 进程状态转换 生产者-消费者问题 哲学家问题等等
上位机采用了生产者消费者模式,有两个主要的线程和一个数据缓冲容器,其中一个线程用于将接收到的图像数据放到缓冲区内,另外一个线程用于从缓冲区中获取图像数据并显示到界面上。博文地址:...