Java 杂谈

CopyOnWriteArrayList 学习笔记

2018-08-20  本文已影响3人  sunshujie1990

CopyOnWrite

WIKI

Copy-on-write (CoW or COW), sometimes referred to as implicit sharing[[1]](https://en.wikipedia.org/wiki/Copy-on-write#cite_note-1) or shadowing,[2] is a resource-management technique used in computer programming to efficiently implement a "duplicate" or "copy" operation on modifiable resources.[3] If a resource is duplicated but not modified, it is not necessary to create a new resource; the resource can be shared between the copy and the original. Modifications must still create a copy, hence the technique: the copy operation is deferred to the first write. By sharing resources in this way, it is possible to significantly reduce the resource consumption of unmodified copies, while adding a small overhead to resource-modifying operations.

简单翻译:

COW有时候是指implicit sharing隐式共享, QT中的一个概念和shadowing. 它是一种资源管理技术.它通过编程的方式针对可编辑的资源此处强调可编辑的资源对我的提示是: 关于高并发无外乎两种思路, 一种是资源共享(java并发模型), 另外一种是消息传递(actor模型, go语言的channel), 在java并发模型中, 共享资源在可编辑时存在线程安全的问题, 这也正是COW在java中的应用场景如果没有编辑, 就没有必要创建一个新的资源, 这个资源仍然可以共享. 如果需要修改资源就必须先copy, 这样可以显著的减少资源的消耗.

COW应用场景

CopyOnWriteArrayList

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();
        }
    }
    // 步骤一
    public boolean addIfAbsent(E e) {
        Object[] snapshot = getArray();
        return indexOf(e, snapshot, 0, snapshot.length) >= 0 ? false :
            addIfAbsent(e, snapshot);
    }
    // 步骤二
    private boolean addIfAbsent(E e, Object[] snapshot) {
            final ReentrantLock lock = this.lock;
            lock.lock();
            try {
                Object[] current = getArray();
                int len = current.length;
                if (snapshot != current) {
                    // Optimize for lost race to another addXXX operation
                    // 优化1
                    int common = Math.min(snapshot.length, len);
                    for (int i = 0; i < common; i++)
                        // 如果current[i] 和snapshot[i]相等则一定不是e, 进行短路
                        // 这么优化的原因推测是 != 比 equals 效率高
                        if (current[i] != snapshot[i] && eq(e, current[i]))
                            return false;
                    // 判断current后半段不存在e
                    if (indexOf(e, current, common, len) >= 0)
                            return false;
                }
                Object[] newElements = Arrays.copyOf(current, len + 1);
                newElements[len] = e;
                setArray(newElements);
                return true;
            } finally {
                lock.unlock();
            }
        }

CopyOnWriteArrayList优缺点和应用场景

上一篇 下一篇

猜你喜欢

热点阅读