public class linkedBlockingDequetake操作extends AbstractQueue implements BlockingDeque , java.io.Serializable { static final class Node { E item; // JDK13中的,jdk8没有 // Node prev; // 队列容量满了,就等待 while (count.get() == capacity) { // 倒过来读:等待不满 notFull.await(); } // 有空位,入队且计数加一 enqueue(node); // 返回的是+1前的值 c = count.getAndIncrement(); if (c + 1 < capacity) // 除了自己put以外,队列还有空位,由自己唤醒之前等待的put线程 // 一次只唤醒一个,避免不必要的竞争 notFull.signal(); } finally { putLock.unlock(); } // 如果队列中中一个元素,叫醒take线程 if (c == 0) // 一次只唤醒一个,避免不必要的竞争 signalNotEmpty(); }
和put类型,不做分析
和Array性能比较:主要列举linkedBlockingQueue(推荐)和ArrayBlockingQueue的性能比较
linked支持有界,Array强制有界linked实现是链表,Array是数组linked是懒惰的,而Array需要提前初始化Node数组linked每次入队会生成新Node,而Array的Node是提前创建好的linked两把锁,Array一把锁 ConcurrentlinkedQueue:
ConcurrentlinkedQueue的设计和linkedBlockingQueue非常像,也是:
两把锁,同一时刻,可以允许两个线程(一个生产者一个消费者)执行dummy节点的引入让两把锁将来锁住的是不同对象,避免竞争只是这锁使用了cas来实现
事实上,ConcurrentlinkedQueue应用还是非常广泛的:
例如之前讲的Tomcat的Connector结构时,Acceptor作为生产者向Poller消费者传递事件信息时,正是采用了ConcurrentlinkedQueue将ScoketChannel给Poller使用:



