0

私は、各スレッドがこのArrayList 'X'にaddAll()を使ってデータを追加する複数のスレッドに渡されるArrayList 'X'を持っています。明らかに、ここではマルチスレッドの問題がありますが、コードのaddAll()部分を 'synchronized'(または)copyOnWriteArrayListを使用して作成するオプションがあります。volatileはスレッドの安全を保証しますか?このArrayListの例

私の質問は、このArrayList 'volatile'を宣言すると同じ目的を達成するでしょうか? JVMはこれらの読み取り/書き込み命令をそれに応じて順序付けし、マルチスレッドの問題を防止しますか?

+4

いいえ、volatileはアクセスを同期させません。つまり、 'synchronized'(または他のロック)が対象です。 – tkausl

+4

ここでは揮発性はお手伝いしません。揮発性とは、リストの内容ではなく参照を指します。 'synchronized'を使ってリストをロックするか、(可能であれば)各スレッドに独自のリストを保持させ、処理が終了したらリストを結合する必要があります。 –

+1

http://shipilev.net/blog/2016/close-encounters-of-jmm-kind/#_pitfall_adding_volatiles_closer_to_the_problem_helps(時間がある場合は記事全体)を読むことをお勧めします。 – C4stor

答えて

4

このArrayList 'volatile'は同じ目的を達成すると宣言しますか?

実際にはできません。あなたが書くとき

volatile ArrayList list; 

これはlistの参照を揮発性で、基礎となるArrayListにしません。また、あなたが

list.add(x); 

を行うときにのみ読み取り障壁ない書き込みバリアを得るようlistが、読まれることを意味しています。

注:実際に必要な操作はアトミックではありませんが、書き込みバリアがないと別のスレッドでもこの操作が表示されないことがあります。

んJVMはそれに応じてこれらのリード/ライト命令を注文すると、マルチスレッドの問題を防ぎますか?

これに応じて読み取りが順序付けられますが、この場合はマルチスレッドの問題を回避するために使用できません。つまり、JVMが心配することなく、あなたが望むことをやると仮定するだけでなく、揮発性でこの作業を行う方法はありません。比較すると正確に使用することができる。

​​あなたはそれでも間違っているかもしれませんが、それは愚かな証拠ではありませんが、あなたは正しいことを得る良いチャンスがあります。

0

いいえ、volatileはここでは機能しません。 Volatileキーワードは、すべての読み取り操作が常に最新の更新値を取得するようにします。ここでは、同期を使用する必要があります。