我正在经历ConcurrentHashMap
and 这个相关教程 http://javarevisited.blogspot.in/2013/02/concurrenthashmap-in-java-example-tutorial-working.html,并提出了一些问题。
文章中,提到了ConcurrentHashMap
允许多个读者同时读取而不会出现任何阻塞。这是通过根据并发级别将 Map 划分为不同部分并在更新期间仅锁定 Map 的一部分来实现的。默认并发级别为16,因此Map被分为16个部分,每个部分由不同的锁控制。这意味着,16个线程可以同时对Map进行操作,直到它们对Map的不同部分进行操作。这使得ConcurrentHashMap
尽管保持线程安全完好无损,但仍具有高性能。不过,它有一个警告:由于更新操作如put()
, remove()
, putAll()
or clear()
不同步,并发检索可能无法反映 Map 上的最新更改
文章中还提到了另外一点:另一个需要记住的要点是 CHM 上的迭代,迭代器由keySet
是弱一致的,它们只反映了状态ConcurrentHashMap
在某个时刻,可能不反映任何最近的变化.
我不明白以粗体突出显示的要点,您能否提供更多信息或在一个简单的程序中向我展示?
-
由于 put()、remove()、putAll() 或clear() 等更新操作不同步,并发检索可能无法反映 Map 上的最新更改
据我了解,这意味着一个线程中对映射的修改不一定会被另一个线程中同时发生的检索看到。考虑以下示例:
Thread 1 starts Thread 1's call to get("a")
a call to get("a") completes, returning null
| |
Thread 1 ---------+---------------------------------+-------
time ----->
Thread 2 -----+---------------------------+-----------------
| |
Thread 2 starts a Thread 2's call to
call to put("a", 1) put("a", 1) completes
尽管线程 2put
线程 1 的映射中的值get
执行完毕,线程1没有“看到”map修改,并返回null
.
-
另一个要记住的重要点是 CHM 上的迭代,ConcurrentHashMap 的 keySet 返回的迭代器是每周一致的,它们仅反映 ConcurrentHashMap 的状态和某些点,可能不反映任何最近的更改。
这是类似的情况。如果线程 1 获得Iterator
from a ConcurrentHashMap
's keySet
,然后线程 2 在映射中放置一个新条目,即线程 1 的Iterator
不保证看到该条目。 (可能会,也可能不会。)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)