java - AbstractQueuedSynchronizer中CAS的疑惑
巴扎黑
巴扎黑 2017-04-18 10:52:59
0
2
632

这段代码是AQS框架中将当前节点入队的操作。

Node pred = tail;
if (pred != null) {
    node.prev = pred;
    if (compareAndSetTail(pred, node)) {
        pred.next = node;
        return node;
    }
}

上面代码中pred被赋值为尾节点,node为当前节点。我理解的将新节点插入链表尾处的逻辑应当如下:
node.prev = pred; node节点的前驱指向尾节点
pred.next = node; 将尾节点的后继设置为当前节点
tail = node; 将node节点设置为尾节点
对于上面代码我的疑问如下:
如果尾节点不为空,node节点的前驱会指向尾节点,然后调用CAS交换pred和node的值。
此时pred(即tail)的值应该已经是当前节点node的值了,再执行pred.next=node是什么意思呢,这是否存在逻辑问题?

巴扎黑
巴扎黑

全員に返信(2)
左手右手慢动作

TZ は、compareAndSetTail について間違った理解を持っている可能性があります。

リーリー

pred の値と AbstractQueuedSynchronizer の tailOffset 位置で期待されるノードの値を比較し、同じであれば、tailOffset 位置の値を更新します。

リーリー

compareAndSetTail(pred, node) このコードの実行が完了すると、オブジェクト AbstractQueuedSynchronizer の tailOffset の値、つまりメンバー変数 tail の値のみが変更され、pred の値には影響しません。二重リンクリストに関しては、末尾の挿入に論理的な問題はありません。

いいねを押す +0
PHPzhong

このデザインは 二重リンク リスト です。
B.prev == A
A.next == B双向链表.
B.prev == A
A.next == B

compareAndSetTail 设置成功只是将 tail 更新为当前node. pred.next 是将上一个尾部节点的next设置为当前node

compareAndSetTail が正常に設定されると、tail が現在の node に更新されます。 pred.next は前の末尾です。 next を現在の node に設定するロジックには問題ありません。🎜
いいねを押す +0
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!