java并发编程(二十五)----(JUC集合)LinkedBlockingDeque和ConcurrentLinkedDeque介绍
Queue除了前面介绍的实现外,还有一种双向的Queue实现Deque。这种队列允许在队列头和尾部进行入队出队操作,因此在功能上比Queue显然要更复杂。
LinkedBlockingDeque
我们来看一下该类中的成员变量:
public class LinkedBlockingDeque<E>
extends AbstractQueue<E>
implements BlockingDeque<E>, java.io.Serializable {
private static final long serialVersionUID = -387911632671998426L;
static final class Node<E> {
E item;
Node<E> prev;
Node<E> next;
Node(E x) {
item = x;
}
}
transient Node<E> first;
transient Node<E> last;
private transient int count;
private final int capacity;
final ReentrantLock lock = new ReentrantLock();
private final Condition notEmpty = lock.newCondition();
private final Condition notFull = lock.newCondition();
}
有一个内部类Node,该类用来标记queue的节点,capacity最大为Integer.MAX_VALUE。然后使用了独占锁和条件机制来保证线程安全和进行阻塞控制。从上面的结构上我们可以看出:
- 要想支持阻塞功能,队列的容量一定是固定的,否则无法在入队的时候挂起线程。也就是capacity是final类型的。
- 既然是双向链表,每一个结点就需要前后两个引用,这样才能将所有元素串联起来,支持双向遍历。也即需要prev/next两个引用。
- 双向链表需要头尾同时操作,所以需要first/last两个节点,当然可以参考LinkedList那样采用一个节点的双向来完成,那样实现起来就稍微麻烦点。
- 既然要支持阻塞功能,就需要锁和条件变量来挂起线程。这里使用一个锁两个条件变量来完成此功能。
上面对LinkedBlockingDeque的结构做了说明,那么原理就很清晰了,无非是用一个独占锁来保持线程安全,然后用Condition来做阻塞操作。双向链表的操作大家都很熟悉就不做过多解释。
ConcurrentLinkedDeque
ConcurrentLinkedDeque是JSR166y中新增的一个无界并发Deque实现,基于已链接节点的、任选范围的双端队列。在迭代时,队列保持弱一致性,但不会抛出ConcurrentModificationException异常。
我们看一下类的成员变量:
public class ConcurrentLinkedDeque<E>
extends AbstractCollection<E>
implements Deque<E>, java.io.Serializable {
private transient volatile Node<E> head;
private transient volatile Node<E> tail;
private static final Node<Object> PREV_TERMINATOR, NEXT_TERMINATOR;
@SuppressWarnings("unchecked")
Node<E> prevTerminator() {
return (Node<E>) PREV_TERMINATOR;
}
@SuppressWarnings("unchecked")
Node<E> nextTerminator() {
return (Node<E>) NEXT_TERMINATOR;
}
}
我们看到成员变量里面有头节点和尾节点,然后是节点的引用PREV_TERMINATOR, NEXT_TERMINATOR,
双向链表的结构都是一样的。ConcurrentLinkedDeque不是阻塞队列所以没有用到条件原语。我们在成员变量里面没有看到使用ReentrantLock,因为所有的操作都是使用原子操作,避免了使用独占锁造成性能问题。
java并发编程(二十五)----(JUC集合)LinkedBlockingDeque和ConcurrentLinkedDeque介绍的更多相关文章
- java并发编程(十五)----(线程池)java线程池简介
好的软件设计不建议手动创建和销毁线程.线程的创建和销毁是非常耗 CPU 和内存的,因为这需要 JVM 和操作系统的参与.64位 JVM 默认线程栈是大小1 MB.这就是为什么说在请求频繁时为每个小的请 ...
- java并发编程(十)----JUC原子类介绍
今天我们来看一下JUC包中的原子类,所谓原子操作是指不会被线程调度机制打断的操作:这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch (切换到另一个线程),原子操作可以是 ...
- java并发编程(十五)内存可见两种方式 加锁和volatile
1.volatile变量是一种稍弱的同步机制在访问volatile变量时不会执行加锁操作,因此也就不会使执行线程阻塞,因此volatile变量是一种比synchronized关键字更轻量级的同步机制. ...
- java并发编程(十一)----(JUC原子类)基本类型介绍
上一节我们说到了基本原子类的简单介绍,这一节我们先来看一下基本类型: AtomicInteger, AtomicLong, AtomicBoolean.AtomicInteger和AtomicLong ...
- java并发编程笔记(五)——线程安全策略
java并发编程笔记(五)--线程安全策略 不可变得对象 不可变对象需要满足的条件 对象创建以后其状态就不能修改 对象所有的域都是final类型 对象是正确创建的(在对象创建期间,this引用没有逸出 ...
- Java并发编程二三事
Java并发编程二三事 转自我的Github 近日重新翻了一下<Java Concurrency in Practice>故以此文记之. 我觉得Java的并发可以从下面三个点去理解: * ...
- 聊聊高并发(二十五)解析java.util.concurrent各个组件(七) 理解Semaphore
前几篇分析了一下AQS的原理和实现.这篇拿Semaphore信号量做样例看看AQS实际是怎样使用的. Semaphore表示了一种能够同一时候有多个线程进入临界区的同步器,它维护了一个状态表示可用的票 ...
- 并发编程(十五)——定时器 ScheduledThreadPoolExecutor 实现原理与源码深度解析
在上一篇线程池的文章<并发编程(十一)—— Java 线程池 实现原理与源码深度解析(一)>中从ThreadPoolExecutor源码分析了其运行机制.限于篇幅,留下了Scheduled ...
- Java并发(二十):线程本地变量ThreadLocal
ThreadLocal是一个本地线程副本变量工具类. 主要用于将私有线程和该线程存放的副本对象做一个映射,各个线程之间的变量互不干扰,在高并发场景下,可以实现无状态的调用,特别适用于各个线程依赖不同的 ...
随机推荐
- Vue兄弟组件(非父子组件)状态共享与传值
前言:网上大部分文章写的有点乱,很少有讲得易懂的文章. 所以,我写了篇在我能看得懂的基础上又照顾到大家的文章 =.= 作者:X1aoYE 备注:此文原创,转载请注明~ 内容里的<br> ...
- NEST 6.X升级到7.X
升级比对可访问 NEST 6.X升级到7.X 查看 ElasticClient-CreateIndex 升级前代码,NEST版本6.6.0 ICreateIndexResponse response ...
- TCP中的粘包问题,以及用TCP和UDP实现多次聊天
TCP协议 在连接内多和客户端说几句 #server端 import socket sk = socket.socket() sk.bind(('127.0.0.1',9001)) sk.listen ...
- C# 创建Windows服务demo
一.准备工作 1.操作系统:Windows 10 X64 2.开发环境:VS2017 3.编程语言:C# 4. .NET版本:.NET Framework 4.5 二.创建Windows Servic ...
- 广告过滤器 Adguard Pre v6.4.1814 Lite V2 简约绿色版
下载地址:点我 基本介绍 当你在浏览网页的时候总是弹出广告是不是非常的不爽,小编为伙伴们提供了Adguard Pre简约绿色版,一款专业的广告过滤器.Adguard Pre简约绿色版可以帮助伙伴们完美 ...
- 阿里云体验:安装jdk
在阿里云的linux服务器上默认是没有安装java环境的,需要自己安装.查了许多资料,发现这篇文章简洁易用.http://www.cnblogs.com/cloudwind/archive/2012/ ...
- Redis+Twemproxy分片存储实现
from unsplash 为提高Redis存储能力的提升,以及对外提供服务可用性提升,有时候有必要针对Redis进行集群式搭建,比较常用的有Twemproxy分片存储以及官方提供的Cluster方式 ...
- springcloud高可用方案
1. 场景描述 公司在规划后续可能会做中台服务,考虑用微服务的方案,让用springcloud部署个简单的高可用Demo. 2. 解决方案 2.1 方案说明 demo用了5台虚拟机: (1)1台gat ...
- 【译】.NET Core 3.0 发布自包含单体可执行程序
.NET Core 提供的发布应用程序选项 self-contained 是共享应用程序的好方法,因为应用程序的发布目录包含所有组件.运行时和框架.您只需要告诉使用者应用程序的入口 exe 文件,就可 ...
- 通过sparkstreaming分析url的数据
spark version 1.6.2 scala verson 2.10.6 此代码参考官方例子---- 自定义接收器 import java.io.BufferedReader import or ...