线程安全的方式来复制地图

时间:2014-09-11 15:51:39

标签: java guava

使用JDK 7,SQLite,并在我的项目中使用Guava。

我有一个少于100个条目的TreeMap,由一个" worker"每秒线程数百次。我现在正在编写一个组件(另一个线程 - "数据库线程"),它将每隔5或10秒将地图写入我的数据库。

我知道我需要制作地图的深层副本,以便数据库线程将使用快照,而工作线程继续其工作。我正在查看Guava Maps class,它有许多制作副本的方法,但我不确定是否有任何方法可以满足我在需要副本时在地图上同步的需要。那里有一种方法可以满足我的需求,还是应该编写一个synchronized块来制作我自己的深层副本?

2 个答案:

答案 0 :(得分:7)

这取决于你想要的东西:

如果你想要一个完全并发的地图(在添加时不能读取等等)你应该使用JSlain在我之前说的话。

如果您想要的只是地图的CURRENT快照,并且只要您使用的迭代器不会被更改,您就不在意是否修改地图。

然后使用ConcurrentSkipListMap

这将为每次迭代提供一个新的独立迭代器,所以即使真实地图被更改,你也不会注意到它。

您将在下次更新中看到它(在您的情况下为5秒。)

答案 1 :(得分:2)

来自TreeMap javadoc:

  

请注意,此实现未同步。如果有多个线程   访问地图       同时,并且至少有一个线程在结构上修改了映射,它必须是       外部同步。 (结构修改是添加或删除一个的任何操作       或更多映射;仅仅改变与现有密钥相关联的值不是a       结构修改。)这通常通过同步某个对象来完成       自然地封装了地图。如果不存在此类对象,则应使用“包装”地图       Collections.synchronizedSortedMap方法。这最好在创建时完成,以防止       意外地不同步访问地图:

   SortedMap m = Collections.synchronizedSortedMap(new TreeMap(...));