栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

ArrayList线程不安全和解决方案

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

ArrayList线程不安全和解决方案

我们通常说的Java中的fail-fast机制(快速失败机制),默认指的是Java集合中的一种错误检测机制,当多个线程对集合进行结构性的改变时,有可能会出发fail-fast机制,这个时候会抛出ConcurrentModificationException异常。

为什么ArrayList线程不安全?Vector却线程安全呢?让我们来一探究竟!
ArrayList:

    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        //ensureCapacityInternal()就是判断如果将当前的新元素加到列表后面,列表的elementData数组的大小是否满足,如果size + 1的这个需求长度大于了elementData这个数组的长度,那么就要对这个数组进行扩容
        elementData[size++] = e;
        return true;
    }

Vector:

    public synchronized boolean add(E e) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = e;
        return true;
    }

显而易见:在ArrayList中,elementData与size都是全局变量,但没有进行sychronization同步处理,elementData是共享的线程不安全的mutable可变数据。

那么如何解决LIst线程安全问题呢?

  1. Vector:Vector list = new Vector<>();
  2. Collections:List list = Collections.synchronizedList(new ArrayList());
  3. CopyOnWriteArrayList:List list = new CopyOnWriteArrayList<>();

我们来看看 CopyOnWriteArrayList 中的add()方法,原理是使用了 写时复制技术:

    public boolean add(E e) {
        final ReentrantLock lock = this.lock;
        // 首先:加锁!
        lock.lock();
        try {
            Object[] elements = getArray();
            int len = elements.length;
            // 1、将内容复制了一份
            Object[] newElements = Arrays.copyOf(elements, len + 1);
            // 2、写入新的内容
            newElements[len] = e;
            // 3、合并
            setArray(newElements);
            return true;
        } finally {
            lock.unlock();
        }
    }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/987961.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号