2016-07-14 8 views
1

これは簡単なことだと思いますが、これが優雅なやり方のパターンがあるかどうかを知りたいと思っていました。私はグアバを見た。 私は、クラスレベルの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のコピーを処理していますが、その効率性はわかりません。

答えて

-2

tl; dr - コードは安全ですが、将来のバグに対してより弾力性を持たせることができます。

最初に、すぐには必要ではないが、特に同時性を扱う場合は、変更可能なコレクションではなく不変のコレクションを優先する傾向があります。望ましくない変更を防ぎ、リストの状態についてもっと簡単に推論できるようにすることをお勧めします。あなたのコードは今では壊れていません。他のスレッドが反復されている間に直接listOfObjectsを修正した場合には、それが不変になります。根本的に変化していることを意味 - listOfObjectsに割り当てることCollections.unmodifableList(tempList)でリストをラップやグアバのは、(unmodifableListだけで不変のビューを作るのに対し、グアバのImmutableListは、実際に、リスト項目のコピーを作成するということで差がImmutableList.copyOf(tempList)つまり

、リストは引き続き表示されます)。または、doSomethingToPopulateList()から不変のリストを返すだけです。

あなたの質問にお答えするには、tempListに新しいリストを収集したときにlistOfObjectsを直接更新しないでください。 referToList()が現在実行中であっても問題は発生しません。 listOfObjectsが参考になるからです。あなたは

for(Object o : listOfObjects){ 
    doSomething(o); 
}  

を実行すると、JVMは、メモリ参照listOfObjectsをとるループを開始し、そのメモリ空間内の項目を反復処理のためのポイントにまで言及しています。その反復が行われている間に、他のコードはlistOfObjectsが参照しているメモリ参照を(updateList()に再割り当てして)更新できますが、実行中のforループの進行には影響しません。

+1

良い点ですが、コードは安全ではありません。このリストは 'updateList'メソッドから安全に公開されていません。 'referToList'を実行するスレッドは、リストが矛盾した状態で見えるかもしれません。何かが欠けていて、同じスレッドが両方のメソッドを実行することが保証されていない限り。 – dnault

+0

変数の割り当てはアトミックな操作ですどのような矛盾した状態がここに見られるでしょうか? – Rik

+0

はい、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

関連する問題