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编程中,装各种各样的对象(引用类型)的叫做容器. 为什么出现集合类? 面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的 ...
随机推荐
- flex 分页
<?xml version="1.0" encoding="utf-8"?><s:Group xmlns:fx="http://ns ...
- UVaLive 6525 Attacking rooks (二分图最大匹配)
题意:给定一个 n * n的图,X是卒, . 是空位置,让你放尽量多的车,使得他们不互相攻击. 析:把每行连续的 . 看成X集体的一个点,同理也是这样,然后求一个最大匹配即可. 代码如下: #prag ...
- HDU 2136 Largest prime factor (素数打表。。。)
题意:给你一个数,让你求它的最大因子在素数表的位置. 析:看起来挺简单的题,可是我却WA了一晚上,后来终于明白了,这个第一层循环不是到平方根, 这个题和判断素数不一样,只要明白了这一点,就很简单了. ...
- python 实现排列组合
1.python语言简单.方便,其内部可以快速实现排列组合算法,下面做简单介绍. 2.一个列表数据任意组合 2.1主要是利用自带的库 #_*_ coding:utf-8 _*_ #__author__ ...
- 6.<1>四则运算的研究[栈]
计算1+2*3=,这个程序还是比较绕的,先将程序简化,只做+-*/和=五个运算符的关系.首先,假定这五个运算符中,=号的优先级最低,其次是+-,最高为*/.接着约定,"1+2*3=" ...
- 3D indoor map positioning with a smartphone image
menu 1. 基于Tango的三维建模技术(SLAM)(视觉SLAM,RGBD单目深度摄像机+罗盘仪)导出或不导出->Android 三维游戏开发技术(普通Android手机) 2. 基于An ...
- poj3321-Apple Tree(DFS序+树状数组)
Apple Tree Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 36442 Accepted: 10894 Desc ...
- Amazon成本和产出的衡量方式
Amazon用一种T-Shirt Size 估计的方式来做项目. 产品经理会对每一条需求评估上业务影响力的尺寸,如:XXXL 影响一千万人以上或是可以占到上亿美金的市场,XXL,影响百万用户或是占了千 ...
- hdu 5032 不易发觉的树状数组
http://acm.hdu.edu.cn/showproblem.php?pid=5032 给定一个1000x1000的点阵,m组询问,每次询问一个由(0,0).(x,0)点一以及从原点出发的方向向 ...
- Android 了解1G 2G 3G 知识
了解1G 2G 3G 相关知识,对网络通讯制式进行了解即可 1.这种网络通讯制式是一步一步发展起来的,由最开始的1G(最典型的手机,例如:大哥大,1G这种制式只能语音通话). 2.后来出现的2G,2G ...