欢迎进入JAVA基础课程

博客地址:https://segmentfault.com/a/1190000019482921
本系列文章将主要针对JAVA一些基础知识点进行讲解,为平时归纳所总结,不管是刚接触JAVA开发菜鸟还是业界资深人士,都希望对广大同行带来一些帮助。若有问题请及时留言或加QQ:243042162。

寄语:
“天眼”之父南仁东,心无旁骛,为崇山峻岭间的中国“天眼”燃尽生命,看似一口“大锅”,天眼是世界上最大、最灵敏的单口径射电望远镜,可以接受百亿光年外的电磁信号。南仁东总工程师执着追求科学梦想的精神,将激励一代又一代科技工作者继续奋斗,勇攀世界科技高峰。作为IT界的从业者,我们需要紧跟时代的步伐,踏过平庸,一生为科技筑梦。

生产者消费者问题

1. 背景

生产者消费者问题(Producer-consumer problem),也称有限缓冲问题(Bounded-buffer problem),是一个多线程同步问题的经典案例。生产者生成一定量的数据放到缓冲区中,然后重复此过程;与此同时,消费者也在缓冲区消耗这些数据。生产者和消费者之间必须保持同步,要保证生产者不会在缓冲区满时放入数据,消费者也不会在缓冲区空时消耗数据。不够完善的解决方法容易出现死锁的情况,此时进程都在等待唤醒。

2. 条件

  • 生产者仅仅在仓储未满时候生产, 仓满则停止生产.
  • 生产者在生产出可消费产品时候, 应该通知等待的消费者去消费.
  • 消费者仅仅在仓储有产品时候才能消费, 仓空则等待.
  • 消费者发现仓储没产品可消费时候会通知生产者生产.

3.实现方式

  • wait() / notify()方法
  • await() / signal()方法
  • BlockingQueue阻塞队列方法
  • Semaphore方法
  • PipedInputStream / PipedOutputStream

下面主要针对前面三种方式做代码实现

(1) wait() / notify()方法

public class ProducerMain {private static Integer count=0;private final Integer full=10;private static String LOCK="LOCK";class  Producer implements Runnable{@Overridepublic void run() {
//            for(int i=0;i<10;i++){
//                try {
//                    Thread.sleep(3000);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//            }synchronized (LOCK){while(count==full){try {LOCK.wait();} catch (InterruptedException e) {e.printStackTrace();}}count++;System.out.println(Thread.currentThread().getName()+"生产者生产,目前共生产了:"+count);LOCK.notifyAll();}}}class Consumer implements Runnable{@Overridepublic void run() {synchronized (LOCK){while (count==0){try {LOCK.wait();} catch (InterruptedException e) {e.printStackTrace();}}count--;System.out.println(Thread.currentThread().getName()+"生产者消费,目前共剩余:"+count);LOCK.notifyAll();}}}public static void main(String[] args) {ProducerMain producer = new ProducerMain();new Thread(producer.new Producer()).start();new Thread(producer.new Consumer()).start();new Thread(producer.new Producer()).start();new Thread(producer.new Consumer()).start();new Thread(producer.new Producer()).start();new Thread(producer.new Consumer()).start();new Thread(producer.new Producer()).start();new Thread(producer.new Consumer()).start();}
}

输出结果

Thread-0生产者生产,目前共生产了:1
Thread-5生产者消费,目前共剩余:0
Thread-2生产者生产,目前共生产了:1
Thread-7生产者消费,目前共剩余:0
Thread-6生产者生产,目前共生产了:1
Thread-1生产者消费,目前共剩余:0
Thread-4生产者生产,目前共生产了:1
Thread-3生产者消费,目前共剩余:0

(2)await() / signal()方法

public class ReentrantLockDemo {private static Integer count = 0;private final Integer FULL = 10;final Lock lock = new ReentrantLock();final Condition NotFull = lock.newCondition();final Condition NotEmpty = lock.newCondition();class Producer implements Runnable {@Overridepublic void run() {for (int i = 0; i < 10; i++) {try {Thread.sleep(3000);} catch (Exception e) {e.printStackTrace();}lock.lock();try {while (count == FULL) {try {NotFull.await();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}count++;System.out.println(Thread.currentThread().getName()+ "生产者生产,目前总共有" + count);NotEmpty.signal();} finally {lock.unlock();}}}}class Consumer implements Runnable {@Overridepublic void run() {for (int i = 0; i < 10; i++) {try {Thread.sleep(3000);} catch (InterruptedException e1) {e1.printStackTrace();}lock.lock();try {while (count == 0) {try {NotEmpty.await();} catch (Exception e) {// TODO: handle exceptione.printStackTrace();}}count--;System.out.println(Thread.currentThread().getName()+ "消费者消费,目前总共有" + count);NotFull.signal();} finally {lock.unlock();}}}}public static void main(String[] args) throws Exception {ReentrantLockDemo hosee = new ReentrantLockDemo();new Thread(hosee.new Producer()).start();new Thread(hosee.new Consumer()).start();new Thread(hosee.new Producer()).start();new Thread(hosee.new Consumer()).start();new Thread(hosee.new Producer()).start();new Thread(hosee.new Consumer()).start();new Thread(hosee.new Producer()).start();new Thread(hosee.new Consumer()).start();}
}

输出结果

Thread-0生产者生产,目前总共有1
Thread-2生产者生产,目前总共有2
Thread-1消费者消费,目前总共有1
Thread-7消费者消费,目前总共有0
Thread-6生产者生产,目前总共有1
Thread-5消费者消费,目前总共有0
Thread-4生产者生产,目前总共有1
Thread-3消费者消费,目前总共有0
Thread-0生产者生产,目前总共有1
Thread-2生产者生产,目前总共有2
Thread-1消费者消费,目前总共有1
Thread-6生产者生产,目前总共有2
Thread-7消费者消费,目前总共有1
Thread-5消费者消费,目前总共有0
Thread-4生产者生产,目前总共有1
Thread-3消费者消费,目前总共有0
Thread-0生产者生产,目前总共有1
Thread-2生产者生产,目前总共有2
Thread-1消费者消费,目前总共有1
Thread-7消费者消费,目前总共有0
Thread-6生产者生产,目前总共有1
Thread-5消费者消费,目前总共有0
Thread-4生产者生产,目前总共有1
Thread-3消费者消费,目前总共有0
Thread-0生产者生产,目前总共有1
Thread-2生产者生产,目前总共有2
Thread-1消费者消费,目前总共有1
Thread-7消费者消费,目前总共有0
Thread-6生产者生产,目前总共有1
Thread-5消费者消费,目前总共有0
Thread-4生产者生产,目前总共有1
Thread-3消费者消费,目前总共有0
Thread-0生产者生产,目前总共有1
Thread-2生产者生产,目前总共有2
Thread-1消费者消费,目前总共有1
Thread-6生产者生产,目前总共有2
Thread-7消费者消费,目前总共有1
Thread-5消费者消费,目前总共有0
Thread-4生产者生产,目前总共有1
Thread-3消费者消费,目前总共有0
Thread-2生产者生产,目前总共有1
Thread-0生产者生产,目前总共有2
Thread-1消费者消费,目前总共有1
Thread-7消费者消费,目前总共有0
Thread-6生产者生产,目前总共有1
Thread-5消费者消费,目前总共有0
Thread-4生产者生产,目前总共有1
Thread-3消费者消费,目前总共有0
Thread-2生产者生产,目前总共有1
Thread-0生产者生产,目前总共有2
Thread-1消费者消费,目前总共有1
Thread-6生产者生产,目前总共有2
Thread-7消费者消费,目前总共有1
Thread-5消费者消费,目前总共有0
Thread-4生产者生产,目前总共有1
Thread-3消费者消费,目前总共有0
Thread-2生产者生产,目前总共有1
Thread-0生产者生产,目前总共有2
Thread-1消费者消费,目前总共有1
Thread-6生产者生产,目前总共有2
Thread-7消费者消费,目前总共有1
Thread-5消费者消费,目前总共有0
Thread-4生产者生产,目前总共有1
Thread-3消费者消费,目前总共有0
Thread-2生产者生产,目前总共有1
Thread-0生产者生产,目前总共有2
Thread-1消费者消费,目前总共有1
Thread-6生产者生产,目前总共有2
Thread-7消费者消费,目前总共有1
Thread-4生产者生产,目前总共有2
Thread-5消费者消费,目前总共有1
Thread-3消费者消费,目前总共有0
Thread-0生产者生产,目前总共有1
Thread-2生产者生产,目前总共有2
Thread-1消费者消费,目前总共有1
Thread-6生产者生产,目前总共有2
Thread-7消费者消费,目前总共有1
Thread-5消费者消费,目前总共有0
Thread-4生产者生产,目前总共有1
Thread-3消费者消费,目前总共有0

(3)BlockingQueue阻塞队列方法

public class BlockingQueueMain {private static Integer count = 0;final BlockingQueue<Integer> bq = new ArrayBlockingQueue<Integer>(10);class Producer implements Runnable {@Overridepublic void run() {for (int i = 0; i < 10; i++) {try {Thread.sleep(3000);} catch (Exception e) {e.printStackTrace();}try {bq.put(1);count++;System.out.println(Thread.currentThread().getName()+ "生产者生产,目前总共有" + count);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}class Consumer implements Runnable {@Overridepublic void run() {for (int i = 0; i < 10; i++) {try {Thread.sleep(3000);} catch (InterruptedException e1) {e1.printStackTrace();}try {bq.take();count--;System.out.println(Thread.currentThread().getName()+ "消费者消费,目前总共有" + count);} catch (Exception e) {// TODO: handle exceptione.printStackTrace();}}}}public static void main(String[] args) throws Exception {BlockingQueueMain hosee = new BlockingQueueMain();new Thread(hosee.new Producer()).start();new Thread(hosee.new Consumer()).start();new Thread(hosee.new Producer()).start();new Thread(hosee.new Consumer()).start();new Thread(hosee.new Producer()).start();new Thread(hosee.new Consumer()).start();new Thread(hosee.new Producer()).start();new Thread(hosee.new Consumer()).start();}
}

输出结果

Thread-1消费者消费,目前总共有0
Thread-4生产者生产,目前总共有1
Thread-0生产者生产,目前总共有0
Thread-5消费者消费,目前总共有0
Thread-3消费者消费,目前总共有0
Thread-2生产者生产,目前总共有1
Thread-6生产者生产,目前总共有1
Thread-7消费者消费,目前总共有0
Thread-4生产者生产,目前总共有1
Thread-1消费者消费,目前总共有0
Thread-0生产者生产,目前总共有1
Thread-5消费者消费,目前总共有0
Thread-2生产者生产,目前总共有1
Thread-3消费者消费,目前总共有0
Thread-6生产者生产,目前总共有0
Thread-7消费者消费,目前总共有0
Thread-4生产者生产,目前总共有0
Thread-1消费者消费,目前总共有0
Thread-0生产者生产,目前总共有1
Thread-5消费者消费,目前总共有0
Thread-2生产者生产,目前总共有1
Thread-3消费者消费,目前总共有0
Thread-6生产者生产,目前总共有1
Thread-7消费者消费,目前总共有0
Thread-4生产者生产,目前总共有1
Thread-1消费者消费,目前总共有0
Thread-0生产者生产,目前总共有1
Thread-5消费者消费,目前总共有0
Thread-2生产者生产,目前总共有1
Thread-3消费者消费,目前总共有0
Thread-6生产者生产,目前总共有1
Thread-7消费者消费,目前总共有0
Thread-4生产者生产,目前总共有2
Thread-0生产者生产,目前总共有1
Thread-1消费者消费,目前总共有0
Thread-5消费者消费,目前总共有1
Thread-2生产者生产,目前总共有1
Thread-3消费者消费,目前总共有0
Thread-6生产者生产,目前总共有1
Thread-7消费者消费,目前总共有0

【全栈之路】JAVA基础课程四_生产者消费者问题(20190614v1.1)相关推荐

  1. 1. JAVA全栈知识体系--- Java基础

    1. JAVA全栈知识体系- Java基础 文章目录 1. JAVA全栈知识体系--- Java基础 1.1 语法基础 面向对象特性? a = a + b 与 a += b 的区别 3*0.1 == ...

  2. 我的全栈之路-Python基础之Python概述与开发环境搭建

    我的全栈之路-Python基础之Python概述与开发环境搭建 我的全栈之路 1.1 信息技术发展趋势 1.2 浅谈计算机系统架构 1.2.1 计算机系统架构概述 1.2.2 计算机硬件系统 1.2. ...

  3. 我的全栈之路-C语言基础之数据存储

    我的全栈之路-C语言基础之数据存储 我的全栈之路 2.1 计算机的计算单位 2.1.1 容量单位 2.1.2 速度单位 2.2 计算机底层为什么只能识别二进制 2.3 进制 2.3.1 进制概述 2. ...

  4. 我的全栈之路-C语言基础之C语言概述与开发环境搭建

    我的全栈之路-C语言基础之C语言概述与开发环境搭建 我的全栈之路 1.1 信息技术发展趋势 1.2 浅谈计算机系统架构 1.2.1 计算机系统架构概述 1.2.2 计算机硬件系统 1.2.2 计算机软 ...

  5. 「全栈之路」Web前端开发的后端指南

    前言 在若干次前的一场面试,面试官看我做过 python爬虫/后端 的工作,顺带问了我些后端相关的问题:你觉得什么是后端? 送命题.当时脑瓦特了,答曰:逻辑处理和数据增删改查... 当场被怼得体无完肤 ...

  6. 「真®全栈之路」Web前端开发的后端指南

    前言 在若干次前的一场面试,面试官看我做过python爬虫/后端 的工作,顺带问了我些后端相关的问题:你觉得什么是后端? 送命题.当时脑瓦特了,答曰:逻辑处理和数据增删改查... 当场被怼得体无完肤, ...

  7. 跳槽者、应届生必看JAVA面试题系列 - JAVA基础知识(四)

    一: 前言 莫等闲,白了少年头,空悲切. 二: 面试挑战   在文章开始前,首先安利下"面试挑战": 凡是满足下面的挑战条件的,如果一个月内没有拿到一个Offer的,免费提供简历封 ...

  8. 1Python全栈之路系列之MySQL数据库基本操作

    Python全栈之路系列之MySQL数据库基本操作 MySQL数据库介绍 MySQL是一种快速易用的关系型数据库管理系统(RDBMS),很多企业都在使用它来构建自己的数据库. MySQL由一家瑞典公司 ...

  9. 4python全栈之路系列之scrapy爬虫s

    python全栈之路系列之scrapy爬虫 An open source and collaborative framework for extracting the data you need fr ...

最新文章

  1. 团队项目第一次冲刺第三天
  2. 学习速率 learning rate
  3. 程序员面试不完全指南
  4. libcurl库进行http通讯网络编程
  5. 施一公:培养本科生比培养博士生要难
  6. web_find()函数检查中文字符串失败的处理方法
  7. 用php脚本获取服务内容,如何使用PHP脚本仅获取数据库的内容
  8. MySQL The JSON Data Type(JSON格式数据)
  9. Java程序员必会!没有返回值的构造函数是怎么完成赋值的?
  10. arm x86 区别_深入了解arm架构和x86架构有什么区别及各自的优势选型者重点查看...
  11. 华为vlan简单配置
  12. MES管理系统应用环境分析,以及实施面临的挑战
  13. 你用过Elasticsearch Percolate 反向检索吗?
  14. IP安全,DDoS攻击、tearDrop攻击和微小IP碎片攻击
  15. 【SSO】单点登录系统实现
  16. 关于华为ensp一些报错处理分享及基础命令
  17. java什么是类枚举类_java枚举类型是什么?
  18. 独热编码(One-Hot Encoding)
  19. AVPlayer进行视频播放
  20. 【3】 Shell基本系统命令

热门文章

  1. 代码随想录Day61
  2. echarts实现2d柱状_Echart---多项柱状图-2D/H5
  3. 蛇形线的作用、特点总结
  4. 手把手教你如何将有线音箱改装成蓝牙音箱
  5. 一篇文章读懂Java类加载器
  6. 【珍爱生命,抵制淘宝,淘宝售后!!!只售不后】
  7. ROS限速、防syn、ip伪装、mac绑定、防火墙、屏蔽端口
  8. redis梦魇:阻塞问题(鼠标打开图片更清晰)
  9. C# DialogResult.OK == Form.ShowDialog()
  10. java后台将html转换为图片