使用线程A的ConcurrentHashMap remove()在使用线程B进行迭代时

时间:2016-10-27 14:45:27

标签: java multithreading concurrency concurrenthashmap

据我了解,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),该怎么办?看起来会破裂吗?

1 个答案:

答案 0 :(得分:2)

好吧,remove()克隆HashEntry元素直到删除元素,而不是修改旧元素。所以你得到了

B * - &gt; A * - &gt; D-&gt; E在桶中,但原始

A-> B-> C- ^序列未被触及。

你可以确定A.equals(A *)== false,即使它们具有相同的键和相等的值。但这对于迭代器来说不是问题,因为它只是使用已经获得的条目A继续前进。

P.S。 ConcurrentHashMap使用桶级别的锁进行修改。它不是无锁的。