Java之集合(十七)ConcurrentLinkedQueue
转载请注明源出处:http://www.cnblogs.com/lighten/p/7491057.html
1.前言
ConcurrentLinkedQueue是一个无界的线程安全队列,遵循FIFO先进先出的原则。头元素就是队列中存在最长时间的一个元素,即插入元素都是尾插入。检索是从头元素开始,不允许存在空元素。迭代器是弱一致性的,不会抛出并发异常。注意:size方法不是一个线性时间操作,这是由于队列的特点,需要遍历统计,如果遍历过程中有修改,就可能得到错误的结果(如果不是需要具体值,一般使用isEmpty来判断,比size>0快)。此外,bulk操作,即addAll,removeAll,retainAll,containsAll和equals,toArray这些方法不保证原子性。
2.ConcurrentLinkedQueue
2.1 数据结构
数据结构非常简单,就只有一个head和一个tail的Node类型头尾节点,所以其size方法是遍历出来的,由于没有加锁,所以该size实际上可能不正确。

Node节点也十分的简单,只有一个值和下一个节点的引用。不过其替换都是通过CAS操作完成的。

头尾结点初始化为一个值为null的结点。
2.2 基本操作
添加一个元素:

第一时间就将tail节点赋值给t,t就是当前时刻的一个快照。先从单线程开始理解,先插入一个元素1,这个时候q==null,设置p的next为元素1,注意此时tail节点并没有被改变。再插入一个元素2,由于tail没有改变,所以p不为null,p = q = 元素1进入下一个循环,元素1的后面节点为null,所以元素2被设置为元素1的next,此时p!=t,重置元素尾。由这个过程可以看出,tail并不是第一时间进行改变,而是要隔一个以上进行变化。多线程下就存在插队的情况了,被插队了还需要判断是否被插入了多个队,尾结点被改变了就被插入两个并改变了,就需要以最新的尾结点进行循环尝试插入,否则就选择后面一个节点。p==q的情况发生在poll操作的时候:假设队列中只有二个节点,但是在重新定义tail节点的时候被其它线程抢占了,此时head和tail都没有改变。A线程再插入一个元素,此时t=tail,p=tail,在q赋值的时候暂停了,这里要明白head与tail是相等的,是为null的结点。B线程执行poll操作,poll第一次头结点元素是null,不是我们需要的,再次循环,找到元素1。元素1更新头结点的时候,队列的head变成了元素2,但是head的next(null节点)变成了head自己。这个时候回到A线程,tail=head的,q=tail.next=tail=p,就是这样产生的p等于q。如果还没明白参考文章:这里。
取出一个元素:

这里在上面也描述了一些。poll设置头结点也是要跳过一个才会设置头结点。理解了这个,这段代码也就没什么了,也就是通过CAS进行保证线程安全。这里p==q的情况就更简单了,就是offer的情况,不过是同时有两个线程poll而已,B线程成功了,C线程失败了就会产生p==q的情况。
其它的方法就不再进行描述了。该集合使用的时候还是需要注意的,使用不当效率反而会下降。再给一篇参考文章:这里。
Java之集合(十七)ConcurrentLinkedQueue的更多相关文章
- 【Java】集合_学习笔记
一.集合 1.集合类也称容器类,主要负责保存.盛装其他数据. 2.集合可以保存数量不确定的数据,保存具有映射关系的数据(也称关联数组). 3.Java5后提供一些多线程安全的集合类,放在java.ut ...
- java的集合框架最全详解
java的集合框架最全详解(图) 前言:数据结构对程序设计有着深远的影响,在面向过程的C语言中,数据库结构用struct来描述,而在面向对象的编程中,数据结构是用类来描述的,并且包含有对该数据结构操作 ...
- 谈谈Java的集合组件
让我们一起谈谈Java的集合组件 我们在使用Java的时候,都会遇到并使用到Java的集合.在这里通过自己的理解和网上的资源对Java的集合方面的使用做一个简单的讲解和总结. Java主要分为3个集合 ...
- java.util 集合框架集合
java的集合框架为程序提供了一种处理对象组的标准方式.设计了一系列标准泛型接口: ⑴Collection ()接口,扩展了Iterable接口,位于集合层次结构的顶部,因此所有的集合都实现Colle ...
- Java基础——集合框架
Java的集合框架是Java中很重要的一环,Java平台提供了一个全新的集合框架.“集合框架”主要由一组用来操作对象的接口组成.不同接口描述一组不同数据类型.Java平台的完整集合框架如下图所示: 上 ...
- Java学习-集合(转)
在编写java程序中,我们最常用的除了八种基本数据类型,String对象外还有一个集合类,在我们的的程序中到处充斥着集合类的身影!java中集合大家族的成员实在是太丰富了,有常用的ArrayList. ...
- java的集合框架之一
java是一套很成熟的东西,很多商用的东西都喜欢用它,用的人多,稳定.不过一般也不怎么说起它,因为太常见了,私下里说,写java应用层得就像农民工,每一处都是搭积木,根据设计师的东西如何优雅地搭好积木 ...
- 浅谈Java的集合框架
浅谈Java的集合框架 一. 初识集合 重所周知,Java有四大集合框架群,Set.List.Queue和Map.四种集合的关注点不同,Set 关注事物的唯一性,List 关注事物的索引列表,Q ...
- Java之集合初探(一)
一.集合概述.区别 集合是一种容器,数组也是一种容器 在Java编程中,装各种各样的对象(引用类型)的叫做容器. 为什么出现集合类? 面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的 ...
随机推荐
- 24. Indoor Air pollution 室内空气污染
. Indoor Air pollution 室内空气污染 ① Priscilla Ouchida's "energy-efficient"house turned out to ...
- WebService测试工具介绍及下载
1 LoadRunner LoadRunner,是一种预测系统行为和性能的负载测试工具.通过以模拟上千万用户实施并发负载及实时性能监测的方式来确认和查找问 题,LoadRunner能够对整个企业架构 ...
- 微信小程序底部导航Tabbar
1,底部导航栏这个功能是非常常见的一个功能,基本上一个完成的app,都会存在一个导航栏,那么微信小程序的导航栏该怎么实现呢?经过无数的踩坑,终于实现了,好了,先看看效果图. 2,对于底部导航栏,小程序 ...
- Bezier曲线
1. 学习网址 http://give.zju.edu.cn/cgcourse/new/book/8.2.htm
- D3_book 11.1 pie
<!-- pie example --> <!DOCTYPE html> <meta charset="utf-8"> <style> ...
- Citrus Engine简单Demo
Citrus Engine是一个的开源flash平台(platform,也可以说是卷轴类)游戏引擎,它基于Starling Framework添加了各种物理引擎,3D引擎,动画引擎. Citrus实现 ...
- 通过FactoryBean方式来配置bean
1.实现FactoryBean接口的java类: 2.相应的.xml文件:
- 用Java取指定时区的时间 北京时间,纽约时间,班加罗尔时间
/** * 取北京时间 * @return */ public static String getBeijingTime(){ return getFormatedDateString(8); } / ...
- 关于java的volatile关键字与线程栈的内容以及单例的DCL
用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的最新的值.volatile很容易被误用,用来进行原子性操作. package com.guangshan.test; pub ...
- SpringBoot tomcat
该文的前提是已经可以在控制台运行成功,有些时候想放在tomcat里运行 大致分为如下几步 1.配置文件更改 <dependency> <groupId>org.springfr ...