ArrayList线程不安全,如何改进?CopyOnWriteArrayList

1、ArrayList线程不安全测试代码

public class testArrayListUnsafe {
    public static void main(String[] args) {

        List<String> list = new ArrayList<>();
       
        list.forEach(System.out::println);
        for (int i = 0; i <30; i++) {
            new Thread(()-> {
                list.add(UUID.randomUUID().toString().substring(0,8));
                System.out.println(list);
            },String.valueOf(i)).start();
            //java.util.ConcurrentModificationException
            /*
            * 1、故障现象
            *
            * 2、导致原因
            *
            * 3、解决方案
            *
            * 4、优化建议(同样的错误不犯第二次)
            *
            * */
        }
    }

2、报错

Exception in thread "24" java.util.ConcurrentModificationException

3、如何解决?

public class testArrayListUnsafe {
    public static void main(String[] args) {

        List<String> list = Collections.synchronizedList(new ArrayList<>());
                //new ArrayList<>();

        list.forEach(System.out::println);
        for (int i = 0; i <30; i++) {
            new Thread(()-> {
                list.add(UUID.randomUUID().toString().substring(0,8));
                System.out.println(list);
            },String.valueOf(i)).start();
            //java.util.ConcurrentModificationException
            /*
            * 1、故障现象
            *
            * 2、导致原因
            *
            * 3、解决方案
            *    a.new Vector<> ();
            *    b.Collections.synchronizedList(new ArrayList<>());
            * 4、优化建议(同样的错误不犯第二次)
            *
            * */
        }
    }

4、如果不许用

*    a.new Vector<> ();
*    b.Collections.synchronizedList(new ArrayList<>());

怎么办?

public class testArrayListUnsafe {
    public static void main(String[] args) {

        List<String> list = new CopyOnWriteArrayList<>();
                // Collections.synchronizedList(new ArrayList<>());
                //new ArrayList<>();

        list.forEach(System.out::println);
        for (int i = 0; i <30; i++) {
            new Thread(()-> {
                list.add(UUID.randomUUID().toString().substring(0,8));
                System.out.println(list);
            },String.valueOf(i)).start();
            //java.util.ConcurrentModificationException
            /*
            * 1、故障现象
            *
            * 2、导致原因
            *
            * 3、解决方案
            *    a.new Vector<> ();
            *    b.Collections.synchronizedList(new ArrayList<>());
            * 4、优化建议(同样的错误不犯第二次)
            *
            * */
        }
    }

5、为什么用

new CopyOnWriteArrayList<>()就能保证线程安全?

CopyOnWriteArrayList的添加元素的方法的源码:写时复制,读写分离的思想。

    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();
        }
    }
发布了85 篇原创文章 · 获赞 21 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_41670928/article/details/103034675