9

我读过哈希表是线程安全的,因为它是同步的。考虑这个代码片段

if(!hashtable.contains(key)){
hashtable.put(key,value);
}

对 hashtable 的操作可能不同步。例如,如果Thread t1访问 hastable 并检查 key 并同时Thread t2检查 key,则在 t1 执行 put 之前。现在两个线程在 if 块内,并且发生键值覆盖。

所以同步块是必要的。

synchronized {
if(!hashtable.contains(key)){
    hashtable.put(key,value);
    }
}

这种理解正确吗?或者对于在 hastables 上执行的操作,hastables 是安全的。我在阅读有关比赛条件的帖子时遇到了这个疑问

4

2 回答 2

13

你是正确的,你需要这个synchronized块。Hashtable's方法是,但是在块synchronized外调用多个方法时,您仍然有可能发生竞争synchronized。例如,内置同步可以防止两个线程put同时调用时出现问题。

您可能还想研究ConcurrentHashMap

于 2013-10-07T21:04:27.567 回答
4

Hashtable方法是同步的,但这仅提供针对竞争条件的方法级保护。(因此,如果多个线程同时尝试修改数据,则a —Hashtable与 a 不同— 不会在内部损坏。)只有在这种意义上,它才是线程安全的。HashMapHashtable

Hashtable和 a都ConcurrentHashMap不会提供更高级别的同步,这通常是您在执行多步操作时需要的无论如何,您都需要一个外部synchronized块,因此您不妨使用开销较低的HashMap而不是Hashtable.

 *正如 Jeff Storey 指出的那样,ConcurrentHashMap有一种putIfAbsent方法可以完全按照您在代码中所做的工作。对于其他多步骤操作,ConcurrentHashMap可能有也可能没有一种方法可以原子地完成您需要的操作。

于 2013-10-07T21:08:04.433 回答