日期:2014-05-20  浏览次数:20620 次

HashMap和HashTable到底该如何选择?
hashtable跟hashmap的区别:
hashtable是线程安全的,即hashtable的方法都提供了同步机制!(这一点是不是很影响性能?)
hashmap不是线程安全的,即不提供同步机制。(在多线程访问是不是会有问题?)
hashtable不允许插入空值,hashmap允许!

现在项目中的问题是,根据当前的订单号调用银行的转账接口,由于性能问题我不能将方法synchronized,因为接口本身速度就不快,为了防止重复提交,我在转账接口中设置了一个全局的集合,用的是HashMap,就是当某一个订单号进入这个方法时,先判断订单号是否在Map集合中,不在我将订单号保存在Map集合中,然后调用转账接口,当这比交易走完了,将订单号从集合中移除。如果订单号在Map集合中将直接返回。以前一直没出现过问题,但是昨天,客户出现了重复交易。是不是我用的hashMap不是线程安全的所导致的,如果我换成了hashTable是不是能解决这个问题?

还有就是hashMap和hashTable在性能上是不是有很大的差别?

还有没有别的解决办法?或者我这方法根本不可取?请各位指点一下。。。谢谢。。。。


------解决方案--------------------
ConcurrentHashMap
------解决方案--------------------
"当某一个订单号进入这个方法时,先判断订单号是否在Map集合中,不在我将订单号保存在Map集合中"
如果没有同步,这里存在竞态条件问题
有可能两个线程同时判断Map中有没有,此时都返回没有,那么就会都去操作一遍

很幸运,ConcurrentHashMap#putIfAbsent(K key, V value) 方法有你要的功能

如果该方法的返回值是非null,表示已经有线程put过了,这个线程就无需再操作了
------解决方案--------------------
看你交易的量,如果不大,完全可以
public static final Object key = new Object()

然后在你的hashMap代码部分
synchronized(key){
hashMap.put(...)
}

类似的方法, 
当然,交易量不大,用HashTable也行,性能差距没想象的大(换句话说,整个交易的性能瓶颈,不是HashTable造成的)
------解决方案--------------------
如果我没记错的话,不是 HashTable,而是 Hashtable 吧?