8

いくつかのスレッド(一般的な同時実行の問題揮発性キーワードメモリモデル)を読んでいます。Javaの同時実行の問題について混乱しています。

複数のスレッドからアクセスされるフィールドがたくさんあります。それらを調べて、すべて揮発性としてマークする必要がありますか?

クラスを構築するとき、複数のスレッドがそれにアクセスするかどうかわからないので、フィールドを揮発性にしないことは確かに安全ではありません。したがって、私の理解では、クラスを使用しないケースはほとんどありません。これは正しいです?

私にとって、これはバージョン1.5 JVM以降に固有ですが、私の特定のセットアップについての回答に限定されているとは感じません。

4

4 に答える 4

4

Well, you've read those other questions and I presume you've read the answers already, so I'll just highlight some key points:

  1. are they going to change? if not, you don't need volatile
  2. if yes, then is the value of a field related to another? if yes, go to point 4
  3. how many threads will change it? if only 1, then volatile is all you need
  4. if the answer to number 2 is "no" or more than one threads is going to write to it, then volatile alone is not enough, you'll probably need to synchronize the access

Added:
If the field reference an Object, then it will have fields of its own and all those consideration also applies to these fields.

于 2009-10-25T18:06:35.300 に答える
3

フィールドが複数のスレッドによってアクセスされる場合は、volatileまたはfinal、または 同期されたブロックでのみアクセスされる必要があります。そうしないと、割り当てられた値が他のスレッドから見えなくなる可能性があります。

クラスは、複数のスレッドによる同時アクセス用に特別に設計する必要があります。フィールドを volatile または final とマークするだけでは、スレッド セーフには不十分です。一貫性の問題 (複数のフィールドへの変更の原子性)、スレッド間のシグナル伝達に関する懸念 (たとえば、waitとの使用notify) などがあります。

そのため、別の方法で文書化されていない限り、オブジェクトは 1 つのスレッドのみに表示される必要があると想定するのが最も安全です。すべてのオブジェクトをスレッド セーフにする必要はなく、コストがかかります (ソフトウェアの速度の点ではコストがかかりますが、さらに重要なのは開発費用の点です)。

代わりに、ソフトウェアは、並行スレッドが相互にできるだけ相互作用しないように、できればまったく相互作用しないように設計する必要があります。適切な同時実行制御を設計できるように、相互作用するポイントを明確に特定する必要があります。

于 2009-10-25T18:15:22.557 に答える
2

尋ねる必要がある場合は、ロックを使用してください。volatile場合によっては便利ですが、正しく理解するのは非常に困難です。例えば:

class Foo {
  private volatile int counter = 0;
  int Increment() {
    counter++;
    return counter;
  }
}

2つのスレッドがIncrement()同時に実行される場合、結果がになる可能性がありますcounter = 1。これは、コンピューターが最初に取得counterし、追加してから保存し直すためです。Volatileは、他のステートメントに対して特定の順序で保存と読み込みを強制するだけです。

synchronized通常、必要がなくなることに注意してくださいvolatile。特定のフィールドへのすべてのアクセスが同じモニターによって保護されている場合は、volatile必要になることはありません。

ロックレスアルゴリズムを作成するために使用volatileすることは、非常に困難です。synchronizedすでに遅すぎるという確固たる証拠がなく、実装する予定のアルゴリズムについて詳細な分析を行っていない限り、これに固執してください。

于 2009-10-25T18:27:14.077 に答える
1

The short answer is no. Threading issues require more thought and planning than this. See this for some limitations on when volatile helps for threading and when it does not. The modification of the values has to be properly synchronized, but very typically modification requires the state of more than one variable at a time. Say for example you have variable and you want to change it if it meets a criteria. The read from the array and the write to the array are different instructions, and need to be synchronized together. Volatile is not enough.

Consider also the case where the variable references a mutable object (say an array or a Collection), then interacting with that object will not be thread safe just because the reference is volatile.

于 2009-10-25T18:11:33.263 に答える