Java ConcurrentHashMap remove()使用线程A,而使用线程B进行迭代
据我所知,Java ConcurrentHashMap remove()使用线程A,而使用线程B进行迭代,java,multithreading,concurrency,concurrenthashmap,Java,Multithreading,Concurrency,Concurrenthashmap,据我所知,put()、clear()和remove()由ConcurrentHashMap提供,它是线程安全操作,不使用任何锁 在ConcurrentHashMap中,有不同的段,每个段有几个散列桶 Clear()和put()是线程安全的,因为Clear()只需清除对该存储桶的哈希链的引用,但哈希链仍然存在,因此如果线程A正在对其进行迭代,它将不会受到影响,而是Clear()来自线程BPut()将始终在该存储桶的哈希链的开头放置一个新节点,因此也可以 然而,我不明白的是为什么remove()会是
put()
、clear()
和remove()
由ConcurrentHashMap
提供,它是线程安全操作,不使用任何锁
在ConcurrentHashMap
中,有不同的段,每个段有几个散列桶
Clear()
和put()
是线程安全的,因为Clear()
只需清除对该存储桶的哈希链的引用,但哈希链仍然存在,因此如果线程A正在对其进行迭代,它将不会受到影响,而是Clear()
来自线程BPut()
将始终在该存储桶的哈希链的开头放置一个新节点,因此也可以
然而,我不明白的是为什么remove()
会是线程安全的?例如,hash bucket是bucket->A->B->C->D->E,线程A调用remove(C)
,ConcurrentHashMap的实现提供的机制是复制,B进入下一个链表,但顺序相反,bucket->B->a->D-E,然后在原始的D->E旁边做a,结果是bucket->B->a->D-E
为什么这是线程安全的?如果线程B
当前正在迭代元素A,然后线程A
调用remove(C),该怎么办。看起来它会断开?嗯,remove()将HashEntry元素克隆到removed元素,而不是修改旧元素。所以你得到了
B*->A*->D->E在桶中,但为原件
A->B->C-^序列未被触摸
您可以确保A.equals(A*)==false,即使它们的键和值相等。但这对迭代器来说不是问题,因为它只是使用已经获得的条目a继续前进
p.S.ConcurrentHashMap使用桶级锁进行修改。它不是无锁的。你说的是什么样的“破坏”?完美,有完美的意义。