Java. util. concurrent package source code reading 08 CopyOnWriteArrayList and CopyOnWriteArraySet, copyonwrite
CopyOnWriteArrayList and CopyOnWriteArraySet are similar in terms of data structure types. They all use arrays to save the data structure of a group of data. The difference is simply the difference between List and set. So here we will first discuss CopyOnWriteArrayList, and then talk about CopyOnWriteArraySet.
Here we focus on CopyOnWrite, which is literally easy to understand. During each write operation, we copy the array of stored data, modify the copy, and overwrite the original array. Therefore, this data structure must be applicable to read operations that account for the vast majority (rarely write operations) and have a small amount of data (such as blacklists ).
So let's take a look at the implementation of CopyOnWriteArrayList. There must be a volatile array, and a lock is used for write operations (no lock is required during read operations ).
/** The lock protecting all mutators */ transient final ReentrantLock lock = new ReentrantLock(); /** The array, accessed only via getArray/setArray. */ private volatile transient Object[] array;
Use Arrays. copyOf to copy the entire array, and use System. arraycopy to partially copy the array. The following uses the add method as an example:
public void add(int index, E element) { final ReentrantLock lock = this.lock; lock.lock(); try { Object[] elements = getArray(); int len = elements.length; if (index > len || index < 0) throw new IndexOutOfBoundsException("Index: "+index+ ", Size: "+len); Object[] newElements; int numMoved = len - index; if (numMoved == 0) newElements = Arrays.copyOf(elements, len + 1); else { newElements = new Object[len + 1]; System.arraycopy(elements, 0, newElements, 0, index); System.arraycopy(elements, index, newElements, index + 1, numMoved); } newElements[index] = element; setArray(newElements); } finally { lock.unlock(); } }
You can see that if you add an element at the end, use Arrays. copyOf to create and copy the entire array. If you insert the element in the middle, use System. arraycopy to copy the element in two segments, and then insert the element. The setArray method overwrites the original array. The Code is as follows:
final void setArray(Object[] a) { array = a; }
Here is a brief introduction to CopyOnWriteArraySet. In fact, CopyOnWriteArraySet is a CopyOnWriteArrayList packaging class:
private final CopyOnWriteArrayList<E> al;
The difference is that because Set does not allow repeated elements, the add method of CopyOnWriteArraySet calls the addIfAbsent method of CopyOnWriteArrayList.
public boolean add(E e) { return al.addIfAbsent(e); }
Cannot CopyOnWriteArrayList be sorted by Collectionssort?
Why not? Does it mean that the demands cannot be sorted by Collections. sort? As far as I know, this can be sorted by Collections. sort.
How to convert ArrayList to CopyOnWriteArrayList
ArrayList list = new ArrayList ();
List. add ("1 ");
List. add ("2"); Object [] aa = list. toArray ();
CopyOnWriteArrayList cal = new CopyOnWriteArrayList (aa); converts an ArrayList into an array and constructs a CopyOnWriteArrayList object using an array.