并发基础_12_并发_容器_阻塞队列
来源:互联网 发布:pdb数据库怎么用 编辑:程序博客网 时间:2024/05/29 13:18
阻塞队列接口
阻塞队列BlockingQueue接口是一个支持两个附加操作的队列。
这两个附加操作支持阻塞的插入和阻塞的移除方法。
a. 支持阻塞的插入方法:当队列满时,队列会阻塞插入元素的线程,直到队列有空余位置。
b. 支持阻塞的移除方法:队列为空时,获取元素的线程会等待队列中有元素。
阻塞队列常用于生产者与消费者的场景,生产者是向队列里添加元素的线程,消费者是从队列里取元素的线程。
(JDK API)
BlockingQueue 方法以四种形式出现,对于不能立即满足但可能在将来某一时刻可以满足的操作,这四种形式的处理方式不同:
第一种是抛出一个异常,
第二种是返回一个特殊值(null 或 false,具体取决于操作),
第三种是在操作可以成功前,无限期地阻塞当前线程,
第四种是在放弃前只在给定的最大时间限制内阻塞
BlockingQueue不支持null元素。
BlockingQueue可以限定容量。
Java中的阻塞队列
(JDK7)
ArrayBlockingQueue
由数组结构组成的有界阻塞队列
此队列按照FIFO原则对元素进行排序,默认情况下不保证线程公平的访问队列
LinkedBlockingQueue
由链表结构组成的有界阻塞队列
此队列默认和最大长度为Integter.MAX_VALUE,按照FIFO原则对元素进行排序
PriorityBlockingQueue
支持优先级排序的无界阻塞队列
此队列支持优先级的无界阻塞队列,默认情况下采用自然顺序升序排序
DelayQueue
使用优先级队列实现的无界队列
此队列支持延时获取元素的无界阻塞队列,队列元素必须实现Delayed接口。
在创建元素时,可以指定多久才能从队列中获取当前元素,只有在延迟期满时,才能从队列中获取元素。
SynchronusQueue
不存储元素的阻塞队列
此队列不存储元素的阻塞队列,每一个put操作必须等待一个take操作,否则不能继续添加元素。
LinkedTransferQueue
由链表结构组成的无界阻塞队列
LinkedBlockingDeque
由链表结构组成的双向阻塞队列
双向队列指的是可以从队列两端插入和移除元素。
阻塞队列Demo就下面一个栗子,阻塞队列另一个使用场景是线程池中的使用。
LinkedBlockingQueue的Demo
LinkedBlockingQueue的实现是线程安全的,实现了FIFO(先进先出)等特性,是作为生产者、消费者的首选。
主要方法:
put:在队列满时会阻塞,直到有队列成员被消费
take:在队列空时阻塞,直到有队列成员进来。
/*** 装苹果的篮子* * @author CYX* @time 2017年7月31日上午8:52:25*/public class Basket {// 篮子,能够容纳3个苹果BlockingQueue<String> basket = new LinkedBlockingQueue<>(3);/** * 生产苹果,放入篮子 * * @throws Exception */public void produce() throws Exception {basket.put("An apple");}/** * 消费苹果,从篮子中拿走 * * @return * @throws Exception */public String consume() throws Exception {return basket.take();}}/*** 苹果生产者* * @author CYX* @time 2017年7月31日上午9:08:42*/public class Producer implements Runnable {private String instance;private Basket basket;public Producer(String instance, Basket basket) {this.instance = instance;this.basket = basket;}@Overridepublic void run() {try {while (true) {// 生产苹果System.out.println("生产者准备生产苹果:" + instance);basket.produce();System.out.println("生产者生产苹果完毕:" + instance);Thread.sleep(300);}} catch (Exception e) {e.printStackTrace();}}}/*** 苹果消费者* * @author CYX* @time 2017年7月31日上午9:24:05*/public class Consumer implements Runnable {private String instance;private Basket basket;public Consumer(String instance, Basket basket) {this.instance = instance;this.basket = basket;}@Overridepublic void run() {try {while (true) {// 消费苹果System.out.println("消费者准备消费苹果:" + instance);System.out.println(basket.consume());System.out.println("消费者消费苹果完毕:" + instance);// 休眠1000msThread.sleep(1000);}} catch (Exception e) {e.printStackTrace();}}}/*** 多线程模拟实现生产者/消费者模型* * @author CYX* @time 2017年7月31日上午8:48:43*/public class BlockingQueueTest {public static void main(String[] args) {Basket basket = new Basket();ExecutorService service = Executors.newCachedThreadPool();Producer producer = new Producer("生产者01", basket);Producer producer2 = new Producer("生产者02", basket);Consumer consumer = new Consumer("消费者01", basket);service.submit(producer);service.submit(producer2);service.submit(consumer);}}输出结果:生产者准备生产苹果:生产者01生产者生产苹果完毕:生产者01消费者准备消费苹果:消费者01An apple消费者消费苹果完毕:消费者01生产者准备生产苹果:生产者02生产者生产苹果完毕:生产者02生产者准备生产苹果:生产者01生产者生产苹果完毕:生产者01生产者准备生产苹果:生产者02生产者生产苹果完毕:生产者02生产者准备生产苹果:生产者01生产者准备生产苹果:生产者02消费者准备消费苹果:消费者01An apple消费者消费苹果完毕:消费者01生产者生产苹果完毕:生产者01生产者准备生产苹果:生产者01消费者准备消费苹果:消费者01An apple消费者消费苹果完毕:消费者01生产者生产苹果完毕:生产者02生产者准备生产苹果:生产者02消费者准备消费苹果:消费者01An apple消费者消费苹果完毕:消费者01生产者生产苹果完毕:生产者01生产者准备生产苹果:生产者01
- 并发基础_12_并发_容器_阻塞队列
- 并发基础_10_并发_容器_ConcurrentHashMap
- 并发基础_11_并发_容器_ConcurrentLinkedQueue
- 并发基础_7_并发_锁_队列同步器(AQS)
- Java并发编程:同步容器、并发容器和阻塞队列
- Java并发容器之阻塞队列简介
- 并发基础_1_并发_底层实现
- 并发基础_3_并发_线程
- 并发基础_6_并发_锁
- 并发基础_8_并发_锁_重入锁
- 【Java基础】并发 - 多线程 - 阻塞队列
- java并发-阻塞队列
- 并发 阻塞队列
- 阻塞式并发队列
- Java同步队列(非阻塞队列与阻塞队列)——java并发容器
- 并发基础_9_并发_锁_读写锁_未详解
- 并发基础_4_并发_线程间通信
- 并发基础_13_并发_框架_Fork/Join
- 中科燕园GIS外包团队 基于三维数字地图的数字物业建设及研究
- SPFA
- 开题
- linux上搭建ftp服务器
- html5的本地存储
- 并发基础_12_并发_容器_阻塞队列
- Linux常用命令大全(新手入门)
- 【oracle】用户权限及角色管理
- 第8章 Vue.js工程实例
- 内存多通道对fluent运算速度的影响
- bootstrap table 导出所有全部数据
- LeetCode
- password_hash
- SPOJ SUBST1