Java中的哈希表与同步

Java中的哈希表与同步,java,multithreading,synchronization,hashtable,Java,Multithreading,Synchronization,Hashtable,我已经读到哈希表是线程安全的,因为它是同步的。考虑这个代码片段 if(!hashtable.contains(key)){ hashtable.put(key,value); } 哈希表上的操作可能不同步。例如,如果线程t1访问hastable并检查key,同时线程t2在t1执行put之前检查key。现在两个线程在if块内,并且键值被覆盖 所以同步块是必要的 synchronized { if(!hashtable.contains(key)){ hashtable.put(key,v

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

if(!hashtable.contains(key)){
hashtable.put(key,value);
}
哈希表上的操作可能不同步。例如,如果
线程t1
访问hastable并检查key,同时
线程t2
在t1执行put之前检查key。现在两个线程在if块内,并且键值被覆盖

所以同步块是必要的

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

这种理解正确吗?或者hastables在hastables上执行的操作是否安全。我在读这篇文章时遇到了这个疑问,你是正确的,你需要
同步的
块。
哈希表的
方法是
同步的
,但是在
同步的
块之外调用多个方法时,仍然有可能发生竞争。例如,内置同步可以防止两个线程同时调用
put
时出现问题


您可能还想查看
ConcurrentHashMap
Hashtable
方法是同步的,但这只提供了针对争用条件的方法级保护。(因此,
Hashtable
——与
HashMap
——不同的是,如果多个线程同时尝试修改数据,
Hashtable
——不会在内部损坏。)只有在这种意义上,
Hashtable
才是线程安全的


无论是
哈希表
还是
ConcurrentHashMap
都不会提供更高级别的同步,这通常是执行多步骤操作时所需要的。无论如何,您都需要一个外部
同步的
块,因此您最好使用开销较低的
HashMap
而不是
Hashtable


*正如Jeff Storey所指出的,
ConcurrentHashMap
有一个
putIfAbsent
方法,该方法与您在代码中所做的完全相同。对于其他多步骤操作,
ConcurrentHashMap
可能有也可能没有一个方法可以自动完成您需要的操作。

ConcurrentHashMap
有一个
putIfAbsent
方法,该方法将自动检查密钥的包含情况,如果没有,则将其放入exist@JeffStorey-是的,我忘了。非常感谢。我会相应地更新我的答案。但是,对于其他多步骤操作,可能需要外部同步。