简体   繁体   English

ConcurrentHashMap remove()使用线程A进行迭代,而使用线程B进行迭代

[英]ConcurrentHashMap remove() using thread A while iterating using thread B

As I understand, put() , clear() and remove() are provided by ConcurrentHashMap and it is thread safe operation without using any locks. 据我了解, put()clear()remove()ConcurrentHashMap提供,它是线程安全的操作,无需使用任何锁。

In ConcurrentHashMap , there are different segments and for each segment there are several hash buckets. ConcurrentHashMap ,存在不同的段,并且对于每个段,都有多个哈希桶。

Clear() and put() are thread safe because clear() just clear the reference to the hash chain for that bucket but the hash chain is still there, so if thread A is iterating over it, it will not be affected but clear() from thread B . Clear()put()是线程安全的,因为clear()只是清除对该存储桶的哈希链的引用,但哈希链仍然存在,因此,如果线程A在其上进行迭代,它将不会受到影响,但clear()线程B。 Put() will always put a new node at the beginning of the hash chain for that bucket, so it is fine also. Put()始终将一个新节点放置在该存储桶的哈希链的开头,因此也可以。

However,What I don't understand is that why remove() will be thread safe? 但是,我不明白的是,为什么remove()将是线程安全的? For example, the hash bucket is bucket->A->B->C->D->E and thread A calls remove(C) , the mechanism provided by the implementation of the ConcurrentHashMap is to copy A, B into a next linked list but in reverse order bucket->B->A->DE and then make A.next to the original D->E which result in bucket->B->A->DE . 例如,哈希存储桶为bucket-> A-> B-> C-> D-> E线程A调用remove(C) ,由ConcurrentHashMap实现提供的机制是将A,B复制到下一个链表,但顺序相反: bucket-> B-> A-> DE ,然后在原始D-> E的 旁边添加A.next ,这会导致bucket-> B-> A-> DE

Why this is thread safe? 为什么这是线程安全的? What if thread B is currently iterating over element A and then thread A calls remove(C). 如果thread B当前正在元素A上进行迭代,然后thread A调用remove(C)怎么办? Looks like it will break? 看起来会破裂吗?

Well, remove() clones HashEntry elements up to removed element, not modifies old ones. 好吧,remove()会将HashEntry元素克隆到被删除的元素,而不是修改旧的元素。 So you get 所以你得到

B*->A*->D->E in bucket, but original B *-> A *-> D-> E在存储桶中,但为原始

A->B->C-^ sequence is not touched. 没有触摸A-> B-> C- ^序列。

You can be sure that A.equals(A*) == false, even though they will have equal keys and equal values. 您可以确定A.equals(A *)== false,即使它们具有相等的键和相等的值。 But that's not a problem for iterator as it simply uses already aquired entry A to move on. 但这对于迭代器来说不是问题,因为它只是使用已经获取的条目A继续前进。

PS ConcurrentHashMap uses locks on bucket level for modifications. PS ConcurrentHashMap使用存储桶级别的锁进行修改。 It's not lock-free. 它不是无锁的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM