- 72
- 0
使用cas操作实现非阻塞链表 其中put方法 代码如下
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();//1
Node<E> residue = curTail.next.get();
if (curTail == tail.get()) {//2
if (residue == null) /* A */ {
if (curTail.next.compareAndSet(null, newNode)) /* C */ {
tail.compareAndSet(curTail, newNode) /* D */ ;
return true;
}
} else {
tail.compareAndSet(curTail, residue) /* B */;
}
}
}
}
}
代码来源: developerworks文章《非阻塞算法简介》 非阻塞链表 章节
疑惑:这段代码的大体思路、原理 是理解的,但2处注释的代码,即if (curTail == tail.get())这行的判断不理解。这个判断是有必要的吗?可以去掉吗?为什么?
2处的curTail就是1处tail.get() 的结果。如果需要判断的话,应该是在并发情况下,1、2处分别调用tail.get()的返回的可能不是同一个对象。也就是说,2处判断的时候,tail可能被修改了。1到2处之间没有修改tail的动作,所以只能是别的一个线程修改了tail;只看这段代码的话,只能是别的线程调用put方法时执行了B或D。所以安插了这么一个判断。
但是有什么用呢?这是个“先判断后执行”的动作,但是因为非阻塞不加锁,[判断+执行]并没有被同步起来;所以,可能刚刚判断之后,tail就被改掉,判断就会失效。所以看起来这个判断是完全可以去掉的。是为了性能,判断失败后 可以少走一次循环体吗?
1
打赏
收藏
点击回答
- 共 0 条
- 全部回答
-
家盛 普通会员 1楼非阻塞链表(Non-blocking linked list)通常在并发编程中使用,其操作不会引起线程阻塞。但你并未给出具体的代码行,所以我无法直接解答你的疑问。不过,我可以尝试解释一下非阻塞链表的一种常见操作——CAS(Compare and Swap)的实现方式。 例如,在Java的ConcurrentLinkedQueue中,非阻塞链表的节点添加操作可能涉及到以下一行代码: ```java node.item = item; // Set item field. Node pred = tail; tail = node; U.compareAndSwapObject(this, TAIL, pred, node); ``` 这里你可能会对最后一行的CAS操作不理解,这是原子地更新尾节点的非阻塞操作。它会比较`this`对象中指向当前尾节点的引用是否还是`pred`,如果是,则更新为新的节点`node`。如果不是,则说明有其他线程在这期间修改了尾节点,那么当前线程会再次尝试获取最新的尾节点并插入新节点,从而保证并发环境下的线程安全。 如果你的问题是关于其他具体的一行代码,请提供详细信息,我会更准确地为你解析。
更多回答
网站公告
- 扫一扫访问手机版
回答动态

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器更新之后。服务器里面有部分玩家要重新创建角色是怎么回事啊?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题函数计算不同地域的是不能用内网吧?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题ARMS可以创建多个应用嘛?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题在ARMS如何申请加入公测呀?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题前端小程序接入这个arms具体是如何接入监控的,这个init方法在哪里进行添加?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器刚到期,是不是就不能再导出存档了呢?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器的游戏版本不兼容 尝试更新怎么解决?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器服务器升级以后 就链接不上了,怎么办?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器转移以后服务器进不去了,怎么解决?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器修改参数后游戏进入不了,是什么情况?预计能赚取 0积分收益
- 回到顶部
- 回到顶部
