Cannot get this condition in ConcurrentLinkedQueue source code.

In the source code of ConcurrentLinkedQueue in the offer method:

 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; } } 

on line 352, this condition is:

 p = (p != t && t != (t = tail)) ? t : q; 

I know that code should put p in the tail, but why use such complex code? and what does (p != t && t != (t = tail)) mean? what is the difference between t!=(t=tail)) and t!=t ? should it always be false?

Are there any materials that can clearly explain ConcurrentLinkedQueue?

+5
source share
2 answers

An interesting question, I asked him more widely there and got some answers. From what I can read on this topic:

t != (t = tail) is just a weird way to write:

 if (t != tail) t = tail; 

In short, you are comparing the value of t with the value of what is assigned to t on the right, here tail .

(All loans go to Eran for his understanding of the topic and his answer)

So, to fully answer your question:

  • I do not know why they used such complex code.
  • (p != t && t != (t = tail)) means if p != t and if t != tail t takes the tail value
  • The difference is due
  • This does not always have to be false (obviously)
0
source

so I would think that another thread might be updated between operations that

 t != (t = tail)) 

checks, and for that he checks. it should rely on atoms to somehow be useful

Edit:

to answer the question of Yasin Badash, which seems correct

 t = tail 

- assignment operator

also,

 if 
Operator

used for branching code based on condition and

 (x = y) 

returns a reference to x, as in (obviously, by checking to anyone who has ever used c)

 if ((p = fopen(f)) == NULL) 

I think OP refers to the internal (or any) internal implementation of the Java concurrency functionality

Edit:

and I think this is a mistake in the implementation of Java and / or insanity

-2
source

Source: https://habr.com/ru/post/1274787/


All Articles