「Java」CopyOnWriteArrayList与Vector

我们都知道ArrayList是线程非安全的。如果我们想要得到一个线程安全的集合。有如下方式 new Vector<String>(); Collections.synchronizedList(new ArrayList<>()); new CopyOnWriteArrayList();

他们实现线程安全的方式

Vector :简单粗暴 // add public synchronized boolean add(E e) { modCount++; ensureCapacityHelper(elementCount + 1); elementData[elementCount++] = e; return true; } // get public synchronized E get(int index) { if (index >= elementCount) throw new ArrayIndexOutOfBoundsException(index); return elementData(index); } Collections.synchronizedList 与Vector类似,也是上种方式。

我们来看看CopyOnWriteArrayList是如何实现线程安全的

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();
        }
    }
首先CopyOnWriteArrayList其采用的COW思想,即在读的时候使用原来了的集合对象,当需要对集合进行写操作时,我们就创建一个新的对象,提供的这个需要进行修改操作的线程,当所有迭代完成后,再将旧集合的指针指向修改后的新集合。没有扩容机制,减少了扩容浪费的时间。 还有与上边两种不同的是,CopyOnWriteArrayList的get()方法没有锁。
经验分享 程序员 微信小程序 职场和发展