2

明確化の餌を必要とする並行プログラムがあります。最初のプログラムはアトミックと見なされますが、2番目のプログラムはそうではありません。

注:ここ//でコメントを意味するのではなく、他のプロセスと同時に実行される別のプロセスであることを意味します。

これが最初です:

int x = 0, y = 0;

co
   x = y + 1;      // y = y + 1;
oc

上記のプログラムはアトミックと見なすことができますが、なぜそうなのかわかりません。しかし、この次のプログラムはそうではありません。

int x = 0, y = 0;

co
   x = y + 1;      // y = x + 1;
oc

アトミックアクションは、コンピューターシステムの状態を個別に変更するプログラミング命令であり、レジスターとの間で値をロードおよびストアすることは、典型的なアトミックアクションであることも知っています。では、上で何が起こっているのでしょうか?

4

3 に答える 3

3

y最初のケースでは、常に増分の前または後に遭遇します。操作は非同期であるため、どちらかはわかりませんが、違いはありません。唯一の観察可能な効果はx、一方のケースではもう一方のケースよりも1大きいことです。これは、2つの順序に基づいて発生した可能性があります。ステートメント。

2番目のケースでは、xとyのどちらかが変更される前に両方ともフェッチされたため、結果のxとyの値がステートメントのどちらの順序とも一致しない状況が発生する可能性があります。

最初のケースは、実際にはJavaの「アトミック」の定義ではなく(コンパイラによって生成される可能性のある「アトミック」ディレクティブとは関係ありません)、単純なプログラミングです。

于 2012-05-18T11:10:49.010 に答える
1

次の事実を確認してください。

例1.Varxは共有されず、共有されるだけyです。左のスレッドは厳密にのリーダーでyあり、右のスレッドはのライターですy。単一の読み取りまたは書き込み操作はアトミックであるため、競合状態はありません。

例2.両方の変数が共有されます。この事実だけでも操作は非アトミックになりますが、これは読み取りと書き込みの相互依存性によってさらに複雑になります。左スレッド:読み取りのy後に書き込みx、右スレッド:読み取りのx後に書き込みy。これらの操作は、任意の順序でインターリーブできます。プログラムの順序と互換性のない順序でも可能です。

x = y + 1;最初の例では、実行の結果は、前に実行されたy = y + 1;か、またはその逆であると解釈できる結果になります。2つ目は、これらの解釈のいずれとも互換性のない結果になる可能性があります。そのため、opsはアトミックではありません。

于 2012-05-18T11:08:16.750 に答える
0

スレッドに関してほとんどアトミックであるということは、別のスレッドがそれにアクセスする前に、ステートメントのブロックにアクセスして完全に続行する必要があることを意味します。こんな感じです

x = x + 1;

トレッドが変数xにアクセスしてその値を読み書きしようとしているときに、他のスレッドもそれを読み書きしようとすると、不運なタイミング(競合状態と呼ばれる)が原因で、スレッドAが変数x値を読み取るように問題が発生します。 0であり、その時点でスレッドBは値を読み取りてxに1として書き込みます。これで、スレッドAは値をxに書き込みます。これも1になります。これは、スレッドAがxが0であることを認識しているためですが、実際には1です。

int x = 0, y = 0;

co
   x = y + 1;      // y = y + 1;
oc

xと同じようにアトミックであり、y値は一度に同じスレッドによって読み書きされる必要があります。複数のスレッドがそれにアクセスすると、一貫性のない結果が得られます。

int x = 0, y = 0;

co
   x = y + 1;      // y = x + 1;
oc

一方、これはアトミックではありません。x= y+1はxのフェッチごとにy=x + 1に影響を与えず、yはここで実行されるためです。

于 2012-05-18T11:15:33.953 に答える