【发布时间】:2015-09-15 13:08:00
【问题描述】:
我有一个疑问。如果我在将一些数据放入地图的同时从地图中获取会发生什么?
我的意思是如果map.get() 和map.put() 同时被两个独立的进程调用。 get() 会等到put() 执行完毕吗?
【问题讨论】:
标签: java dictionary concurrency
我有一个疑问。如果我在将一些数据放入地图的同时从地图中获取会发生什么?
我的意思是如果map.get() 和map.put() 同时被两个独立的进程调用。 get() 会等到put() 执行完毕吗?
【问题讨论】:
标签: java dictionary concurrency
这取决于您使用的 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)不支持并发,不应由多个线程同时使用。
【讨论】:
它可能会抛出 ConcurrentModificationException - 不确定。使用 synchronizedMap 总是更好。这通常是通过在一些自然封装地图的对象上同步来完成的。如果不存在这样的对象,则应使用 Collections.synchronizedMap 方法“包装”地图。最好在创建时完成,以防止对地图的意外不同步访问:
Map map = Collections.synchronizedMap(new HashMap(...));
【讨论】:
Map 是一个接口,因此答案取决于您使用的实现。
一般来说,这个接口的简单实现,例如HashMap 和TreeMap,不是线程安全的。如果您没有围绕它们构建一些同步,同时puting 和geting 将导致未定义的行为 - 您可能会获得新值,您可能会获得旧值,很可能您只是获取ConcurrentModificationException,或者更糟的。
如果您想处理来自不同线程的相同Map,请使用ConcurrentMap 的实现之一(例如,ConcurrentHashMap),这可以保证发生前发生序列(即,如果get 在put 之前被触发,即使put 正在进行,您也会得到旧值,反之亦然),或者同步Map 的访问(例如,通过调用@987654326 @。
【讨论】: