据我了解,put()
,clear()
和remove()
由ConcurrentHashMap
提供,并且在不使用任何锁定的情况下是线程安全操作。
在ConcurrentHashMap
中,有不同的段,每个段有几个哈希桶。
Clear()
和put()
是线程安全的,因为clear()
只清除对该存储桶的哈希链的引用,但哈希链仍然存在,所以如果线程A < / strong>正在迭代它,它不会受到影响,但来自主题B 的clear()
。 Put()
将始终在该存储桶的哈希链的开头放置一个新节点,因此也可以。
但是,我不明白为什么remove()
将是线程安全的?例如,哈希桶是 bucket-&gt; A-> B-> C-> D-> E 和线程A 调用{{1} },remove(C)
的实现提供的机制是将A,B复制到下一个链接列表中,但顺序相反 bucket-&gt; B-&gt; A-&gt; DE 然后将A.next设为原始 D-> E ,这导致桶 - > B-> A-> DE 。
为什么这是线程安全的?如果ConcurrentHashMap
当前正在迭代元素A然后thread B
调用remove(C),该怎么办?看起来会破裂吗?
答案 0 :(得分:2)
好吧,remove()克隆HashEntry元素直到删除元素,而不是修改旧元素。所以你得到了
B * - &gt; A * - &gt; D-&gt; E在桶中,但原始
A-> B-> C- ^序列未被触及。
你可以确定A.equals(A *)== false,即使它们具有相同的键和相等的值。但这对于迭代器来说不是问题,因为它只是使用已经获得的条目A继续前进。
P.S。 ConcurrentHashMap使用桶级别的锁进行修改。它不是无锁的。