【发布时间】:2013-11-16 06:59:18
【问题描述】:
我有一个 Map 对象,它对应于存储在文件中的键值对。
private static Map myMap;
这个 Map 对象有一个管理器类,它有一个 getMap() 方法,该方法将对象返回给调用者。
public static Map getMap()
它还有一个同步方法 saveMap() 将内容保存回文件
public static synchronized void saveMap(Map map)
问题在于,有些线程获取了 Map 对象但不想保存,即他们不调用 saveMap()。
假设 thread1 获取地图对象并对其进行修改,即向地图添加键值对。 key1=value1,一旦任务完成,从地图中删除这个键值对。在这之间有另一个线程 thread2 将另一个键值对添加到映射 key2=value2 并在 thread1 实际删除 之前保存它>key1 来自地图。这会导致 key1=value1 和 key2=value2 都保存到文件中。这不是我想要的。
我该如何克服这种情况?我正在考虑用
之类的方法修改 getMap() 方法public Map getMap(boolean readonly) {
if (readonly)
return myMap.clone();
return myMap;
}
这能解决我的问题吗?
注意:我不想使用互斥锁并锁定 Map 对象,因为我有长时间运行的进程会阻塞其他线程。
【问题讨论】:
-
如果这不是你想要的,你为什么允许它发生?也许您应该将地图的 副本 提供给您不想保存其模组的线程。
-
@EJP 他提议的代码不就是这样吗?
-
无论您在做什么,如果您有多个线程对地图进行修改,您的代码就不是线程安全的,并且迟早,地图将处于不一致的状态。您根本不应该公开地图。将其封装在您的类中,并同步每个对地图的访问。
-
^+1^ 似乎要走的路。
-
@Sonic 一个鲜为人知的事实是,只有从一个线程读取地图,而另一个线程正在写入它,而两个线程都没有正确同步,可能会导致您的程序挂起!这是由于 HashMap 是如何实现的。
标签: java multithreading map synchronization