Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CopyOnWriteArrayList #36

Open
diaosichengxuyuan opened this issue Aug 18, 2020 · 0 comments
Open

CopyOnWriteArrayList #36

diaosichengxuyuan opened this issue Aug 18, 2020 · 0 comments

Comments

@diaosichengxuyuan
Copy link
Owner

diaosichengxuyuan commented Aug 18, 2020

CopyOnWriteArrayList是线程安全的List,数据结构是数组,线程安全体现在每次修改会重新copy一份数据。

public class CopyOnWriteArrayList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
    private static final long serialVersionUID = 8673264195747942595L;

    /** The lock protecting all mutators */
    final transient ReentrantLock lock = new ReentrantLock();

    /** The array, accessed only via getArray/setArray. */
    private transient volatile Object[] array;

    public CopyOnWriteArrayList() {
        setArray(new Object[0]);
    }

    public E get(int index) {
        return get(getArray(), index);
    }

    //添加时,加锁,重新copy一份数组,用新数组覆盖原来的数组
    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();
        }
    }    

思考一下,为什么add时要重新copy一份数组,只加锁不行吗?如果只加锁不copy,那就相当于变成了ArrayList修改时加锁,读取时不加锁,假如有一个线程在for循环,另一个线程在修改,就会产生ConcurrentModificationException。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant