web-dev-qa-db-ja.com

WeakHashMapに相当するJava.util.concurrentはありますか?

次のコードは、Collections.synchronizedMap()を使用せずに、並行性で正確性を維持しながら書き直すことができますか?

Collections.synchronizedMap(new WeakHashMap<Class, Object>());

つまり、代わりに使用できるJava.util.concurrentの何かがありますか?単に置き換えることに注意してください

new ConcurrentHashMap<Class, Object>(new WeakHashMap<Class, Object>()));

明らかに動作しません

46
Nikita

Guava 's CacheBuilder クラスを使用すると、これを簡単に行うことができます。

_CacheBuilder.newBuilder().weakKeys().build()
_

これにより、キーの等価セマンティクスが.equals()ではなく_==_に変更されることに注意してください。これは、Classインスタンスを使用する場合は問題ではありませんが、潜在的な落とし穴です。

36

あるとは思わない。実際、javadocはCollections.synchronizedMap()の使用を提案しています

「ほとんどのコレクションクラスと同様に、このクラスは同期されていません。同期されたWeakHashMapは、Collections.synchronizedMapメソッドを使用して構築できます。」

19
objects

Cafeine は、グアバキャッシュの人気ライバルです。

- keys automatically wrapped in weak references
- values automatically wrapped in weak or soft references

使用法:

LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
 .weakKeys()
 .weakValues()
 .build(key -> createExpensiveGraph(key));
1

ガベージコレクターは同期マップラッパーをバイパスして、いつでも直接弱参照を変更できるため、同期マップでのWeakHashMapのラップは引き続き正しく機能しますか? WeakHashMapは、シングルスレッドモデルでのみ実際に機能すると思います。

上記のように、WeakHashMapのドキュメント https://docs.Oracle.com/javase/7/docs/api/Java/util/WeakHashMap.html には、具体的に次のように記載されています。

「同期されたWeakHashMapは、Collections.synchronizedMapメソッドを使用して構築できます」

これは、この手法がガベージコレクターの動作と連携して機能する必要があることを意味します(ドキュメントにバグがある場合を除く)。

0
Slim Duiker

Java 7以降を使用している場合、このユースケースはClassValuehttps://docs.Oracle.com/)を使用してスレッドセーフな方法で解決されます。 javase/7/docs/api/Java/lang/ClassValue.htmlremoveの使用が必要な場合は、並行性について慎重に検討し、ドキュメントをよく読んでください。

Java 6以下を使用している場合。いいえ、WeakHashMapを同期する必要があります。

0
Scott Carey