嗨,伙计,我班上有一个全局哈希表,还有两个线程 A 和 B 与她一起工作。A 从 HashTable 中读取,B 在 Hashtable 中写入。是否存在互斥问题?我需要同步它或 Hashtable 类是安全的吗?
5 回答
Hashtable
是Map
接口的线程安全实现。
在常规的 put 和 get 操作中,您将是安全的。但是,当您在一个线程中对其进行迭代并从另一个线程修改其内容时,您将遇到ConcurrentModificationException
问题。因此,在迭代时,请确保迭代原始Hashtable
.
您应该改用ConcurrentHashMap
它,这是一个更好/更快的java.util.Map
接口实现。
使用 java 集合提供的同步 HashMap 很有用。这个类是一个简单的包装器并封装了 hashmap :
Collections.synchronizedMap(new HashMap());
更多示例在 java 文档中: http: //docs.oracle.com/javase/1.4.2/docs/api/java/util/Collections.html synchronizedMap
每个人都说了可以说的,但这只是对您所说的进行补充mutual exclusion
。你问会不会有这样的问题。线程安全程序必须确保如果threadA
正在使用一个代码块,block1
则在线程完成之前没有其他线程可以访问它。所以,如果我理解你的意思mutual exclusion
,是的,访问同一个同步(线程安全)共享资源的线程是互斥的,因为它们都不能同时访问它。如果您选择其中一种建议的安全实现
,Java 实际上会为您完成很多工作。Map
现在,如果您的 Hashtable (或您喜欢的任何其他线程安全的 mao )是共享资源,那么您唯一需要注意的是happens-before关系。如果一个线程正在读取数据而另一个线程正在写入数据,这一点很重要。
更多可以在java并发教程和java并发包文档中找到
HashTable
保证对其执行的任何操作都是原子的。但是如果你正在执行多个操作,你应该synchronize
这样做。在下面的示例中,即使contains
andput
是原子的,但代码具有check and act
引发条件,因此您需要额外synchronization
的。
if(!hashtable.contains(Object))
{
hashtable.put(key, value);
}
还要检查Collections.synchronizedMap()
orConcurrentHashMap
而不是HashTable