4.JAVA大厂面试第二季-集合类不安全

三种解决方法:Vector(效率低),Collections.synchronized...(效率也低),CopyOnWriteArrayList

public class UnSafeTest {
    public static void main(String[] args) {
        //List<String> list = new ArrayList<>();//方法一:vector是线程安全的但是性能低所以不使用
        //方法二:使用工具类Collections这个集合类同时也能解决map,set的不安全问题
        //List<String> list1 = Collections.synchronizedList(list);
        //方法三:使用JUC的类CopyOnWriteArrayList
        CopyOnWriteArrayList<Object> list1 = new CopyOnWriteArrayList<>();
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                //arrayList的线程不安全体现在add方法没有加锁
                list1.add(UUID.randomUUID().toString().substring(0,3));
                System.out.println(list1);//发现并发修改异常java.util.ConcurrentModificationException
            }, "" + i).start();
        }
    }
}

CopyOnWriteArrayList详解

public boolean add(E var1) {
        ReentrantLock var2 = this.lock;
        var2.lock();

        boolean var6;
        try {
            Object[] var3 = this.getArray();//拿到数组
            int var4 = var3.length;
            Object[] var5 = Arrays.copyOf(var3, var4 + 1);//拷贝扩容
            var5[var4] = var1;//写入新值
            this.setArray(var5);//设置数组
            var6 = true;//操作完毕
        } finally {
            var2.unlock();//释放锁
        }

        return var6;
    }

CopyOnWrite也就是写时复制。往容器里添加一个元素的时候,不直接在当前容器Object[]添加,而是将当前容器Object[]进行复制,拷贝出一个新的容器后,再将原有的容器的引用指向新的容器,这样做的好处时可以对CopyOnWrite容器进行并发的读,读的时候不需要加锁,因为当前的容器不会添加任何的元素,所以CopyOnWrite也是一种读写分离的思想。

对于CopyOnWriteArraySet我们可以看到其底层也就是CopyOnWriteArrayList

 

类似于HashSet的底层是HashMap,但是HashSet只需要一个元素,HashMap需要两个元素,为什么呢?HashiSet的值其实就是HashMap的key,其value值为一个叫Present的常量。

同样的HashMap也是线程不安全的,但是在JUC中并不叫CopyOnWriteHashMap而是叫ConcurrentHashMap,其效果就是保证线程安全,这里不再赘述。需要注意的是ConcurrentHashMap的底层和HashMap底层实现有很大的区别

ConcurrentHashMap 由 Segment 数组结构 和 HashEntry 数组结构组成,一个ConcurrentHashMap 里面包含一个 Segment 数组(数组链表结构),一个 Segment 里面包含一个 HashEntry 数组 (链表结构),每个 Segment 守护一个HashEntry 数组里的元素,当对 HashEntry 数组的数据进行修改时,必须首先获得它对应的 Segment 锁,这个是java7之前的,在java8后又做了一些改动

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值