java.util.Hashtable 线程安全吗?
我已经有一段时间没有使用哈希表来做任何重要的事情了,但我似乎记得 get() 和 put() 方法是同步的。
JavaDocs 没有反映这一点。他们只是说 Hashtable 类是同步的。我可以假设什么?如果多个线程同时访问哈希表(假设它们没有修改同一个条目),操作就会成功,对吧?我想我要问的是“java.util.Hashtable 线程安全吗?”
请指导我摆脱这个问题......
It's been a while since I've used hashtable for anything significant, but I seem to recall the get() and put() methods being synchronized.
The JavaDocs don't reflect this. They simply say that the class Hashtable is synchronized. What can I assume? If several threads access the hashtable at the same time (assuming they are not modifying the same entry), the operations will succeed, right? I guess what I'm asking is "Is java.util.Hashtable thread safe?"
Please Guide me to get out of this issue...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
它是线程安全的,因为 get、put、contains 方法等是同步的。此外,多个线程将无法同时访问哈希表,无论它们正在修改哪些条目。
编辑 - 修改为包括同步使哈希表内部线程安全的规定,因为它是原子修改的;它不能防止由于多个线程并发访问哈希表而导致外部代码中的竞争条件。
It is threadsafe because the get, put, contains methods etc are synchronized. Furthermore, Several threads will not be able to access the hashtable at the same time, regardless of which entries they are modifying.
edit - amended to include the provisio that synchronization makes the hashtable internally threadsafe in that it is modified atomically; it doesn't guard against race conditions in outside code caused by concurrent access to the hashtable by multiple threads.
对于一般用途,它是线程安全的。
但您必须了解,它并不能使您的应用程序逻辑成为线程安全的。例如,考虑实现将值放入地图中(如果该值尚不存在)。
这个惯用语称为
putIfAbsent
。单独使用 HashTable 很难以线程安全的方式实现这一点。对于成语replace(k,V,V)
也是如此。因此,对于某些惯用语,例如
putIfAbsent
和replace(K,V,V)
,我建议使用 ConcurrentHashMapFor general usage it is thread safe.
But you have to understand that it doesn't make your application logic around it thread-safe. For e.g. consider implementing to put a value in a map, if it's not there already.
This idiom is called
putIfAbsent
. Its difficult to implement this in a thread-safe manner using HashTable alone. Similarly for the idiomreplace(k,V,V)
.Hence for certain idioms like
putIfAbsent
and andreplace(K,V,V)
, I would recommend using ConcurrentHashMap哈希表已被弃用。忘了它。如果您想使用同步集合,请使用 Collections.syncrhonize*() 包装器来实现此目的。但这些都是不推荐的。在Java 5中,实现了6种新的并发算法。写时复制、CAS、无锁算法。
对于 Map 接口,有两个并发实现。 ConcurrentHashMap(并发哈希映射)和ConcurrentSkipListMap - 并发排序映射实现。
第一个针对读取进行了优化,因此即使在更新表时检索也不会阻塞。与同步包装器相比,写入速度也快得多,因为 ConcurrentHashMap 不是由一个表组成,而是由一组表(称为段)组成。它可以通过构造函数中的最后一个参数进行管理:
ConcurrentHashMap 在高度并发的上下文中是不可或缺的,它的性能远远优于任何可用的替代方案。
Hashtable is deprecated. Forget it. If you want to use synchronized collections, use Collections.syncrhonize*() wrapper for that purpose. But these ones are not recommended. In Java 5, 6 new concurrent algorithms have been implemented. Copy-on-write, CAS, lock-free algorithms.
For Map interface there are two concurrent implementations. ConcurrentHashMap (concurrent hash map) and ConcurrentSkipListMap - concurrent sorted map implementaion.
The first one is optimized for reading, so retrievals do not block even while the table is being updated. Writes are also work much faster comparing with synchronized wrappers cause a ConcurrentHashMap consists of not one but a set of tables, called segments. It can be managed by the last argument in the constructor:
ConcurrentHashMap is indispensable in highly concurrent contexts, where it performs far better than any available alternative.
不。它是“线程安全的”仅在其方法是同步的情况下。然而,它通常不是线程安全的,也不可能是线程安全的,因为导出内部状态的类(例如迭代器或枚举)也需要使用内部状态进行同步。这就是为什么新的 Collections 类不是同步的,因为 Java 设计者认识到线程安全取决于类的用户,而不是类本身。
No. It is 'threadsafe' only to the extent that its methods are synchronized. However it is not threadsafe in general, and it can't be, because classes that export internal state such as Iterators or Enumerations require the use of the internal state to be synchronized as well. That's why the new Collections classes are not synchronized, as the Java designers recognized that thread-safety is up to the user of the class, not the class itself.
是的,Hashtable 是线程安全的,如果应用程序中不需要线程安全,则使用 HashMap,如果需要线程安全的实现,则建议使用 ConcurrentHashMap 代替 Hashtable。
Yes Hashtable is thread safe, If a thread safe is not needed in your application then go through HashMap, In case, If a thread-safe implementation is desired,then it is recommended to use ConcurrentHashMap in place of Hashtable.
请注意,很多答案都表明哈希表是同步的。但这只会给你很少的东西。访问器/修改器方法上的同步将阻止两个线程同时从映射中添加或删除,但在现实世界中,您通常需要额外的同步。
即使迭代 Hashtable 的条目也不是线程安全的,除非您还通过额外的同步来保护 Map 不被修改。
Note, that a lot of the answers state that Hashtable is synchronised. but this will give you a very little. The synchronization is on the accessor / mutator methods will stop two threads adding or removing from the map concurrently, but in the real world you will often need additional synchronisation.
Even iterating over a Hashtable's entries is not thread safe unless you also guard the Map from being modified through additional synchronization.
如果你查看 Hashtable 代码,你会发现方法是同步的,例如:
你可以按住 control 键(mac 上的命令),然后单击 eclipse 中的任何方法名称来转到 java 源代码。
If you look into Hashtable code, you will see that methods are synchronized such as:
You can keep pressing on control key (command for mac) and then click on any method name in the eclipse to go to the java source code.
与新的集合实现不同,Hashtable 是同步的。 *如果不需要线程安全实现,建议使用 HashMap* 代替 Hashtable。如果需要线程安全的高并发实现,那么建议使用ConcurrentHashMap代替Hashtable。
http://download.oracle.com/javase/7/docs/api/java/util/Hashtable.html
Unlike the new collection implementations, Hashtable is synchronized. *If a thread-safe implementation is not needed, it is recommended to use HashMap* in place of Hashtable. If a thread-safe highly-concurrent implementation is desired, then it is recommended to use ConcurrentHashMap in place of Hashtable.
http://download.oracle.com/javase/7/docs/api/java/util/Hashtable.html
是的,Hashtable 线程安全,因此任何时候只有一个线程可以访问哈希表
,而另一方面,HashMap 不是线程安全的(因此“更快”)。
Yes, Hashtable thread safe, so only one thread can access a hashtable at any time
HashMap, on the other side, is not thread safe (and thus 'faster').