Javaの並行性とマップに関して少し問題があります。基本的に、私は独自のマップを使用(読み取りおよび変更)する複数のスレッドを持っていますが、これらのマップのそれぞれは、別のスレッドによって読み取られて変更されているより大きなマップの一部です。
私のメインメソッドはすべてのスレッドを作成し、スレッドはそれぞれのマップを作成し、それが「メイン」マップに配置されます。
Map<String, MyObject> mainMap = new HashMap<String, Integer>();
FirstThread t1 = new FirstThread();
mainMap.putAll(t1.getMap());
t1.start();
SecondThread t2 = new SecondThread();
mainMap.putAll(t2.getMap());
t2.start();
ThirdThread t3 = new ThirdThread(mainMap);
t3.start();
私が今直面している問題は、他のスレッドの一方または両方が「それらの」アイテムを更新するタイミングに応じて、3番目の(メイン)スレッドがマップ内の任意の値を参照することです。ただし、読み取られているものの一部が「古い」ことを恐れることなく、3番目のスレッドがマップを反復処理できること(およびマップの値を使用できること)を保証する必要があります。
FirstThread(SecondThreadのアナログ):
for (MyObject o : map.values()) {
o.setNewValue(getNewValue());
}
ThirdThread:
for (MyObject o : map.values()) {
doSomethingWith(o.getNewValue());
}
何か案は?マップを変更する必要があるときに各スレッドで同期される、グローバルにアクセス可能な(静的クラスを介した静的な最終オブジェクト)ロックを使用することを検討しました。または、私が使用できるこの特定の問題を評価する特定のMap実装はありますか?
前もって感謝します!
編集: @Pyranjaによって提案されたように、getNewValue()メソッドを同期することは可能です。しかし、私は実際にトランザクションのラインに沿って何かをしようとしていることを言及するのを忘れました。そこでは、t3が上記の値で動作する前/後にt1とt2が複数の値を変更します。t3は、値が変更されていない場合、doSomethingWith()が実際には値に対して何も実行しないように実装されています。