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();
            }
        }
        
  • 相关阅读:
    linux多线程学习笔记五--线程安全【转】
    linux多线程学习笔记六--一次性初始化和线程私有数据【转】
    【Linux】可重入函数和线程安全的区别与联系【转】
    【Linux】自主实现my_sleep【转】
    Linux/Unix编程中的线程安全问题【转】
    C语言字符串操作总结大全(超详细)【转】
    linux中的strip命令简介------给文件脱衣服【转】
    FTK应用程序编程接口(API)手册-1【转】
    python编程(python开发的三种运行模式)【转】
    ftk学习记(label篇)【转】
  • 原文地址:https://www.cnblogs.com/flgb/p/11768503.html
Copyright © 2011-2022 走看看