Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

ReentrantLock的内存可见性语义

オープン
#9 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
35/100
issue の種類
ドキュメント
明瞭さ
説明が足りない
活発さ
停滞
技術スタック
java, linux

調査の方向性

Start with ReentrantLock's NonfairSync.lock, AbstractQueuedSynchronizer.compareAndSetState, setState, and tryRelease, then compare their documented volatile memory semantics with the referenced JSR-133 Cookbook. Review the Linux Atomic::cmpxchg implementation and x86 lock-prefixed instruction discussion. Done means documenting the acquire and release ordering clearly, including what is guaranteed by Java rather than by x86 alone.

索引モデルが issue の本文から書いたものです。

説明

加锁

以NonfairSync为例:

final void lock() {
    if (compareAndSetState(0, 1))
        setExclusiveOwnerThread(Thread.currentThread());
     else
        acquire(1);
}

关键在于compareAndSetState方法:

/**
     * Atomically sets synchronization state to the given updated
     * value if the current state value equals the expected value.
     * This operation has memory semantics of a {@code volatile} read
     * and write.
     *
     * @param expect the expected value
     * @param update the new value
     * @return {@code true} if successful. False return indicates that the actual
     *         value was not equal to the expected value.
     */
protected final boolean compareAndSetState(int expect, int update) {
    return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}

注释里写了,此方法有相当于volatile读写的内存语义。所以这个内存语义又是什么?
参考Doug lea的: The JSR-133 Cookbook for Compiler Writers

  1. Issue a StoreStore barrier before each volatile store
  2. Issue a StoreLoad barrier after each volatile store.(Alternatively, if available, you can implement volatile store as an atomic instruction (for example XCHG on x86) and omit the barrier. This may be more efficient if atomic instructions are cheaper than StoreLoad barriers.)
  3. Issue LoadLoad and LoadStore barriers after each volatile load.

unsafe.compareAndSwapInt由Atomic::cmpxchg实现(Linux):

inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value) {
  bool mp = os::is_MP();
  __asm__ __volatile__ (LOCK_IF_MP(%4) "cmpxchgq %1,(%3)"
                        : "=a" (exchange_value)
                        : "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
                        : "cc", "memory");
  return exchange_value;
}

所以这在x86上就是加了lock前缀的cmpxhgg指令,而lock前缀在intel上便充当了读写memory barrier的作用,来自书中的摘抄L:

On the other hand, x86 CPUs have traditionally given no ordering guarantees for loads, so the smp_mb() and smp_rmb() primitives expand to lock;addl. This atomic instruction acts as a barrier to both loads and stores.

解锁

只看一行:

protected final boolean tryRelease(int releases) {
    // ...
    setState(c);
    // ...
}

/**
     * Sets the value of synchronization state.
     * This operation has memory semantics of a {@code volatile} write.
     * @param newState the new state value
     */
protected final void setState(int newState) {
    state = newState;
}

从前面Doug lea的文章中可以看出,volatile写会导致在后面追加一个StoreLoad屏障,而此屏障在x86上:
image
So,也许又是一条lock前缀指令。

主要言語
Java
スター
2k
フォーク
716
PR マージ指標
30日以内にマージされた PR はありません

環境構築

このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

seaswalker/jdk-sourcecode-analysis のほかの issue

seaswalker/jdk-sourcecode-analysis の issue をすべて見る

似ている issue

Java の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。