[java基础-集合篇]LinkedBlockingQueue源码解析
关联较强的上一篇:
[java基础-集合篇]有界阻塞队列ArrayBlockingQueue源码解析-CSDN博客
总的来说。LinkedBlockingQueue 是一个基于链表节点的自定大小的线程安全的阻塞队列。遵循FIFO,结构上一端进一端出的单向队列。
源码注释
|
翻译
|
An optionally-bounded blocking queue based on linked nodes. This queue orders elements FIFO (first-in-first-out). The head of the queue is that element that has been on the queue the longest time. The tail of the queue is that element that has been on the queue the shortest time. New elements are inserted at the tail of the queue, and the queue retrieval operations obtain elements at the head of the queue. Linked queues typically have higher throughput than array-based queues but less predictable performance in most concurrent applications.
The optional capacity bound constructor argument serves as a way to prevent excessive queue expansion. The capacity, if unspecified, is equal to Integer.MAX_VALUE. Linked nodes are dynamically created upon each insertion unless this would bring the queue above capacity.
This class and its iterator implement all of the optional methods of the Collection and Iterator interfaces.
This class is a member of the Java Collections Framework.
|
基于链接节点的可选有界 阻塞队列 。此队列对元素 FIFO (先进先出) 进行排序。队列的 头部 是在队列中停留时间最长的元素。队列的 尾 部是在队列中时间最短的元素。新元素入到队列的尾部,队列检索操作在队列的头部获取元素。链接队列通常比基于阵列的队列具有更高的吞吐量,但在大多数并发应用程序中,性能的可预测性较差。
可选的 capacity bound constructor 参数用作防止过度队列扩展的一种方式。如果未指定,则 capacity 等于 Integer.MAX_VALUE。链接节点在每次插入时动态创建,除非这会使队列超过容量。
这个类及其迭代器实现了 and Iterator 接口的所有Collection可选方法。
此类是 Java Collections Framework 的成员
|
A variant of the "two lock queue" algorithm. The putLock gates
entry to put (and offer), and has an associated condition for
waiting puts. Similarly for the takeLock. The "count" field
that they both rely on is maintained as an atomic to avoid
needing to get both locks in most cases. Also, to minimize need
for puts to get takeLock and vice-versa, cascading notifies are
used. When a put notices that it has enabled at least one take,
it signals taker. That taker in turn signals others if more
items have been entered since the signal. And symmetrically for
takes signalling puts. Operations such as remove(Object) and
iterators acquire both locks.
Visibility between writers and readers is provided as follows:
Whenever an element is enqueued, the putLock is acquired and
count updated. A subsequent reader guarantees visibility to the
enqueued Node by either acquiring the putLock (via fullyLock)
or by acquiring the takeLock, and then reading n = count.get();
this gives visibility to the first n items.
To implement weakly consistent iterators, it appears we need to
keep all Nodes GC-reachable from a predecessor dequeued Node.
That would cause two problems:
|
这是“双锁队列”算法的一个变体。putLock控制进入put(和offer)方法,并有一个关联的条件用于等待put操作。
takeLock同样如此。
它们都依赖的“count”字段被维护为原子操作,以避免在大多数情况下需要获取两个锁。
此外,为了最小化put操作需要获取takeLock以及反之亦然的需求,这里使用了级联通知。
当一个put操作发现它至少使得一个take操作成为可能时,它会向取者发送信号。
如果自信号发出以来有更多元素加入,则该取者进而会向其他取者发送信号。
对put操作向take操作发送信号的情况也是类似的处理方式。
诸如remove(Object)和迭代器的操作需要同时获取这两个锁。
写入者和读者之间的可见性通过以下方式提供:
每当一个元素被入队时,就会获取putLock并更新count。
随后的读者通过要么获取putLock(通过fullyLock方法)要么获取takeLock然后读取n = count.get()来保证能看到入队节点的可见性;这使得前n个项是可见的。
为了实现弱一致性的迭代器,看起来我们需要保持所有节点从一个被移除的前置节点GC可达。这会导致两个问题:
这种设计确保了高并发性能,同时也考虑到了内存管理和垃圾回收的影响,旨在减少不必要的内存占用,并避免由于对象引用跨越不同的垃圾回收代而导致的复杂性。此外,它还讨论了如何通过最小化获取锁的需求和利用级联通知来优化性能。对于迭代器,文中提到了维持弱一致性所带来的挑战,特别是与垃圾收集相关的方面。
|
LinkedBlockingQueue特点
和ArrayBlockingQueue一样,Linked标识着其链表的实现。其他LinkedBlockingQueue主要特点如下:
双锁队列(非公平锁)
可定大小边界的单向链表
生产者消费者模型
LinkedBlockingQueue结构与属性
LinkedBlockingQueue核心方法
put-添加元素(阻塞)
offer方法
take-获取元素(阻塞)
遍历
remove移除
原文地址:https://blog.csdn.net/mdwsmg/article/details/145160588
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!