首页 文章

Map 对象的同步

提问于
浏览
0

我有一个Map对象,它对应于存储在File中的键值对 .

private static Map myMap;

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

public static Map getMap()

它还有一个synchronized方法saveMap(),它将内容保存回File

public static synchronized void saveMap(Map map)

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

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

我怎样才能克服这种情况?我正在考虑用类似的方法修改getMap()方法

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

这会解决我的问题吗?

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

1 回答

  • 3

    我会做两件事之一 .

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

    在你的manager类中,删除了getMap()和saveMap(),并用getValue()和setValue()替换它们 . 我会使这些方法同步,或用ConcurrentMap替换Map . 这样你就不会有人坚持整个 Map 的实例 .

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

相关问题