生产者-消费者模型的Java实现
2016-07-29 18:24
519 查看
生产者-消费者(producer-consumer)问题,也称作有界缓冲区(bounded-buffer)问题,两个进程共享一个公共的固定大小的缓冲区。其中一个是生产者,用于将消息放入缓冲区;另外一个是消费者,用于从缓冲区中取出消息。问题出现在当缓冲区已经满了,而此时生产者还想向其中放入一个新的数据项的情形,其解决方法是让生产者此时进行休眠,等待消费者从缓冲区中取走了一个或者多个数据后再去唤醒它。同样地,当缓冲区已经空了,而消费者还想去取消息,此时也可以让消费者进行休眠,等待生产者放入一个或者多个数据时再唤醒它。
一,首先定义公共资源类,其中的变量number是保存的公共数据。并且定义两个方法,增加number的值和减少number的值。由于多线程的原因,必须加上synchronized关键字,注意while判断的条件。
案例2:
一,首先定义公共资源类,其中的变量number是保存的公共数据。并且定义两个方法,增加number的值和减少number的值。由于多线程的原因,必须加上synchronized关键字,注意while判断的条件。
/** * 公共资源类 */ public class PublicResource { public int number = 0; /** * 增加公共资源 */ public synchronized void produce() { while (number == 10) { try { wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } number++; System.out.println(Thread.currentThread().getName() + "生产:" + number); notify(); } /** * 减少公共资源 */ public synchronized void consume() { while (number == 0) { try { wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } number--; System.out.println(Thread.currentThread().getName() + "消费:" + number); notify(); } }二,分别定义生产者线程和消费者线程,并模拟多次生产和消费,即增加和减少公共资源的number值
/** * 生产者线程,负责生产公共资源 */ public class ProducerThread implements Runnable { private PublicResource resource; public ProducerThread(PublicResource resource) { this.resource = resource; } @Override public void run() { // TODO Auto-generated method stub for (int i = 0; i < 10; i++) { try { Thread.sleep((long) (Math.random() * 1000)); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } resource.produce(); } } }
/** * 消费者线程,负责消费公共资源 */ public class ConsumerThread implements Runnable { private PublicResource resource; public ConsumerThread(PublicResource resource) { this.resource = resource; } @Override public void run() { // TODO Auto-generated method stub for (int i = 0; i < 10; i++) { try { Thread.sleep((long) (Math.random() * 1000)); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } resource.consume(); } } }三,模拟多个生产者和消费者操作公共资源的情形,结果须保证是在允许的范围内。
public class ProducerConsumerTest { public static void main(String[] args) { PublicResource resource = new PublicResource(); new Thread(new ProducerThread(resource),"producter1").start(); new Thread(new ConsumerThread(resource),"consumer1").start(); } }四,输出
producter1生产:1 consumer1消费:0 producter1生产:1 consumer1消费:0 producter1生产:1 consumer1消费:0 producter1生产:1 producter1生产:2 consumer1消费:1 producter1生产:2 producter1生产:3 consumer1消费:2 consumer1消费:1 producter1生产:2 producter1生产:3 consumer1消费:2 consumer1消费:1 producter1生产:2 consumer1消费:1 consumer1消费:0
案例2:
/** * 仓库类Storage实现缓冲区 * */ public class Storage { // 仓库最大存储量 private final int MAX_SIZE = 100; // 仓库存储的载体 private LinkedList<Object> list = new LinkedList<Object>(); // 生产num个产品 public void produce(int num) { synchronized (list) { // 如果仓库剩余容量不足 while (list.size() + num > MAX_SIZE) { System.out.println("【要生产的产品数量】:" + num + "\t【库存量】:" + list.size() + "\t暂时不能执行生产任务!"); try { // 由于条件不满足,生产阻塞 list.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } // 生产条件满足情况下,生产num个产品 for (int i = 1; i <= num; ++i) { list.add(new Object()); } System.out.println("【已经生产产品数】:" + num + "\t【现仓储量为】:" + list.size()); list.notifyAll(); } } // 消费num个产品 public void consume(int num) { synchronized (list) { // 如果仓库存储量不足 while (list.size() < num) { System.out.println("【要消费的产品数量】:" + num + "\t【库存量】:" + list.size() + "\t暂时不能执行生产任务!"); try { // 由于条件不满足,消费阻塞 list.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } // 消费条件满足情况下,消费num个产品 for (int i = 1; i <= num; ++i) { list.remove(); } System.out.println("【已经消费产品数】:" + num + "\t【现仓储量为】:" + list.size()); list.notifyAll(); } } }
public class Producer extends Thread { // 每次生产的产品数量 private int num; // 所在放置的仓库 private Storage storage; // 构造函数,设置仓库 public Producer(Storage storage) { this.storage = storage; } public int getNum() { return num; } public void setNum(int num) { this.num = num; } @Override public void run() { // TODO Auto-generated method stub storage.produce(num); } }
public class Consumer extends Thread { // 每次消费的产品数量 private int num; // 所在放置的仓库 private Storage storage; // 构造函数,设置仓库 public Consumer(Storage storage) { this.storage = storage; } public int getNum() { return num; } public void setNum(int num) { this.num = num; } @Override public void run() { // TODO Auto-generated method stub storage.consume(num); } }
public class Test { public static void main(String[] args) { // 仓库对象 Storage storage = new Storage(); // 生产者对象 Producer p1 = new Producer(storage); Producer p2 = new Producer(storage); Producer p3 = new Producer(storage); Producer p4 = new Producer(storage); Producer p5 = new Producer(storage); Producer p6 = new Producer(storage); Producer p7 = new Producer(storage); // 消费者对象 Consumer c1 = new Consumer(storage); Consumer c2 = new Consumer(storage); Consumer c3 = new Consumer(storage); // 设置生产者产品生产数量 p1.setNum(10); p2.setNum(10); p3.setNum(10); p4.setNum(10); p5.setNum(10); p6.setNum(10); p7.setNum(80); // 设置消费者产品消费数量 c1.setNum(50); c2.setNum(20); c3.setNum(30); // 线程开始执行 c1.start(); c2.start(); c3.start(); p1.start(); p2.start(); p3.start(); p4.start(); p5.start(); p6.start(); p7.start(); } }OutPut:
【要消费的产品数量】:50 【库存量】:0 暂时不能执行生产任务! 【已经生产产品数】:10 【现仓储量为】:10 【要消费的产品数量】:50 【库存量】:10 暂时不能执行生产任务! 【已经生产产品数】:10 【现仓储量为】:20 【要消费的产品数量】:30 【库存量】:20 暂时不能执行生产任务! 【已经消费产品数】:20 【现仓储量为】:0 【已经生产产品数】:10 【现仓储量为】:10 【已经生产产品数】:10 【现仓储量为】:20 【要消费的产品数量】:30 【库存量】:20 暂时不能执行生产任务! 【要消费的产品数量】:50 【库存量】:20 暂时不能执行生产任务! 【已经生产产品数】:10 【现仓储量为】:30 【要消费的产品数量】:50 【库存量】:30 暂时不能执行生产任务! 【已经消费产品数】:30 【现仓储量为】:0 【已经生产产品数】:80 【现仓储量为】:80 【已经生产产品数】:10 【现仓储量为】:90 【已经消费产品数】:50 【现仓储量为】:40
相关文章推荐
- 从java多线程实现“生产者-消费者”模型来谈谈操作系统中线程状态的转换及线程同步的总结
- 生产者-消费者模型的Java实现
- java 多线程实现生产者消费者模型
- 生产者-消费者模型的Java实现
- 生产者消费者模型java实现(一)
- JAVA实现多线程生产者消费者模型
- Java多线程15:Queue、BlockingQueue以及利用BlockingQueue实现生产者/消费者模型
- 基于JAVA实现的生产者消费者模型
- Java---实现生产者消费者模型
- 生产者-消费者模型的Java实现
- JAVA实现多线程生产者消费者模型
- java实现生产者消费者模型
- java线程间通信[实现不同线程之间的消息传递(通信),生产者和消费者模型]
- 用java实现的生产者与消费者多线程同步互斥模型
- Java 多线程学习之生产者消费者模型:一个较完善的实现
- 生产者-消费者模型的3种Java实现:synchronized,signal/notifyAll及BlockingQueue
- Java多线程之~~~~使用wait和notify实现生产者消费者模型
- Java实现生产者-消费者模型
- Java实现生产者与消费者模型
- 生产者-消费者模型的java实现