MST

星途 面试题库

面试题:Java Collection继承体系下的线程安全实现

在Java的Collection接口继承体系中,很多实现类不是线程安全的。请说明如何使这些非线程安全的集合类在线程环境中安全使用?以ArrayList为例,阐述至少两种实现线程安全的方式及其优缺点。
25.4万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

使用 Collections.synchronizedList

  1. 实现方式:通过 Collections.synchronizedList(new ArrayList<>()) 方法将 ArrayList 包装成线程安全的列表。例如:
List<String> synchronizedList = Collections.synchronizedList(new ArrayList<>());
  1. 优点:实现简单,只需调用一个静态方法即可将非线程安全的 ArrayList 转换为线程安全的。
  2. 缺点:性能相对较低,因为在每次访问集合时都需要进行同步操作,这会引入额外的开销。

使用 CopyOnWriteArrayList

  1. 实现方式:直接使用 CopyOnWriteArrayList 类,它内部实现了线程安全机制。例如:
List<String> copyOnWriteList = new CopyOnWriteArrayList<>();
  1. 优点:读操作性能高,因为读操作不需要加锁,在多线程环境下读操作可以并行执行。适用于读多写少的场景。
  2. 缺点:写操作性能低,每次写操作都会创建一个新的数组,然后将原数组的内容复制到新数组中,这会带来较大的开销。同时,由于写操作创建新数组,迭代器遍历的是旧数组,可能会导致迭代器看到的数据与集合当前的数据不一致(产生弱一致性)。

使用 ConcurrentHashMap 替代 ArrayList(适用于特定场景)

  1. 实现方式:如果 ArrayList 主要用于存储键值对形式的数据,且需要线程安全,可以考虑使用 ConcurrentHashMap。例如:
ConcurrentHashMap<Integer, String> concurrentMap = new ConcurrentHashMap<>();
  1. 优点:在高并发环境下性能表现良好,支持高效的并发读写操作。
  2. 缺点:结构与 ArrayList 不同,如果业务逻辑依赖 ArrayList 的特定顺序或索引访问特性,ConcurrentHashMap 无法满足需求。