Today take a look at CopyOnWriteArrayList under the Concurrent package. As a class under the Concurrent package, it certainly solves some concurrency problems —— is completely biased towards improving read performance. CopyOnWriteArraySet relies on the implementation of the CopyOnWriteArrayList class, which is documented here.

The class definition

public class CopyOnWriteArrayList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable
Copy the code

You can see that it implements the List, RandomAccess, Cloneable, and Serializable interfaces.

  • List CopyOnWriteArrayList itself is a List and there’s nothing to say about that.
  • RandomAccess a randomly accessible tag with no methods (see the binarySearch method in the Collections class)
  • Cloneable Cloneable tag, no method
  • Java.io.Serializable

variable

Final TRANSIENT ReentrantLock lock = new ReentrantLock(); final TRANSIENT ReentrantLock(); private transient volatile Object[] array; Private static final sun.misc.Unsafe Unsafe; // Unsafe-to-hate classCopy the code
private static final long lockOffset; / / used to locate the object lock is held in memory location static {try {UNSAFE = sun. Misc. UNSAFE. GetUnsafe (); Class<? > k = CopyOnWriteArrayList.class; lockOffset = UNSAFE.objectFieldOffset (k.getDeclaredField("lock")); } catch (Exception e) { throw new Error(e); Unsafe. putObjectVolatile(this, lockOffset, new ReentrantLock()); unsafe. putObjectVolatile(this, lockOffset, new ReentrantLock()); }Copy the code

The inner class

Static final class COWIterator<E> implements ListIterator<E> private static class COWSubList<E> extends AbstractList<E> implements RandomAccess Private static class COWSubListIterator<E> implements ListIterator<E> // An iterator for COWSubListCopy the code

Comparison of accessor methods

public E get(int index) { return get(getArray(), index); } @SuppressWarnings("unchecked") private E get(Object[] a, int index) { return (E) a[index]; } public boolean add(E e) { final ReentrantLock lock = this.lock; lock.lock(); try { Object[] elements = getArray(); int len = elements.length; Object[] newElements = array.copyof (elements, len + 1); newElements[len] = e; setArray(newElements); return true; } finally { lock.unlock(); }}Copy the code

The sample selects a representative read-write method from CopyOnWriteArrayList. We can see that the read method is not locked, and the write method does not affect the read operation in the case of locking.

conclusion

CopyOnWriteArrayList The read operation has no lock, but the write operation has a lock. This is to support the scenario of more reading and less writing.