BlockingQueue

BlockingQueue、解决了多线程中,如何高效安全“传输”数据的问题。程序员无需关心什么时候阻塞线程,什么时候唤醒线程,该唤醒哪个线程。

方法介绍


BlockingQueue是Queue的子类

void put(E e)

插入指定元素,当BlockingQueue为满,则线程阻塞,进入Waiting状态,直到BlockingQueue有空闲空间再继续。
这里以ArrayBlockingQueue为例进行分析

void take()

队首出队,当BlockingQueue为空,则线程阻塞,进入Waiting状态,直到BlockingQueue不为空再继续。

int drainTo(Collection<? super E> c)

从队列中批量取出数据,并放入到另一个集合中,返回转移数据的数量,只需一次加锁和解锁。

BlockingQueue的实现类

ArrayBlockingQueue

    /** Concurrency control uses the classic two-condition algorithm* found in any textbook.*//** Main lock guarding all access */final ReentrantLock lock;/** Condition for waiting takes */private final Condition notEmpty;/** Condition for waiting puts */private final Condition notFull;

基于数组实现的BlockingQueue,需要指定队列容量,可以指定是否为公平锁;只有一个ReentrantLock,生产者和消费者不能异步执行。

LinkedBlockingQueue

    /** Lock held by take, poll, etc */private final ReentrantLock takeLock = new ReentrantLock();/** Wait queue for waiting takes */private final Condition notEmpty = takeLock.newCondition();/** Lock held by put, offer, etc */private final ReentrantLock putLock = new ReentrantLock();/** Wait queue for waiting puts */private final Condition notFull = putLock.newCondition();

基于链表实现的BlockingQueue,可以指定队列容量,不指定队列容量默认为Integer.MAX_VALUE;有两个ReentrantLock,生产者和消费者可以异步执行。

BlockingQueue实现生产者消费者模型

  • 缓冲区可以存放大量数据
  • 生产者和消费者速度各不相同
public class MyThread42 {public static void main(String[] args){final BlockingQueue<String> bq = new ArrayBlockingQueue<String>(10);Runnable producerRunnable = new Runnable(){int i = 0;public void run(){while (true){try{System.out.println("我生产了一个" + i++);bq.put(i + "");Thread.sleep(1000);}catch (InterruptedException e){e.printStackTrace();}}}};Runnable customerRunnable = new Runnable(){public void run(){while (true){try{System.out.println("我消费了一个" + bq.take());Thread.sleep(3000);}catch (InterruptedException e){e.printStackTrace();}}}};Thread producerThread = new Thread(producerRunnable);Thread customerThread = new Thread(customerRunnable);producerThread.start();customerThread.start();}
}

输出结果如下

我生产了一个0
我消费了一个1
我生产了一个1
我生产了一个2
我消费了一个2
我生产了一个3
我生产了一个4
我生产了一个5
我消费了一个3
我生产了一个6
我生产了一个7
我生产了一个8
我消费了一个4
我生产了一个9
我生产了一个10
我生产了一个11
我消费了一个5
我生产了一个12
我生产了一个13
我生产了一个14
我消费了一个6
我生产了一个15
我生产了一个16
我消费了一个7
我生产了一个17
我消费了一个8
我生产了一个18
我消费了一个9
我生产了一个19
我消费了一个10
我生产了一个20
我消费了一个11
我生产了一个21
我消费了一个12
我生产了一个22
我消费了一个13
我生产了一个23
我消费了一个14
我生产了一个24······

生产者没有生产到BlockingQueue的容量(极限是10)之前,生产3个,消费1个,再生产到BlockingQueue的容量之后,生产一个消费一个,因为不能超过BlockingQueue的容量。

转载于:https://www.cnblogs.com/Java-Starter/p/11315057.html

Java多线程(十):BlockingQueue实现生产者消费者模型相关推荐

  1. 【Linux入门】多线程(线程概念、生产者消费者模型、消息队列、线程池)万字解说

    目录 1️⃣线程概念 什么是线程 线程的优点 线程的缺点 线程异常 线程异常 Linux进程VS线程 2️⃣线程控制 创建线程 获取线程的id 线程终止 等待线程 线程分离 3️⃣线程互斥 进程线程间 ...

  2. Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例

    Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例 本文由 TonySpark 翻译自 Javarevisited.转载请参见文章末尾的要求. Java.util.concurr ...

  3. 【Linux篇】第十六篇——生产者消费者模型

    生产者消费者模型 生产者消费者模型的概念 生产者消费者模型的特点 生产者消费者模型优点 基于BlockingQueue的生产消费者模型 基于阻塞队列的生产者消费者模型 模拟实现基于阻塞队列的生产消费模 ...

  4. Linux 多线程编程(实现生产者消费者模型)

    Linux 多线程编程 线程分类 线程按照其调度者可以分为用户级线程和内核级线程两种. 内核级线程 在一个系统上实现线程模型的方式有好几种,因内核和用户空间提供的支持而有一定程度的级别差异.最简单的模 ...

  5. Java多线程(3)—生产者/消费者

    这个是一个典型的线程问题.生成者(Productor)生产商品并交给店员(Clerk),消费者(Customer)从店员处购买商品,店员一次性只能购买固定数量的产品,如果生产者试图生成更多的商品,店员 ...

  6. Java多线程之并发协作生产者消费者设计模式

    转载请注明出处:blog.csdn.net/linglongxin- 两个线程一个生产者个一个消费者 需求情景 两个线程,一个负责生产,一个负责消费,生产者生产一个,消费者消费一个 涉及问题 同步问题 ...

  7. 用java智能锁远程,从生产者-消费者模型了解线程、同步、锁(java)

    代码主要包括4个类和1个测试类: 1.Egg 类: 鸡蛋,可以由生产者放入到篮子中,供消费者消费食用. 2.Blanket 类:一个篮子,最多能装5个鸡蛋. 3.Producer 类: 生产者(可以有 ...

  8. 【Java】生产者消费者模型

    [Java]生产者消费者模型 0x1 前言 生产者和消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一个存储空间,生产者往存储空间中添加产品,消费者从存储空间中取走产品,当存储空间 ...

  9. < Linux > 多线程(生产者消费者模型)

    目录 1.生产者消费者模型 生产者消费者模型的例子 生产者消费者模型的特点 生产者消费者模型的优点 2.基于BlockingQueue的生产者消费者模型 概念 模拟实现基于阻塞队列的生产消费模型 基于 ...

最新文章

  1. JAVA面向对象的特征
  2. java回退一格_api短信接口
  3. iOS 中strong,weak,copy,assign区别
  4. 【STM32】新建基于STM32F40x 固件库的MDK5 工程
  5. Java程序员应该知道的10个Eclipse调试技巧
  6. Python __call__()方法
  7. mysql外建名是随机的吗_创建角色随机名字(mysql抽取随机记录)和mysql游标的使用_MySQL...
  8. Linux 上最好的视频编辑软件
  9. C语言库函数查找工具MSDN
  10. Java面试知识点概览(持续更新)
  11. vue-cli脚手架中使用talkingData埋点的方法
  12. 力扣42.接雨水C++解法
  13. vi使用的时候按esc后按**shift + :**时进入不了末行
  14. 微信小程序学习第8天——自定义组件的数据监听器Observer小案例
  15. 关于SpringOpenSessionInViewFilter的配置及处理方案
  16. 工作多年,我对架构的一些理解
  17. 按广义表表示二叉树结构生成二叉树链表的算法
  18. angular5解决chrome等浏览器不能播放.m3u8视频流
  19. 创建SpringMVC项目的基本步骤
  20. 一次Oday提权批量拿取商城服务器root权限

热门文章

  1. JAVA引用类型在变量槽,浅析Java的内存模型
  2. 从数学到计算机 从莱布尼兹到冯诺依曼 从数理逻辑到算法分析
  3. 【Java】Java反射异常处理之InvocationTargetException
  4. JAVA抽象类和接口的深入探讨
  5. 算法导论-堆排序习题解
  6. 编程珠玑---第二章 啊哈!算法
  7. Linux内存管理(一)——从硬件角度看内存管理
  8. mysql replace update_mysql的replace,存在更新,不存在插入
  9. access的papersize命令_[access报表]报表中使用自定义纸张,及设置自定义纸张大小
  10. (36)FPGA打N拍设计(第8天)