Java 入门指南:并发设计模式 —— Copy-on-Write 模式

文章目录

    • Copy-On-Write
      • 工作原理
      • Copy-On-Write 的应用场景
      • Java 中的 CopyOnWriteArrayList
        • CopyOnWriteArrayList 的特点
      • 示例代码
      • Copy-On-Write 的优缺点

Copy-On-Write

CopyOnWrite写时复制,简称COW)是一种在计算机领域中广泛应用的优化策略,主要用于提高内存和存储的使用效率,同时确保数据的一致性和线程安全。

CopyOnWrite 的核心思想是,在多个调用者(如线程或进程)共享相同资源(如内存或磁盘上的数据存储)时,他们最初会共同获取相同的指针或引用指向该资源当某个调用者尝试修改资源时,系统会为其创建一个资源的副本,并将修改操作应用到这个副本上,而其他调用者则继续访问原始资源,从而避免了因修改操作而对其他调用者造成影响。

Copy-On-Write 技术适合于读多写少的场景,特别是那些要求读取操作高效且不需要频繁写入的场景

工作原理

CopyOnWrite模式的工作流程可以概括为以下几个步骤:

  1. 共享资源:多个调用者共同访问和读取一个原始的资源或数据块。

  2. 写操作检测:当某个调用者尝试对资源进行写操作时,系统会检测到这一行为。

  3. 创建副本:系统为尝试写操作的调用者创建一个资源的副本。

  4. 修改副本:调用者在副本上进行写操作,而不会影响其他调用者所看到的原始资源。

  5. 更新引用(可选):在某些情况下,可能需要更新对资源的引用,以便其他调用者在需要时能够访问到最新的副本。

Copy-On-Write 的应用场景

  • 操作系统中的页面共享:在操作系统层面,Copy-On-Write 用于内存管理,特别是当一个进程创建另一个进程的子进程时。父进程和子进程最初共享相同的内存页。只有当子进程试图修改某一页时,操作系统才会为子进程创建该页的一个副本。这样,只有真正需要修改的页面才会被复制,而不是一开始就复制所有的页面。

  • 编程语言中的数据结构:在编程语言中,Copy-On-Write 可以用于实现不可变对象的高效共享。当一个不可变对象(如字符串、列表等)被多个引用共享时,只有在某个引用试图修改该对象时,才会创建一个新的副本。这样可以避免不必要的数据复制,尤其是在并发环境下。

  • 容器技术:容器镜像层也是基于 Copy-On-Write 的。每个镜像层都是只读的,当容器运行时,会在最上层创建一个可写的层。对于读操作,容器可以从任意一层获取数据;对于写操作,数据会被写入到最上层的可写层中。

Java 中的 CopyOnWriteArrayList

在 Java 中,有一个著名的基于 Copy-On-Write 技术实现的集合类 CopyOnWriteArrayList。这个类实现了 List 接口,并且是线程安全的。它通过在每次修改时创建新的数组来实现线程安全,因此读取操作不需要加锁,从而提高了并发读取的性能。

CopyOnWriteArrayList 的特点
  1. 读取操作无需加锁:由于每次修改都会创建一个新的数组,所以读取操作可以安全地进行,无需加锁。

  2. 写入操作需要创建新数组:每次写入操作(如 addremove 等)都会创建一个新的数组,并将修改后的数组赋值给原来的引用。

  3. 适用于读多写少的场景:由于写入操作涉及到数组的复制,因此在写入频繁的情况下性能较差。但在读多写少的情况下,由于读取无需加锁,因此性能较好。

示例代码

下面是一个简单的 Java 示例,演示了 CopyOnWriteArrayList 的使用:

import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;public class CopyOnWriteExample {public static void main(String[] args) {CopyOnWriteArrayList<Integer> list = new CopyOnWriteArrayList<>();// 添加元素list.add(1);list.add(2);list.add(3);// 迭代器遍历Iterator<Integer> iterator = list.iterator();while (iterator.hasNext()) {Integer value = iterator.next();System.out.println(value);// 尝试在迭代过程中修改if (value.equals(2)) {list.remove(value); // 这里可以安全地移除元素list.add(4); // 同样可以安全地添加元素}}}
}

在这个例子中,即使我们在迭代过程中修改了列表,也不会抛出 ConcurrentModificationException,因为 CopyOnWriteArrayList 在修改时会创建新的数组。

Copy-On-Write 的优缺点

优点

  1. 提高性能:避免了频繁的复制操作,减少了不必要的数据复制,提高了系统的响应速度。
  2. 节省资源:只有在需要修改时才创建副本,减少了内存和存储空间的消耗。
  3. 确保一致性:保证了原始数据的一致性,不会因为某个用户的修改而影响其他用户。

缺点

  1. 额外的开销:在第一次写入时,需要创建副本,这可能会带来一些延迟。
  2. 增加复杂性:实现 CopyOnWrite 机制需要额外的逻辑来管理数据的引用和副本。
  3. 数据一致性问题:CopyOnWrite 容器只能保证数据的最终一致性,而不能保证实时一致性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/55049.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Go函数式编程与闭包

1. 什么是函数式编程 函数式编程&#xff08;Functional Programming&#xff09;是一种编程范式&#xff0c;它将计算视为数学函数的求值&#xff0c;强调使用高阶函数和不可变数据。在函数式编程中&#xff0c;函数是第一类公民&#xff0c;意味着函数可以像其他数据类型一样…

自动化办公-Python-os模块的使用

os.path 模块的使用 在指定文件路径时&#xff0c;由于操作系统的差异&#xff0c;直接使用硬编码的路径可能会导致程序在不同平台上无法正常运行。为了解决这个问题&#xff0c;Python 提供了 os.path 模块&#xff0c;它包含了一系列用于路径操作的函数&#xff0c;可以帮助您…

Python:lambda 函数详解 以及使用

一、lambda 语法 lambda 函数的语法只包含一个语句&#xff0c;表现形式如下&#xff1a; lambda [arg1 [,arg2,.....argn]]:expression 其中&#xff0c;lambda 是 Python 预留的关键字&#xff0c;[arg…] 和 expression 由用户自定义。 具体如下: [arg…] 是参数列表&#…

Java2 实用教程(第6版)习题2 第五题

五、编程题 1、编写一个应用程序&#xff0c;给出汉字“你”“我”“他”在Unicode表中的位置。 public class F2_1 {public static void main(String args[]){char ch1你,ch2我,ch3他;System.out.println("\""ch1"\"的位置"(int)ch1);System.…

Unity开发绘画板——01.前言

在做这个之前其实是想研究一下在Unity中交互雪的实现&#xff0c;交互雪顾名思义就是可以进行交互的雪&#xff0c;玩家角色从雪上走过时雪被踩凹陷的效果&#xff1b;交互雪的一种实现方案就是将地面看做一个画板&#xff0c;将玩家角色的躯体看做笔刷&#xff0c;将角色经过的…

钉钉如何请求webhook发送信息

代码&#xff1a;js const myHeaders new Headers(); myHeaders.append("Content-Type", "application/json");const raw JSON.stringify({"at": {"atMobiles": ["180xxxxxx"],"atUserIds": ["user123&qu…

我们是向量数据库的领军企业,我们只招TOP人才

我们是全球领先的向量数据库企业&#xff0c;业务正在快速发展&#xff0c;现开放大量岗位&#xff1a; 前端、产品经理、数据库开发工程师、C、数据库运维、数据库测试…… 我们招聘的唯一目标&#xff0c;寻找 TOP人才&#xff01; 如果你已经有丰富的经验&#xff0c;那么加…

CMake set_property设置全局变量属性

在 CMake 中&#xff0c;set_property(GLOBAL PROPERTY LD_SCRIPT "路径") 是用来设置全局属性的。在你的例子中&#xff0c;它设置了一个名为 LD_SCRIPT 的全局属性&#xff0c;并将其值设为 "${NUTTX_BOARD_DIR}/scripts/gnu-elf.ld"。 具体解释&#x…

jmeter-请求参数加密-MD5加密

方法1 &#xff1a;使用jmeter自带的函数助手digest Tool(工具)---Function Helper Dialog(函数助手对话框) 第一个参数是要md5加密的值&#xff0c;第二个参数是保存加密后值的变量 &#xff08; 此处变量是从txt文件导入的&#xff0c;所以使用的是${wd} &#xff09; …

overlayscrollbars使用

官网 https://github.com/KingSora/OverlayScrollbars 使用 <link href"https://cdn.bootcdn.net/ajax/libs/overlayscrollbars/2.10.0/styles/overlayscrollbars.css" rel"stylesheet"> <script src"https://cdn.bootcdn.net/ajax/libs/…

Elasticsearch 中变更索引的方法

Elasticsearch 提供了几种方法来变更索引。以下是一些常用的方法&#xff1a; 1. 更新索引设置 可以使用 Update Index Settings API 来修改部分索引设置。例如: PUT /my-index/_settings {"index" : {"number_of_replicas" : 2} }2. 重新索引数据 使用…

OMRON欧姆龙E5GN温控器手测

OMRON欧姆龙E5GN温控器手测

17【Protues单片机仿真】基于51单片机的太阳能智能谷物翻晒机器人

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于51单片机&#xff0c;避障&#xff0c;低于50CM报警&#xff0c;LED灯亮起&#xff0c;自动翻晒用光敏电阻&#xff0c;光照强度大&#xff0c;电机转动&#xff0c;相当于翻晒粮食&#xff0…

拿到一个新项目,如何开展测试

1. 拿到一个新的项目或者新的需求&#xff0c;首先需要搞清楚他的背景、目标和需求&#xff0c;这个过程需要和产品、开发、客户去沟通。 2. 清楚需求后&#xff0c;首先将业务流程走通&#xff0c;确保项目的基础功能是正常的 3. 根据项目需求明确测试的目标&#xff0c;如&…

【中间件——基于消息中间件的分布式系统的架构】

1. 基于消息中间件的分布式系统的架构 从上图中可以看出来&#xff0c;消息中间件的是 1&#xff1a;利用可靠的消息传递机制进行系统和系统直接的通讯 2&#xff1a;通过提供消息传递和消息的排队机制&#xff0c;它可以在分布式系统环境下扩展进程间的通讯。 1.1 消息中间件…

PostgreSQL的学习心得和知识总结(一百五十一)|[performance] PostgreSQL列对齐

目录结构 注&#xff1a;提前言明 本文借鉴了以下博主、书籍或网站的内容&#xff0c;其列表如下&#xff1a; 1、参考书籍&#xff1a;《PostgreSQL数据库内核分析》 2、参考书籍&#xff1a;《数据库事务处理的艺术&#xff1a;事务管理与并发控制》 3、PostgreSQL数据库仓库…

算法题——滑动窗口(图示+代码)

什么时候可以使用滑动窗口&#xff1f; 当我们尝试对一条题目进行暴力插解时&#xff0c;若发现 一、长度最小的子数组 题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09;. - 备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程…

一个 Java 语言简化处理 PDF 的框架,提供了一套简单易用的 API 接口,满足多样化需求又能简化开发流程的处理方案(附教程)

前言 当前市面上处理 PDF 文件的工具众多&#xff0c;但它们往往存在一定的局限性&#xff0c;比如复杂交互、功能单一等问题。尤其对于那些需要频繁生成或编辑 PDF 文档的应用场景来说&#xff0c;找到一个既能满足多样化需求又能简化开发流程的处理方案显得尤为重要。那么&a…

借用连接2-得到主库或从库池子连接

二、借用连接--AbstractRoutingDataSource类 目的&#xff1a;基于look up data&#xff0c;然后从目标数据源借用连接 注look up key确定走主 or 从数据库连接池代码开发&#xff1a; 1.定义子类继承AbstractRoutingDataSource&#xff0c;并覆写determineCurrentLookupKey方…

【前端】ES13:ES13新特性

文章目录 1 类新增特性1.1 私有属性和方法1.2 静态成员的私有属性和方法1.3 静态代码块1.4 使用in来判断某个对象是否拥有某个私有属性 2 支持在最外层写await3 at函数来索引元素4 正则匹配的开始和结束索引5 findLast() 和 findLastIndex() 函数6 Error对象的Cause属性 1 类新…