私は並行マルチマップを作成する問題を検討してきましたが、 Google Guava AbstractSetMultimapと、ConcurrentHashMap上のセットビューとして値コレクションをオンデマンドで作成するMapMakerコンピューティングマップに裏打ちされた実装があります。ビューコレクションとさまざまなラッパーに注意を払うと、これはかなり近くなると思います。
これを試した他の人によってすでに議論されている大きな問題は、競合状態を導入せずに、値コレクションが空になったときに、基になるマップから値コレクションを削除することであるように見えます。
いくつかのオプションが存在するようです。
- 空のコレクションはそのままにしておきます。これにより一部のCHMがリークしますが、少なくとも正しいと思います。
- 空のときにコレクションを削除し、他に何かが表示されている場合は補正するように楽観的に試してください。これは人種でいっぱいで、修正することは本質的に不可能のようです。
- 値コレクションのすべてを同期します。これにより、少なくともこの削除が可能になりますが、キーによる最初のルックアップ後の同時実行が犠牲になります。
- より小さなペナルティ(おそらく、使用パターンに応じて?)の場合、おそらく値コレクションの作成と削除で同期し、それがすべてをカバーしているかどうかを確認する必要があります。
質問:
- これよりも優れた実装を知っている人はいますか?MapMakerのビットをより適切に作成できますか、それともゼロから作成された特殊なConcurrentHashMultimapが必要ですか?
- これを大幅に改善することが難しい場合、このリークは実際には多くの問題になる可能性がありますか?java.util.HashMap、juc.ConcurrentHashMap、ArrayDequeなどの注目すべきコレクションは、バッキングストアのサイズを下方に変更しません。また、ArrayListは自動的にサイズを変更しません。オブジェクトをクリアする限り、これはあまり重要ではないかと思います。
ありがとう
編集:グアバメーリングリストのここでの議論も参照してください。
編集2:それ以来私はこれを書きました。実装については、このGoogleコードエリアをご覧ください。ここではなく、そこで試してみた人からのフィードバックをいただければ幸いです。