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


    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();
            }
        }
        
  • 相关阅读:
    WebDriverException:Message:'geckodriver'executable needs to be in Path
    如何使用NSDL玩转微信跳一跳
    python多线程下载网页图片并保存至特定目录
    sql之将一个表中的数据注入另一个表中
    sql之分区域分段统计
    sql之分段统计
    ajax二次封装之异步加载
    vue组件之echarts报表
    url查询参数解析
    template.js 数据渲染引擎
  • 原文地址:https://www.cnblogs.com/flgb/p/11768503.html
Copyright © 2020-2023  润新知