意见箱
恒创运营部门将仔细参阅您的意见和建议,必要时将通过预留邮箱与您保持联络。感谢您的支持!
意见/建议
提交建议

源码角度了解双端队列LinkedBlockingDeque

来源:恒创科技 编辑:恒创科技编辑部
2024-01-28 14:24:59
源码角度了解双端队列LinkedBlockingDeque

LinkedBlockingDeque实现了BlockingDeque接口,既然是双端队列,也就是从两端都可以放入和获取元素

LinkedBlockingDeque和LinkedBlockingDeque差不多,初始容量也是可选的,不设置的话就是Integer的最大值,它有一个ReentrantLock锁和两个Condition条件,分别是非满和非空,既然是一把锁,那么也就是说获取元素和放入元素是互斥的,同一个时刻,只能有一个线程拿到这把锁

putFirst()方法

putFirst()方法就是插入队列元素到头部


源码角度了解双端队列LinkedBlockingDeque

public void putFirst(E e) throws InterruptedException {
    if (e == null) throw new NullPointerException();
    Node<E> node = new Node<E>(e);
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
        while (!linkFirst(node))
            notFull.await();
    } finally {
        lock.unlock();
    }
}
加锁 调用linkFirst()方法,linkFirst()将节点链接为第一个元素,如果已满则返回 false,通知消费者可以取元素了。如果满的话,满足notFull条件的线程阻塞 解锁

也有putLast()方法,把元素插入尾部

takeFirst()方法

takeFirst()方法就是用来获取头部元素的方法

public E takeFirst() throws InterruptedException {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            E x;
            while ( (x = unlinkFirst()) == null)
                notEmpty.await();
            return x;
        } finally {
            lock.unlock();
        }
    }
加锁 调用unlinkFirst()方法来获取元素,如果为空阻塞,unlinkFirst()方法的功能是删除并返回第一个元素,如果为空,则返回 null,这个方法里会唤醒满足notFull条件的线程来放元素 解锁

也有takeLast()方法,用来获取最后一个位置的元素

总结

这篇文章从源码角度分析了LinkedBlockingDeque的功能,包括它的putFirst()方法和takeFirst()方法,LinkedBlockingDeque的实现原理比较简单,它的成员变量主要有一个ReentrantLock锁和两个Condition条件,添加元素和获取元素都是基于链表的操作,这两个操作是互斥的,因为只有一把锁。因为它是双端队列,所以删除元素比较快,随机访问相对数组来说比较慢,但是它的节点需要记录前驱和后继节点,所以占用一定的空间。

❤️ 感谢大家

如果你觉得这篇内容对你挺有有帮助的话:

欢迎关注我❤️,点赞
上一篇: 源码角度了解CopyOnWriteArrayList和CopyOnWriteArraySet 下一篇: 手机怎么远程登录云服务器?