3

スレッド干渉の概念を学習しようとしていますが、Java Tutorial Oracle で次の例に遭遇しました。

class Counter {
    private int c = 0;

    public void increment() {
        c++;
    }

    public void decrement() {
        c--;
    }

    public int value() {
        return c;
    }

}

Oracle のチュートリアルでは、2 つのスレッドが variablecにアクセスしようとすると、一方のスレッドによる変更が他方のスレッドに反映されないスレッド干渉が発生する可能性があると述べています。

ただし、実際に概念を説明するコードは提供されていません。Counterスレッド干渉が実際にどのように発生するかを示すために、クラスに基づいたコード例を提供してもらえますか?

4

3 に答える 3

3

コードよりも、何が起こるかを説明することを好みます。A と B の 2 つのスレッドが同じカウンター オブジェクトにアクセスしているとします。Aincrementを呼び出し、 Bはdecrementを呼び出します。これらの操作はいずれも、少なくとも 3 つのステップで構成されています。

  1. メモリからCを読み取る
  2. インクリメントまたはデクリメントC
  3. Cをメモリに書き戻します。

A と B が同時にインクリメントとデクリメントを試みると、一方のスレッドがメモリからCを読み取ることができます (ステップ 1)。もう一方のスレッドはステップ 2です。このような場合、cの初期値が 5 の場合、最初にスレッド A が読み取り、6 にインクリメントします。次に、スレッド B が読み取り、4 にデクリメントします。A がcをメモリに書き戻す前に、B がこれらの変更を行っていることを思い出してください。ステップが重複しているため、1 つのスレッドによって行われた変更は他のスレッドには表示されず、最終的なcの値は 6または4になります。しかし、実際に期待したのは5でした。

これは、2 つのスレッドが互いに干渉している例です。これを避けるために、スレッド同期を使用します。

于 2016-02-28T04:38:24.343 に答える