面试题答案
一键面试线程安全机制
- Hashtable:
- 实现方式:对几乎所有涉及修改数据结构的方法(如
put
、get
、remove
等)都使用synchronized
关键字进行同步,这意味着同一时间只有一个线程可以访问这些方法,通过锁住整个哈希表来保证线程安全。 - 缺点:在高并发场景下,由于锁的粒度太大,会导致大量线程竞争同一把锁,从而造成性能瓶颈。
- 实现方式:对几乎所有涉及修改数据结构的方法(如
- ConcurrentHashMap:
- 实现方式:在Java 1.7及之前版本,采用分段锁(Segment)机制。每个Segment独立加锁,不同Segment之间的操作可以并发执行。比如在
put
操作时,只需要锁住当前元素对应的Segment,而不是整个哈希表。在Java 8及之后版本,摒弃了分段锁机制,采用Node数组 + 链表 + 红黑树的数据结构,并使用CAS
(Compare - and - Swap)算法和synchronized
关键字结合的方式实现线程安全。CAS
用于更新一些基本操作,而synchronized
则主要用于锁住链表头节点或红黑树的根节点,锁的粒度更细。 - 优点:大大提高了并发性能,允许多个线程同时访问不同部分的数据,减少了线程竞争。
- 实现方式:在Java 1.7及之前版本,采用分段锁(Segment)机制。每个Segment独立加锁,不同Segment之间的操作可以并发执行。比如在
迭代器
- Hashtable:
- 实现方式:当使用
Iterator
遍历Hashtable
时,如果在遍历过程中其他线程对Hashtable
进行了修改(增、删、改操作),会抛出ConcurrentModificationException
异常,即采用快速失败(fail - fast)机制。 - 缺点:这种机制在高并发场景下可能会导致遍历过程频繁失败,影响程序的正常执行。
- 实现方式:当使用
- ConcurrentHashMap:
- 实现方式:其迭代器采用弱一致性(weakly consistent)机制。在遍历过程中,允许其他线程对
ConcurrentHashMap
进行修改,迭代器能感知到部分修改,但不会抛出ConcurrentModificationException
异常。迭代器遍历的是创建迭代器时哈希表的快照,而在遍历过程中新增的元素可能不会被遍历到,删除和修改的元素则会根据具体情况有不同表现。 - 优点:在高并发环境下,迭代操作不会因为其他线程的修改而频繁失败,保证了遍历的相对稳定性,提高了并发性能。
- 实现方式:其迭代器采用弱一致性(weakly consistent)机制。在遍历过程中,允许其他线程对
性能优化
- Hashtable:
- 性能表现:由于锁粒度大,在高并发场景下,大量线程竞争锁,导致线程频繁阻塞和唤醒,上下文切换开销大,从而性能较低。
- ConcurrentHashMap:
- 性能表现:通过更细粒度的锁机制和
CAS
操作,减少了线程竞争,降低了上下文切换开销,提高了并发读写性能。例如在Java 8中,当链表长度超过阈值(默认为8)时会将链表转换为红黑树,提高了查找性能,进一步优化了高并发场景下的整体性能。
- 性能表现:通过更细粒度的锁机制和