gpt4 book ai didi

java - 不可修改的 map 是否需要同步?

转载 作者:行者123 更新时间:2023-12-02 12:52:36 25 4
gpt4 key购买 nike

我使用的是 JDK 1.4...所以我无法访问 1.5+ 中出色的并发功能。

考虑以下类片段:

private Map map = Collections.EMPTY_MAP;

public Map getMap() {
return map;
}

public synchronized void updateMap(Object key, Object value) {
Map newMap = new HashMap(map);
newMap.put(key, value);
map = Collections.unmodifiableMap(newMap);
}

鉴于我只能通过 updateMap 方法(已同步)更新 map ,是否有必要同步(或易失) map 引用?

map 对象将在多个线程中被访问(读取),特别是通过迭代器。知道如果后端映射的结构发生更改,迭代器将引发异常,我想我应该使映射不可修改。因此,当我通过 updateMap 更改 map 的结构时,现有迭代器将继续在“旧” map 上工作(这对我的目的来说很好)。

副作用是,我不必担心同步读取。从本质上讲,与写入相比,我的读取量将大得多。当前正在迭代 map 对象的线程将继续这样做,并且启动的任何新线程都将获取最新的 map 。 (好吧,我假设它将考虑埃里克森在这里的评论 - Java concurrency scenario -- do I need synchronization or not?)

有人可以评论一下这个想法是否好?

谢谢!

最佳答案

应该使用volatile关键字,以确保线程能够看到最新的Map版本。否则,如果没有同步,就无法保证其他线程会看到除空映射之外的任何内容。

由于您的 updateMap() 已同步,因此每次访问都会看到 map 的最新值。因此,您不会丢失任何更新。这是有保证的。但是,由于您的 getMap() 未同步,并且 map 不是 volatile ,因此无法保证线程会看到最新的值map 除非该线程本身是更新 map 的最新线程。使用 volatile 将解决这个问题。

但是,您确实可以访问 Java 1.5 和 1.6 并发附加功能。一个backport存在。我强烈建议使用向后移植,因为当您能够迁移到更高版本的 JDK 时,它可以轻松迁移到 JDK 并发类,并且它比您的方法具有更高的性能。 (尽管如果您的 map 很少更新,您的性能应该还可以。)

关于java - 不可修改的 map 是否需要同步?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/987679/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com