【问题标题】:Is a non-synchronized WeakHashMap harmful?非同步的 WeakHashMap 有害吗?
【发布时间】:2019-11-23 10:46:44
【问题描述】:

我的代码看起来像这样。

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 没有同步。我只是不关心Patterns 的多重构造。

如果是多线程环境,PATTERNS 是否应该同步?

【问题讨论】:

  • 您是否尝试实现singleton pattern?如果是这样,在定义时初始化字段,这保证了线程安全的初始化。如果这太昂贵并且您需要即时创建线程安全的单例,this article 在最后有一个可行的解决方案。
  • @Turing85 不,先生。我打算重用预编译的模式。

标签: java thread-safety concurrentmodification weakhashmap


【解决方案1】:

非同步的 WeakHashMap 有害吗?

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

因此在 Javadoc 类中找到的建议:

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

PATTERNS = Collections.synchronized( new WeakHashMap<>() ) ;

this Question

【讨论】:

    【解决方案2】:

    HashMaps 的多线程使用会导致无限循环。 IIRC,并发重新散列可以使存储桶形成链。

    一般来说,避免任何有竞争条件的事情。也有例外,例如不可变的缓存值。

    还有:

    表示值的类型(例如String)不是用作WeakHashMap 的键的好类型。

    JVM 免费提供的延迟初始化通常是不值得的。在这种情况下,您最终可能会得到两张地图并不重要。

    【讨论】:

    • @user7294900 我没有所有内容的链接列表 - 你必须自己用谷歌搜索。
    • 感谢您指出,它在 Java 8 中是否仍然相关? stackoverflow.com/questions/35534906/…
    • @user7294900 这不是 JDK 中的错误。实现有所不同,因此确切的行为可能会改变。一般的观点是,同时使用的可变对象可能会导致错误输出之外的问题。您的代码示例暗示显然非可变代码可能在接口后面有某种缓存,结果相同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-30
    • 2011-05-21
    • 1970-01-01
    • 2017-06-15
    • 2013-08-06
    • 2012-11-24
    相关资源
    最近更新 更多