在Java中同时获取并放入Map

时间:2015-06-29 06:50:39

标签: java dictionary concurrency

我有一个疑问。如果我在绘制一些数据的同时从地图中获取会发生什么?

我的意思是,map.get()map.put()同时由两个独立的进程调用。 get()会等到put()执行完毕吗?

3 个答案:

答案 0 :(得分:5)

这取决于您使用的Map实现。

例如,ConcurrentHashMap支持完全并发,get()不会等待put()执行,并在Javadoc中声明:

 * <p> Retrieval operations (including <tt>get</tt>) generally do not
 * block, so may overlap with update operations (including
 * <tt>put</tt> and <tt>remove</tt>). Retrievals reflect the results
 * of the most recently <em>completed</em> update operations holding
 * upon their onset.

其他实现(例如HashMap)不支持并发,不应该同时被多个线程使用。

答案 1 :(得分:2)

它可能会抛出ConcurrentModificationException-不确定它。使用synchronizedMap总是更好。这通常通过同步一些自然封装地图的对象来实现。如果不存在这样的对象,则应使用Collections.synchronizedMap方法“包装”地图。这最好在创建时完成,以防止意外地不同步访问地图:

Map map = Collections.synchronizedMap(new HashMap(...));

答案 2 :(得分:1)

Map是一个接口,因此答案取决于您正在使用的实现。

一般来说,此界面的简单实现,例如HashMapTreeMap 非线程安全。如果你没有围绕它们构建一些同步,同时putget将导致一个未定义的行为 - 你可能得到新的值,你可能得到旧的,最可能破坏你只会得到一个ConcurrentModificationException或更糟糕的东西。

如果你想从不同的线程处理相同的Map,可以使用ConcurrentMap的一个实现(例如,一个ConcurrentHashMap),这可以保证之前发生的事情。序列(即,如果getput之前被触发,则即使put正在进行,也会获得旧值,反之亦然),或同步{ {1}}访问权限(例如,通过调用Collections#synchronizedMap(Map)