本文介绍了在执行调整大小时在多线程环境中使用Hashmap的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习一个教程,它基本上解释了在多线程环境中调整Hashmap大小时出现的竞争状态的原因:

在阅读完这篇文章后,我有两个问题:


  1. 为什么每个存储桶的链接表按顺序颠倒?

  2. 我可以看到可能存在竞争条件,但看不到无限循环是怎么来的?是否因为一个线程可能会将元素尾部附加到尾部,而另一个线程则以相反的顺序进行追加?

请帮我澄清一下这非常感谢!

解决方案

实际上,至少有一个与 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以 rehash = true ,并且线程T2以 rehash = false 结尾(让我们假设T1已经改变了 this.useAltHashing

现在,猜猜哪个线程将写入 this.table - 你不知道,可以。所以,无论你是否得到一致的内部状态,这都是一个运气问题。



无论如何,正如我在设计中评论时所说的那样,在多线程环境中使用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:

  1. Why is the linked list for each bucket be reversed in order?
  2. I can see there could be race condition, but cannot see how the infinite loop comes? Is it because one thread might append the element head to tail while the other doing it in the reverse order?

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):

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;

Here It is possible that thread T1 ends up with rehash = true and thread T2 ends up with rehash = false (let's suppose T1 has already changed the value of this.useAltHashing).

Now, guess that which thread will write the this.table - you have no idea, either can. So, it's a question of luck whether you get a consistent internal state or not.

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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-20 09:26