源码角度了解双端队列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(); } }
加锁
调用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条件,添加元素和获取元素都是基于链表的操作,这两个操作是互斥的,因为只有一把锁。因为它是双端队列,所以删除元素比较快,随机访问相对数组来说比较慢,但是它的节点需要记录前驱和后继节点,所以占用一定的空间。
❤️ 感谢大家
如果你觉得这篇内容对你挺有有帮助的话:
欢迎关注我❤️,点赞👍🏻,评论🤤,转发🙏
关注盼盼小课堂,定期为你推送好文,还有群聊不定期抽奖活动,可以畅所欲言,与大神们一起交流,一起学习。
有不当之处欢迎批评指正。