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

这篇具有很好参考价值的文章主要介绍了【JUC并发编程】集合类安全问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、并发下,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方法是同步方法,但是效率很低
    【JUC并发编程】集合类安全问题,JUC并发编程,java
  • 代码演示
    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类转换为安全的集合类
    【JUC并发编程】集合类安全问题,JUC并发编程,java

  • 代码演示

    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)是计算机领域的一种优化策略。底层源码如下:
    【JUC并发编程】集合类安全问题,JUC并发编程,java

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

  • add()方法源码
    【JUC并发编程】集合类安全问题,JUC并发编程,java

  • 代码演示

    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对象【JUC并发编程】集合类安全问题,JUC并发编程,java

  • add()方法源码
    【JUC并发编程】集合类安全问题,JUC并发编程,java

  • 代码演示

    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();
            }
        }
    }
    
  • 构造器源码
    【JUC并发编程】集合类安全问题,JUC并发编程,java
  • add()方法源码
    【JUC并发编程】集合类安全问题,JUC并发编程,java

五、并发下,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底层源码!!文章来源地址https://www.toymoban.com/news/detail-522368.html

到了这里,关于【JUC并发编程】集合类安全问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JUC并发编程学习笔记(三)生产者和消费者问题

    synchronized版- wait/notify juc版-Lock 面试:单例模式、排序算法、生产者和消费者、死锁 生产者和消费者问题 Synchronized版 存在的问题:A、B、C、D四个线程 在线程中判断业务完成唤醒等待应该使用while循环判断,而非if判断,因为if判断值判断一次,在线程中存在一种状态叫虚假唤

    2024年02月06日
    浏览(38)
  • java JUC并发编程 第九章 对象内存布局与对象头

    第一章 java JUC并发编程 Future: link 第二章 java JUC并发编程 多线程锁: link 第三章 java JUC并发编程 中断机制: link 第四章 java JUC并发编程 java内存模型JMM: link 第五章 java JUC并发编程 volatile与JMM: link 第六章 java JUC并发编程 CAS: link 第七章 java JUC并发编程 原子操作类增强: link 第八章

    2024年02月07日
    浏览(44)
  • JUC并发编程-线程和进程、Synchronized 和 Lock、生产者和消费者问题

    源码 + 官方文档 面试高频问! java.util 工具包、包、分类 业务:普通的线程代码 Thread Runnable Runnable 没有返回值、效率相比入 Callable 相对较低! 线程、进程,如果不能使用一句话说出来的技术,不扎实! 进程:一个程序,QQ.exe Music.exe 程序的集合; 一个进程往往可以包含多

    2024年01月20日
    浏览(51)
  • 【JavaEE】JUC(java.util.concurrent)的常见类以及线程安全的集合类

    目录 1、JUC(java.util.concurrent)的常见类 1.1、Callable接口的用法(创建线程的一种写法)  1.2、ReentrantLock可重入互斥锁 1.2.1、ReentrantLock和synchronized的区别  1.2.2、如何选择使用哪个锁 1.3、Semaphore信号量 1.4、CountDownLatch  2、线程安全的集合类 2.1、多线程环境使用ArrayList  2.2、

    2024年02月07日
    浏览(48)
  • 【并发编程】JUC并发编程(彻底搞懂JUC)

    如果你对多线程没什么了解,那么从入门模块开始。 如果你已经入门了多线程(知道基础的线程创建、死锁、synchronized、lock等),那么从juc模块开始。 新手学技术、老手学体系,高手学格局。 JUC实际上就是我们对于jdk中java.util .concurrent 工具包的简称 ,其结构如下: 这个包

    2024年02月20日
    浏览(51)
  • Java 8并发集合:安全高效的多线程集合

    在多线程环境中,使用线程安全的数据结构非常重要,以避免竞态条件和数据不一致的问题。Java 8引入了一些并发集合类,提供了安全高效的多线程集合操作。本教程将介绍Java 8中的并发集合类,包括ConcurrentHashMap、ConcurrentLinkedQueue、ConcurrentSkipListSet和CopyOnWriteArrayList。 Conc

    2024年02月04日
    浏览(55)
  • Java - JUC(java.util.concurrent)包详解,其下的锁、安全集合类、线程池相关、线程创建相关和线程辅助类、阻塞队列

    JUC是java.util.concurrent包的简称,在Java5.0添加,目的就是为了更好的支持高并发任务。让开发者进行多线程编程时减少竞争条件和死锁的问题 java.lang.Thread.State tools(工具类):又叫信号量三组工具类,包含有 CountDownLatch(闭锁) 是一个同步辅助类,在完成一组正在其他线程中

    2024年02月05日
    浏览(35)
  • 并发编程-JUC-原子类

    JUC 整体概览 原子类 基本类型-使用原子的方式更新基本类型 AtomicInteger:整形原子类 AtomicLong:长整型原子类 AtomicBoolean :布尔型原子类 引用类型 AtomicReference:引用类型原子类 AtomicStampedReference:原子更新引用类型里的字段原子类 AtomicMarkableReference :原子更新带有标记位的引

    2024年02月21日
    浏览(41)
  • 第九章 JUC并发编程

    http://t.csdn.cn/UgzQi 使用 AQS加 Lock 接口实现简单的不可重入锁 早期程序员会自己通过一种同步器去实现另一种相近的同步器,例如用可重入锁去实现信号量,或反之。这显然不够优雅,于是在 JSR166(java 规范提案)中创建了 AQS,提供了这种通用的同步器机制。 AQS 要实现的功能

    2023年04月08日
    浏览(40)
  • JUC并发编程(二)

    JUC并发编程(续) 接上一篇笔记:https://blog.csdn.net/weixin_44780078/article/details/130694996 五、Java内存模型 JMM 即 Java Memory Model,它定义了主存、工作内存抽象概念,底层对应着CPU寄存器、缓存、硬件内存、CPU 指令优化等。 JMM 体现在以下几个方面: 原子性:保证指令不会受到线程

    2024年02月05日
    浏览(93)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包