【发布时间】:2018-12-25 11:15:26
【问题描述】:
我在 IBM Developer 中找到了这个关于并发链接队列的代码段。
但我无法理解其中的一部分。这是
while(true){
...
if(curTail == Tail.get()){
if(residue == null){
...
}
}
}
根据curTail和residual的定义,我认为curTail是Tail的副本,curTail是等于Tail.next的指针。
我担心函数 compareAndSet 会判断调用者对象是否等于第一个参数,为什么必须在调用这个函数之前判断它们?我认为下面的代码可以做到同样的事情。
while (true) {
Node<E> curTail = tail.get();
Node<E> residue = curTail.next.get();
if (curTail.next.compareAndSet(null, newNode)) /* C */ {
tail.compareAndSet(curTail, newNode) /* D */ ;
return true;
} else {
tail.compareAndSet(curTail, residue) /* B */;
}
}
}
任何帮助将不胜感激。 谢谢。
public class LinkedQueue <E> {
private static class Node <E> {
final E item;
final AtomicReference<Node<E>> next;
Node(E item, Node<E> next) {
this.item = item;
this.next = new AtomicReference<Node<E>>(next);
}
}
private AtomicReference<Node<E>> head
= new AtomicReference<Node<E>>(new Node<E>(null, null));
private AtomicReference<Node<E>> tail = head;
public boolean put(E item) {
Node<E> newNode = new Node<E>(item, null);
while (true) {
Node<E> curTail = tail.get();
Node<E> residue = curTail.next.get();
if (curTail == tail.get()) {
if (residue == null) /* A */ {
if (curTail.next.compareAndSet(null, newNode)) /* C */ {
tail.compareAndSet(curTail, newNode) /* D */ ;
return true;
}
} else {
tail.compareAndSet(curTail, residue) /* B */;
}
}
}
}
}
【问题讨论】:
-
我猜代码尽量避免调用“compareAndSet”。可能成本更高...我找到了一些链接 stackoverflow.com/questions/4183202/… 和 stackoverflow.com/questions/4187914/…
-
@Surely 感谢您的提示。我只关注代码的逻辑而忽略了CAS的成本......
-
我不太确定是不是这样。等待更擅长此主题的人回答。
标签: java multithreading thread-safety