我想要一个带有弱元素引用的并发集。我想过使用Guava的MapMaker
:
Set<Object> concurrentSet = Collections.newSetFromMap(
new MapMaker<Object, Boolean>().weakKeys().makeMap());
Guava会自动给你带弱键的身份哈希。
但是,事实证明MapMaker
不允许使用类型参数。
file.java:123 type com.google.common.collect.MapMaker does not take parameters
new MapMaker<Object, Boolean>().weakKeys().makeMap());
^
任何解决方案我如何获得对元素的弱引用的并发集?
答案 0 :(得分:5)
正如in the documentation所述,MapMaker
不是通用类型;它是<Object, Object>
。这意味着您可以将任何内容作为键或值放置,只需在撤消时进行转换即可。引用链接:
ConcurrentMap<Request, Stopwatch> timers = new MapMaker()
.concurrencyLevel(4)
.weakKeys()
.makeMap();
要获得Set
个Map
条目,请致电Map#entrySet()
。
答案 1 :(得分:5)
为了充实the accepted answer中提到的代码和注释,这是我自己对代码的看法,以获得并发的弱集。
使用类文档中建议的习语,使用Collections.newSetFromMap将并发Map包装为Set。使用Boolean
作为地图的值类型只是填充,无关紧要。
Set< YourObjectTypeGoesHere > concurrentWeakSet =
Collections.synchronizedSet(
Collections.newSetFromMap(
new WeakHashMap< YourObjectTypeGoesHere , Boolean >()
)
)
;
可以推断参数化类型,将代码简化为:
Set< YourObjectTypeGoesHere > concurrentWeakSet =
Collections.synchronizedSet(
Collections.newSetFromMap(
new WeakHashMap<>() // Types inferred, so omitted.
)
)
;
或者,我们可以使用Google Guava库中的MapMaker
。
我们不是使用该文档包装WeakHashMap的示例,而是根据Guava doc的建议将WeakHashMap替换为来自Google Guava的MapMaker的地图,以调用new MapMaker().weakKeys().makeMap()
。 Guava文档指出,此映射“使用对象标识比较键,而WeakHashMap使用Object.equals
”。
使用它比理解它更容易!
要创建并发弱集,请复制粘贴以下代码。替换两次YourObjectTypeGoesHere
。
int level = 16; // Basically, the approximate number of threads that may simultaneously try to mutate the map. See Guava doc.
ConcurrentMap<YourObjectTypeGoesHere , Boolean> concurrentWeakMap = new MapMaker().concurrencyLevel( level ).weakKeys().makeMap(); // Google Guava team recommends MapMaker > weakKeys > makeMap as a replacement for weakHashMap.
Set<YourObjectTypeGoesHere> concurrentWeakSet = Collections.newSetFromMap( concurrentWeakMap ); // Concurrency protection carries over to Set wrapper.
要添加到集合中:
concurrentWeakSet.add( myObject );
访问集合中的元素:
Iterator<YourObjectTypeGoesHere> iterator = concurrentWeakSet.iterator();
while(iterator.hasNext()) {
YourObjectTypeGoesHere myObject = iterator.next();
if( myObject != null ) { // Not sure if needed. Is it possible for object to be garbage-collected but not yet have its entry removed from the Set/Map?
// Work with the object.
}
}
弱是意味着不需要删除元素。随着元素被废弃和垃圾收集,它们会从我们的集合中消失(Map / Set)。
答案 2 :(得分:1)
您的原始方法可以正常工作,您只需将您的类型参数设置为makeMap()
Set<Object> concurrentSet = Collections.newSetFromMap(
new MapMaker().weakKeys().<Object, Boolean> makeMap());
使用Java较少使用的泛型方法调用语法。 Java Specification