地图对象的同步

时间:2013-11-16 06:59:19

标签: java multithreading map synchronization

我有一个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对象,因为我有长时间运行的进程会阻塞其他线程。

1 个答案:

答案 0 :(得分:3)

我会做两件事之一。

第一个,也就是我推荐的那个,是不要通过地图的副本。除了不使用同步对象的多线程问题之外,没有办法确保不会丢失/覆盖交叉获取/保存的值。

在你的经理类中,删除了getMap()和saveMap(),并用getValue()和setValue()替换它们。我会使这些方法同步,或用ConcurrentMap替换Map。这样你就不会有人抓住整个地图的实例。

第二个选项是用Hashtable替换地图。这是同步和线程安全的,但速度较慢。那会解决你的一些问题,但不是全部问题。你仍然对代码周围的地图有松散的引用。