当前位置: 首页 > news >正文

Java高频面试之集合-06

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

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

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


1. 使用 Collections.synchronizedList 包装

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

List<String> syncList = Collections.synchronizedList(new ArrayList<>());

特点

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

示例

// 写入操作自动同步
syncList.add("value");

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

2. 使用 CopyOnWriteArrayList

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

CopyOnWriteArrayList<String> cowList = new CopyOnWriteArrayList<>();

特点

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

示例

cowList.add("value"); // 写操作加锁
cowList.get(0);       // 读操作无锁

3. 使用 Vector(遗留方案)

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

Vector<String> vector = new Vector<>();

特点

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

示例

vector.add("value"); // 同步方法
vector.get(0);       // 同步方法

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

通过显式使用synchronizedReentrantLock控制对ArrayList的访问。
实现方式

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
实现方式

BlockingQueue<String> queue = new LinkedBlockingQueue<>();

特点

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

对比与选型建议

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

🧣

  • 通用场景:优先选择CopyOnWriteArrayList(读多写少)或Collections.synchronizedList(兼容List接口)。
  • 高并发写入:考虑手动同步或使用并发队列(如ConcurrentLinkedQueue)。
  • 避免使用Vector:除非需兼容旧代码,其性能和功能已落后于现代并发工具。

在这里插入图片描述

相关文章:

  • 深度链接技术解析:openinstall如何通过场景还原优化用户体验?
  • 如何利用Postman对比出新旧接口之间的差异(Diff)
  • dfs:五子棋对弈15蓝桥杯a组1题
  • 数据结构第八节:红黑树(初阶)
  • 【图灵商城项目-登录失败:密码不正确,问题已解决】
  • Python使用MyQR生成动态二维码
  • 【LangChain】理论及应用实战(2)
  • Git基础之基本操作
  • 【GPT入门】第2课 跑通第一openAI程序
  • 【C++】:STL详解 —— 红黑树封装map和set
  • 《C#上位机开发从门外到门内》1-2:上位机开发语言与工具、开发环境部署
  • 初识Bert
  • Javascript 原型和原型链
  • [项目]基于FreeRTOS的STM32四轴飞行器: 七.遥控器按键
  • 【Recon】Git源代码泄露题目解题方法
  • java项目之基于ssm的智能训练管理平台(源码+文档)
  • 每日一题-----面试
  • 【Transformer优化】Transformer的局限在哪?
  • docker启动jenkins,jenkins中调用docker
  • KubeKey 与 KubeSphere:快速构建 Kubernetes 集群
  • 4台肺癌手术,2名“90后”患者,这届年轻人的肺怎么了?
  • 国台办:实现祖国完全统一是大势所趋、大义所在、民心所向
  • 巴方:印度上周导弹袭击造成至少40名平民死亡
  • 西北大学副校长范代娣成陕西首富?系家庭财富,本人已从上市公司退出
  • Manus向全球用户开放注册
  • 科普|“小”耳洞也会引发“大”疙瘩,如何治疗和预防?