![](/img/trans.png)
[英]Should I declare java.util.concurrent.ConcurrentLinkedQueue references volatile?
[英]How is java.util.concurrent.ConcurrentLinkedQueue#head updated after initialisation?
環境:
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
時, head
和tail
的item
為 null。
public ConcurrentLinkedQueue() {
head = tail = new Node<E>(null);
}
但是在我第一次調用ConcurrentLinkedQueue#offer
(使用queue.offer(1)
)並且代碼執行了p.casNext(null, newNode)
行(這里p
和head
是相同的引用)之后, head
的引用被更改為newNode
,並且 head 的 'item' 值更改為1
。
p.casNext
的細節是這樣的
boolean casNext(Node<E> cmp, Node<E> val) {
return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
}
在 cas 方法中似乎只修改了 head 的 next 字段,但是為什么 head 的引用發生了變化?
你能給我一些解釋嗎? 提前致謝!
好像只修改了 head 的 next 字段,head 的引用是如何改變的?
正確, head.next
已更改。
offer(e)
方法有意不修改隊列的head
字段。
隊列的head
和tail
字段永遠不會為null
,因此當隊列為空時,它們都引用同一個節點,並且該節點具有item = null
。 一個或多個節點的item = null
總是有效的。 查詢或輪詢隊列時將跳過這些節點。
這一切都是為了使代碼在不使用鎖定的情況下成為線程安全的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.