多线程及并发面试基础(4)——谈谈集合类(Arraylist)

1、谈谈Arraylist

1. ArrayList 底层数据结构是数组,数组的特点就是可以快速随机访问,直接根据下标定位,缺点是插入和删除速度比较慢,需要移动元素。
2. ArrayList 每次扩容之后的大小为之前的 1.5 倍。默认初始容量大小为 10。ArrayList只不过是对数组的包装,因为数组在内存中分配时必须指定长度,且一旦分配好后便无法再增加长度,即不可能在原数组后面再接上一段的。ArrayList之所以可以一直往里添加,是因为它内部做了处理。当底层数组填满后,它会再分配一个更大的新的数组,把原数组里的元素拷贝过来,然后把原数组抛弃掉。使用新的数组作为底层数组来继续存储。

Arraylist不安全代码:

public class ArraylistDemo {
    public static void main(String[] args) {
        ArrayList arrayList =  new ArrayList();
         for (int i = 0; i< 30; i++) {
             final int temp=i;
             new Thread(()->{
                 arrayList.add(temp);
                 System.out.println(arrayList);
             },String.valueOf(i)).start();
         }
    }
}

结果:
arraylist不安全

2、Arraylist不安全的解决方案,至少三个

1、Vector。 Vector arrayList = new Vector<>();
2、Collections.synchronizedList。
List arrayList = Collections.synchronizedList(new ArrayList());
3、CopyOnWriteArrayList写时复制。
原理:往一个容器中添加元素的时候,不直接往当前容器Object[]添加,而是先将当前容器Object[]进行copy,复制出一个新的容器Object[] newElements,然后新的容器Object[] newElements里添加新元素,添加元素之后,再将原容器的引用指向新的容器setArray(newElements);这样做的好处是可以对CopyOnWrite容器进行并发的读,而不是需要加锁,因为当前容器不会添加任何元素,所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器。

多线程及并发场景下我们使用的CopyOnWriteArrayList。
结合CopyOnWrite中add操作的源码深入理解一下它的原理:

 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();
        }
    }

源码中使用了lock锁机制。并在复制时使用了Arrays.copyOf方法,然后讲新值插入到复制之后的容器尾部。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值