扩展HashMap< K,V>并仅同步put [英] Extending HashMap<K,V> and synchronizing only puts

查看:181
本文介绍了扩展HashMap< K,V>并仅同步put的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近在我们的代码库上遇到了一个类,它扩展了HashMap并同步了put方法。



除了使用ConcurrentHashMap效率较低之外,可能会出现与扩展HashMap和同步只有put(K,V)?



假设我们不关心get(K)是否返回最新的值(例如,我们很好与线程覆盖彼此,我们不在乎



例如:

pre> public class MyMap< K,V>扩展HashMap< K,V> {
// ...
public synchronized void put(K key,V value){
// ...
}

...
}

据我所知,HashMap put方法,并且由于put在映射实例级别同步,在并发重新调整大小期间遇到的问题(可能)不会遇到。



即使有上述的可疑假设,我的直觉告诉我,可能会出现更多的问题。或者我只是偏执吗?



更新:谢谢大家,这是有趣和启发。如果我遇到这个特定班的作者的原作,我现在可以详细解释他的蠢话。 :)



总之:
putAll仍然可以破坏数据结构,并在可怕的无限循环/数据竞争条件下结束。
get依赖于hashmap的底层内部数据结构,可能在同时被修改的过程中导致get进程异常行为。
这只是一个很糟糕的主意。至少,作者可以使用Collections.synchronizedMap(Map)。



注意:这篇文章给出的所有三个答案都是正确的,但我选择了一个关于get()作为正确答案,因为它是我最不明显的一个。因为 get()可以读取不断变化的数据结构,因此

解决方案

一切都可能发生。



我已经看到get()陷入死循环,所以这不只是一个理论的可能性,坏事情发生。


I recently encountered a class on our code base that extends HashMap and synchronizes the put method.

Aside from it being less efficient than using ConcurrentHashMap, what sort of problems may arise with extending HashMap and synchronizing only put(K,V)?

Assume that we don't care whether get(K) returns the latest value or not(e.g. we are fine with threads overwriting each other and we don't care about the possible race conditions that may arise if the values of the map are used as locks themselves).

Example:

public class MyMap<K,V> extends HashMap<K,V> {
  //...
   public synchronized void put(K key, V value) {
      //...
   }

  //...
}

As far as I know, HashMap does its re-size with the put method and since the put is synchronized at the map instance level, the problems encountered during concurrent re-sizing will(probably) not be encountered.

Even with the questionable assumptions above, my gut-feeling is telling me that there are more problems that may arise. Or am I just being paranoid?

Update: Thank you all, that was fun and enlightening. If I ever meet the original of author of this particular class, I can now explain his folly in detail. :)

In summary: putAll can still screw up the data structure horribly and end up in the dreaded infinite-loop/data-race condition. get relies on the underlying internal data structures of hashmap that may be in the process of being modified concurrently causing the get process to behave weirdly. This is just a generally bad idea. At the very least, the author could have used Collections.synchronizedMap(Map) instead.

Note: All three answers given as of this writing are actually correct but I picked the one about get() as the correct answer since it was the least obvious one for me.

解决方案

since get() can be reading a changing data structure, everything bad can happen.

I've seen get() trapped in dead loop, so it's not just a theoretical possibility, bad things do happen.

这篇关于扩展HashMap&lt; K,V&gt;并仅同步put的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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