2013-09-09 6 views
6

http://www.java2s.com/Open-Source/Java-Open-Source-Library/7-JDK/java/java/util/concurrent/ConcurrentLinkedQueue.java.htmConcurrentLinkedQueue код Пояснение

Выше исходный код ConcurrentLinkedQueue. Я не могу понять одно условие.

Как условие (р == д) придет ниже фрагмент кода из предложения метода

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)) { 
        // Successful CAS is the linearization point 
        // for e to become an element of this queue, 
        // and for newNode to become "live". 
        if (p != t) // hop two nodes at a time 
         casTail(t, newNode); // Failure is OK. 
        return true; 
       } 
       // Lost CAS race to another thread; re-read next 
      } 
      else if (p == q) 
       // We have fallen off list. If tail is unchanged, it 
       // will also be off-list, in which case we need to 
       // jump to head, from which all live nodes are always 
       // reachable. Else the new tail is a better bet. 
       p = (t != (t = tail)) ? t : head; 
      else 
       // Check for tail updates after two hops. 
       p = (p != t && t != (t = tail)) ? t : q; 
     } 
    } 

, а также то, что делает автор в виду под «Мы отвалились список»

ответ

5

ConcurrentLinkedQueue позволяет одновременное изменение внутреннего списка во время прохождения его. Это означает, что узел, на который вы смотрите, мог быть удален одновременно. Чтобы обнаружить такие ситуации, следующий указатель удаляемого узла изменится, чтобы указать на себя. Посмотрите на номер updateHead (L302).

+0

@Holger: Можете ли вы объяснить, как работает метод remove concurrentlinkedqueue? Потому что, когда я пытался понять его в многопоточных средах, кажется, что это не работает, что я чего-то не хватает –

+0

public boolean remove (Object o) { if (o == null) return false; Узел pred = null; для (Узел p = first(); p! = Null; p = succ (p)) { E item = p.item; if (item! = Null && o.equals (item) && p.casItem (item, null)) { Узел next = succ (p); if (pred! = Null && next! = Null) pred.casNext (p, next); return true; } pred = p; } return false; } –

+0

@Aarish: что вы имеете в виду «кажется, что не работает»? – Holger

2

Условие задает вопрос «Является ли текущий узел таким же, как следующий узел?»

Если да, то вы вылезли список

Основной контур шагов (документации в строке.):

  1. создать новый узел для предлагаемых данных.
  2. Пройдите список, чтобы найти последний узел
  3. Вставить новый узел в качестве нового хвоста.

Другие части оператора if обрабатывают проблемы одновременной модификации.

Чтобы лучше понять, что происходит, читайте Node.casTail() и casNext()

+1

«Условие задает вопрос« Является ли текущий узел таким же, как следующий узел? »« Разве это не главный вопрос, потому что не очень понятно, почему следующий узел, который мы получили с помощью p.next, будет равен Вверх. – mawia

+0

@ Iscoughlin да мавия правы ?. спасибо mawia для очистки – veritas

+0

Это одно из условий, которые могут возникнуть из-за одновременной модификации списка. – lscoughlin