我有一个Map对象,它对应于存储在File中的键值对。
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对象,因为我有长时间运行的进程会阻塞其他线程。
答案 0 :(得分:3)
我会做两件事之一。
第一个,也就是我推荐的那个,是不要通过地图的副本。除了不使用同步对象的多线程问题之外,没有办法确保不会丢失/覆盖交叉获取/保存的值。
在你的经理类中,删除了getMap()和saveMap(),并用getValue()和setValue()替换它们。我会使这些方法同步,或用ConcurrentMap替换Map。这样你就不会有人抓住整个地图的实例。
第二个选项是用Hashtable替换地图。这是同步和线程安全的,但速度较慢。那会解决你的一些问题,但不是全部问题。你仍然对代码周围的地图有松散的引用。