我已经有一段时间没有使用hashtable做任何重要的事情了,但我似乎记得get()和put()方法是同步的。JavaDocs没有反映这一点。它们只是说Hashtable类是同步的。我能假设什么?如果多个线程同时访问哈希表(假设它们没有修改同一个条目),操作将成功,对吗?我想我问的是“java.util.Hashtable线程安全吗?”“请引导我走出这个问题…
eaf3rand1#
它是线程安全的,因为get、put、contains等方法都是同步的。此外,多个线程将无法同时访问哈希表,无论它们正在修改哪些条目。编辑-修改为包括同步使哈希表内部线程安全的规定,因为它是原子修改的;它不能防止外部代码中由多个线程并发访问哈希表引起的竞争条件。
s3fp2yjn2#
对于一般用途,它是线程安全的。但是您必须明白,它并不能使围绕它的应用程序逻辑成为线程安全的。例如,考虑实现将值放入Map中,如果它还没有。这个习惯用法叫做putIfAbsent。单独使用HashTable很难以线程安全的方式实现这一点。类似的还有成语replace(k,V,V)。因此,对于某些习惯用法,如putIfAbsent和replace(K,V,V),我建议使用ConcurrentHashMap
putIfAbsent
replace(k,V,V)
replace(K,V,V)
bgibtngc3#
Hashtable已弃用。如果你想使用synchronized collections,使用Collections.syncrhonize*() Package 器就可以了。但是这些是不推荐的。在Java 5中,实现了6个新的并发算法。写时复制、CAS、无锁算法。对于Map接口,有两个并发实现。ConcurrentHashMap(并发哈希Map)和ConcurrentSkipListMap -并发排序Map实现。第一个是为阅读而优化的,因此即使在更新表时检索也不会阻塞。与同步 Package 器相比,写操作也要快得多,因为ConcurrentHashMap由一组表(称为段)组成,而不是一个表。它可以通过构造函数中的最后一个参数进行管理:
public ConcurrentHashMap(int initialCapacity, float loadFactor, int concurrencyLevel);
字符串ConcurrentHashMap在高度并发的上下文中是必不可少的,它的性能远远优于任何可用的替代方案。
txu3uszq4#
不。它是'线程安全'的 * 只有在 * 它的方法是同步的。然而,它通常不是线程安全的,也不可能是线程安全的,因为导出内部状态的类(如迭代器或枚举)也需要使用内部状态进行同步。这就是为什么新的Collections类不是同步的,因为Java设计者认识到线程安全性取决于类的用户,而不是类本身。
ljo96ir55#
我问的是“java.util.Hashtable线程安全吗?“.是的Hashtable是线程安全的,如果你的应用程序中不需要线程安全,然后通过HashMap,如果需要线程安全的实现,那么建议使用ConcurrentHashMap来代替Hashtable。
xiozqbni6#
注意,很多答案都说Hashtable是同步的。但这个只能给予你一点点同步是在accessor / mutator方法上进行的,它会阻止两个线程并发地添加或删除map,但在真实的世界中,你经常需要额外的同步。即使遍历Hashtable的条目也不是线程安全的,除非您还通过额外的同步来防止Map被修改。
r1zhe5dt7#
如果你查看Hashtable代码,你会看到方法是同步的,比如:
public synchronized V get(Object key) public synchronized V put(K key, V value) public synchronized boolean containsKey(Object key)
字符串你可以一直按下control键(mac的command),然后点击eclipse中的任何方法名,进入java源代码。
nafvub8i8#
与新的集合实现不同,Hashtable是同步的。 如果不需要线程安全的实现,建议使用HashMap代替Hashtable。如果需要线程安全的高并发实现*,建议使用ConcurrentHashMap代替Hashtable。http://download.oracle.com/javase/7/docs/api/java/util/Hashtable.html
yr9zkbsy9#
是的,Hashtable是线程安全的,所以任何时候只有一个线程可以访问一个Hashtable另一方面,HashMap不是线程安全的(因此“更快”)。
9条答案
按热度按时间eaf3rand1#
它是线程安全的,因为get、put、contains等方法都是同步的。此外,多个线程将无法同时访问哈希表,无论它们正在修改哪些条目。
编辑-修改为包括同步使哈希表内部线程安全的规定,因为它是原子修改的;它不能防止外部代码中由多个线程并发访问哈希表引起的竞争条件。
s3fp2yjn2#
对于一般用途,它是线程安全的。
但是您必须明白,它并不能使围绕它的应用程序逻辑成为线程安全的。例如,考虑实现将值放入Map中,如果它还没有。这个习惯用法叫做
putIfAbsent
。单独使用HashTable很难以线程安全的方式实现这一点。类似的还有成语replace(k,V,V)
。因此,对于某些习惯用法,如
putIfAbsent
和replace(K,V,V)
,我建议使用ConcurrentHashMapbgibtngc3#
Hashtable已弃用。如果你想使用synchronized collections,使用Collections.syncrhonize*() Package 器就可以了。但是这些是不推荐的。在Java 5中,实现了6个新的并发算法。写时复制、CAS、无锁算法。对于Map接口,有两个并发实现。ConcurrentHashMap(并发哈希Map)和ConcurrentSkipListMap -并发排序Map实现。
第一个是为阅读而优化的,因此即使在更新表时检索也不会阻塞。与同步 Package 器相比,写操作也要快得多,因为ConcurrentHashMap由一组表(称为段)组成,而不是一个表。它可以通过构造函数中的最后一个参数进行管理:
字符串
ConcurrentHashMap在高度并发的上下文中是必不可少的,它的性能远远优于任何可用的替代方案。
txu3uszq4#
不。它是'线程安全'的 * 只有在 * 它的方法是同步的。然而,它通常不是线程安全的,也不可能是线程安全的,因为导出内部状态的类(如迭代器或枚举)也需要使用内部状态进行同步。这就是为什么新的Collections类不是同步的,因为Java设计者认识到线程安全性取决于类的用户,而不是类本身。
ljo96ir55#
我问的是“java.util.Hashtable线程安全吗?“.
是的Hashtable是线程安全的,如果你的应用程序中不需要线程安全,然后通过HashMap,如果需要线程安全的实现,那么建议使用ConcurrentHashMap来代替Hashtable。
xiozqbni6#
注意,很多答案都说Hashtable是同步的。但这个只能给予你一点点同步是在accessor / mutator方法上进行的,它会阻止两个线程并发地添加或删除map,但在真实的世界中,你经常需要额外的同步。
即使遍历Hashtable的条目也不是线程安全的,除非您还通过额外的同步来防止Map被修改。
r1zhe5dt7#
如果你查看Hashtable代码,你会看到方法是同步的,比如:
字符串
你可以一直按下control键(mac的command),然后点击eclipse中的任何方法名,进入java源代码。
nafvub8i8#
与新的集合实现不同,Hashtable是同步的。 如果不需要线程安全的实现,建议使用HashMap代替Hashtable。如果需要线程安全的高并发实现*,建议使用ConcurrentHashMap代替Hashtable。
http://download.oracle.com/javase/7/docs/api/java/util/Hashtable.html
yr9zkbsy9#
是的,Hashtable是线程安全的,所以任何时候只有一个线程可以访问一个Hashtable
另一方面,HashMap不是线程安全的(因此“更快”)。