JUC--集合不安全类

JUC

1. ArrayList线程不安全演示-什么故障?什么原因?怎么解决?

ArrayList底层是一个数组,默认大小10,超过就扩容,扩原值的一半10+5=15

线程不安全,因为add方法没有加锁。

不安全案例:

public class ContainerNotSafeDemo {

    /**
     * 1. 故障
     *      java.util.ConcurrentModificationException   并发修改异常
     *
     * 2. 原因
     *      线程并发修改导致,线程1正在写入,线程2抢占资源,导致数据不一致。
     *
     * 3. 解决
     *      1 new Vector(); add方法加锁,线程安全,并发性差。
     *      2 Collections.synchronizedList(new ArrayList<>()); 包装成安全的,还是加锁,并发性差。
     *      3 new CopyOnWriteArrayList<>();  juc的类,写时复制
     * 4. 优化
     */
    public static void main(String[] args) {
//        List<String> list = new ArrayList<>();
//        List<String> list = new Vector<>();
 //       List<String> list = Collections.synchronizedList(new ArrayList<>());
       List<String> list = new CopyOnWriteArrayList<>();

        for (int i = 1; i <= 30; i++) {
            new Thread(()->{
                list.add(UUID.randomUUID().toString().substring(0,4));
                System.out.println(Thread.currentThread().getName()+"\t"+list);
            },String.valueOf(i)).start();
        }
    }
}

2. CopyOnWriteArrayList原理?它有什么好?

参考:https://blog.csdn.net/linsongbin1/article/details/54581787

add源码:

public boolean add(E e) {
    // 1. 加锁
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
        Object[] elements = getArray();
        int len = elements.length;
        // 2. 拷贝数组
        Object[] newElements = Arrays.copyOf(elements, len + 1);
        // 3. 新增元素到新数组
        newElements[len] = e;
        // 4. 将array引用指向新数组
        setArray(newElements);
        return true;
    } finally {
        // 解锁
        lock.unlock();
    }
}

解释写时复制:

  1. 写操作时,先从原有的数组中拷贝一份出来,然后在新的数组做写操作,写完之后,再将原来的数组引用指向到新数组。整个add操作都是在锁的保护下进行的。
  2. 读操作时,如果写完成且引用指向新数组,则读到的是最新数据;否则读到的是原始数组数据。可见读操作是不加锁的

3. CopyOnWriteArrayList 缺点&使用场合

  1. 消耗内存。写操作,拷贝数组,消耗内存,数组大的话可能导致gc
  2. 不能实时读。拷贝新增需要时间,读到的可能是旧数据,能保证最终一致性,但不满足实时要求。
    因此,适合读多写少的场景。

CopyOnWriteArrayList透露的思想

  1. 读写分离,提高并发
  2. 不能满则实时性,可保证最终一致性
  3. 通过另辟空间,来解决并发冲突

4. 集合类不安全Set

Set同理

HashSet > Collections.synchronizedSet() > CopyOnWriteArraySet

且CopyOnWriteArraySet底层还是用的CopyOnWriteArrayList

HashSet底层是HashMap, add(key,一个常量)

5.集合类不安全Map

Map类似

HashMap > Collections.synchronizedMap() > ConcurrentHashMap

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值