Java高频面试之集合-06

hello啊,各位观众姥爷们!!!本baby今天来报二次道了!哈哈哈哈哈嗝🐶

面试官:ArrayList有哪几种线程安全的实现方式?

在Java中,ArrayList本身是非线程安全的,但在多线程环境下可以通过以下几种方式实现线程安全的操作:


1. 使用 Collections.synchronizedList 包装

通过Collections.synchronizedList()方法将ArrayList包装为线程安全的列表。
实现方式:

java 复制代码
List<String> syncList = Collections.synchronizedList(new ArrayList<>());

特点:

  • 所有方法(如add、remove)通过synchronized同步,保证线程安全。
  • 缺点 :
    • 高并发时性能较差(锁竞争)。
    • 迭代时需手动同步,否则可能抛出ConcurrentModificationException。

示例:

java 复制代码
// 写入操作自动同步
syncList.add("value");

// 迭代时需手动同步
synchronized (syncList) {
    Iterator<String> it = syncList.iterator();
    while (it.hasNext()) {
        System.out.println(it.next());
    }
}

2. 使用 CopyOnWriteArrayList

java.util.concurrent.CopyOnWriteArrayList 是专为读多写少场景设计的线程安全列表。
实现方式:

java 复制代码
CopyOnWriteArrayList<String> cowList = new CopyOnWriteArrayList<>();

特点:

  • 读操作无锁:直接访问底层数组,性能高。
  • 写操作加锁:通过复制新数组实现,保证线程安全。
  • 缺点 :
    • 写操作开销大(需复制数组),不适合频繁修改的场景。
    • 数据弱一致性(迭代器遍历的是写操作前的快照)。

示例:

java 复制代码
cowList.add("value"); // 写操作加锁
cowList.get(0);       // 读操作无锁

3. 使用 Vector(遗留方案)

Vector是Java早期的线程安全列表,通过synchronized修饰所有方法实现同步。
实现方式:

java 复制代码
Vector<String> vector = new Vector<>();

特点:

  • 方法级同步,线程安全。
  • 缺点 :
    • 性能差(锁粒度大,高并发时竞争激烈)。
    • 功能落后(如没有Iterator的快速失败机制)。

示例:

java 复制代码
vector.add("value"); // 同步方法
vector.get(0);       // 同步方法

4. 手动同步(显式加锁)

通过显式使用synchronized或ReentrantLock控制对ArrayList的访问。
实现方式:

java 复制代码
List<String> list = new ArrayList<>();
ReentrantLock lock = new ReentrantLock();

// 写入操作
lock.lock();
try {
    list.add("value");
} finally {
    lock.unlock();
}

// 读取操作
lock.lock();
try {
    String value = list.get(0);
} finally {
    lock.unlock();
}

特点:

  • 灵活控制锁粒度(如读写分离)。
  • 缺点 :
    • 代码复杂度高(需手动管理所有访问点)。
    • 容易遗漏同步,导致线程安全问题。

5. 使用并发工具类(如BlockingQueue)

对于特定场景(如生产者-消费者模型),可用线程安全的队列代替ArrayList。
实现方式:

java 复制代码
BlockingQueue<String> queue = new LinkedBlockingQueue<>();

特点:

  • 内置阻塞/超时机制,适合任务队列场景。
  • 缺点 :
    • 功能与List不同(如无随机访问)。

对比与选型建议

方案 线程安全机制 性能 适用场景
Collections.synchronizedList 方法级synchronized 一般 低并发,需兼容现有List接口
CopyOnWriteArrayList 写时复制 读高,写低 读多写少(如配置表、监听器列表)
Vector 方法级synchronized 低 遗留系统兼容
手动同步 显式锁 灵活 需细粒度控制的场景
BlockingQueue 内部锁/条件变量 高(队列场景) 生产者-消费者模型

🧣

  • 通用场景 :优先选择CopyOnWriteArrayList(读多写少)或Collections.synchronizedList(兼容List接口)。
  • 高并发写入 :考虑手动同步或使用并发队列(如ConcurrentLinkedQueue)。
  • 避免使用Vector:除非需兼容旧代码,其性能和功能已落后于现代并发工具。
相关推荐
谢尔登11 小时前
02_开发环境配置
java
Ven%12 小时前
在魔搭 Notebook 容器里跑 Qwen Code:从零配置到省魔粒的完整实践
人工智能·python·ai·ai编程·modelscope
学长毕设12 小时前
基于springboot的实验室设备管理系统
java·spring boot·后端
2401_8858850412 小时前
巴林语音通知接口如何对接?系统告警语音API接入教程
android·前端·网络·python·语音识别
学长毕设12 小时前
基于springboot的社区养老监护系统的设计与实现
java·spring boot·后端
执假以为真12 小时前
Python内存分析器memray的简单介绍
python
会编程的吕洞宾12 小时前
RAG检索质量怎么评估?3个指标+LLM裁判实战
java·开发语言·人工智能·后端
卢总霸气12 小时前
上海交大机动学院学位论文参考文献Zotero CSL 样式-2026
java
收纳过往12 小时前
数据库加索引的时机:慢查询日志说话
android·开发语言·数据库·python·低代码·rxjava
段一凡-华北理工大学12 小时前
高炉能源系统智能化:热风炉、煤气与极致能效~系列文章07:高炉煤气:产生规律与全厂用户平衡
java·前端·能源