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

Posted sasworld

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java并发包中的并发队列简记相关的知识,希望对你有一定的参考价值。

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并发包中的并发队列简记的主要内容,如果未能解决你的问题,请参考以下文章

Java并发包下锁学习第二篇Java并发基础框架-队列同步器介绍

Java 并发编程 进阶 -- Java并发包中锁原理剖析(LockSupport抽象同步队列AQS独占锁ReentrantLock读写锁ReentrantReadWriteLock)

Java 并发编程 进阶 -- Java并发包中锁原理剖析(LockSupport抽象同步队列AQS独占锁ReentrantLock读写锁ReentrantReadWriteLock)

3.java并发包

Java并发包--LinkedBlockQueue

深入剖析java并发之阻塞队列LinkedBlockingQueue与ArrayBlockingQueue