zoukankan      html  css  js  c++  java
  • 多线程下集合不安全问题

    public class CollectionDemo {
    
        public static void main(String[] args) {
            List<String> list = new ArrayList<String>();
            for (int i = 1; i < 40; i++) {
                new Thread(() -> {
                    list.add(UUID.randomUUID().toString().substring(0, 8));
                    System.out.println(list);
                }, "线程" + String.valueOf(i)).start();
            }
            //list.forEach(System.out::println);
        }
    }

    结果:发现不是打印出三个参数值,出现异常

    Exception in thread "线程6" java.util.ConcurrentModificationException
        at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
        at java.util.ArrayList$Itr.next(Unknown Source)
        at java.util.AbstractCollection.toString(Unknown Source)
        at java.lang.String.valueOf(Unknown Source)
        at java.io.PrintStream.println(Unknown Source)
        at com.shangguigu.collection.CollectionDemo.lambda$0(CollectionDemo.java:14)
        at java.lang.Thread.run(Unknown Source)

    修改成集合安全

    //ArrayList特性,初始化默认大小10,每次扩容一半,15,22
        //先getArray(),size()+1,copyOf()
        public static void main(String[] args) {
            List<String> list = Collections.synchronizedList(new ArrayList<String>());
            for (int i = 1; i < 40; i++) {
                new Thread(() -> {
                    list.add(UUID.randomUUID().toString().substring(0, 8));
                    System.out.println(list);
                }, "线程" + String.valueOf(i)).start();
            }
            //list.forEach(System.out::println);
        }
    public static void main(String[] args) {
            List<String> list = new CopyOnWriteArrayList<>();//reentrantlock 底层,先复制改完,指针重指向新数组
            for (int i = 1; i < 40; i++) {
                new Thread(() -> {
                    list.add(UUID.randomUUID().toString().substring(0, 8));
                    System.out.println(list);
                }, "线程" + String.valueOf(i)).start();
            }
            //list.forEach(System.out::println);
        }

    hashSet和HashMap也一样

    public static void main(String[] args) {
            //listdemo();
            setdemo();
            mapdemo();
        }
        /**
         * HashMap初始值16,每次扩容一倍
         */
        
        private static void mapdemo() {
            Map<String,String> map = new ConcurrentHashMap<>();//Collections.synchronizedSet(new HashMap<>());
            for (int i = 1; i < 40; i++) {
                new Thread(() -> {
                    map.put(Thread.currentThread().getName(),UUID.randomUUID().toString().substring(0, 8));
                    System.out.println(map);
                }, "线程" + String.valueOf(i)).start();
            }
        }
        
        private static void setdemo() {
            Set<String> set = new CopyOnWriteArraySet<>();//Collections.synchronizedSet(new HashSet<>());
            for (int i = 1; i < 40; i++) {
                new Thread(() -> {
                    set.add(UUID.randomUUID().toString().substring(0, 8));
                    System.out.println(set);
                }, "线程" + String.valueOf(i)).start();
            }
        }
        
  • 相关阅读:
    【转】Redis概念原理、redis面试
    mysql登录后显示用户名与当前数据库名
    (5.3.10)数据库迁移——sql server降级操作
    navicat下载安装破解
    sql server2016+windows server2016使用日志传送做主从,主库无法备份事务日志
    (4.41)sql server如何把xml转换成表格数据?
    .NET Core SDK在Windows系统安装后出现Failed to load the hostfxr.dll等问题的解决方法
    .NET Core实战项目之CMS 第七章 设计篇-用户权限极简设计全过程
    .NET Core实战项目之CMS 第六章 入门篇-Vue的快速入门及其使用
    [译]聊聊C#中的泛型的使用(新手勿入)
  • 原文地址:https://www.cnblogs.com/flgb/p/11768503.html
Copyright © 2011-2022 走看看