CopyOnWriteArraySet怎么用

news2024/11/20 3:26:10

在这里插入图片描述

简介

CopyOnWriteArraySet是一个线程安全的无序集合,它基于“写时复制”的思想实现。它继承自AbstractSet,可以将其理解成线程安全的HashSet。

CopyOnWriteArraySet在读取操作比较频繁、写入操作相对较少的情况下可以提高程序的性能和可靠性。它的线程安全机制和CopyOnWriteArrayList一样,是通过volatile和互斥锁实现的。

在这里插入图片描述

应用场景

CopyOnWriteArraySet的应用场景主要是在并发编程中,特别是那些需要高并发的场景。它适用于数据量较小且读多写少的场景,例如,一个Web应用程序中的用户状态信息,这是一个读取操作远多于写入操作的典型场景。

它的线程安全机制避免了在迭代过程中其他线程对集合的修改操作引发的并发冲突,使得在迭代过程中可以安全地进行读取操作。然而,由于CopyOnWriteArraySet的写时复制机制,它可能存在一些性能开销,因此,如果需要频繁的写入操作,可能不适合使用CopyOnWriteArraySet。

总的来说,CopyOnWriteArraySet适合用在读多写少、对数据一致性要求不高、对线程安全性要求高的场景。

在这里插入图片描述

性能问题

CopyOnWriteArraySet的性能问题主要集中在以下几个方面:

  1. 写操作的开销 :由于CopyOnWriteArraySet采用的是写时复制的策略,每次写操作都需要复制一份底层数组,这会导致写操作的开销比较大。如果写操作比较频繁,可能会影响程序的性能。
  2. 内存占用 :由于每次写操作都需要复制一份底层数组,这会导致内存占用比较高。如果集合中的元素数量比较大,可能会导致内存溢出的问题。
  3. 迭代器的性能 :由于CopyOnWriteArraySet的迭代器是基于底层数组的快照实现的,如果在迭代过程中底层数组发生变化,迭代器不会反映这些变化。这可能会导致迭代器的性能不稳定,甚至引发并发问题。

针对以上问题,可以考虑以下优化策略:

  1. 使用其他线程安全集合类 :如果写操作比较频繁,可以考虑使用其他线程安全集合类,如ConcurrentHashMap或ConcurrentSkipListSet等。这些集合类采用了不同的同步策略,可以更好地支持并发访问。
  2. 控制集合的大小 :如果集合中的元素数量比较大,可以考虑控制集合的大小,避免内存溢出的问题。例如,可以设置集合的最大容量,当元素数量超过最大容量时进行清理或压缩操作。
  3. 减少迭代操作 :如果迭代操作比较频繁,可以考虑减少迭代操作的次数或使用其他方式来访问集合中的元素。例如,可以使用流(Stream) API 来处理集合中的元素,避免使用迭代器。

需要注意的是,在选择和优化线程安全集合类时需要根据具体的应用场景和需求进行权衡和选择。

在这里插入图片描述

源码解析

CopyOnWriteArraySet的源码实现相对比较简单,主要基于CopyOnWriteArrayList实现。以下是对CopyOnWriteArraySet源码的简单讲解:

public class CopyOnWriteArraySet<E> extends AbstractSet<E> {
    private final List<E> array;

    public CopyOnWriteArraySet() {
        this.array = new CopyOnWriteArrayList<>();
    }

    @Override
    public boolean add(E e) {
        return array.add(e);
    }

    @Override
    public boolean remove(Object o) {
        return array.remove(o);
    }

    @Override
    public boolean contains(Object o) {
        return array.contains(o);
    }

    @Override
    public int size() {
        return array.size();
    }

    @Override
    public Iterator<E> iterator() {
        return new COWIterator<>(array.listIterator());
    }
}

在CopyOnWriteArraySet中,所有的操作都是通过调用CopyOnWriteArrayList的实现来完成的。CopyOnWriteArrayList的实现细节可以参考之前对CopyOnWriteArrayList的讲解。其中,COWIterator是一个简单的迭代器实现,用于包装ListIterator并确保线程安全。在迭代过程中,COWIterator会持有一个快照,不允许修改操作。

在这里插入图片描述

扩容机制

CopyOnWriteArraySet的扩容机制是基于CopyOnWriteArrayList实现的。当集合的元素数量超过当前数组的容量时,会创建一个新的数组,然后将原数组中的元素复制到新数组中。这个过程是线程安全的,因为整个复制过程是一个原子操作。

具体的扩容过程如下:

  1. 当集合的元素数量超过当前数组的容量时,会创建一个新的数组,大小是原数组的两倍。
  2. 然后将原数组中的元素复制到新数组中,每个元素复制的顺序是按照它们在原数组中的顺序。
  3. 复制完成后,将原数组清空,并将新数组赋值给集合的内部数组。

这种扩容机制的优点是可以在多线程环境下实现高效的并发访问,因为复制操作是一个原子操作,不会受到其他线程的干扰。同时,由于每次扩容时都会创建一个新的数组,因此可以避免因为元素插入导致的数组重新排列的开销。但是,由于每次扩容都需要创建一个新的数组并复制元素,所以如果集合中的元素数量非常大,扩容过程可能会比较耗时。

与CopyOnWriteArrayList的区别

CopyOnWriteArraySet和CopyOnWriteArrayList都是基于“写时复制”的思想实现的线程安全的数据结构,适用于读多写少的场景。它们的主要区别在于:

  1. 数据结构:CopyOnWriteArraySet是Set,而CopyOnWriteArrayList是List。因此,CopyOnWriteArraySet不允许存放重复值,而CopyOnWriteArrayList可以。
  2. 存储方式:CopyOnWriteArraySet内部持有一个CopyOnWriteArrayList引用,所有的操作都是由CopyOnWriteArrayList来实现的。它是无序的,不允许存放重复值。
  3. 迭代器行为:CopyOnWriteArraySet的迭代器使用了“快照”技术,存储了内部数组快照,不支持remove、set、add操作,但通过迭代器进行并发读取时效率很高。这是与CopyOnWriteArrayList的主要区别。

两者都是线程安全的数据结构,适用于读多写少的场景。主要区别在于数据结构、存储方式和迭代器行为。

代码示例

在多线程环境下,可以使用CopyOnWriteArraySet来保证线程安全。以下是一个简单的示例:

import java.util.concurrent.CopyOnWriteArraySet;

public class Example {
    private static CopyOnWriteArraySet<String> set = new CopyOnWriteArraySet<>();

    public static void main(String[] args) {
        new Thread(() -> {
            for (int i = 0; i < 5000; i++) {
                set.add("a" + System.currentTimeMillis());
            }
        }).start();

        new Thread(() -> {
            for (int i = 0; i < 5000; i++) {
                set.add("b" + System.currentTimeMillis());
            }
        }).start();
    }
}

在这个示例中,我们创建了一个CopyOnWriteArraySet,并启动了两个线程,每个线程都向集合中添加元素。由于CopyOnWriteArraySet是线程安全的,因此在迭代过程中,其他线程对集合的修改操作不会引发并发冲突。

在这里插入图片描述

拓展

  • 线程安全集合类
    除了CopyOnWriteArraySet和CopyOnWriteArrayList,Java中还有其他一些线程安全的集合类,包括:
  1. ConcurrentHashMap:线程安全的Map实现,使用分段锁技术实现并发访问。
  2. ConcurrentSkipListMap:基于跳表(Skip List)实现的线程安全Map,具有较高的并发性能。
  3. ConcurrentLinkedQueue:基于链接节点的线程安全队列,支持高效的并发访问。
  4. ConcurrentSkipListSet:基于跳表(Skip List)实现的线程安全Set,具有较高的并发性能。

这些线程安全集合类的使用方法和普通的集合类类似,但它们能够在多线程环境下提供更好的并发性能和数据安全性。

  • CopyOnWriteArrayList讲解
    快点我呀✋🏻

  • 更多集合

ConcurrentLinkedDeque详解-Deque接口链表实现方案

ArrayDeque详解-Deque接口数组实现方案

LinkedList详解-Deque接口链表实现方案

Java中Deque接口方法解析

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

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

相关文章

Win10 安装.NET Framework 3.5 报错0x80240438

环境&#xff1a; Win10专业版 NET Framework 3.5 问题描述&#xff1a; Win10 安装.NET Framework 3.5 报错0x80240438 解决方案&#xff1a; 1.检查自动更新服务是否未开启&#xff0c;开启自动更新失败&#xff0c;用工具开启自动更新,重启电脑&#xff08;未解决&am…

SAP UI5 walkthrough step2 Bootstrap

我的理解&#xff0c;这就是一个引导指令 1.我们右键打开命令行--执行 ui5 use OpenUI5 2.执行命令&#xff1a;ui5 add sap.ui.core sap.m themelib_sap_horizon 执行完之后&#xff0c;会更新 yaml 文件 3.修改index.html <!DOCTYPE html> <html> <head&…

学习spring、springmvc、mybatis、ssm所有可能用到的依赖总结,父工程pom文件依赖,<packaging>pom</packaging>

1、父工程pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/PO…

VR转接线方案/VR Link串流数据线方案/VR眼镜PD快充方案

虚拟现实技术(英文名称&#xff1a;Virtual Reality&#xff0c;缩写为VR)&#xff0c;又称虚拟实境或灵境技术&#xff0c;是20世纪发展起来的一项全新的实用技术。虚拟现实技术囊括计算机、电子信息、仿真技术&#xff0c;其基本实现方式是以计算机技术为主&#xff0c;利用并…

Appium python自动化测试系列之移动自动化测试!

1.1 移动自动化测试现状 因为软件行业越来越发达&#xff0c;用户的接受度也在不断提高&#xff0c;所以对软件质量的要求也随之提高&#xff0c;当然这个也要分行业&#xff0c;但这个还是包含了大部分。因为成本、质量的变化现在对自动化测试的重视度越来越高&#xff0c;在…

【TiDB理论知识09】TiFlash

一 TiFlash架构 二 TiFlash 核心特性 TiFlash 主要有 异步复制、一致性、智能选择、计算加速 等几个核心特性。 1 异步复制 TiFlash 中的副本以特殊角色 (Raft Learner) 进行异步的数据复制&#xff0c;这表示当 TiFlash 节点宕机或者网络高延迟等状况发生时&#xff0c;Ti…

Java一对一聊天

服务端 package 一对一用户;import java.awt.BorderLayout; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.Vector;…

[idea]idea连接clickhouse23.6.2.18

一、安装驱动 直接在pom.xml加上那个lz4也是必要的不然会报错 <dependency><groupId>com.clickhouse</groupId><artifactId>clickhouse-jdbc</artifactId><version>0.4.2</version></dependency><dependency><group…

Python函数默认参数设置

在某些情况下&#xff0c;程序需要在定义函数时为一个或多个形参指定默认值&#xff0c;这样在调用函数时就可以省略为该形参传入参数值&#xff0c;而是直接使用该形参的默认值。 为形参指定默认值的语法格式如下&#xff1a; 形参名 默认值 从上面的语法格式可以看出&…

一篇解析context_switch进程切换(针对ARM体系架构)

一. 概述 在最近初学ebpf时&#xff0c;使用到了挂载点finish_task_switch统计内核线程的运行时间&#xff0c;遂进入内核源码对其进行学习分析。 finish_task_switch在context_switch被调用&#xff0c;其功能是完成进程切换的收尾工作&#xff0c;比如地址空间的清理。而co…

理解自我效能感:你的内在动力来源

1. 自我效能感&#xff1a;开启个人潜能的心理动力 想象一下&#xff0c;面对生活的挑战和机遇时&#xff0c;是什么内在力量驱使你去采取行动&#xff0c;或者让你犹豫不决&#xff1f;这种力量&#xff0c;与我们的心理状态紧密相关&#xff0c;其中一个关键因素就是我们的自…

【AIGC】prompt工程从入门到精通

注&#xff1a;本文示例默认“文心大模型3.5”演示&#xff0c;表示为>或w>&#xff08;wenxin)&#xff0c;有时为了对比也用百川2.0展示b>&#xff08;baichuan) 有时候为了模拟错误输出&#xff0c;会用到m>&#xff08;mock)表示&#xff08;因为用的大模型都会…

uView框架的安装与Git管理

参考链接&#xff1a;Http请求 | uView - 多平台快速开发的UI框架 - uni-app UI框架 安装 打开我们项目的cmd进行下载&#xff1a; yarn add uview-ui 首先我们要确定&#xff0c;未下载前的文件目录以及下载后&#xff0c;是多了个文件目录node_modules 下载完成之后我们就…

MTU TCP-MSS(转载)

MTU MTU 最大传输单元&#xff08;Maximum Transmission Unit&#xff0c;MTU&#xff09;用来通知对方所能接受数据服务单元的最大尺寸&#xff0c;说明发送方能够接受的有效载荷大小。 是包或帧的最大长度&#xff0c;一般以字节记。如果MTU过大&#xff0c;在碰到路由器时…

汽车电子之深力科推荐安森美车规级芯片

车规级芯片 在汽车制造业&#xff0c;就可靠性要求而言&#xff0c;车规级芯片无疑是要高于商业级和工业级。 而车规级芯片&#xff1a;顾名思义&#xff0c;就是应用到汽车中的芯片&#xff0c;它不同于日常生活中的消费品和工业品&#xff0c;该类芯片对可靠性要求较高&…

vue2+datav可视化数据大屏(3)

接上一节所说&#xff0c;当我们将接口封装完了后&#xff0c;我们需要给大屏进行内容填充啦 1,新建组件 &#x1f4d3; 我们在ser-views文件夹下新建9个vue组件&#xff0c;如下图所示&#xff0c;我给编号为1到9 &#x1f4d3;在组件里写入内容我是第一块...一次类推&#x…

100. 相同的树(Java)

目录 解法&#xff1a; 官方解法&#xff1a; 方法一&#xff1a;深度优先搜索 复杂度分析 时间复杂度&#xff1a; 空间复杂度&#xff1a; 方法二&#xff1a;广度优先搜索 复杂度分析 时间复杂度&#xff1a; 空间复杂度&#xff1a; 给你两棵二叉树的根节点 p 和…

学习IO的第五天

作业 &#xff1a;使用两个线程完成文件的拷贝写入&#xff0c;分线程1写入前半段&#xff0c;分线程2写入后半段&#xff0c;主线程用来回收资源 #include <head.h>void *sork(void *arg); void *sork2(void *arg);int file_copy(int start,int len) //拷贝的函数 {i…

Vulnerability: File Upload(Medium)--MYSQL注入

选择难度&#xff1a; 1.打开DVWA&#xff0c;并登录账户 2.选择模式&#xff0c;这里我们选择 文件上载的中级模式&#xff08;Medium&#xff09; 准备工作 1.在vsc里面写个一句话木马 2.下载BurpSuiteCommunit软件&#xff1a;百度搜索“burp suite官网” 下载地址www…

Xilinx FPGA——ISE时序约束“建立时间不满足”问题解决记录

一、现象 最近使用赛灵思的FPGA设计项目时&#xff0c;出现时序约束失效问题。 点进去发现如下&#xff1a; 一个始终约束没有生效&#xff0c;有多处报错。 二、原因 出现这个问题的原因是&#xff0c;建立时间不满足。 时序违例的主要原因是建立时间和保持时间不满足要求&a…