2017-08-11 23 views
2

私はAのオブジェクトを作成しのJava - 同じオブジェクト、異なる変数、複数のスレッド

class A { 
    Integer x; 
    String y 
} 

いくつかのコードを書いていますし、私は2つの実行可能スレッドに渡しています。最初のスレッドは値xを更新し、2番目のスレッドは値yを更新します。

これが壊れる可能性のあるシナリオはありますか?つまり、同じオブジェクトの異なる変数を更新する2つのスレッドがある場合、競合状態が存在する可能性がありますか?

+2

なぜ単一のオブジェクトが必要ですか?別のオブジェクトを別のスレッドに渡す –

+1

はい、これが壊れる可能性のあるシナリオはたくさんあります。あなたはhttp://jcip.net/を読む必要があります – Oleg

+1

どのスレッドがデータを読み込んでいますか? –

答えて

0

いいえ、正常に動作します。与えられた変数があるスレッドによってのみ更新されている限り(他のスレッドによる変数の読み込みに関するいくつかの条件付きで)、あなたは大丈夫です。

あなたがしていることによっては、最も理解しやすい設計ではないかもしれません - また、上記のように、他のスレッドからそれらの変数を確実に読み取ってはいけません。揮発性。 (アトミックは、複数のスレッドからの書き込みに対して迅速になり、あなただけの1つのスレッドからの書き込みや他人から読んでいる場合はまだ良いかもしれ揮発性)

+2

この答えは手伝い波のように感じます。「他のスレッドによる変数の読み方のいくつかの条件」が最も重要な部分です!ここで重要な部分である 'x'と' y'がどこにあるのかに応じて、記述されたシナリオで発生する可能性のある非明白な振る舞いがたくさんあります。 –

0

マルチスレッドだけでなく、競合状態についてです、それは
jsr-133によって策定メモリの可視性についてもですJavaの並行性を理解したい場合は、絶対に学ばなければなりません。

コードが破損する可能性がある方法はたくさんあります。たとえば、スレッドAの変更xでスレッドBのオブジェクトを作成し、スレッドCのyをスレッドAで変更したことがない場合があります。

説明するためにいくつかのコード:

A a = new A(); 
a.x = 0; 

Thread t1 = new Thread(() -> { 
    while (true) { 
     a.x = 1; 
    } 
}); 

Thread t2 = new Thread(() -> { 
    a.y = "a"; 
}); 

t1.start(); 
t2.start(); 

while(a.x == 0) { 
} 

System.out.println("might never get here"); 

一つの可能​​な修正はこれがすべてのスレッドがxとyの変化を見ることを保証しますxとyの揮発性

class A { 
    volatile Integer x; 
    volatile String y; 
} 

を作ることであるにAのインスタンスが安全に公開されていることを確認する必要があります。

+0

@BillK「著者が単に2つのスレッドから異なる変数を書いている場合、彼は大丈夫です」**絶対にそうではありません!!! **書き込みが正しく表示されることなく、予期しない動作と不正確な値になります。私は彼の質問と休憩に合ったシナリオを作りました(少なくとも、それは実際に起こるのを見るのは難しいでしょう)。 – Oleg

関連する問題