在二叉树中,我试图以原子方式将父节点的左子节点替换为新节点。
在下面的方法中,pnode.left
指向node
,而我试图将其更改
到replaceNode
。
在第1行中,childPtr
指向pnode.left
在第2行中,oldChildPtr
指向pnode.left
在第3行中,childPtr
从指向pnode.left
的原子更改为replaceNode
。
但是pnode.left
不变。我了解这就是Java中的工作方式。
但是,如何修改此代码,以使pnode.left
原子替换为replaceNode
。
atomicReplaceLeftChild(node,pnode,replaceNode)
{
AtomicReference<Node> childPtr = new AtomicReference<Node>(pnode.left);
Node oldChildPtr = childPtr.get();
childPtr.compareAndSet(oldChildPtr, replaceNode);
}
最佳答案
您的问题(以及同时用java
和c
标记的事实)表明您来自C背景。这没有错,但是我相信您在Java方面的“原子”概念并不是您所想的。 Atomic*
包中的java.util.concurrent
类使用内部锁定机制来确保它们中的值在另一个线程访问它们之前不能部分完成。仅仅因为在代码中使用Atomic*
类并不意味着您的代码执行了原子操作。
您的三行代码是“奇数”,似乎并不代表真实的用例。我之所以这样说,是因为代码不执行任何操作。它创建一个AtomicReference实例,并与引用的值混淆,但是它对更改pnode
上的任何内容均无济于事,这是我认为您正在尝试做的...。
因此,在某些时候您需要具有pnode.left = replaceNode
。您可能希望pnode.left实际上是AtomicReference本身,在这种情况下,它是:pnode.left.compareAndSet(oldChildPtr, replaceNode)
在当前状态下,您的代码没有任何意义,当然也没有达到您描述的目的。
希望这不会阻止您。...假设您是Java新手,我不羡慕您必须从Atomics和并发开始。