これは簡単なことだと思いますが、これが優雅なやり方のパターンがあるかどうかを知りたいと思っていました。私はグアバを見た。 私は、クラスレベルのList、スケジューラー上のこのlistOfObjectsを参照するメソッド、およびスケジューラー上でそれを更新するメソッドを持っています。 updaterメソッドは、このリストに含まれるすべてのオブジェクトを収集し、listOfObjectsを再初期化する準備ができた新しいリストを持ちます。しかし、それを参照しているメソッドによって使用されている場合でも、私はそれを設定する必要がありますか、それを行うより安全な方法があります。スケジューラでアクティブなコレクションを更新する
private List<Object> listOfObjects = new ArrayList<Object>();
@Scheduled
public referToList(){
for(Object o : listOfObjects){
doSomething(o);
}
}
@Scheduled
public updateList(){
List<Object> tempList = new ArrayList<Object>();
tempList = doSomethingToPopulateList();
this.listOfObjects = tempList;
}
したがって、可能なupdateListは、referToListが反復処理の途中にあるときにリストを更新することができます。私はreferToListにtempリストを作成することもできます。そのため、listOfObjectsのコピーを処理していますが、その効率性はわかりません。
良い点ですが、コードは安全ではありません。このリストは 'updateList'メソッドから安全に公開されていません。 'referToList'を実行するスレッドは、リストが矛盾した状態で見えるかもしれません。何かが欠けていて、同じスレッドが両方のメソッドを実行することが保証されていない限り。 – dnault
変数の割り当てはアトミックな操作ですどのような矛盾した状態がここに見られるでしょうか? – Rik
はい、Javaでの変数代入は常にアトミックです。しかし、可視性は別の問題です。安全な公開がなければ、スレッドAはスレッドBによる割り当てを決して*見ることはできません。あるいは、悪いことに、参照の割り当てを見るかもしれませんが、部分的に構築された状態。 [このSOの質問](http://stackoverflow.com/questions/801993/java-multi-threading-safe-publication)と[この記事Brian Goetz](http://www.ibm.com/developerworks/)を参照してください。 library/j-jtp0618 /)(主に安全な*建設について*が、 "可視性の危険"というセクションもここで適用されます)。 – dnault