面试题答案
一键面试1. HashMap和HashTable在高并发场景下的性能表现
- HashMap:
- 非线程安全:在高并发环境下,多个线程同时对HashMap进行操作(如put、get、resize等)可能会导致数据不一致、死循环等问题。例如,在多线程同时进行扩容操作时,可能会形成环形链表,导致get操作进入死循环。所以HashMap在高并发场景下性能不稳定且不安全。
- HashTable:
- 线程安全:HashTable的方法(如put、get等)大多是synchronized修饰的,这意味着同一时间只有一个线程可以访问这些方法。虽然保证了线程安全,但这种粗粒度的锁机制在高并发场景下会造成严重的性能瓶颈,因为其他线程需要等待锁的释放,导致并发度很低。
2. 针对HashMap优化以适应高并发场景的方案
- 使用ConcurrentHashMap:
- 锁分段技术:ConcurrentHashMap采用了锁分段的机制,它将整个哈希表分成多个段(Segment),每个段都有自己独立的锁。在高并发情况下,不同的线程可以同时访问不同的段,从而提高并发度。例如,在进行put操作时,线程只会锁住要插入元素所在的段,而不会锁住整个哈希表。
- 读操作无锁:ConcurrentHashMap的读操作大多数情况下是无锁的,因为它使用了volatile关键字来保证内存可见性,所以在读取数据时不需要获取锁,进一步提高了并发性能。
- 使用Collections.synchronizedMap(new HashMap<>()):
- 原理:通过Collections的synchronizedMap方法,将HashMap包装成一个线程安全的Map。它内部使用了一个对象锁,对所有的操作进行同步。
- 缺点:与HashTable类似,这种方式也是粗粒度的锁,在高并发场景下,性能不如ConcurrentHashMap,因为所有的操作都需要竞争同一个锁。不过在并发度不高的情况下,可以使用这种方式简单地将HashMap变成线程安全的。