深入浅出 Java Concurrency (25): 并发容器 part 10 双向并发阻塞队列 BlockingDeque[转]
这个小节介绍Queue的最后一个工具,也是最强大的一个工具。从名称上就可以看到此工具的特点:双向并发阻塞队列。所谓双向是指可以从队列的头和尾同时操作,并发只是线程安全的实现,阻塞允许在入队出队不满足条件时挂起线程,这里说的队列是指支持FIFO/FILO实现的链表。
首先看下LinkedBlockingDeque的数据结构。通常情况下从数据结构上就能看出这种实现的优缺点,这样就知道如何更好的使用工具了。
![]()
从数据结构和功能需求上可以得到以下结论:
- 要想支持阻塞功能,队列的容量一定是固定的,否则无法在入队的时候挂起线程。也就是capacity是final类型的。
- 既然是双向链表,每一个结点就需要前后两个引用,这样才能将所有元素串联起来,支持双向遍历。也即需要prev/next两个引用。
- 双向链表需要头尾同时操作,所以需要first/last两个节点,当然可以参考LinkedList那样采用一个节点的双向来完成,那样实现起来就稍微麻烦点。
- 既然要支持阻塞功能,就需要锁和条件变量来挂起线程。这里使用一个锁两个条件变量来完成此功能。
有了上面的结论再来研究LinkedBlockingDeque的优缺点。
优点当然是功能足够强大,同时由于采用一个独占锁,因此实现起来也比较简单。所有对队列的操作都加锁就可以完成。同时独占锁也能够很好的支持双向阻塞的特性。
凡事有利必有弊。缺点就是由于独占锁,所以不能同时进行两个操作,这样性能上就大打折扣。从性能的角度讲LinkedBlockingDeque要比LinkedBlockingQueue要低很多,比CocurrentLinkedQueue就低更多了,这在高并发情况下就比较明显了。
前面分析足够多的Queue实现后,LinkedBlockingDeque的原理和实现就不值得一提了,无非是在独占锁下对一个链表的普通操作。
有趣的是此类支持序列化,但是Node并不支持序列化,因此fist/last就不能序列化,那么如何完成序列化/反序列化过程呢?
清单1 LinkedBlockingDeque的序列化、反序列化
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException {
lock.lock();
try {
// Write out capacity and any hidden stuff
s.defaultWriteObject();
// Write out all elements in the proper order.
for (Node<E> p = first; p != null; p = p.next)
s.writeObject(p.item);
// Use trailing null as sentinel
s.writeObject(null);
} finally {
lock.unlock();
}
}private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
s.defaultReadObject();
count = 0;
first = null;
last = null;
// Read in all elements and place in queue
for (;;) {
E item = (E)s.readObject();
if (item == null)
break;
add(item);
}
}
清单1 描述的是LinkedBlockingDeque序列化/反序列化的过程。序列化时将真正的元素写入输出流,最后还写入了一个null。读取的时候将所有对象列表读出来,如果读取到一个null就表示结束。这就是为什么写入的时候写入一个null的原因,因为没有将count写入流,所以就靠null来表示结束,省一个整数空间。
深入浅出 Java Concurrency (25): 并发容器 part 10 双向并发阻塞队列 BlockingDeque[转]的更多相关文章
- 深入浅出 Java Concurrency (15): 锁机制 part 10 锁的一些其它问题
主要谈谈锁的性能以及其它一些理论知识,内容主要的出处是<Java Concurrency in Practice>,结合自己的理解和实际应用对锁机制进行一个小小的总结. 首先需要强调的 ...
- 深入浅出 Java Concurrency (15): 锁机制 part 10 锁的一些其它问题[转]
主要谈谈锁的性能以及其它一些理论知识,内容主要的出处是<Java Concurrency in Practice>,结合自己的理解和实际应用对锁机制进行一个小小的总结. 首先需要强调的一点 ...
- [转] 多线程 《深入浅出 Java Concurrency》目录
http://ifeve.com/java-concurrency-thread-directory/ synchronized使用的内置锁和ReentrantLock这种显式锁在java6以后性能没 ...
- 《深入浅出 Java Concurrency》目录
最近在学习J.U.C,看到一个大神 关于这个系列写的非常精辟,由于想做笔记,故系列转载并记录之. 原文:http://www.blogjava.net/xylz/archive/2010/07/08/ ...
- 深入浅出 Java Concurrency - 目录 [转]
这是一份完整的Java 并发整理笔记,记录了我最近几年学习Java并发的一些心得和体会. J.U.C 整体认识 原子操作 part 1 从AtomicInteger开始 原子操作 part 2 数组. ...
- Java并发(十八):阻塞队列BlockingQueue
阻塞队列(BlockingQueue)是一个支持两个附加操作的队列. 这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空.当队列满时,存储元素的线程会等待队列可用. 阻塞队列常用于生产 ...
- 《深入浅出 Java Concurrency》—并发容器 ConcurrentMap
(转自:http://blog.csdn.net/fg2006/article/details/6404226) 在JDK 1.4以下只有Vector和Hashtable是线程安全的集合(也称并发容器 ...
- 深入浅出 Java Concurrency (21): 并发容器 part 6 可阻塞的BlockingQueue (1)[转]
在<并发容器 part 4 并发队列与Queue简介>节中的类图中可以看到,对于Queue来说,BlockingQueue是主要的线程安全版本.这是一个可阻塞的版本,也就是允许添加/删除元 ...
- 深入浅出 Java Concurrency (16): 并发容器 part 1 ConcurrentMap (1)[转]
从这一节开始正式进入并发容器的部分,来看看JDK 6带来了哪些并发容器. 在JDK 1.4以下只有Vector和Hashtable是线程安全的集合(也称并发容器,Collections.synchro ...
随机推荐
- fastReport.net 初了解
delphi 中fastReport rmReport都很好用,转到.net了,第一想法也是这两个,好在这里有个fastReport; 这个安装呢 找个破解的 有个4.x版 安完建一个winForm ...
- NEO4J中文分词全文索引自动更新解决方案
NEO4J中文分词全文索引自动更新解决方案 一.样例数据 二.英文与中文全文索引差别 1.创建NEO4J默认索引 2.删除索引 3.创建支持中文分词的索引 三.APOC自带英文全文索引过程(可自动更新 ...
- 生产环境Docker部署ELK跨区访问kafka不通问题的解决
由于分布式系统的日志集中采集的需求非常强烈,我们组通过调研和实践搭建了一套基于Docker的日志收集系统Amethyst. 我们首先在测试环境搭建了一套基于Docker swarm集群的ELK分布式环 ...
- Balking Pattern不需要就不用做
word自动保存功能,如果文档被修改了,后台线程每隔一段时间会自动执行保存功能,但是如果用户在自动保存之前用Ctrl+S手动保存呢?自动保存还会执行吗?答案是不会,因为这个操作时不需要重复做的. pu ...
- Spark应用程序
- 解决VS2012新建MVC4等项目时,收到此模板加载程序集“NuGet.VisualStudio.Interop…”的错误
1.错误如图所示: 2.不管是VS2012,还是2013如果开始没安装Nuget包都或报这个错,因为VS2012就已经全面切换到使用NuGet这个第三方开源工具来管理项目包和引用模块了,使用VS201 ...
- vue项目 上传到git
1. git add . 效果: 2. git commit -m '' 3. git push 效果: 4.在码云上就可以看到修改啦 2018-05-19 08:52:52
- 解决 php Call to undefined function shm_attach()
学习php 多进程的时候,运行脚本报错 Call to undefined function shm_attach() ,搜了一下,看到stack overflow 里面提示需要配置这些扩展 exte ...
- SpringMVC的孪生兄弟WebFlux
一.入门文字介绍 官方口水话简短翻译: Spring WebFlux是一个非阻塞的Web框架,用于利用多核,短时间可一处理大量并发连接. 非阻塞式 在servlet3.1提供了非阻塞的API,WebF ...
- duilib教程之duilib入门简明教程18.其他
一.超链接按钮 代码很简单,参见360Demo: <Button text="{u}{a}求助{/a}{/u}" showhtml="true&qu ...