源码角度了解双端队列LinkedBlockingDeque
【摘要】 源码角度了解双端队列LinkedBlockingDequeLinkedBlockingDeque实现了BlockingDeque接口,既然是双端队列,也就是从两端都可以放入和获取元素LinkedBlockingDeque和LinkedBlockingDeque差不多,初始容量也是可选的,不设置的话就是Integer的最大值,它有一个ReentrantLock锁和两个Condition条件,...
源码角度了解双端队列LinkedBlockingDeque
LinkedBlockingDeque实现了BlockingDeque接口,既然是双端队列,也就是从两端都可以放入和获取元素
LinkedBlockingDeque和LinkedBlockingDeque差不多,初始容量也是可选的,不设置的话就是Integer的最大值,它有一个ReentrantLock锁和两个Condition条件,分别是非满和非空,既然是一把锁,那么也就是说获取元素和放入元素是互斥的,同一个时刻,只能有一个线程拿到这把锁
putFirst()方法
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();
}
}
- 第一步同样是先进行加锁
- 调用linkFirst()方法,linkFirst()将节点链接为第一个元素,如果已满则返回 false,通知消费者可以取元素了。如果满的话,满足notFull条件的线程阻塞
- 最后进行解锁
也有putLast()方法,把元素插入尾部
takeFirst()方法
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条件,添加元素和获取元素都是基于链表的操作,这两个操作是互斥的,因为只有一把锁。因为它是双端队列,所以删除元素比较快,随机访问相对数组来说比较慢,但是它的节点需要记录前驱和后继节点,所以占用一定的空间。文章若有不当之处欢迎批评指正。
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)