簡體   English   中英

java.util.concurrent.ConcurrentLinkedQueue#head 初始化后如何更新?

[英]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時, headtailitem為 null。

 public ConcurrentLinkedQueue() {
        head = tail = new Node<E>(null);
    }

但是在我第一次調用ConcurrentLinkedQueue#offer (使用queue.offer(1) )並且代碼執行了p.casNext(null, newNode)行(這里phead是相同的引用)之后, 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字段。

隊列的headtail字段永遠不會為null ,因此當隊列為空時,它們都引用同一個節點,並且該節點具有item = null 一個或多個節點的item = null總是有效的。 查詢或輪詢隊列時將跳過這些節點。

這一切都是為了使代碼在不使用鎖定的情況下成為線程安全的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM