面试题答案
一键面试性能
- Hashtable:由于其所有操作(如
put
、get
等)都通过synchronized
方法实现同步,在多线程环境下,同一时间只能有一个线程访问Hashtable
,这会导致严重的性能瓶颈,特别是在高并发场景下。 - ConcurrentHashMap:采用了更细粒度的锁机制,例如在JDK1.7中采用分段锁(Segment),JDK1.8中采用CAS + synchronized来保证线程安全。在高并发环境下,不同的线程可以同时访问不同的段(JDK1.7)或不同的链表/红黑树节点(JDK1.8),大大提高了并发性能。
锁机制
- Hashtable:使用
synchronized
关键字对整个哈希表进行加锁,即每次操作都需要获取整个Hashtable
对象的锁。这意味着当一个线程在执行put
操作时,其他线程无法进行get
、remove
等任何操作。 - ConcurrentHashMap:
- JDK1.7:采用分段锁(Segment)机制,每个Segment独立加锁,类似一个小型的哈希表。默认有16个Segment,因此最多可以同时支持16个线程并发访问不同的Segment,降低了锁竞争。
- JDK1.8:摒弃了分段锁机制,采用Node数组 + 链表/红黑树的数据结构,利用CAS(Compare - And - Swap)操作来更新节点,对于链表或红黑树的头节点使用
synchronized
关键字加锁,锁的粒度更细,进一步提升了并发性能。
适用场景
- Hashtable:适用于单线程环境或对并发性能要求不高,且需要简单实现线程安全的场景。例如在一些简单的桌面应用程序中,多线程访问频率较低的情况下可以使用。
- ConcurrentHashMap:适用于高并发环境,如大型的Web应用、分布式系统等,需要在保证线程安全的同时,尽可能提高系统的并发处理能力。在这些场景下,
ConcurrentHashMap
能够提供更好的性能和扩展性。