Member variables
//CopyOnWriteArrayList holds an internal reentrant lock for thread safety
final transient ReentrantLock lock = new ReentrantLock();
// The array is volatile, and therefore is read without locking
private transient volatile Object[] array;
Copy the code
A constructor
// Assign an empty array to the member variable array
public CopyOnWriteArrayList(a) {
setArray(new Object[0]);
}
final void setArray(Object[] a) {
array = a;
}
Copy the code
Common interface
The add method
public boolean add(E e) {
final ReentrantLock lock = this.lock;
/ / lock
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
// Copy the elements of the old array directly into the new array of length +1
Object[] newElements = Arrays.copyOf(elements, len + 1);
// Place the inserted element at the end of the new array
newElements[len] = e;
// Set array to point to the new array
setArray(newElements);
return true;
} finally {
// Release the lock in the finally block to ensure that the lock can be released in exceptional caseslock.unlock(); }}// Return array array
final Object[] getArray() {
return array;
}
Copy the code
Here’s where CopyOnWriteArrayList got its name: it copies the array at write time
As you can see, CopyOnWriteArrayList does not use the 1.5x space preallocation strategy found in ArrayList
The get method
public E get(int index) {
return get(getArray(), index);
}
// The following table is used to fetch and return elements from the array directly. Since the array is volatile, no lock is required to ensure thread-safe read operations
private E get(Object[] a, int index) {
return (E) a[index];
}
Copy the code
Size method and isEmpty method
// Return the length of the array without locking it
public int size(a) {
return getArray().length;
}
// Check whether size is 0
public boolean isEmpty(a) {
return size() == 0;
}
Copy the code