HashTable 是Java1.0/1,1中的container,是老的java版本中遗留下来的类,为了使使用过HashTable的老代码仍能运行,新版java中仍保存了这个类,也就是为了兼容旧版本。
HashTable跟HashMap非常相似,连方法名都是差不多一样的。在新代码中没有必要使用HashTable,只需要HashMap就可以了。
Hashtable的性能跟HashMap是几乎一样的。因为HashMap的目的就是为了取代HashTable,它们的底层实现使用的是相同的存储和查找机制。
Hashtable跟HashMap的一个不同点是Hashtable是synchronized,它的实现机制是synchronize HashTable中的每一个get/set方法,也就是两个线程不能同时做添加或删除记录。但是这种做法并不能满足实际的需求,实际 中我们经常需要额外的同步。
比方说,有这样的情况就是检查key是否存在,不存在的话添加一条记录,不管是使用HashTable还是HashMap,这都不是一个atomic 操作。要正确的实现这个逻辑,我们需要这样做:
synchronized(myMap) {
if (!myMap.containsKey("key1"))
myMap.put("key1", "value1");
}
HashTable的遍历也不是线程安全的,除非我们提供额外的同步来阻止hashtable不被修改。
所以,HashTable内部提供的同步是没什么大用的,新代码中就不应该使用它了。
更好的同步可以通过Collections.synchronizedMap(HashMap)来实现,更多详情Javadoc,
以下是Javadoc中的使用举例:
Map m = Collections.synchronizedMap(new HashMap());
...
Set s = m.keySet(); // Needn't be in synchronized block
...
synchronized (m) { // Synchronizing on m, not s!
Iterator i = s.iterator(); // Must be in synchronized block
while (i.hasNext())
foo(i.next());
}
另外一个 接口ConcurrentMap,通过加入先检查后操作的机制解决了这个问题:
ConcurrentMap.putIfAbsent(key, value);