java并发编程之美 学习笔记
JUC并发队列
jdk提供了一系列场景的并发安全
的队列。按照实现方式的不同分为:
阻塞队列
:—使用锁实现非阻塞队列
: — 使用cas算法实现.
在进行学习之前,回顾一下Queue,Deque
的api。
Queue
队列
通常是FIFO 数据结构.
public interface Queue<E> extends Collection<E> {
/**
* 将指定的元素插入此队列
* 成功时返回 true,
* 如果当前没有可用的空间,则抛出 IllegalStateException。
*/
boolean add(E e);
/**
* 将指定的元素插入此队列(队尾)
* 成功时返回 true,
* 如果当前没有可用的空间,返回false;
*
* 当队列有容量限制时,优于add()方法
*/
boolean offer(E e);
//移除队首;如果此队列为空,抛出NoSuchElementException异常
E remove();
//获取并移除此队列的头,如果此队列为空,则返回 null。
E poll();
//获取但不移除此队列的头;如果此队列为空,抛出NoSuchElementException异常
E element();
//获取但不移除此队列的头;如果此队列为空,则返回 null。
E peek();
}
Deque
Deque继承自Queue,它是一个双向队列结构,支持在两端插入和移除元素
public interface Deque<E> extends Queue<E> {
void addFirst(E e);
void addLast(E e);
boolean offerFirst(E e);
boolean offerLast(E e);
E removeFirst();
E removeLast();
E pollFirst();
E pollLast();
//同Queue element方法;
E getFirst();
E getLast();
E peekFirst();
E peekLast();
//同removeFirstOccurrence ---Queue 并无此方法.
boolean remove(Object o);
//删除第一次出现元素o
boolean removeFirstOccurrence(Object o);
boolean removeLastOccurrence(Object o);
//同addFirst()
void push(E e);
//继承自Queue接口方法 略.....
}
哨兵节点(sentinel)
是一个哑元节点(dummy node)
,可以简化边界条件。是一个附加的链表节点,该节点作为第一个节点,它的值域中并不存储任何东西,只是为了操作的方便而引入的。如果一个链表有哨兵节点的话,那么线性表的第一个元素应该是链表的第二个节点。
带哨兵节点的链表,需要额外的一个节点,但插入和删除等操作不需要额外的判断;不带哨兵节点,在处理链表为空时,和其他情况不一样,需要单独判断一次。
带哨兵节点的链表,插入或删除时,不论操作的位置,表头都不变,不需要额外的判断;不带哨兵节点的链表,插入或删除操作发生在第一个节点时,表头指针都要变化,需要额外的处理。
引用: https://blog.csdn.net/bg2wlj/article/details/52300565
JUC-Queue
ConcurrentLinkedQueue
: 线程安全的、无界的、非阻塞队列。CAS算法实现LinkedBlockingQueue
: 有界的、阻塞队列(也提供非阻塞方法),
. ReentrantLock独占锁实现。–底层使用单向链表
实现ArrayBlockingQueue
: 有界的、阻塞队列(也提供非阻塞方法),
. ReentrantLock独占锁实现。–底层使用数组
实现PriorityBlockingQueue
:带优先级的
、无界的、阻塞队列.DelayQueue
: 无界的、阻塞的、延迟队列
。