java - map 对象同步

标签 java multithreading dictionary synchronization

我有一个 Map 对象,它对应于存储在文件中的键值对。

private static Map myMap;

此 Map 对象有一个管理器类,它有一个 getMap() 方法,该方法将对象返回给调用者。

public static Map getMap() 

它还有一个同步方法 saveMap() 将内容保存回文件

public static synchronized void saveMap(Map map)

问题是,有些线程获取了 Map 对象但不想保存,即它们不调用 saveMap()。

假设thread1获取map对象并对其进行修改,即向map添加一个键值对。 key1=value1,任务完成后,从 map 中删除此键值对。中间有另一个线程thread2,它将另一个键值对添加到映射key2=value2,并在thread1实际删除之前保存它>key1 从 map 上。这会导致 key1=value1 和 key2=value2 都保存到文件中。这不是我想要的。

我该如何克服这种情况?我正在考虑用类似的东西修改 getMap() 方法

public Map getMap(boolean readonly) {
       if (readonly)
            return myMap.clone();
       return myMap;
}

这能解决我的问题吗?

注意:我不想使用互斥锁并锁定 Map 对象,因为我有长时间运行的进程,这会阻塞其他线程。

最佳答案

我会做两件事之一。

第一个,也是我推荐的,是不要分发 map 的副本。除了不使用同步对象导致的多线程问题之外,无法确保值不会因交错获取/保存而丢失/覆盖。

在您的管理器类中,删除了 getMap() 和 saveMap(),并将其替换为 getValue() 和 setValue()。我将使这些方法同步,或者将 Map 替换为 ConcurrentMap 。这样就不会有人持有整个 map 的实例。

第二个选项是将 map 替换为 Hashtable 。它是同步且线程安全的,但速度较慢。这会解决你的一些问题,但不是全部。您仍然对代码周围运行的 map 有松散的引用。

关于java - map 对象同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20015749/

相关文章:

java - Collection 的 Collection

java - 转换为 JAR 文件时未找到 UCanAccess 驱动程序

java - 表达式语言的 requestScope 对象如何在 JSP 文件中工作?

java - 在 Java 中,如何确保 boolean 标志的安全和一致的并发使用,同时最大限度地减少对时间性能的影响?

c# - 多线程场景调用Dictionary对象的set_item方法抛出NullReferenceException

java - 依赖于多个条件的执行和操作的解决方案模式

java - 当第一个线程完成时在第二个线程中使用 HashMap

java - 线程共享的 ReentrantLock 似乎不支持锁定

python - 从列表创建字典

c# - 垃圾收集会处理列表列表的值吗