0
点赞
收藏
分享

微信扫一扫

源码角度了解双端队列LinkedBlockingDeque

源码角度了解双端队列LinkedBlockingDeque

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

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

putFirst()方法

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

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();
}
}
  1. 加锁
  2. 调用linkFirst()方法,linkFirst()将节点链接为第一个元素,如果已满则返回 false,通知消费者可以取元素了。如果满的话,满足notFull条件的线程阻塞
  3. 解锁

也有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();
}
}
  1. 加锁
  2. 调用unlinkFirst()方法来获取元素,如果为空阻塞,unlinkFirst()方法的功能是删除并返回第一个元素,如果为空,则返回 null,这个方法里会唤醒满足notFull条件的线程来放元素
  3. 解锁

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

总结

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

❤️ 感谢大家

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

  1. 欢迎关注我❤️,点赞👍🏻,评论🤤,转发🙏
  2. 关注盼盼小课堂,定期为你推送好文,还有群聊不定期抽奖活动,可以畅所欲言,与大神们一起交流,一起学习。
  3. 有不当之处欢迎批评指正。
举报

相关推荐

0 条评论