生产者消费者
生产者消费者模型最早出现在操作系统的多道程序设计中。到这里我们发现在并发程序设计中经常使用的就是操作系统的思想,这也体现出了计算机基础专业课程的重要性,在这些课程中我们可以学到很多重要的思想。
什么是生产者消费者呢?
该问题描述了两个共享固定大小缓冲区的线程——即所谓的“生产者”和“消费者”——在实际运行时会发生的问题。生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。
在这里我们会用到一些工具:
- BlockingQueue:这个类是一个在并发下安全的队列
- ExecutorService threadPool = Executors.newCachedThreadPool();线程池的另一种实现。
因为JDK提供了线程的包,我们可以不用太关注于太复杂的并发问题。那么请使用这两个工具试着实现生产者消费者模型吧。这个程序算是并发编程的综合应用,对并发的思想有一定的了解会写出来这个程序的。
参考答案
可能大家写的程序不一定一致,这里是我自己写的一个程序可以作为参考:
public class ProduSp {
public static void main(String[] args){
ProduSp ps=new ProduSp();
midPro midpro=ps.new midPro();
ExecutorService threadPool = Executors.newCachedThreadPool();
Productor p1=ps.new Productor(midpro);
Productor p2=ps.new Productor(midpro);
Productor p3=ps.new Productor(midpro);
Consumers c1=ps.new Consumers(midpro);
threadPool.submit(p1);
threadPool.submit(p2);
threadPool.submit(p3);
threadPool.submit(c1);
}
volatile int count=0;
class midPro{
BlockingQueue<Product> blockingQueue=new LinkedBlockingQueue<Product>(4);
public void put(Product product){
try {
count+=1;
blockingQueue.put(product);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public Product get() throws InterruptedException {
count-=1;
return blockingQueue.take();
}
}
class Productor implements Runnable{
private midPro midpro=null;
public Productor(midPro midpro){
this.midpro=midpro;
}
public void run() {
while (true){
Product product=new Product();
midpro.put(product);
System.out.println(Thread.currentThread().getId()+":生产者生产"+count);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Consumers implements Runnable{
private midPro midpro=null;
public Consumers(midPro midpro){
this.midpro=midpro;
}
public void run() {
while(true){
try {
midpro.get();
System.out.println(Thread.currentThread().getId()+":消费者消费"+count);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Product{
}
}
这里队列就相当于一个缓冲区。
网友评论