问题描述
我正在学习一个教程,它基本上解释了在多线程环境中调整Hashmap大小时出现的竞争状态的原因:
在阅读完这篇文章后,我有两个问题:
- 为什么每个存储桶的链接表按顺序颠倒?
- 我可以看到可能存在竞争条件,但看不到无限循环是怎么来的?是否因为一个线程可能会将元素尾部附加到尾部,而另一个线程则以相反的顺序进行追加?
请帮我澄清一下这非常感谢!
实际上,至少有一个与 rehashing 相关的争用条件。看看这个代码片段(它来自Sun JDK7):
布尔值oldAltHashing = this.useAltHashing;
this.useAltHashing | = sun.misc.VM.isBooted()&& (this.newCapacity> = Holder.ALTERNATIVE_HASHING_THRESHOLD);
boolean rehash = oldAltHashing ^ this.useAltHashing;
转账(newTable,rehash);
this.table = newTable;
这可能是线程T1以 现在,猜猜哪个线程将写入 无论如何,正如我在设计中评论时所说的那样,在多线程环境中使用HashMap 。不起作用。要么是因为这个原因,要么是因为其他原因。以上只是一个例子,为什么你不应该试图违背合同。 I am following a tutorial and it basically explains about the cause of race condition which happens when resizing Hashmap in a multithreaded environment: I have two questions after reading this: Please help me to clarify this, much appreciated! Actually there is at least one race condition related to rehashing. Look at this code fragment (it is from Sun JDK7): Here It is possible that thread T1 ends up with Now, guess that which thread will write the Anyway, as I mentioned in my comment by design, it is not supposed to use HashMap in a multithreaded environment. It will not work. Either because of this, or because of other reasons. The above was just one example why you shouldn't try to go against the contracts. 这篇关于在执行调整大小时在多线程环境中使用Hashmap的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! rehash = true
,并且线程T2以
rehash = false
结尾(让我们假设T1已经改变了 this.useAltHashing $ c的值
this.table
- 你不知道,可以。所以,无论你是否得到一致的内部状态,这都是一个运气问题。
boolean oldAltHashing = this.useAltHashing;
this.useAltHashing |= sun.misc.VM.isBooted() && (this.newCapacity >= Holder.ALTERNATIVE_HASHING_THRESHOLD);
boolean rehash = oldAltHashing ^ this.useAltHashing;
transfer(newTable, rehash);
this.table = newTable;
rehash = true
and thread T2 ends up with rehash = false
(let's suppose T1 has already changed the value of this.useAltHashing
).this.table
- you have no idea, either can. So, it's a question of luck whether you get a consistent internal state or not.