多线程下集合不安全问题

Posted on 2019-10-30 22:39  FLGB  阅读(331)  评论(0编辑  收藏  举报
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();
        }
    }
    

 

Copyright © 2024 FLGB
Powered by .NET 9.0 on Kubernetes