• 多线程下集合不安全问题


    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();
            }
        }
        
  • 相关阅读:
    NOIP2017 D1T2 时间复杂度
    NOIP2017 游记
    NOIP2017 Day-1 模板荟萃
    NOIP2013 货车运输 倍增
    洛谷3933 Chtholly Nota Seniorious 二分答案+贪心
    洛谷2474 [SCOI2008] 天平 差分约束->枚举
    bzoj1270 BeijingWc2008 雷涛的小猫 DP
    poj1061--青蛙的约会--扩展欧几里得
    “整除”的相关
    poj1067--取石子游戏--(神奇的黄金分割比)
  • 原文地址:https://www.cnblogs.com/flgb/p/11768503.html
Copyright © 2020-2023  润新知