0

二分木で、親の左の子を新しいノードにアトミックに置き換えようとしています。以下のメソッドでpnode.leftは、 は を指してnodeおり、 に変更しようとしていreplaceNodeます。

In line1 はchildPtrIn line2を指している In line3は In line3 を指しており、 to から toへアトミックに変更されています。pnode.left
oldChildPtrpnode.left
childPtrpnode.leftreplaceNode

でも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);
}
4

2 に答える 2

1

javaあなたの質問 (およびと の両方でタグ付けされているという事実c) は、あなたが C のバックグラウンドを持っていることを示唆しています。これには何も問題はありませんが、Java の意味での「アトミック」の概念は、あなたが考えているものではないと思います。パッケージ内のAtomic*クラスは、java.util.concurrent内部ロック メカニズムを使用して、別のスレッドがアクセスする前にそれらの値が部分的に完了できないようにします。コードでクラスを使用しているからといっAtomic*て、コードがアトミック操作を行うわけではありません。

あなたの 3 行のコードは「奇数」であり、実際の使用例を表しているようには見えません。コードが何もしないので、私はこれを言います。それは AtomicReference インスタンスを作成し、参照された値を台無しにしますが、pnodeあなたがやろうとしていると私が思っていたものを変更することは何もしません....

したがって、ある時点でpnode.left = replaceNode. pnode.left を実際に AtomicReference 自体にしたい場合があります。その場合は次のようになります。pnode.left.compareAndSet(oldChildPtr, replaceNode)

現在の状態では、あなたのコードは何の意味も持たず、あなたが説明したようにすべきことを確実に行っていません。

これがあなたを落胆させないことを願っています....あなたがJavaに慣れていないと仮定すると、アトミックと並行性から始めなければならないことをうらやましく思いません....もっと簡単に始められる場所があります。

于 2013-10-30T04:38:33.777 に答える
0
static final AtomicReferenceFieldUpdater<Node, Node> c0Update = AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "c0");
static final AtomicReferenceFieldUpdater<Node, Node> c1Update = AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "c1");
static final AtomicReferenceFieldUpdater<Node, Node> c2Update = AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "c2");
static final AtomicReferenceFieldUpdater<Node, Node> c3Update = AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "c3");
static final AtomicReferenceFieldUpdater<Node, UpdateStep> infoUpdate = AtomicReferenceFieldUpdater.newUpdater(Node.class, UpdateStep.class, "pending");

を使用してCASを行います

c0Update.compareAndSet(pending.p, pending.l, pending.newChild)

配列要素を手動で展開する以外に簡単な方法はありますか?

于 2013-11-19T08:29:10.707 に答える