Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/372.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 非同步WeakHashMap有害吗?_Java_Thread Safety_Concurrentmodification_Weakhashmap - Fatal编程技术网

Java 非同步WeakHashMap有害吗?

Java 非同步WeakHashMap有害吗?,java,thread-safety,concurrentmodification,weakhashmap,Java,Thread Safety,Concurrentmodification,Weakhashmap,我有一个这样的代码 private static Map<String, Pattern> PATTERNS; private static Map<String, Pattern> patterns() { if (PATTERNS == null) { PATTERNS = new WeakHashMap<>(); // ok? or should be synchronized? } return PATTERN

我有一个这样的代码

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);
}
私有静态映射模式;
私有静态映射模式(){
if(PATTERNS==null){
PATTERNS=new WeakHashMap();//确定?还是应该同步?
}
返回模式;
}
//打算重用那些预编译的模式
私有静态模式(最终字符串正则表达式){
返回模式().computeFabSent(
requirennull(regex,“regex为null”),Pattern::compile);
}
我已经知道
WeakHashMap
未同步。我只是不关心
Pattern
s的多重构造


在多线程环境中,
模式是否应该同步?

多线程使用
HashMap
s会导致无限循环。IIRC,同时再灰化可以使桶形成链条

一般情况下,避免任何与比赛条件。也有例外,例如,不可变的缓存值

此外:

表示值的类型,例如
String
,不适合用作
WeakHashMap
的键

惰性初始化,超出JVM免费提供的范围,通常是不值得的。在这种情况下,你可能会得到两张地图,这并不特别重要

非同步WeakHashMap有害吗

对。您必须添加额外的保护才能跨线程使用
WeakHashMap

因此,Javadoc类中的建议是:

同步的
WeakHashMap
可以使用
Collections.synchronizedMap
方法构建

PATTERNS=Collections.synchronized(新的WeakHashMap());

请参阅。

您是否正在尝试实施?如果是这样,在定义字段时初始化该字段,这将保证线程安全初始化。如果这太昂贵,您需要及时创建线程安全的单例,那么在最后有一个有效的解决方案。@Turing85否,先生。我打算重用预编译的模式。@user7294900我没有所有内容的链接列表-你必须自己用谷歌搜索。谢谢你指出这一点,它在Java 8中仍然相关吗@user7294900它不是JDK中的bug。实现方式有所不同,因此确切的行为可能会发生变化。一般来说,并发使用的可变对象可能会导致错误输出以外的问题。您的代码示例提示,显然不可变的代码可能在接口后面有某种缓存,结果相同。
PATTERNS = Collections.synchronized( new WeakHashMap<>() ) ;