队列是一个先入先出的数据结构(FIFO)队列接口和set,List是同级的。都继承了collection接口。
LinkedList实现了双端接口队列deque。
非阻塞队列
- PriorityQueue
PriorityQueue 类实质上维护了一个有序列表。加入到 Queue 中的元素根据它们的天然排序(通过其 java.util.Comparable 实现)或者根据传递给构造函数的 java.util.Comparator 实现来定位。
- ConcurrentLinkedQueue
ConcurrentLinkedQueue 是基于链接节点的、线程安全的队列。并发访问不需要同步。因为它在队列的尾部添加元素并从头部删除它们,但是并发队列很难统计列表中的数量,因为统计数量需要进行遍历。入队和出队操作均利用CAS(compare and set)更新,这样允许多个线程并发执行,并且不会因为加锁而阻塞线程,使得并发性能更好。
Java并发CAS 指的是现代 CPU 广泛支持的一种对内存中的共享数据进行操作的一种特殊指令。
首 先,CPU 会将内存中将要被更改的数据与期望的值做比较。然后,当这两个值相等时,CPU 才会将内存中的数值替换为新的值。否则便不做操作。最后,CPU 会将旧的数值返回。这一系列的操作是原子的。
简单来说,CAS 的含义是“我认为原有的值应该是什么,如果是,则将原有的值更新为新值,否则不做修改,并告诉我原来的值是多少”
Compare and Set 就是利用 Compare and Swap 实现的非阻塞的线程安全的写操作算法。它的实现过程如下:首先读取你要更改的数据的原值,然后将其和你要更新成的值作为 Compare and Swap 操作的两个参数,如果 Compare and Swap 的返回值和原值不同,便重复这一过程,直至成功。
Compare and Set 是一个非阻塞的算法,这是它的优势。但是有一个问题就是存在这样的可能,在每次读操作之后,写操作之前,都有另外一个线程更改了原先的值,这样 Compare and Set 操作就会不停地重试。但这样的可能只存在于理论,在实际中很少发生。
Compare and Set 广泛使用在 Java 5 中的 Atomic 类中,其它的诸如 ReetrantLock、Semaphore 等的类也通过 AbstractQueuedSynchronizer 类间接地使用了 Compare and Set。
阻塞队列
java.util.concurrent 中加入了 BlockingQueue 接口和五个阻塞队列类。如果队列中没有空间进行阻塞,直到空间可用。
ArrayBlockingQueue :一个由数组支持的有界队列。
LinkedBlockingQueue :一个由链接节点支持的可选有界队列。
PriorityBlockingQueue :一个由优先级堆支持的无界优先级队列。
DelayQueue :一个由优先级堆支持的、基于时间的调度队列。
SynchronousQueue :一个利用 BlockingQueue 接口的简单聚集(rendezvous)机制。
操作
add 增加一个元索 如果队列已满,则抛出一个IIIegaISlabEepeplian异常
remove 移除并返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常
element 返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常
offer 添加一个元素并返回true 如果队列已满,则返回false
poll 移除并返问队列头部的元素 如果队列为空,则返回null
peek 返回队列头部的元素 如果队列为空,则返回null
put 添加一个元素 如果队列满,则阻塞
take 移除并返回队列头部的元素 如果队列为空,则阻塞
网友评论