zoukankan      html  css  js  c++  java
  • java集合并发操作异常解决方法:CopyOnWriteArrayList

    一、我们知道ArrayList是线程不安全的,请编写一个不安全的案例并给出解决方案

    HashSet与ArrayList一致 HashMap

    HashSet底层是一个HashMap,存储的值放在HashMap的key里,value存储了一个PRESENT的静态Object对象

    protected transient int modCount = 0; 记录集合操作次数的,这个变量如果不一致与期望的不一致,就会产生ConcurrentModificationException

    1、线程不安全

    package com.jian8.juc.collection;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.UUID;
    
    /**
     * 集合类不安全问题
     * ArrayList
     */
    public class ContainerNotSafeDemo {
        public static void main(String[] args) {
            notSafe();
        }
    
        /**
         * 故障现象
         * java.util.ConcurrentModificationException
         */
        public static void notSafe() {
            List<String> list = new ArrayList<>();
            for (int i = 1; i <= 30; i++) {
                new Thread(() -> {
                    list.add(UUID.randomUUID().toString().substring(0, 8));
                    System.out.println(list);
                }, "Thread " + i).start();
            }
        }
    }
    

    报错:

    Exception in thread "Thread 10" java.util.ConcurrentModificationException

    2、导致原因

    并发正常修改导致

    一个人正在写入,另一个同学来抢夺,导致数据不一致,并发修改异常

    3、解决方法:**CopyOnWriteArrayList

    List<String> list = new Vector<>();//Vector线程安全
    List<String> list = Collections.synchronizedList(new ArrayList<>());//使用辅助类
    List<String> list = new CopyOnWriteArrayList<>();//写时复制,读写分离
    
    Map<String, String> map = new ConcurrentHashMap<>();
    Map<String, String> map = Collections.synchronizedMap(new HashMap<>());
    

    CopyOnWriteArrayList.add方法:

    CopyOnWrite容器即写时复制,往一个元素添加容器的时候,不直接往当前容器Object[]添加,而是先将当前容器Object[]进行copy,复制出一个新的容器Object[] newElements,让后新的容器添加元素,添加完元素之后,再将原容器的引用指向新的容器setArray(newElements),这样做可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素,所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器

    	public boolean add(E e) {
            final ReentrantLock lock = this.lock;
            lock.lock();
            try {
                Object[] elements = getArray();
                int len = elements.length;
                Object[] newElements = Arrays.copyOf(elements, len + 1);
                newElements[len] = e;
                setArray(newElements);
                return true;
            } finally {
                lock.unlock();
            }
        }
  • 相关阅读:
    自介
    打招呼
    试验四
    作业:实验二
    个人简介
    实验4
    构建之法—心得体会
    作业:实验二
    个人简介
    软件测试第四次博客作业2
  • 原文地址:https://www.cnblogs.com/hejunhong/p/13290342.html
Copyright © 2011-2022 走看看