我有一个类似这样的代码。
private static Map<String, Pattern> PATTERNS;
private static Map<String, Pattern> patterns() {
if (PATTERNS == null) {
PATTERNS = new WeakHashMap<>(); // ok? or should be synchronized?
}
return PATTERNS;
}
// intending to reuse those pre-compiled patters
private static Pattern pattern(final String regex) {
return patterns().computeIfAbsent(
requireNonNull(regex, "regex is null"), Pattern::compile);
}
我已经知道
WeakHashMap
不同步。我只是不关心 Pattern
的多重构造。
在多线程环境下,
PATTERNS
是否应该同步?
非同步WeakHashMap有害吗?
是的。您必须添加额外的保护才能跨线程使用
WeakHashMap
。
因此在 Javadoc 类中找到的建议:
可以使用
方法构造同步WeakHashMap
Collections.synchronizedMap
PATTERNS = Collections.synchronizedMap(new WeakHashMap<>())
参见这个问题。
多线程使用
HashMap
可能会导致无限循环。 IIRC,并发重新哈希可以使桶形成一条链。
一般来说,避免任何有竞争条件的事情。但也有例外,例如不可变的缓存值。
还有:
表示值的类型(例如
String
)不适合用作 WeakHashMap
的键。
除了 JVM 免费提供的之外,延迟初始化通常是不值得的。在这种情况下,您最终可能会得到两张地图,这并不特别重要。