并发添加非线程安全的HashSet - 可能发生的最坏情况是什么? [英] Concurrent add on non threadsafe HashSet - what is the worst that could happen?

查看:129
本文介绍了并发添加非线程安全的HashSet - 可能发生的最坏情况是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

情况:

多个线程只向非线程安全 java.util.HashSet添加值并且在 Set 上没有进行任何其他操作,直到这些线程被停止。

Multiple Threads are only adding values to a non threadsafe java.util.HashSet and no other operation is done on the Set until these threads have been stopped.

问题:

可能发生的最坏情况是什么?

What is the worst that could happen?

推荐答案

这取决于你认为是最差的。

That depends on what you consider as being "worst".

我不确定这个问题是否针对当前实施的详细技术分析,考虑到所有可能的竞争条件和Java内存模型的细节。

I'm not sure whether this question aimed at a detailed, technical analysis of the current implementation considering all possible race conditions and the nitty-gritty details of the Java memory model.

因此,如果问题是:当前实施中可证明会发生什么?然后我不得不说:我不知道。而且我认为几乎没有人知道这一点。 (这有点像问你以100英里/小时的速度碰到一堵墙后,你的汽车的哪些部分会被打破? - 好吧,也许方向盘仍然完好无损,但这有关系吗?)

So if the question is: "What can provably happen in the current implementation?" then I have to say: "I don't know". And I assume that hardly anybody knows this for sure in detail. (It's somehow like asking "Which parts of your car will be broken after you hit a wall with 100 mph?" - well, maybe the steering wheel will still be intact, but does this matter?)

但如果问题是在使用多个线程访问not-threadsafe HashMap 时不太可能发生什么?那么有很多可能的答案:

But if the question is "What is not unlikely to happen when accessing a not-threadsafe HashMap with multiple threads?" then there are many possible answers:


  • 死锁

  • 例外

  • 缺少元素

  • 多次插入元素

  • 元素被插入到错误的哈希箱中

  • ...

  • Deadlocks
  • Exceptions
  • Missing elements
  • Elements being inserted multiple times
  • Elements being inserted into the wrong hash bin
  • ...

(根据我对恶劣的主观解释大致有序......)

(Roughly ordered by my subjective interpretation of "badness"...)

编辑:评论的澄清:当然,如果插入的调用多次发生,则只能添加两次元素。根据具体情况, HashMap 应该包含最多一次的每个键。但是,在 HashMap 中添加新条目的要求最终会委托给该电话

A clarification for the comment: Of course, an element could only be added twice if the call to insert it occurs multiple times. According to the specifiction, the HashMap should contain each key at most once. But the call for adding a new entry to the HashMap eventually delegates to the call

void createEntry(int hash, K key, V value, int bucketIndex) {
    Entry<K,V> e = table[bucketIndex];
    table[bucketIndex] = new Entry<>(hash, key, value, e);
    size++;
}

并且没有(明显的)理由为什么没有其他线程会导致重新散列(因此,在此方法的第一行和第二行之间创建一个新的数组)。然后这次调用的 bucketIndex 将是错误的。当第二次添加条目时,它可以使用(然后) <$ em> c> bucketIndex ,因此,之后将包含地图中的两次

And there is no (obvious) reason why no other thread should cause a rehash (and thus, the creation of a new table array) between the first and the second line of this method. Then the bucketIndex for this call would be wrong. When the entry is then added a second time, it could use the (then) right bucketIndex, and thus, would afterwards be contained twice in the map.

但是再次:为了真正证明这可能会发生,我们必须研究在一个几乎不可行的细节中实现。底线是:基本上任何在将具有多个线程的元素添加到非线程安全 HashMap 时可能会出错。

But again: In order to really prove that this might happen, one would have to study the implementation in a detail that is hardly feasible. The bottom line is: Basically anything can go wrong when adding elements with multiple threads to a non-threadsafe HashMap.

这篇关于并发添加非线程安全的HashSet - 可能发生的最坏情况是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆