java.util.Hashtable线程安全吗?

已经有一段时间了,因为我已经将哈希表用于任何重要的事情,但我似乎记得get()和put()方法是同步的。

JavaDocs没有反映这一点。 他们只是说Hashtable类是同步的。 我能假设什么? 如果多个线程同时访问哈希表(假设它们没有修改相同的条目),则操作将成功,对吧? 我想我要问的是“java.util.Hashtable线程安全吗?”

请指导我摆脱这个问题……

它是线程安全的,因为get,put,contains方法等是同步的。 此外,无论要修改哪些条目,多个线程都无法同时访问哈希表。

编辑 – 修改以包括同步使得哈希表内部线程安全的条件,因为它是primefaces地修改的; 它不能防止由多个线程并发访问哈希表导致的外部代码中的竞争条件。

对于一般用途,它是线程安全的。

但你必须明白,它会使你的应用程序逻辑在线程安全的周围。 例如,考虑实现在地图中放置一个值,如果它还没有。 这个成语叫做putIfAbsent。 单独使用HashTable以线程安全的方式实现它很困难。 类似地,对于成语替换(k,V,V)。

因此,对于像putIfAbsentreplace(K,V,V)这样的习语,我建议使用ConcurrentHashMap

Hashtable已弃用。 算了吧。 如果要使用同步集合,请使用Collections.syncrhonize *()包装器来实现此目的。 但不推荐这些。 在Java 5中,已经实现了6个新的并发算法。 写时复制,CAS,无锁算法。 对于Map接口,有两个并发实现。 ConcurrentHashMap(并发哈希映射)和ConcurrentSkipListMap – 并发排序映射实现。

第一个针对读取进行了优化,因此即使在更新表时,检索也不会阻塞。 与同步包装器相比,写入的工作速度要快得多,因此ConcurrentHashMap不是一个而是一组表,称为段。 它可以由构造函数中的最后一个参数来管理:

public ConcurrentHashMap(int initialCapacity, float loadFactor, int concurrencyLevel); 

ConcurrentHashMap在高度并发的上下文中是必不可少的,它比任何可用的替代方案都要好得多。

我问的是“java.util.Hashtable线程是否安全?”。

是Hashtable是线程安全的,如果您的应用程序中不需要线程安全,那么请通过HashMap,如果需要线程安全实现,那么建议使用ConcurrentHashMap代替Hashtable。

请注意,许多答案表明Hashtable已同步。 但这会给你一点点。 访问器/ mutator方法上的同步将阻止两个线程同时添加或从地图中删除,但在现实世界中,您经常需要额外的同步。

即使迭代Hashtable的条目也不是线程安全的,除非您还通过其他同步保护Map不被修改。

不可以。 只有在方法同步的情况下才是“线程安全”。 但是它通常不是线程安全的,并且它不能,因为导出内部状态的类(例如Iterators或Enumerations)也需要使用内部状态进行同步。 这就是为什么新的Collections类同步,因为Java设计者认识到线程安全取决于类的用户,而不是类本身。

如果查看Hashtable代码,您将看到方法是同步的,例如:

 public synchronized V get(Object key) public synchronized V put(K key, V value) public synchronized boolean containsKey(Object key) 

您可以继续按下控制键(mac命令),然后单击eclipse中的任何方法名称转到java源代码。

与新的集合实现不同, Hashtable是同步的。 * 如果不需要线程安全实现,建议使用HashMap *代替Hashtable。 如果需要线程安全的高度并发实现 ,那么建议使用ConcurrentHashMap代替Hashtable。

http://download.oracle.com/javase/7/docs/api/java/util/Hashtable.html

是的,Hashtable线程安全,因此任何时候只有一个线程可以访问哈希表

另一方面,HashMap不是线程安全的(因此“更快”)。