java.util包下提供了部分线程安全的类,有Vector、Stack、HashTable、Enumeration。当多个线程并发访问时,可以保证线程安全。通过其在jdk中的内部实现可知,它们的线程安全都是通过Synchronized关键字控制的。
HashMap和HashTable都实现了Map接口,在很多方面它们都一样。但是使用它们是得清楚它们的区别:
1.HashMap允许键值为null,而HashTable不允许键值为null
2.HashMap是线程不安全的,在多线程并发访问时需要通过外部控制以保证线程安全,例如通过:
Collections.synchronizedMap(hashMap);
而HashTable是线程安全的,其内部对HashTable操作的方法通过Synchronized关键字控制线程安全;jdk5提供了ConcurrentHashMap线程安全类,用于替代HashTable,性能比HashTable好;HashTable在线程安全实现上对整个map加锁,而ConcurrentHashMap采用分段加锁的方式,减小锁粒度,提高了性能。
3.HashMap的迭代器(Iterator)是快速失败迭代器,而HashTable的迭代器(enumerator)不是快速失败迭代器;这意味着HashMap迭代器在迭代元素时,若有其他线程改变了HashMap的结构,将抛出ConcurrentModificationException异常,但迭代器本身的remove方法不会抛出ConcurrentModificationException。
4.HashMap不能保证随着时间的推移其中的元素的顺序是不变的。
5.由于HashTable是线程安全的,并且使用Synchronized关键字对整个HashMap加锁,因此在单线程环境中,HashMap的性能要比HashTable好。
总结:
在单线程环境中使用HashMap,在多线程环境中可以使用HashTable,也可以对HashMap外部加锁等方式保证线程安全;但是如果使用的jdk版本在5以上的话,建议使用ConcurrentHashMap(要求保证线程线程),它的性能要比HashTable好。