尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

Java集合之【CopyOnWrite和Collections.synchronizedList()的区别】

Java集合之【CopyOnWrite和Collections.synchronizedList()的区别】
📅 发布时间:2026/6/19 10:01:17

CopyOnWriteArrayList 介绍

什么是 CopyOnWriteArrayList

适合读多写少的场景

是一个线程安全的List实现,特点是写时复制

当CopyOnWriteArrayList进行修改操作(如add,set,remove)的时候,会复制原数组的值到创建的新数组中,并且读操作的时候不加锁,写操作会加锁

CopyOnWriteArrayList 的读操作

不加锁,每次写操作都会创建并复制新的数组,所以读数据的时候不会发生冲突,所以读操作不需要加锁,这样读操作的效率就会很高

CopyOnWriteArrayList 的写操作

加锁,会复制并创建新数组,因此开销大,数据量大的时候,在同一时刻会存在两倍大小的List大小的内存占用

public E set(int index, E element) {final ReentrantLock lock = this.lock;lock.lock();try {// ...CODE...} finally {lock.unlock();}
}

CopyOnWriteArrayList 会出现读写不一致吗?

会,CopyOnWriteArrayList 使用的是弱一致性。

通过设计上的取舍

  • 换取高性能的读操作

  • 保证线程安全

  • 不保证实时一致性

因此CopyOnWriteArrayList 适合读多写少的场景

代码检测

public class CopyOnWriteDemo {public static void main(String[] args) throws InterruptedException {List<String> list = new CopyOnWriteArrayList<>();list.add("A");list.add("B");// 线程:不停读Thread reader = new Thread(() -> {for (int i = 0; i < 5; i++) {System.out.println("Reader: " + list);try {Thread.sleep(200);} catch (InterruptedException ignored) {}}});// 线程:写入数据Thread writer = new Thread(() -> {try {Thread.sleep(300);} catch (InterruptedException ignored) {}list.add("C");System.out.println("Writer added C");});reader.start();writer.start();reader.join();writer.join();}
}

join():让主线程等待子线程,避免出现数据不一致,或主线程结束了子线程才结束

输出结果:

Reader: [A, B]
Writer added C
Reader: [A, B, C]
Reader: [A, B, C]
Reader: [A, B, C]
Reader: [A, B, C]

显然:

写操作对应的数组是“新”数组

读操作对应的数组是“旧”数组

写完成之后就将旧数组替换成新数组

Collections.synchronizedList() 介绍

是Collections的一个包装方法,可以将List转换为线程安全的版本,对每个方法(set,get,add,remove) 都会添加一个sychronized关键字,进行同步锁,从而保证线程安全

适用场景

需要将ArrayList<>()快速转换成为线程安全的版本,以及是在简单将List转换为线程安全版本临时使用的场景

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

缺点

缺点就是不适用于高并发的场景,因为每个操作都会使用同一个sychronized同步锁

源码所示:

 public E get(int index) {synchronized (mutex) {return list.get(index);}}
public E set(int index, E element) {synchronized (mutex) {return list.set(index, element);}
}
public void add(int index, E element) {synchronized (mutex) {list.add(index, element);}
}
public E remove(int index) {synchronized (mutex) {return list.remove(index);}
}

mutex: 一般指的是this,也就是说所有的读写都是用同一把锁

源码:

final Collection<E> c;  // Backing Collection
final Object mutex;     // Object on which to synchronizeSynchronizedCollection(Collection<E> c) {this.c = Objects.requireNonNull(c);mutex = this;
}

所以Collections.synchronizedList()是不适合在高并发场景下使用的

总结

特性 synchronizedList CopyOnWriteArrayList
线程安全方式 synchronized 锁 写时复制(读无锁)
读操作 加锁(慢) 无锁(快)
写操作 加锁(较快) 复制数组(很慢)
适用场景 写多读少 读多写少
迭代器 不安全,需手动 synchronized 安全,不会抛 CME

相关新闻

  • 20232324 2024-2025-1 《网络与系统攻防技术》实验六实验报告
  • 复杂状态与数据流管理:分布式定时任务系统的设计
  • 【第6章 字符串】Python 字符串常用操作完全教程(含代码演示)

最新新闻

  • 2026年评价高的精密注塑/苏州注塑稳定供货厂家推荐 - 品牌宣传支持者
  • 2026年比较好的深圳 LED屏/LED屏工程/东莞LED屏可靠供应商推荐 - 品牌宣传支持者
  • LoadRunner 12.6社区版:性能测试入门与轻量级压测实战指南
  • C#软件加密5大漏洞与实战防护方案:从字符串硬编码到时间校验
  • RAMP技术:基于强化学习的自适应混合精度量化解析
  • 构建稳健的股票数据管道:从yfinance/AkShare到自动化更新

日新闻

  • 信任的进化:技术实现详解——如何用JavaScript构建博弈论模拟器
  • Terrakube自定义工作流:如何集成OPA、Infracost等工具扩展IaC能力
  • grunt-concurrent快速入门:5分钟学会并行运行Grunt任务

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号