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

ConcurrentHashMap remove() using thread A while iterating using thread B

据我了解,put()clear()remove() 是由 ConcurrentHashMap 提供的,它是线程安全操作,无需使用任何锁。

ConcurrentHashMap中,有不同的段,每个段有几个散列桶。

Clear()put() 是线程安全的,因为 clear() 只是清除了对该桶的哈希链的引用,但哈希链仍然存在,所以如果 thread A 正在迭代它,它不会受到影响,但 thread Bclear()Put() 总是会在该桶的哈希链的开头放置一个新节点,所以也可以。

但是,我不明白的是为什么remove()会是线程安全的?比如hash bucket是bucket->A->B->C->D->E并且线程A调用remove(C)ConcurrentHashMap实现提供的机制是将A,B复制到下一个链表中,但顺序相反bucket->B->A->D-E 然后将 A.next 变成原来的 D->E,结果是 bucket->B->A->D-E

为什么这是线程安全的?如果 thread B 当前正在遍历元素 A 然后 thread A 调用 remove(C) 怎么办?好像要坏了?

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

B*->A*->D->E 在桶中,但原始

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

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

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