2019年互联网(1.4)

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

问题描述

**   已知:list、Set、Map在多线程的环境下,会尝试异常,也就是发生线程不安全事件
 *  1. 故障现象
 *      java.util.ConcurrentModificationException
 *  2. 导致原因
 *      多线程并发争取同一个资源,且未加锁
  *3.解决方法
 *      3.1 new Vector<>();
 *      3.2 Collections.synchronizedList(new ArrayList<String>());
 *      3.3 new CopyOnWriteArrayList(); //写时复制
 * 4.优化建议(同样的错误不犯第二次)

案例一:list线程不安全

下面我们来简单看一下代码:

public class NotSafeDemo03 {
    public static void main (String[] args) {
        listNotSafe();
    }
      private static void listNotSafe () {
        //出现问题的方法
        // List<String> list = new ArrayList <>();
        // 解决方法 1 ,采用底层采用 synchronized实现的Vector
        // List <String> list = new Vector <>();
        // 解决方法 2 ,采用Collections.synchronizedList来实现,还可以解决Set,Map中线程不安全的问题
        // List<String> list =Collections.synchronizedList(new ArrayList <>());
        // 解决方法 3 , 采用JUC中新方法,CopyOnWriteArrayList(); 写实复制,  底层采用可从重入锁来完成的
        List <String> list = new CopyOnWriteArrayList();
        for (int i = 0; i < 10; i++) {
            new Thread(()->{
                    list.add(UUID.randomUUID().toString().substring(0,8));
                System.out.println(list);
            },String.valueOf("A")).start();
        }
    }
}

在代码块中,我们可以清晰看到,list出现问题的方法,以及各种解决方案,读者可以试运行一下。

体验完以后,为什么会发生线程不安全事件呢

/ * 分析问题源头, 扩容事件
   new ArrayList() 实际上是new了一个大小为10的object数组
 * 存25个元素,会自动扩容,第一次 扩到15,(扩充原来值的一半) 
   HashMap的原值大小为16,扩容一次扩充一倍
 * 采用Array.copyOf进行辅助
 * 第二次扩容 扩到 22 (15的一半7.5,取整)
 */

为什么可以用上述三种方案解决呢,源码解释:

image-20210127011901169

噢,原来他们都是List的子接口,而且查看底层源码,发现Vector前面就已经扩容好了,不会发现扩充导致的异常,CopyOnWriteArrayList,采用的是一种写时复制的策略。synchronizedList,就像他的名字一样,采用synchronized加锁实现。

写时复制
* CopyOnWrite 容器即写时复制的容器。往一个容器中添加新的元素的时候,不直接往当前容器Object[]添加,而是先将当前容器Object[]进行copy
* 复制出一个新的容器Object[] newElements,然后新的容器Object[] newElements 添加新元素,添加完元素以后
* 再将原来容器的引用指向setArray(newElement);这样做的好处就是可以对CopyOnWrite容器进并发的读,而且不需要加锁,
* 即 CopyOnWrite也是一种读写分离的思想,读和写不同的容器

Set集合类可以采用CopyOnwriteHashSet,以及Map集合类使用专门的ConcurrentHashMap工具类

posted @ 2021-02-14 23:28  Hugo_nice  阅读(75)  评论(0)    收藏  举报