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();
            }
        }
        
  • 相关阅读:
    十张伟大的科学瞬间
    机器学习如何破译早已消亡的古老语言?
    如何阻止「数码黑帮」偷走你的时间
    社会地位即服务, Status as a Service (二): 社交网络的投资回报率 (ROI)
    谁是你的创业竞争对手?
    酷!美国国家安全局(NSA)开源了逆向工程工具 Ghidra
    Linux终端下Ctrl+S卡死
    操作系统损坏重装是否能恢复lvm硬盘数据的相关实验
    How to write an iso file to usb driver
    linux screen的用法
  • 原文地址:https://www.cnblogs.com/flgb/p/11768503.html
Copyright © 2011-2022 走看看