1

2つのインスタンス変数と次のメソッドを持つクラスがあるとします(この質問のために簡略化されています):

private final Object lock = new Object();
private boolean running;

public MyClass() {
    synchronized(lock) {
        running = false;
    }
}
public void methodA() {
    synchronized(lock) {
        running = true;
    }
}
public void methodB() {
    synchronized(lock) {
        if (!running) {
            return;
        }
    }
}

私はこのコードを見ていて、 について読んだAtomicBoolean後、特にMyClassコンストラクターとmethodA. よくわからなかったmethodBけど。

これらのメソッドが複数のスレッドから呼び出される可能性があると仮定すると、次のメソッドはスレッドセーフになりますか?:

private AtomicBoolean running;

public MyClass() {
    running = new AtomicBoolean(false);
}
public void methodA() {
    running.set(true);
}
public void methodB() {
    if (!running.get()) {
        return;
    }
}

別のスレッド経由または別のスレッドからrunning.get()の更新が表示されることが保証されますか?running.set(true)running.set(false)

4

3 に答える 3

1

methodB変数を読み取っvolatileても同期順序が作成されないため、一般的に言えば、これらのコード ブロックは に対して等しくありません。

int x = 42メソッド B で更新されるクラスに他のフィールドがあるとします。

public void methodB() {
    if (!running.get()) {
        return;
    }
    if (x < 50) x++; // just example
}

次に、を呼び出すスレッドがいくつかありますmethodB

  • synchronized キーワードを使用すると、更新は安全で、すべてのスレッドに表示されます。
  • AtomicBoolean/volatile の可視性が壊れている場合

変数の更新でそのようなケースがなく、タスクが methodA - methodB シーケンス間の可視性を保証することだけであれば、問題ありません - AtomicBoolean で十分です。

于 2016-03-07T19:09:45.827 に答える
0

はい。の Javadoc からAtomicBoolean:

アトミックに更新できる {@code boolean} 値。

これは、 への更新AtomicBoolean分割できないことを意味します。したがって、そのような使用はスレッドセーフAtomicBooleanであると考えます。

AtomicBooleanfinalの宣言を行うことを検討する必要があります。

private final AtomicBoolean running;

于 2016-03-07T19:05:14.110 に答える