欢迎进入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. java location_JAVA setlocation()方法并不能定义组件的位置,setBounds()方法无法改变组件的大小。小白一枚...
  2. 虚拟内存(VirtualAlloc),堆(HeapAlloc/malloc/new)和Memory Mapped File
  3. easyui validatebox验证
  4. 腾讯微信是通过美国服务器传的吗,原来微信和QQ的文件是可以相互传输的!现在才知道,真是太可惜了...
  5. Redis-学习笔记05【Jedis连接池】
  6. nodejs实现文件上传
  7. 设置MAC 下 Vim 语法高亮显示
  8. app嵌入jsp页面的项目工作量_好程序员Java学习路线分享jsp为什么用的不多了
  9. Python和C++交互
  10. maven scm 配置git
  11. 《凤凰项目 一个IT运维的传奇故事》读后感
  12. android edittext 英文数字键盘,Adroid EditText限制输入数字与英文默认弹出数字键盘...
  13. 哪里可以在线转二维码?
  14. 如何快速调出软键盘_软键盘怎么打开,软键盘怎么调出来【图文教程】
  15. vscode中用emmet语法a{}*3无法自动换行
  16. java使用poi读取跨行跨列excel
  17. 适合苹果的蓝牙耳机推荐,音质超好的蓝牙耳机推荐
  18. 设计模式 -- 门面模式
  19. 使用MobaXterm tunneling访问集群(服务器)jupyter notebook
  20. COB小间距的工艺技术,cob小间距相比常规表贴(SMD)小间距有何优势?

热门文章

  1. Android 蓝牙开发(九)A2DP基本功能
  2. 17岁男孩跳下高架桥死亡:你在等父母道歉,父母在等你认错
  3. 灾难恢复全攻略:从定级、规划到实施
  4. 别让你的灵魂跟不上你的脚步_你如何跟上?
  5. 在PWM控制下的直流有刷电机性能优化
  6. Windows 11 Manager v1.1.8 系统优化工具中文便携版
  7. hive中日期格式转换
  8. 04-27 Mysql 考试 55 分 简答题记录
  9. acer台式电脑怎么重装系统_宏碁台式机怎么装系统 宏基台式机装系统操作步骤【图文】...
  10. 如何查看安装的eclipse版本