【JUC并发编程】集合类安全问题

news2024/11/26 16:59:16

一、并发下,ArrayList类是不安全的

  • 代码演示
    package CollectionSafe;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.UUID;
    
    /**
     * @author swaggyhang
     * @create 2023-07-02 17:26
     */
    public class Test01 {
        public static void main(String[] args) {
            List<String> list = new ArrayList<>();
            for (int i = 1; i <= 10; i++) {
                new Thread(() -> {
                    list.add(UUID.randomUUID().toString().substring(0, 5));
                    System.out.println(list);
                }, String.valueOf(i)).start();
            }
        }
    }
    
  • 上面代码会报错并发修改异常“java.util.ConcurrentModificationException”

二、解决方案

1. 使用Vector类【不推荐】

  • Vector类的add方法是同步方法,但是效率很低
    在这里插入图片描述
  • 代码演示
    package CollectionSafe;
    
    import java.util.List;
    import java.util.UUID;
    import java.util.Vector;
    
    /**
     * @author swaggyhang
     * @create 2023-07-02 17:26
     */
    public class Test01 {
        public static void main(String[] args) {
    //        List<String> list = new ArrayList<>();
            List<String> list = new Vector<>();
            for (int i = 1; i <= 10; i++) {
                new Thread(() -> {
                    list.add(UUID.randomUUID().toString().substring(0, 5));
                    System.out.println(list);
                }, String.valueOf(i)).start();
            }
        }
    }
    

2. 使用Collections工具类

  • 使用Collections.synchronizedList()方法将普通的ArrayList类转换为安全的集合类
    在这里插入图片描述

  • 代码演示

    package CollectionSafe;
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    import java.util.UUID;
    
    /**
     * @author swaggyhang
     * @create 2023-07-02 17:26
     */
    public class Test01 {
        public static void main(String[] args) {
    //        List<String> list = new ArrayList<>();
    //        List<String> list = new Vector<>();
            List<String> list = Collections.synchronizedList(new ArrayList<>());
            for (int i = 1; i <= 10; i++) {
                new Thread(() -> {
                    list.add(UUID.randomUUID().toString().substring(0, 5));
                    System.out.println(list);
                }, String.valueOf(i)).start();
            }
        }
    }
    

3. 使用CopyOnWriteArrayList类

  • 写入时复制(简称:COW)是计算机领域的一种优化策略。底层源码如下:
    在这里插入图片描述

  • 多线程调用list时,读取的时候,是固定的,写入的时候,避免覆盖,造成数据问题(类似读写分离)

  • add()方法源码
    在这里插入图片描述

  • 代码演示

    package CollectionSafe;
    
    import java.util.List;
    import java.util.UUID;
    import java.util.concurrent.CopyOnWriteArrayList;
    
    /**
     * @author swaggyhang
     * @create 2023-07-02 17:26
     */
    public class Test01 {
        public static void main(String[] args) {
    //        List<String> list = new ArrayList<>();
    //        List<String> list = new Vector<>();
    //        List<String> list = Collections.synchronizedList(new ArrayList<>());
            List<String> list = new CopyOnWriteArrayList<>();
            for (int i = 1; i <= 10; i++) {
                new Thread(() -> {
                    list.add(UUID.randomUUID().toString().substring(0, 5));
                    System.out.println(list);
                }, String.valueOf(i)).start();
            }
        }
    }
    

三、并发下,HashSet类是不安全的

  • HashSet本质就是HashMap,其构造器生成一个map对象在这里插入图片描述

  • add()方法源码
    在这里插入图片描述

  • 代码演示

    package CollectionSafe;
    
    import java.util.HashSet;
    import java.util.Set;
    import java.util.UUID;
    
    /**
     * @author swaggyhang
     * @create 2023-07-04 10:42
     */
    public class Test02 {
        public static void main(String[] args) {
            Set<String> set = new HashSet<>();
            for (int i = 1; i <= 100; i++) {
                new Thread(() -> {
                    set.add(UUID.randomUUID().toString().substring(0, 5));
                    System.out.println(set);
                }, String.valueOf(i)).start();
            }
        }
    }
    
  • 上面代码会报错并发修改异常“java.util.ConcurrentModificationException”

四、解决方案

1. 使用Collections工具类

  • 使用Collections.synchronizedSet()方法将普通的HashSet类转换为安全的集合类

    package CollectionSafe;
    
    import java.util.Collections;
    import java.util.HashSet;
    import java.util.Set;
    import java.util.UUID;
    
    /**
     * @author swaggyhang
     * @create 2023-07-04 10:42
     */
    public class Test02 {
        public static void main(String[] args) {
    //        Set<String> set = new HashSet<>();
            Set<String> set = Collections.synchronizedSet(new HashSet<>());
            for (int i = 1; i <= 100; i++) {
                new Thread(() -> {
                    set.add(UUID.randomUUID().toString().substring(0, 5));
                    System.out.println(set);
                }, String.valueOf(i)).start();
            }
        }
    }
    

2. 使用CopyOnWriteArraySet类

  • CopyOnWriteArraySet底层还是使用CopyOnWriteArrayList那一套逻辑
    package CollectionSafe;
    
    import java.util.Set;
    import java.util.UUID;
    import java.util.concurrent.CopyOnWriteArraySet;
    
    /**
     * @author swaggyhang
     * @create 2023-07-04 10:42
     */
    public class Test02 {
        public static void main(String[] args) {
    //        Set<String> set = new HashSet<>();
    //        Set<String> set = Collections.synchronizedSet(new HashSet<>());
            Set<String> set = new CopyOnWriteArraySet<>();
            for (int i = 1; i <= 100; i++) {
                new Thread(() -> {
                    set.add(UUID.randomUUID().toString().substring(0, 5));
                    System.out.println(set);
                }, String.valueOf(i)).start();
            }
        }
    }
    
  • 构造器源码
    在这里插入图片描述
  • add()方法源码
    在这里插入图片描述

五、并发下,HashMap类是不安全的

  • 代码演示

    package CollectionSafe;
    
    import java.util.HashMap;
    import java.util.Map;
    import java.util.UUID;
    
    /**
     * @author swaggyhang
     * @create 2023-07-04 11:08
     */
    public class Test03 {
        public static void main(String[] args) {
            Map<String, String> map = new HashMap<>();
            for (int i = 1; i <= 10; i++) {
                new Thread(() -> {
                    map.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0, 5));
                    System.out.println(map);
                }, String.valueOf(i)).start();
            }
        }
    }
    
  • 上面代码会报错并发修改异常“java.util.ConcurrentModificationException”

六、解决方案

1. 使用Collections工具类

  • 使用Collections.synchronizedMap()方法将普通的HashMap类转换为安全的集合类
    package CollectionSafe;
    
    import java.util.Collections;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.UUID;
    
    /**
     * @author swaggyhang
     * @create 2023-07-04 11:08
     */
    public class Test03 {
        public static void main(String[] args) {
    //        Map<String, String> map = new HashMap<>();
            Map<String, String> map = Collections.synchronizedMap(new HashMap<>());
            for (int i = 1; i <= 10; i++) {
                new Thread(() -> {
                    map.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0, 5));
                    System.out.println(map);
                }, String.valueOf(i)).start();
            }
        }
    }
    

2. 使用ConcurrentHashMap类

  • 代码演示

    package CollectionSafe;
    
    import java.util.Map;
    import java.util.UUID;
    import java.util.concurrent.ConcurrentHashMap;
    
    /**
     * @author swaggyhang
     * @create 2023-07-04 11:08
     */
    public class Test03 {
        public static void main(String[] args) {
    //        Map<String, String> map = new HashMap<>();
    //        Map<String, String> map = Collections.synchronizedMap(new HashMap<>());
            Map<String, String> map = new ConcurrentHashMap<>();
            for (int i = 1; i <= 10; i++) {
                new Thread(() -> {
                    map.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0, 5));
                    System.out.println(map);
                }, String.valueOf(i)).start();
            }
        }
    }
    
  • 研究ConcurrentHashMap底层源码!!

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

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

相关文章

ubuntu下 C/C++程序读取设置环境变量

设置环境变量很简单比如&#xff1a; export QMCY_LOCAL_PORT8888 追加的话 export QMCY_LOCAL_PORT$QMCY_LOCAL_PORT:8000 可以通过echo回显 读取的话 main函数多加一个env参数 一个字符串数组 然后遍历这个数组 即可 使用的时候 如下&#xff1a; bool QMCY_APP::Init(s…

【若依框架学习】day1-启动项目

若依开源框架&#xff0c;前后端分离项目&#xff0c;地址&#xff1a;http://doc.ruoyi.vip/ruoyi-vue/ 先配置环境 JDK1.8&#xff0c; MySQL5.7 &#xff0c;Maven3.6&#xff0c;redis、nginx(可以不配)、 node 具体见&#xff1a;https://ygstriver.blog.csdn.net/articl…

day28-JSP

0目录 JSP 1.为什么使用JSP 2.B/S和C/S的区别 3.URL 4.Tomcat 5.JSP实战综合项目 1.为什么使用JSP 1.1 JSP定义&#xff1a; &#xff08;1&#xff09;是一种动态网页技术 &#xff08;2&#xff09;Java Server Pages&#xff08;Java服务器端页面技术&#xff09; 1.2 …

docker进阶

Docker网络 [rootecs-56325218 ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 2c63c1a8145c bridge bridge local 70d3439bbb55 host host local ffc74cf89143 none null local[rootecs-56325218 ~]# docker network cre…

day 42 01背包

01背包裸题 有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。 每件物品只能用一次&#xff0c;求解将哪些物品装入背包里物品价值总和最大。 二维数组 dp含义&#xff1a; dp[ i ][ j ] 表示从下标为 [ 0 - i ]的物品里…

SpringBoot 整合RabbitMQ

SpringBoot 整合 RabbitMQ 概念 2007 年发布&#xff0c;是一个在 AMQP(高级消息队列协议)基础上完成的&#xff0c;可复用的企业消息系统&#xff0c;是当前最主流的消息中间件之一。 RabbitMQ是一个由erlang开发的AMQP&#xff08;Advanced Message Queue 高级消息队列协议…

Driver、CUDA、CUDNN和TensorRT的关系【深蓝学院】

文章目录 1、Driver、CUDA、CUDNN和TensorRT的关系2、如何选择CUDA版本2.1 如何选择CUDA版本的一个例子 3、手动安装实操 1、Driver、CUDA、CUDNN和TensorRT的关系 2、如何选择CUDA版本 上面的显卡架构及其对应的CUDA版本和稳定版本是怎么得出来的呢&#xff1f;请看下图&#…

【数据结构与算法】将含有n个元素的整数数组A[0…n-1]的元素循环右移1≤m<n)位。要求算法的空间复杂度为O(1)。

题目&#xff1a; Qestion:  设计一个算法 , 将含有 n 个元素的整数数组 A [ 0 … n − 1 ] 的元素循环右移 ( 1 ≤ m < n ) 位。要求算法的空间复杂度为 O ( 1 ) 设计一个算法,将含有n个元素的整数数组A[0…n-1]的元素循环右移(1≤m<n)位。要求算法的空间复杂度为O(1) …

[MySQL]MySQL数据库基础

[MySQL]MySQL数据库基础 文章目录 [MySQL]MySQL数据库基础1. 什么是数据库2. 主流数据库3. 服务器数据库表之间的关系4. 数据逻辑结构5. MySQL架构6. SQL语句分类7. 存储引擎 1. 什么是数据库 数据库是存储在计算机系统内的有结构的数据集合&#xff0c;是相关数据的集合&#…

【业务功能篇38】Springboot+activiti7 工作流引擎 增加网关组件、Assignment分配权限

在前面的一篇文章中&#xff0c;简单举例了一个 工单电子流&#xff0c;【业务功能篇36】Springbootactiviti7 工作流引擎_studyday1的博客-CSDN博客仅有一个子任务&#xff0c;这种一般是针对比较简单的一个遗留问题记录场景&#xff0c;今天再介绍一个&#xff0c;相对比较复…

rabbitMq怎么查看队列消息-Tracing日志

Trace 是Rabbitmq用于记录每一次发送的消息&#xff0c;方便使用Rabbitmq的开发者调试、排错。 1、启动Tracing插件 在RabbitMQ中默认是关闭的&#xff0c;需手动开启。此处rabbitMQ是使用docker部署的 ## 进入rabbitMq中 docker exec -it rabbitmq1 bash ## 启动日志插件 rabb…

每天五分钟机器学习:构建多特征的线性回归模型

本文重点 在实际应用中,有时候一个单一特征的线性回归模型可能无法很好地解释数据,因此我们可以构建多特征的线性回归模型来提高模型的预测能力。本文还是拿房价问题来举例,来看以下多特征的线性回归模型如何构建? 多特征的数据集 以房价预测为例,现在的样本特征不再是…

贵阳阿里云代理商:阿里云中国区副总裁李国欢:数字经济与实体经济如何融合

中国青年报客户端讯&#xff08;中青在线记者 于璧嘉&#xff09;6月21日&#xff0c;在第六届世界智能大会即将召开之际&#xff0c;阿里云中国区副总裁李国欢在接受媒体专访时表示&#xff1a;“数字经济已经成为社会生产力革命的一个重要生产要素。” 6月21日&#xff0c;阿…

Linux下GO IDE安装和配置(附快捷键)

目前&#xff0c;GoLand、VSCode 这些 IDE 都很优秀&#xff0c;但它们都是 Windows 系统下的 IDE。在 Linux 系统下我们可以选择将 Vim 配置成 Go IDE。熟练 Vim IDE 操作之后&#xff0c;开发效率不输 GoLand 和 VSCode。有多种方法可以配置一个 Vim IDE&#xff0c;这里我选…

mqadmin命令的使用

mqadmin命令的使用 F:\rocketmq-all-4.9.7-bin-release\bin>mqadmin The most commonly used mqadmin commands are: updateTopic Update or create topic deleteTopic Delete topic from broker and NameServer. updateSubGroup Update or create subscription group delet…

【虚拟化】虚拟机xml文件解析

文章目录 虚拟机xml文件解析nameuuidmemory/currentMemoryvcpubootcpuon_poweroffon_rebooton_crashdiskinterfaceinputgraphics 补充说明1.磁盘总线类型 虚拟机xml文件解析 name name # 虚拟机名称&#xff0c;具有唯一性&#xff0c;不可与已建立的虚拟机重复uuid uuid #虚…

MoblieNetV1、V2、V3、ViT四种Moblie模型的分析对比

1、MoblieNetV1 2017年提出&#xff0c;论文地址为&#xff1a;https://arxiv.org/pdf/1704.04861.pdf 1.1 相关知识 提到了标准卷积、深度可分卷积、点卷积&#xff0c;并分析了不同卷积结构的计算量&#xff0c;&#xff08;假设 D k D_k Dk​为ksize&#xff0c;M为卷积的…

在VMware Workstation虚拟机上安装centos服务,并使用xshell连接centos服务。

一、安装VMware Workstation 可前往http://www.kkx.net/soft/22239.html&#xff0c;附带有下载链接&#xff0c;和对应的破解码。 二、下载centos .iso格式文件 前往https://mirrors.aliyun.com/centos/7/isos/x86_64/下载。 以下两个&#xff0c;选择哪一个都行。 记得要下…

【MySQL进阶篇】学习笔记

文章目录 MySQL进阶学习前言1、存储引擎1.1 MySQL体系结构概览1.2 存储引擎介绍1.3 常见存储引擎的特点1.3.1 InnoDB的特点1.3.2 MyISAM1.3.3 Memory1.3.4 总结 2、索引2.1 索引介绍2.2 索引的结构2.2.1 前置知识2.2.2 索引结构的种类 2.3 索引的分类2.4 索引的使用2.4.1 索引的…

Vue3 通过ref获取 el-dialog 内容(组件)中的dom元素的问题

问题描述&#xff1a; 项目中&#xff0c;使用el-dialog组件展示内容&#xff0c;内容是自己封装的一个组件&#xff0c;组件中通过ref获取dom元素然后进行绘制echarts图形的。 问题是&#xff1a;在弹出el-dialog组件后&#xff0c;echarts图形没有渲染出来。刚开始还以为是自…