Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ConcurrentHashMap remove()使用线程A,而使用线程B进行迭代_Java_Multithreading_Concurrency_Concurrenthashmap - Fatal编程技术网

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()
来自线程B
Put()
将始终在该存储桶的哈希链的开头放置一个新节点,因此也可以

然而,我不明白的是为什么
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使用桶级锁进行修改。它不是无锁的。

你说的是什么样的“破坏”?完美,有完美的意义。