LinkedBlockingQueue

简介: LinkedBlockingQueue

https://www.jianshu.com/p/cc2281b1a6bc

https://blog.csdn.net/tonywu1992/article/details/83419448

继承关系图

 

 

 

 

/**
     * 节点类,用于存储数据
     */
    static class Node<E> {
        E item;
        Node<E> next;
        Node(E x) { item = x; }
    }
    /**
     * 阻塞队列的大小,默认为Integer.MAX_VALUE
     */
    private final int capacity;
    /**
     * 当前阻塞队列中的元素个数
     */
    private final AtomicInteger count = new AtomicInteger();
    /**
     * 阻塞队列的头结点
     */
    transient Node<E> head;
    /**
     * 阻塞队列的尾节点
     */
    private transient Node<E> last;
    /**
     * 获取并移除元素时使用的锁,如take, poll, etc
     */
    private final ReentrantLock takeLock = new ReentrantLock();
    /**
     * notEmpty条件对象,当队列没有数据时用于挂起执行删除的线程 
     */
    private final Condition notEmpty = takeLock.newCondition();
    /**
     * 添加元素时使用的锁如 put, offer, etc
     */
    private final ReentrantLock putLock = new ReentrantLock();
    /**
     * notFull条件对象,当队列数据已满时用于挂起执行添加的线程
     */
    private final Condition notFull = putLock.newCondition();

这里如果不指定队列的容量大小,也就是使用默认的Integer.MAX_VALUE,如果存在添加速度大于删除速度时候,有可能会内存溢出,这点在使用前希望慎重考虑。

另外,LinkedBlockingQueue对每一个lock锁都提供了一个Condition用来挂起和唤醒其他线程。

默认的构造函数和最后一个构造函数创建的队列大小都为Integer.MAX_VALUE,只有第二个构造函数用户可以指定队列的大小。第二个构造函数最后初始化了last和head节点,让它们都指向了一个元素为null的节点。

最后一个构造函数使用了putLock来进行加锁,但是这里并不是为了多线程的竞争而加锁,只是为了放入的元素能立即对其他线程可见。

put方法来看,它总共做了以下情况的考虑:

队列已满,阻塞等待。

队列未满,创建一个node节点放入队列中,如果放完以后队列还有剩余空间,继续唤醒下一个添加线程进行添加。如果放之前队列中没有元素,放完以后要唤醒消费线程进行消费。

 

链表算法

 

 

private E dequeue() {
    // 获取到head节点
    Node<E> h = head;
    // 获取到head节点指向的下一个节点,也就是节点A
    Node<E> first = h.next;
    // 获取到下下个节点,也就是节点B
    Node<E> next = first.next;
    // head的next指向下下个节点,也就是图中的B节点
    h.next = next;
    // 得到节点A的值
    E x = first.item;
    first.item = null; // help GC
    first.next = first; // help GC
    return x;
}

 

目录
相关文章
|
存储 安全 Java
ArrayBlockingQueue 和 LinkedBlockingQueue 有什么区别?
ArrayBlockingQueue 和 LinkedBlockingQueue 有什么区别?
阻塞队列BlockingQueue
阻塞队列BlockingQueue
57 0
阻塞队列BlockingQueue
|
存储 缓存 安全
JUC之阻塞队列解读(BlockingQueue)
JUC之阻塞队列解读(BlockingQueue)
|
算法
BlockingQueue二
接着上篇BlockingQueue没讲完的 LinkedTransferQueue LinkedTransferQueue是一个由链表结构组成的无界阻塞队列,相对于其它阻塞队列,LinkedBlockingQueue可以算是LinkedBlockingQueue与SynhronoousQueue结合,LinkedtransferQueue是一种无界阻塞队列,底层基于单链表实现,其内部结构分为数据节点、请求节点,基于CAS无锁算法实现
128 0
BlockingQueue二
|
缓存 安全 Java
JUC系列学习(四):线程池阻塞队列BlockingQueue及其相关实现ArrayBlockingQueue、LinkedBlockingQueue
线程池阻塞队列BlockingQueue及其相关实现ArrayBlockingQueue、LinkedBlockingQueue
119 0
|
存储 Java 索引
BlockingQueue
网上看了好多文章将线程池的但是似乎都没的多少人会详细讲解里面的任务队列,所以只有自己动手学习其中的任务队列 BlockingQueue
3070 0
BlockingQueue
|
缓存 安全 Java
JUC - BlockingQueue
JUC - BlockingQueue
135 0
JUC - BlockingQueue
|
消息中间件 存储 Java
阻塞队列 BlockingQueue
学数据结构时学过队列,特点是FIFO,先进先出。那么什么阻塞队列呢?一起来看看。
阻塞队列 BlockingQueue
|
存储 缓存 安全
BlockingQueue 阻塞队列详解(上)
BlockingQueue 是一个 Queue , 它是一个线程安全的阻塞队列接口。 ​
318 0
BlockingQueue 阻塞队列详解(上)
立正、稍息、入"ArrayBlockingQueue"(中)
大家好,我是指北君。 在前面的文章中,已经对 ArrayBlockingQueue 进行了一次源码分析,对它的核心源码做了分析,今天来解析一波同为 BlockingQueue 家族中的一员的 LinkedBlockingQueue。它的底层基于单向链表实现。
立正、稍息、入"ArrayBlockingQueue"(中)