码迷,mamicode.com
首页 > 编程语言 > 详细

Java并发包中的并发队列简记

时间:2019-10-07 11:19:57      阅读:78      评论:0      收藏:0      [点我收藏+]

标签:queue   循环   方法   not   一个   lin   队列   返回结果   添加   

ConcurrentLinkedQueue

ConcurrentLinkedQueue内部的队列使用带头节点的单向链表实现,并且维持头尾两个指针,头指针出队、尾指针入队。该队列的出队入队操作都是线程安全的。

保证安全的方式

对于头尾指针均使用volatile关键字修饰从而保证可见性,对于头尾指针的修改使用CAS操作保证了原子性。所以对于出入队是线程安全的。

主要方法

offer:入队操作

add:添加元素,内部通过调用offer实现

poll:出队操作,删除队头元素并返回

peek:获取对头元素,不删除结点

size:返回队列的大小,由于队列没有加锁,返回结果可能不准确,在返回时队列有可能被其它线程修改

remove:删除队列中指定的元素,有多个满足的元素时删除第一个

contains:判断是否包含某个元素,和size一样的原因,导致结果也可能不准确

LinkedBlockingQueue

LinkedBlockingQueue同样使用单向链表,并且维持头尾两个指针,另外使用了一个原子变量count来记录当前队列的结点数量。

保证线程安全的方式

对于出队和入队分别设置了takeLock和putLock两个独占锁,保证同一时刻只有一个线程可以进行出队或者入队操作,另外使用notEmpty和notFull两个条件变量用于存由于放入队和出队阻塞的线程。

主要方法

offer:非阻塞的入队操作,如果没有空间,则直接丢弃入队的元素返回false

put:阻塞的入队操作,如果没有空间,就把当前线程放入notFull的条件队列中,并且在获取锁时可相应中断

poll:非阻塞的出队操作,如果队列为空则直接返回false

peek:获取对头元素,不删除队头,该操作也是非阻塞的

take:阻塞的出队操作,如果队列为空,则线程被放入notEmpty条件队列中,并且在获取锁时可相应中断

remove:删除队列指定的元素

size:获取队列的大小,通过count原子变量获取,由于出对入队均加锁,所以结果是准确的

ArrayBlockingQueue

ArrayBlockingQueue与LinkedBlockingQueue的具体操作基本一致,不同点在于ArrayBlockingQueue底层是使用数组实现的循环队列,另外关于加锁方面ArrayBlockingQueue对出队和入队使用的是同一个锁,锁的粒度比LinkedBlockingQueue大,在获取size时ArrayBlockingQueue需要加锁获取,因为count使用的是普通变量。

Java并发包中的并发队列简记

标签:queue   循环   方法   not   一个   lin   队列   返回结果   添加   

原文地址:https://www.cnblogs.com/sasworld/p/11629636.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!