初始化后如何更新java.util.concurrent.ConcurrentLinkedQueue#head?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了初始化后如何更新java.util.concurrent.ConcurrentLinkedQueue#head?相关的知识,希望对你有一定的参考价值。
环境:java:java version "1.8.0_201"
操作系统:Ubuntu 16.04.6 LTS Linux version 4.15.0-91-generic
最近我阅读了java.util.concurrent.ConcurrentLinkedQueue#offer
的源代码,并对下面的代码感到困惑。
public boolean offer(E e){
checkNotNull(e);
final Node<E> newNode = new Node<E>(e);
for (Node<E> t = tail, p = t; ; ) {
Node<E> q = p.next;
if (q == null) {
// p is last node
if (p.casNext(null, newNode)) {
......
初始化ConcurrentLinkedQueue
时,item
的head
和tail
为空。
public ConcurrentLinkedQueue() {
head = tail = new Node<E>(null);
}
但是在我第一次调用ConcurrentLinkedQueue#offer
之后,代码执行了该行p.casNext(null, newNode)
(此处p
和head
是相同的参考),更改了head
的参考。p.casNext
的细节像这样
boolean casNext(Node<E> cmp, Node<E> val) {
return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
}
似乎只有头部的下一个字段被修改,头部的引用如何改变?你能给我些解释吗?预先感谢!
似乎只有头部的下一个字段被修改,头部的参考如何改变?
正确,head.next
已更改。
head
方法故意不修改队列的offer(e)
字段。
head
和tail
字段永远不会是null
,因此,当队列为空时,它们都引用相同的节点,并且该节点具有item = null
。一个或多个节点具有item = null
始终有效。查询或轮询队列时将跳过这些节点。
通过这种方式使代码在不使用锁定的情况下成为线程安全的。
以上是关于初始化后如何更新java.util.concurrent.ConcurrentLinkedQueue#head?的主要内容,如果未能解决你的问题,请参考以下文章
如何在表初始化后更新 ag-Grid 的 autoGroupColumnDef 属性