集合类线程安全的问题

原创
03/31 21:52
阅读数 25

1、当new ArrayList( )时,底层是new了一个什么?

new了一个长度为10的空数组

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

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

//HashSet的案例类似:Collections.synchronizedSet、CopyOnWriteArraySet
//HashMap的案例:Collections.synchronizedMap、ConcurrentHashMap


for (int i = 1; i <= 30; i++) {
    new Thread(() -> {
        list.add(UUID.randomUUID().toString().substring(0, 8));

        System.out.println(list);

    },String.valueOf(i)).start();
}

/**
 * 1、故障现象
 *      ArrayList、HashSet、HashMap在并发环境下添加元素时都会发生以下的异常
 *      java.util.ConcurrentModificationException 并发修改异常
 *
 * 2、导致原因
 *      并发争抢修改导致
 *
 *
 * 3、解决方案
 *      3.1 new Vector<>(); vector是加了synchronized,并且比ArrayList要发布的早
 *      3.2 Collections.synchronizedList(new ArrayList<>());
 *      3.3 new CopyOnWriteArrayList<>(); CopyOnWrite写时复制
 *
 *
 * 4、优化建议
 *      写时复制 CopyOnWrite 
        (1)容器即写时复制的容器。
        (2)往一个容器添加元素的时候,不直接往当前容器Object[]添加,而是先将当前object[]进行Copy,
           复制出一个新的容器Object[] newElements,然后往新的容器Object[] newElements里添加元素,
           添加完元素之后,再将原容器的引用指向新的容setArray(newElements);
        (3)这样做的好处是可以对copyonwrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。
           所以 copyonwrite 容器也是一种读写分离的思想,读和写不同的容器。
 */

 

 

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部