简体   繁体   English

Hashtable vs ConcurrentHashMap,答案是否正确,为什么?

[英]Hashtable vs ConcurrentHashMap, is the answer correct, why?

I read somewhere about replacing Hashtable with ConcurrentHashMap:我在某处读到了关于用 ConcurrentHashMap 替换 Hashtable:

Since Hashtable locks whole Map instead of a portion of Map, compound operations like if(Hashtable.get(key) == null) put(key, value) works in Hashtable but not in concurrentHashMap.由于 Hashtable 锁定整个 Map 而不是 Map 的一部分,因此 if(Hashtable.get(key) == null) put(key, value) 等复合操作在 Hashtable 中有效,但在 concurrentHashMap 中无效。 instead of this use putIfAbsent() method of ConcurrentHashMap而不是这个使用 ConcurrentHashMap 的 putIfAbsent() 方法

Since there is a gap between the get and the put, why does the hashtable work?既然get和put之间有差距,那hashtable为什么会起作用呢?

if(Hashtable. get (key) == null) put (key, value) if( Hashtable.get (key) == null) put (key, value)

In your question you quoted this as fact:在您的问题中,您将此作为事实引用:

"Since Hashtable locks whole Map instead of a portion of Map , compound operations like if (hashtable.get(key) == null) hashtable.put(key, value) works in Hashtable but not in ConcurrentHashMap ." “由于Hashtable锁定整个Map而不是Map的一部分,因此if (hashtable.get(key) == null) hashtable.put(key, value)等复合操作在Hashtable中有效,但在ConcurrentHashMap中无效。”

Unfortunately it is incorrect.不幸的是,这是不正确的。 That code using Hashtable does NOT work... in the sense that the author means.使用Hashtable的代码不起作用......在作者的意思上。

Yes, the get and put methods do lock the entire table.是的, getput方法确实会锁定整个表。 But these methods only hold the lock for the duration of the operation.但是这些方法只在操作期间持有锁。 Between the get and put , the above code will release the lock on hashTable and then reacquire it.getput之间,上面的代码将释放hashTable上的锁,然后重新获取它。

This means that a second thread could call put to put a different value for the key.这意味着第二个线程可以调用put为键放置不同的值。 The sequence might look like this:序列可能如下所示:

  1. thread A - hashtable.get("a") -> null线程 A - hashtable.get("a") -> null
  2. thread B - hashtable.get("a") -> null线程 B - hashtable.get("a") -> null
  3. thread B - hashtable.put("a", 1)线程 B - hashtable.put("a", 1)
  4. thread A - hashtable.put("a", 2)线程 A - hashtable.put("a", 2)

And we have called put twice with different values for the same key.我们已经为同一个键调用put两次不同的值。

Which thread will "win"?哪个线程会“赢”? In general, we can't say.一般来说,我们不能说。 It depends on the precise timing, and other things.这取决于精确的时间和其他因素。 It is not predictable.这是不可预测的。

So, if the intended behavior is that the first thread to call get on the key should always win, then this is not a thread-safe implementation.因此,如果预期的行为是第一个调用get的线程应该总是获胜,那么这不是线程安全的实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM