(手写生产者消费者模型,写BlockingQueue较简便 )

1、背景                                                                    

生产者生产数据到缓冲区中,消费者从缓冲区中取数据。

如果缓冲区已经满了,则生产者线程阻塞;

如果缓冲区为空,那么消费者线程阻塞。

2、方式一:synchronized、wait和notify

add()和remove()方法是synchronized 的

package producerConsumer;
//wait 和 notify
public class ProducerConsumerWithWaitNofity {public static void main(String[] args) {Resource resource = new Resource();//生产者线程ProducerThread p1 = new ProducerThread(resource);ProducerThread p2 = new ProducerThread(resource);ProducerThread p3 = new ProducerThread(resource);//消费者线程ConsumerThread c1 = new ConsumerThread(resource);//ConsumerThread c2 = new ConsumerThread(resource);//ConsumerThread c3 = new ConsumerThread(resource);
    p1.start();p2.start();p3.start();c1.start();//c2.start();//c3.start();
    }}
/*** 公共资源类* @author **/
class Resource{//重要//当前资源数量private int num = 0;//资源池中允许存放的资源数目private int size = 10;/*** 从资源池中取走资源*/public synchronized void remove(){if(num > 0){num--;System.out.println("消费者" + Thread.currentThread().getName() +"消耗一件资源," + "当前线程池有" + num + "个");notifyAll();//通知生产者生产资源}else{try {//如果没有资源,则消费者进入等待状态
                wait();System.out.println("消费者" + Thread.currentThread().getName() + "线程进入等待状态");} catch (InterruptedException e) {e.printStackTrace();}}}/*** 向资源池中添加资源*/public synchronized void add(){if(num < size){num++;System.out.println(Thread.currentThread().getName() + "生产一件资源,当前资源池有" + num + "个");//通知等待的消费者
            notifyAll();}else{//如果当前资源池中有10件资源try{wait();//生产者进入等待状态,并释放锁System.out.println(Thread.currentThread().getName()+"线程进入等待");}catch(InterruptedException e){e.printStackTrace();}}}
}
/*** 消费者线程*/
class ConsumerThread extends Thread{private Resource resource;public ConsumerThread(Resource resource){this.resource = resource;}@Overridepublic void run() {while(true){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}resource.remove();}}
}
/*** 生产者线程*/
class ProducerThread extends Thread{private Resource resource;public ProducerThread(Resource resource){this.resource = resource;}@Overridepublic void run() {//不断地生产资源while(true){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}resource.add();}}}

View Code

3、方式二:lock和condition的await、signalAll

package producerConsumer;import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/*** 使用Lock 和 Condition解决生产者消费者问题* @author tangzhijing**/
public class LockCondition {public static void main(String[] args) {Lock lock = new ReentrantLock();Condition producerCondition = lock.newCondition();Condition consumerCondition = lock.newCondition();Resource2 resource = new Resource2(lock,producerCondition,consumerCondition);//生产者线程ProducerThread2 producer1 = new ProducerThread2(resource);//消费者线程ConsumerThread2 consumer1 = new ConsumerThread2(resource);ConsumerThread2 consumer2 = new ConsumerThread2(resource);ConsumerThread2 consumer3 = new ConsumerThread2(resource);producer1.start();consumer1.start();consumer2.start();consumer3.start();}
}
/*** 消费者线程*/
class ConsumerThread2 extends Thread{private Resource2 resource;public ConsumerThread2(Resource2 resource){this.resource = resource;//setName("消费者");
    }public void run(){while(true){try {Thread.sleep((long) (1000 * Math.random()));} catch (InterruptedException e) {e.printStackTrace();}resource.remove();}}
}
/*** 生产者线程* @author tangzhijing**/
class ProducerThread2 extends Thread{private Resource2 resource;public ProducerThread2(Resource2 resource){this.resource = resource;setName("生产者");}public void run(){while(true){try {Thread.sleep((long) (1000 * Math.random()));} catch (InterruptedException e) {e.printStackTrace();}resource.add();}}
}
/*** 公共资源类* @author tangzhijing**/
class Resource2{private int num = 0;//当前资源数量private int size = 10;//资源池中允许存放的资源数目private Lock lock;private Condition producerCondition;private Condition consumerCondition;public Resource2(Lock lock, Condition producerCondition, Condition consumerCondition) {this.lock = lock;this.producerCondition = producerCondition;this.consumerCondition = consumerCondition;}/*** 向资源池中添加资源*/public void add(){lock.lock();try{if(num < size){num++;System.out.println(Thread.currentThread().getName() + "生产一件资源,当前资源池有" + num + "个");//唤醒等待的消费者
                consumerCondition.signalAll();}else{//让生产者线程等待try {producerCondition.await();System.out.println(Thread.currentThread().getName() + "线程进入等待");} catch (InterruptedException e) {e.printStackTrace();}}}finally{lock.unlock();}}/*** 从资源池中取走资源*/public void remove(){lock.lock();try{if(num > 0){num--;System.out.println("消费者" + Thread.currentThread().getName() + "消耗一件资源," + "当前资源池有" + num + "个");producerCondition.signalAll();//唤醒等待的生产者}else{try {consumerCondition.await();System.out.println(Thread.currentThread().getName() + "线程进入等待");} catch (InterruptedException e) {e.printStackTrace();}//让消费者等待
            }}finally{lock.unlock();}}}

View Code

4、方式三:BlockingQueue

package producerConsumer;import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;//使用阻塞队列BlockingQueue解决生产者消费者
public class BlockingQueueConsumerProducer {public static void main(String[] args) {Resource3 resource = new Resource3();//生产者线程ProducerThread3 p = new ProducerThread3(resource);//多个消费者ConsumerThread3 c1 = new ConsumerThread3(resource);ConsumerThread3 c2 = new ConsumerThread3(resource);ConsumerThread3 c3 = new ConsumerThread3(resource);p.start();c1.start();c2.start();c3.start();}
}
/*** 消费者线程* @author tangzhijing**/
class ConsumerThread3 extends Thread {private Resource3 resource3;public ConsumerThread3(Resource3 resource) {this.resource3 = resource;//setName("消费者");
    }public void run() {while (true) {try {Thread.sleep((long) (1000 * Math.random()));} catch (InterruptedException e) {e.printStackTrace();}resource3.remove();}}
}
/*** 生产者线程* @author tangzhijing**/
class ProducerThread3 extends Thread{private Resource3 resource3;public ProducerThread3(Resource3 resource) {this.resource3 = resource;//setName("生产者");
    }public void run() {while (true) {try {Thread.sleep((long) (1000 * Math.random()));} catch (InterruptedException e) {e.printStackTrace();}resource3.add();}}
}
class Resource3{private BlockingQueue<Integer> resourceQueue = new LinkedBlockingQueue<>(10);/*** 向资源池中添加资源*/public void add(){try {resourceQueue.put(1); //1当做生产和消费的Integer资源System.out.println("生产者" + Thread.currentThread().getName()+ "生产一件资源," + "当前资源池有" + resourceQueue.size() + "个资源");} catch (InterruptedException e) {e.printStackTrace();}}/*** 向资源池中移除资源*/public void remove(){try {resourceQueue.take();System.out.println("消费者" + Thread.currentThread().getName() + "消耗一件资源," + "当前资源池有" + resourceQueue.size() + "个资源");} catch (InterruptedException e) {e.printStackTrace();}}
}

View Code

转载于:https://www.cnblogs.com/twoheads/p/10137263.html

【1】生产者-消费者模型的三种实现方式相关推荐

  1. 生产者消费者模型的三种实现方式

    某个线程或模块的代码负责生产数据(工厂),而生产出来的数据却不得不交给另一模块(消费者)来对其进行处理,在这之间使用了队列.栈等类似超市的东西来存储数据(超市),这就抽象除了我们的生产者/消费者模型. ...

  2. 生产者-消费者模式的三种实现方式

    2.生产者-消费者模式的三种实现方式 1.背景                                                                    生产者生产数据到缓 ...

  3. java生产者消费者流程图_Java 生产者消费者模型的三种实现过程

    生产者一边在生产,消费者一边消耗.当库存满的时候生产者暂停生产,直到有空位:当库存空的时候消费者暂停消费,直到有产品. 关键点: 生产者和消费者都是在不断生产和消费的,是同时并发的,不应该等满了再消费 ...

  4. 生产者-消费者模型的两种实现方式

    https://www.cnblogs.com/caolicangzhu/p/7086176.html 本文主要来总结生产者-消费者模型的代码实现,至于其原理,请大家自行百度. 一.基于链表的生产-消 ...

  5. 生产者消费者模式的三种实现方式

    原作者:老铁123 出处:https://blog.csdn.net/qewgd/article/details/85926275 本文归作者[老铁123]和博客园共有,欢迎转载,但未经作者同意必须保 ...

  6. 【Java】生产者消费者模式的三种实现

    原文地址:https://blog.csdn.net/u010983881/article/details/78554671 前言 生产者消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内 ...

  7. 操作系统:生产者消费者模型的两种实现(C++)

    文章目录 生产者消费者模型 什么是生产者消费者模型 生产者消费者模型的321原则 生产者消费者模型的优点 生产者消费者模型的实现方法 基于循环队列,信号量实现 基于阻塞队列,互斥锁.条件变量实现 生产 ...

  8. Java生产者 消费者模型的一种实现

    本文主要介绍java中生产者/消费者模式的实现,对java线程锁机制的一次深入理解. 生产者/消费者模型 生产者/消费者模型要保证,同一个资源在同一时间节点下只能被最多一个线程访问,这个在java中用 ...

  9. 生产者消费者问题Java三种实现

    生产者-消费者Java实现 2017-07-27 1 概述 生产者消费者问题是多线程的一个经典问题,它描述是有一块缓冲区作为仓库,生产者可以将产品放入仓库,消费者则可以从仓库中取走产品. 解决生产者/ ...

最新文章

  1. python基础-第九篇-9.3线程池
  2. python 3.7.732位安装步骤_python安装教程(Windows系统,python3.7为例)
  3. 2的1000 次是超出python表示范围的整数。_第4卷讲解Python语言计算机等级考试二级操作题...
  4. 用神经网络分类随机数与无理数
  5. Topk 问题详解及代码和数据分析
  6. node简介及安装、下载及运行hexo
  7. python爬去百度百科词条_Python爬虫入门学习实践——爬取小说
  8. cefSharp 开发随笔
  9. python 下载csv文件保存到 redis
  10. Tensorflow(r1.4)API--tf.truncated_normal()
  11. 23. 变量、作用域和内存问题
  12. apache 添加虚拟机
  13. 第一部分 第二章 答案合集(part 2)1024-1038
  14. 图灵奖Alan Kay:突破常规思维!道翰天琼认知智能机器人平台API接口大脑为您揭秘
  15. 在追梦的路上,唯独脚踏实地,才能梦想成真
  16. HDU 6617 Enveloping Convex(凸包+半平面交+二分)
  17. 集线器、交换机以及路由器异同 + 冲突域和广播域详解
  18. android SAF存储访问框架
  19. 【MPLS】LDP保留的标签
  20. CentOS wc命令详解

热门文章

  1. 【Linux】FTP文件下载
  2. Linux下获得线程ID syscall(224)
  3. [Redux/Mobx] 你有使用过redux-saga中间件吗?它是干什么的?
  4. javascript学习系列(8):数组中的splice方法
  5. 前端学习(3135):react-hello-react之函数的柯里化
  6. 前端学习(3014):vue+element今日头条管理--自定义验证
  7. [css] 对比下px、em、rem有什么不同?
  8. [css] 说说你对GPU的理解,举例说明哪些元素能触发GPU硬件加速?
  9. 工作213:不能改变父组件值
  10. 前端学习(2239):小滴后台管理系统简介