JavaにおけるVolatileとStaticの違い 質問する

JavaにおけるVolatileとStaticの違い 質問する

staticこれはすべてのオブジェクトに対して値の 1 つのコピーを意味し、volatileすべてのスレッドに対して値の 1 つのコピーを意味すると言うのは正しいですか?

いずれにしても、static変数値はすべてのスレッドに対して 1 つの値になるので、なぜ を選択する必要がありますかvolatile?

ベストアンサー1

Java で静的変数を宣言すると、クラスのオブジェクトがいくつ作成されても、コピーは 1 つだけになります。変数は、まったくObjects作成されていなくてもアクセスできます。ただし、スレッドにはローカルにキャッシュされた値が存在する場合があります。

変数がvolatilestaticでない場合は、 ごとに 1 つの変数が存在しますObject。そのため、表面的には通常の変数と違いはありませんが、staticとはまったく異なるように見えます。ただし、フィールドがあってもObject、スレッドは変数値をローカルにキャッシュする場合があります。

つまり、2 つのスレッドが同じオブジェクトの変数を同時に更新し、その変数が volatile として宣言されていない場合、スレッドの 1 つに古い値がキャッシュされている可能性があります。

複数のスレッドを通じて静的な値にアクセスする場合でも、各スレッドはローカルにキャッシュされたコピーを持つことができます。これを回避するには、変数をstatic volatileとして宣言し、これによりスレッドがグローバル値を毎回読み取るように強制します。

ただし、volatile は適切な同期の代替にはなりません。
たとえば、次のようになります。

private static volatile int counter = 0;

private void concurrentMethodWrong() {
  counter = counter + 5;
  //do something
  counter = counter - 5;
}

同時に何度も実行すると、concurrentMethodWrongカウンターの最終値がゼロと異なる可能性があります。
この問題を解決するには、ロックを実装する必要があります。

private static final Object counterLock = new Object();

private static volatile int counter = 0;

private void concurrentMethodRight() {
  synchronized (counterLock) {
    counter = counter + 5;
  }
  //do something
  synchronized (counterLock) {
    counter = counter - 5;
  }
}

または、AtomicIntegerクラス。

おすすめ記事