ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jdk8/java/util/concurrent/CopyOnWriteArrayList.java
Revision: 1.2
Committed: Tue Nov 15 23:14:35 2016 UTC (7 years, 6 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +161 -250 lines
Log Message:
sync with main

File Contents

# User Rev Content
1 jsr166 1.1 /*
2     * Written by Doug Lea with assistance from members of JCP JSR-166
3     * Expert Group. Adapted and released, under explicit permission,
4     * from JDK ArrayList.java which carries the following copyright:
5     *
6     * Copyright 1997 by Sun Microsystems, Inc.,
7     * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
8     * All rights reserved.
9     *
10     * This software is the confidential and proprietary information
11     * of Sun Microsystems, Inc. ("Confidential Information"). You
12     * shall not disclose such Confidential Information and shall use
13     * it only in accordance with the terms of the license agreement
14     * you entered into with Sun.
15     */
16    
17     package java.util.concurrent;
18    
19 jsr166 1.2 import java.lang.reflect.Field;
20 jsr166 1.1 import java.util.AbstractList;
21     import java.util.Arrays;
22     import java.util.Collection;
23     import java.util.Comparator;
24     import java.util.ConcurrentModificationException;
25     import java.util.Iterator;
26     import java.util.List;
27     import java.util.ListIterator;
28     import java.util.NoSuchElementException;
29     import java.util.Objects;
30     import java.util.RandomAccess;
31     import java.util.Spliterator;
32     import java.util.Spliterators;
33     import java.util.function.Consumer;
34     import java.util.function.Predicate;
35     import java.util.function.UnaryOperator;
36    
37     /**
38     * A thread-safe variant of {@link java.util.ArrayList} in which all mutative
39     * operations ({@code add}, {@code set}, and so on) are implemented by
40     * making a fresh copy of the underlying array.
41     *
42     * <p>This is ordinarily too costly, but may be <em>more</em> efficient
43     * than alternatives when traversal operations vastly outnumber
44     * mutations, and is useful when you cannot or don't want to
45     * synchronize traversals, yet need to preclude interference among
46     * concurrent threads. The "snapshot" style iterator method uses a
47     * reference to the state of the array at the point that the iterator
48     * was created. This array never changes during the lifetime of the
49     * iterator, so interference is impossible and the iterator is
50     * guaranteed not to throw {@code ConcurrentModificationException}.
51     * The iterator will not reflect additions, removals, or changes to
52     * the list since the iterator was created. Element-changing
53     * operations on iterators themselves ({@code remove}, {@code set}, and
54     * {@code add}) are not supported. These methods throw
55     * {@code UnsupportedOperationException}.
56     *
57     * <p>All elements are permitted, including {@code null}.
58     *
59     * <p>Memory consistency effects: As with other concurrent
60     * collections, actions in a thread prior to placing an object into a
61     * {@code CopyOnWriteArrayList}
62     * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
63     * actions subsequent to the access or removal of that element from
64     * the {@code CopyOnWriteArrayList} in another thread.
65     *
66     * <p>This class is a member of the
67     * <a href="{@docRoot}/../technotes/guides/collections/index.html">
68     * Java Collections Framework</a>.
69     *
70     * @since 1.5
71     * @author Doug Lea
72     * @param <E> the type of elements held in this list
73     */
74     public class CopyOnWriteArrayList<E>
75     implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
76     private static final long serialVersionUID = 8673264195747942595L;
77    
78     /**
79     * The lock protecting all mutators. (We have a mild preference
80     * for builtin monitors over ReentrantLock when either will do.)
81     */
82     final transient Object lock = new Object();
83    
84     /** The array, accessed only via getArray/setArray. */
85     private transient volatile Object[] array;
86    
87     /**
88     * Gets the array. Non-private so as to also be accessible
89     * from CopyOnWriteArraySet class.
90     */
91     final Object[] getArray() {
92     return array;
93     }
94    
95     /**
96     * Sets the array.
97     */
98     final void setArray(Object[] a) {
99     array = a;
100     }
101    
102     /**
103     * Creates an empty list.
104     */
105     public CopyOnWriteArrayList() {
106     setArray(new Object[0]);
107     }
108    
109     /**
110     * Creates a list containing the elements of the specified
111     * collection, in the order they are returned by the collection's
112     * iterator.
113     *
114     * @param c the collection of initially held elements
115     * @throws NullPointerException if the specified collection is null
116     */
117     public CopyOnWriteArrayList(Collection<? extends E> c) {
118     Object[] elements;
119     if (c.getClass() == CopyOnWriteArrayList.class)
120     elements = ((CopyOnWriteArrayList<?>)c).getArray();
121     else {
122     elements = c.toArray();
123     // defend against c.toArray (incorrectly) not returning Object[]
124     // (see e.g. https://bugs.openjdk.java.net/browse/JDK-6260652)
125     if (elements.getClass() != Object[].class)
126     elements = Arrays.copyOf(elements, elements.length, Object[].class);
127     }
128     setArray(elements);
129     }
130    
131     /**
132     * Creates a list holding a copy of the given array.
133     *
134     * @param toCopyIn the array (a copy of this array is used as the
135     * internal array)
136     * @throws NullPointerException if the specified array is null
137     */
138     public CopyOnWriteArrayList(E[] toCopyIn) {
139     setArray(Arrays.copyOf(toCopyIn, toCopyIn.length, Object[].class));
140     }
141    
142     /**
143     * Returns the number of elements in this list.
144     *
145     * @return the number of elements in this list
146     */
147     public int size() {
148     return getArray().length;
149     }
150    
151     /**
152     * Returns {@code true} if this list contains no elements.
153     *
154     * @return {@code true} if this list contains no elements
155     */
156     public boolean isEmpty() {
157     return size() == 0;
158     }
159    
160     /**
161     * static version of indexOf, to allow repeated calls without
162     * needing to re-acquire array each time.
163     * @param o element to search for
164     * @param elements the array
165     * @param index first index to search
166     * @param fence one past last index to search
167     * @return index of element, or -1 if absent
168     */
169     private static int indexOf(Object o, Object[] elements,
170     int index, int fence) {
171     if (o == null) {
172     for (int i = index; i < fence; i++)
173     if (elements[i] == null)
174     return i;
175     } else {
176     for (int i = index; i < fence; i++)
177     if (o.equals(elements[i]))
178     return i;
179     }
180     return -1;
181     }
182    
183     /**
184     * static version of lastIndexOf.
185     * @param o element to search for
186     * @param elements the array
187     * @param index first index to search
188     * @return index of element, or -1 if absent
189     */
190     private static int lastIndexOf(Object o, Object[] elements, int index) {
191     if (o == null) {
192     for (int i = index; i >= 0; i--)
193     if (elements[i] == null)
194     return i;
195     } else {
196     for (int i = index; i >= 0; i--)
197     if (o.equals(elements[i]))
198     return i;
199     }
200     return -1;
201     }
202    
203     /**
204     * Returns {@code true} if this list contains the specified element.
205     * More formally, returns {@code true} if and only if this list contains
206     * at least one element {@code e} such that {@code Objects.equals(o, e)}.
207     *
208     * @param o element whose presence in this list is to be tested
209     * @return {@code true} if this list contains the specified element
210     */
211     public boolean contains(Object o) {
212     Object[] elements = getArray();
213     return indexOf(o, elements, 0, elements.length) >= 0;
214     }
215    
216     /**
217     * {@inheritDoc}
218     */
219     public int indexOf(Object o) {
220     Object[] elements = getArray();
221     return indexOf(o, elements, 0, elements.length);
222     }
223    
224     /**
225     * Returns the index of the first occurrence of the specified element in
226     * this list, searching forwards from {@code index}, or returns -1 if
227     * the element is not found.
228     * More formally, returns the lowest index {@code i} such that
229     * {@code i >= index && Objects.equals(get(i), e)},
230     * or -1 if there is no such index.
231     *
232     * @param e element to search for
233     * @param index index to start searching from
234     * @return the index of the first occurrence of the element in
235     * this list at position {@code index} or later in the list;
236     * {@code -1} if the element is not found.
237     * @throws IndexOutOfBoundsException if the specified index is negative
238     */
239     public int indexOf(E e, int index) {
240     Object[] elements = getArray();
241     return indexOf(e, elements, index, elements.length);
242     }
243    
244     /**
245     * {@inheritDoc}
246     */
247     public int lastIndexOf(Object o) {
248     Object[] elements = getArray();
249     return lastIndexOf(o, elements, elements.length - 1);
250     }
251    
252     /**
253     * Returns the index of the last occurrence of the specified element in
254     * this list, searching backwards from {@code index}, or returns -1 if
255     * the element is not found.
256     * More formally, returns the highest index {@code i} such that
257     * {@code i <= index && Objects.equals(get(i), e)},
258     * or -1 if there is no such index.
259     *
260     * @param e element to search for
261     * @param index index to start searching backwards from
262     * @return the index of the last occurrence of the element at position
263     * less than or equal to {@code index} in this list;
264     * -1 if the element is not found.
265     * @throws IndexOutOfBoundsException if the specified index is greater
266     * than or equal to the current size of this list
267     */
268     public int lastIndexOf(E e, int index) {
269     Object[] elements = getArray();
270     return lastIndexOf(e, elements, index);
271     }
272    
273     /**
274     * Returns a shallow copy of this list. (The elements themselves
275     * are not copied.)
276     *
277     * @return a clone of this list
278     */
279     public Object clone() {
280     try {
281     @SuppressWarnings("unchecked")
282     CopyOnWriteArrayList<E> clone =
283     (CopyOnWriteArrayList<E>) super.clone();
284     clone.resetLock();
285     return clone;
286     } catch (CloneNotSupportedException e) {
287     // this shouldn't happen, since we are Cloneable
288     throw new InternalError();
289     }
290     }
291    
292     /**
293     * Returns an array containing all of the elements in this list
294     * in proper sequence (from first to last element).
295     *
296     * <p>The returned array will be "safe" in that no references to it are
297     * maintained by this list. (In other words, this method must allocate
298     * a new array). The caller is thus free to modify the returned array.
299     *
300     * <p>This method acts as bridge between array-based and collection-based
301     * APIs.
302     *
303     * @return an array containing all the elements in this list
304     */
305     public Object[] toArray() {
306     Object[] elements = getArray();
307     return Arrays.copyOf(elements, elements.length);
308     }
309    
310     /**
311     * Returns an array containing all of the elements in this list in
312     * proper sequence (from first to last element); the runtime type of
313     * the returned array is that of the specified array. If the list fits
314     * in the specified array, it is returned therein. Otherwise, a new
315     * array is allocated with the runtime type of the specified array and
316     * the size of this list.
317     *
318     * <p>If this list fits in the specified array with room to spare
319     * (i.e., the array has more elements than this list), the element in
320     * the array immediately following the end of the list is set to
321     * {@code null}. (This is useful in determining the length of this
322     * list <i>only</i> if the caller knows that this list does not contain
323     * any null elements.)
324     *
325     * <p>Like the {@link #toArray()} method, this method acts as bridge between
326     * array-based and collection-based APIs. Further, this method allows
327     * precise control over the runtime type of the output array, and may,
328     * under certain circumstances, be used to save allocation costs.
329     *
330     * <p>Suppose {@code x} is a list known to contain only strings.
331     * The following code can be used to dump the list into a newly
332     * allocated array of {@code String}:
333     *
334     * <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
335     *
336     * Note that {@code toArray(new Object[0])} is identical in function to
337     * {@code toArray()}.
338     *
339     * @param a the array into which the elements of the list are to
340     * be stored, if it is big enough; otherwise, a new array of the
341     * same runtime type is allocated for this purpose.
342     * @return an array containing all the elements in this list
343     * @throws ArrayStoreException if the runtime type of the specified array
344     * is not a supertype of the runtime type of every element in
345     * this list
346     * @throws NullPointerException if the specified array is null
347     */
348     @SuppressWarnings("unchecked")
349     public <T> T[] toArray(T[] a) {
350     Object[] elements = getArray();
351     int len = elements.length;
352     if (a.length < len)
353     return (T[]) Arrays.copyOf(elements, len, a.getClass());
354     else {
355     System.arraycopy(elements, 0, a, 0, len);
356     if (a.length > len)
357     a[len] = null;
358     return a;
359     }
360     }
361    
362     // Positional Access Operations
363    
364     @SuppressWarnings("unchecked")
365 jsr166 1.2 static <E> E elementAt(Object[] a, int index) {
366 jsr166 1.1 return (E) a[index];
367     }
368    
369     static String outOfBounds(int index, int size) {
370     return "Index: " + index + ", Size: " + size;
371     }
372    
373     /**
374     * {@inheritDoc}
375     *
376     * @throws IndexOutOfBoundsException {@inheritDoc}
377     */
378     public E get(int index) {
379 jsr166 1.2 return elementAt(getArray(), index);
380 jsr166 1.1 }
381    
382     /**
383     * Replaces the element at the specified position in this list with the
384     * specified element.
385     *
386     * @throws IndexOutOfBoundsException {@inheritDoc}
387     */
388     public E set(int index, E element) {
389     synchronized (lock) {
390     Object[] elements = getArray();
391 jsr166 1.2 E oldValue = elementAt(elements, index);
392 jsr166 1.1
393     if (oldValue != element) {
394     int len = elements.length;
395     Object[] newElements = Arrays.copyOf(elements, len);
396     newElements[index] = element;
397     setArray(newElements);
398     } else {
399     // Not quite a no-op; ensures volatile write semantics
400     setArray(elements);
401     }
402     return oldValue;
403     }
404     }
405    
406     /**
407     * Appends the specified element to the end of this list.
408     *
409     * @param e element to be appended to this list
410     * @return {@code true} (as specified by {@link Collection#add})
411     */
412     public boolean add(E e) {
413     synchronized (lock) {
414     Object[] elements = getArray();
415     int len = elements.length;
416     Object[] newElements = Arrays.copyOf(elements, len + 1);
417     newElements[len] = e;
418     setArray(newElements);
419     return true;
420     }
421     }
422    
423     /**
424     * Inserts the specified element at the specified position in this
425     * list. Shifts the element currently at that position (if any) and
426     * any subsequent elements to the right (adds one to their indices).
427     *
428     * @throws IndexOutOfBoundsException {@inheritDoc}
429     */
430     public void add(int index, E element) {
431     synchronized (lock) {
432     Object[] elements = getArray();
433     int len = elements.length;
434     if (index > len || index < 0)
435     throw new IndexOutOfBoundsException(outOfBounds(index, len));
436     Object[] newElements;
437     int numMoved = len - index;
438     if (numMoved == 0)
439     newElements = Arrays.copyOf(elements, len + 1);
440     else {
441     newElements = new Object[len + 1];
442     System.arraycopy(elements, 0, newElements, 0, index);
443     System.arraycopy(elements, index, newElements, index + 1,
444     numMoved);
445     }
446     newElements[index] = element;
447     setArray(newElements);
448     }
449     }
450    
451     /**
452     * Removes the element at the specified position in this list.
453     * Shifts any subsequent elements to the left (subtracts one from their
454     * indices). Returns the element that was removed from the list.
455     *
456     * @throws IndexOutOfBoundsException {@inheritDoc}
457     */
458     public E remove(int index) {
459     synchronized (lock) {
460     Object[] elements = getArray();
461     int len = elements.length;
462 jsr166 1.2 E oldValue = elementAt(elements, index);
463 jsr166 1.1 int numMoved = len - index - 1;
464     if (numMoved == 0)
465     setArray(Arrays.copyOf(elements, len - 1));
466     else {
467     Object[] newElements = new Object[len - 1];
468     System.arraycopy(elements, 0, newElements, 0, index);
469     System.arraycopy(elements, index + 1, newElements, index,
470     numMoved);
471     setArray(newElements);
472     }
473     return oldValue;
474     }
475     }
476    
477     /**
478     * Removes the first occurrence of the specified element from this list,
479     * if it is present. If this list does not contain the element, it is
480     * unchanged. More formally, removes the element with the lowest index
481     * {@code i} such that {@code Objects.equals(o, get(i))}
482     * (if such an element exists). Returns {@code true} if this list
483     * contained the specified element (or equivalently, if this list
484     * changed as a result of the call).
485     *
486     * @param o element to be removed from this list, if present
487     * @return {@code true} if this list contained the specified element
488     */
489     public boolean remove(Object o) {
490     Object[] snapshot = getArray();
491     int index = indexOf(o, snapshot, 0, snapshot.length);
492     return (index < 0) ? false : remove(o, snapshot, index);
493     }
494    
495     /**
496     * A version of remove(Object) using the strong hint that given
497     * recent snapshot contains o at the given index.
498     */
499     private boolean remove(Object o, Object[] snapshot, int index) {
500     synchronized (lock) {
501     Object[] current = getArray();
502     int len = current.length;
503     if (snapshot != current) findIndex: {
504     int prefix = Math.min(index, len);
505     for (int i = 0; i < prefix; i++) {
506     if (current[i] != snapshot[i]
507     && Objects.equals(o, current[i])) {
508     index = i;
509     break findIndex;
510     }
511     }
512     if (index >= len)
513     return false;
514     if (current[index] == o)
515     break findIndex;
516     index = indexOf(o, current, index, len);
517     if (index < 0)
518     return false;
519     }
520     Object[] newElements = new Object[len - 1];
521     System.arraycopy(current, 0, newElements, 0, index);
522     System.arraycopy(current, index + 1,
523     newElements, index,
524     len - index - 1);
525     setArray(newElements);
526     return true;
527     }
528     }
529    
530     /**
531     * Removes from this list all of the elements whose index is between
532     * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.
533     * Shifts any succeeding elements to the left (reduces their index).
534     * This call shortens the list by {@code (toIndex - fromIndex)} elements.
535     * (If {@code toIndex==fromIndex}, this operation has no effect.)
536     *
537     * @param fromIndex index of first element to be removed
538     * @param toIndex index after last element to be removed
539     * @throws IndexOutOfBoundsException if fromIndex or toIndex out of range
540     * ({@code fromIndex < 0 || toIndex > size() || toIndex < fromIndex})
541     */
542     void removeRange(int fromIndex, int toIndex) {
543     synchronized (lock) {
544     Object[] elements = getArray();
545     int len = elements.length;
546    
547     if (fromIndex < 0 || toIndex > len || toIndex < fromIndex)
548     throw new IndexOutOfBoundsException();
549     int newlen = len - (toIndex - fromIndex);
550     int numMoved = len - toIndex;
551     if (numMoved == 0)
552     setArray(Arrays.copyOf(elements, newlen));
553     else {
554     Object[] newElements = new Object[newlen];
555     System.arraycopy(elements, 0, newElements, 0, fromIndex);
556     System.arraycopy(elements, toIndex, newElements,
557     fromIndex, numMoved);
558     setArray(newElements);
559     }
560     }
561     }
562    
563     /**
564     * Appends the element, if not present.
565     *
566     * @param e element to be added to this list, if absent
567     * @return {@code true} if the element was added
568     */
569     public boolean addIfAbsent(E e) {
570     Object[] snapshot = getArray();
571     return indexOf(e, snapshot, 0, snapshot.length) >= 0 ? false :
572     addIfAbsent(e, snapshot);
573     }
574    
575     /**
576     * A version of addIfAbsent using the strong hint that given
577     * recent snapshot does not contain e.
578     */
579     private boolean addIfAbsent(E e, Object[] snapshot) {
580     synchronized (lock) {
581     Object[] current = getArray();
582     int len = current.length;
583     if (snapshot != current) {
584     // Optimize for lost race to another addXXX operation
585     int common = Math.min(snapshot.length, len);
586     for (int i = 0; i < common; i++)
587     if (current[i] != snapshot[i]
588     && Objects.equals(e, current[i]))
589     return false;
590     if (indexOf(e, current, common, len) >= 0)
591     return false;
592     }
593     Object[] newElements = Arrays.copyOf(current, len + 1);
594     newElements[len] = e;
595     setArray(newElements);
596     return true;
597     }
598     }
599    
600     /**
601     * Returns {@code true} if this list contains all of the elements of the
602     * specified collection.
603     *
604     * @param c collection to be checked for containment in this list
605     * @return {@code true} if this list contains all of the elements of the
606     * specified collection
607     * @throws NullPointerException if the specified collection is null
608     * @see #contains(Object)
609     */
610     public boolean containsAll(Collection<?> c) {
611     Object[] elements = getArray();
612     int len = elements.length;
613     for (Object e : c) {
614     if (indexOf(e, elements, 0, len) < 0)
615     return false;
616     }
617     return true;
618     }
619    
620     /**
621     * Removes from this list all of its elements that are contained in
622     * the specified collection. This is a particularly expensive operation
623     * in this class because of the need for an internal temporary array.
624     *
625     * @param c collection containing elements to be removed from this list
626     * @return {@code true} if this list changed as a result of the call
627     * @throws ClassCastException if the class of an element of this list
628     * is incompatible with the specified collection
629     * (<a href="{@docRoot}/../api/java/util/Collection.html#optional-restrictions">optional</a>)
630     * @throws NullPointerException if this list contains a null element and the
631     * specified collection does not permit null elements
632     * (<a href="{@docRoot}/../api/java/util/Collection.html#optional-restrictions">optional</a>),
633     * or if the specified collection is null
634     * @see #remove(Object)
635     */
636     public boolean removeAll(Collection<?> c) {
637 jsr166 1.2 Objects.requireNonNull(c);
638     return bulkRemove(e -> c.contains(e));
639 jsr166 1.1 }
640    
641     /**
642     * Retains only the elements in this list that are contained in the
643     * specified collection. In other words, removes from this list all of
644     * its elements that are not contained in the specified collection.
645     *
646     * @param c collection containing elements to be retained in this list
647     * @return {@code true} if this list changed as a result of the call
648     * @throws ClassCastException if the class of an element of this list
649     * is incompatible with the specified collection
650     * (<a href="{@docRoot}/../api/java/util/Collection.html#optional-restrictions">optional</a>)
651     * @throws NullPointerException if this list contains a null element and the
652     * specified collection does not permit null elements
653     * (<a href="{@docRoot}/../api/java/util/Collection.html#optional-restrictions">optional</a>),
654     * or if the specified collection is null
655     * @see #remove(Object)
656     */
657     public boolean retainAll(Collection<?> c) {
658 jsr166 1.2 Objects.requireNonNull(c);
659     return bulkRemove(e -> !c.contains(e));
660 jsr166 1.1 }
661    
662     /**
663     * Appends all of the elements in the specified collection that
664     * are not already contained in this list, to the end of
665     * this list, in the order that they are returned by the
666     * specified collection's iterator.
667     *
668     * @param c collection containing elements to be added to this list
669     * @return the number of elements added
670     * @throws NullPointerException if the specified collection is null
671     * @see #addIfAbsent(Object)
672     */
673     public int addAllAbsent(Collection<? extends E> c) {
674     Object[] cs = c.toArray();
675     if (cs.length == 0)
676     return 0;
677     synchronized (lock) {
678     Object[] elements = getArray();
679     int len = elements.length;
680     int added = 0;
681     // uniquify and compact elements in cs
682     for (int i = 0; i < cs.length; ++i) {
683     Object e = cs[i];
684     if (indexOf(e, elements, 0, len) < 0 &&
685     indexOf(e, cs, 0, added) < 0)
686     cs[added++] = e;
687     }
688     if (added > 0) {
689     Object[] newElements = Arrays.copyOf(elements, len + added);
690     System.arraycopy(cs, 0, newElements, len, added);
691     setArray(newElements);
692     }
693     return added;
694     }
695     }
696    
697     /**
698     * Removes all of the elements from this list.
699     * The list will be empty after this call returns.
700     */
701     public void clear() {
702     synchronized (lock) {
703     setArray(new Object[0]);
704     }
705     }
706    
707     /**
708     * Appends all of the elements in the specified collection to the end
709     * of this list, in the order that they are returned by the specified
710     * collection's iterator.
711     *
712     * @param c collection containing elements to be added to this list
713     * @return {@code true} if this list changed as a result of the call
714     * @throws NullPointerException if the specified collection is null
715     * @see #add(Object)
716     */
717     public boolean addAll(Collection<? extends E> c) {
718     Object[] cs = (c.getClass() == CopyOnWriteArrayList.class) ?
719     ((CopyOnWriteArrayList<?>)c).getArray() : c.toArray();
720     if (cs.length == 0)
721     return false;
722     synchronized (lock) {
723     Object[] elements = getArray();
724     int len = elements.length;
725     if (len == 0 && cs.getClass() == Object[].class)
726     setArray(cs);
727     else {
728     Object[] newElements = Arrays.copyOf(elements, len + cs.length);
729     System.arraycopy(cs, 0, newElements, len, cs.length);
730     setArray(newElements);
731     }
732     return true;
733     }
734     }
735    
736     /**
737     * Inserts all of the elements in the specified collection into this
738     * list, starting at the specified position. Shifts the element
739     * currently at that position (if any) and any subsequent elements to
740     * the right (increases their indices). The new elements will appear
741     * in this list in the order that they are returned by the
742     * specified collection's iterator.
743     *
744     * @param index index at which to insert the first element
745     * from the specified collection
746     * @param c collection containing elements to be added to this list
747     * @return {@code true} if this list changed as a result of the call
748     * @throws IndexOutOfBoundsException {@inheritDoc}
749     * @throws NullPointerException if the specified collection is null
750     * @see #add(int,Object)
751     */
752     public boolean addAll(int index, Collection<? extends E> c) {
753     Object[] cs = c.toArray();
754     synchronized (lock) {
755     Object[] elements = getArray();
756     int len = elements.length;
757     if (index > len || index < 0)
758     throw new IndexOutOfBoundsException(outOfBounds(index, len));
759     if (cs.length == 0)
760     return false;
761     int numMoved = len - index;
762     Object[] newElements;
763     if (numMoved == 0)
764     newElements = Arrays.copyOf(elements, len + cs.length);
765     else {
766     newElements = new Object[len + cs.length];
767     System.arraycopy(elements, 0, newElements, 0, index);
768     System.arraycopy(elements, index,
769     newElements, index + cs.length,
770     numMoved);
771     }
772     System.arraycopy(cs, 0, newElements, index, cs.length);
773     setArray(newElements);
774     return true;
775     }
776     }
777    
778     public void forEach(Consumer<? super E> action) {
779     if (action == null) throw new NullPointerException();
780     for (Object x : getArray()) {
781     @SuppressWarnings("unchecked") E e = (E) x;
782     action.accept(e);
783     }
784     }
785    
786     public boolean removeIf(Predicate<? super E> filter) {
787     if (filter == null) throw new NullPointerException();
788 jsr166 1.2 return bulkRemove(filter);
789     }
790    
791     // A tiny bit set implementation
792    
793     private static long[] nBits(int n) {
794     return new long[((n - 1) >> 6) + 1];
795     }
796     private static void setBit(long[] bits, int i) {
797     bits[i >> 6] |= 1L << i;
798     }
799     private static boolean isClear(long[] bits, int i) {
800     return (bits[i >> 6] & (1L << i)) == 0;
801     }
802    
803     private boolean bulkRemove(Predicate<? super E> filter) {
804 jsr166 1.1 synchronized (lock) {
805 jsr166 1.2 return bulkRemove(filter, 0, getArray().length);
806     }
807     }
808    
809     boolean bulkRemove(Predicate<? super E> filter, int i, int end) {
810     // assert Thread.holdsLock(lock);
811     final Object[] es = getArray();
812     // Optimize for initial run of survivors
813     for (; i < end && !filter.test(elementAt(es, i)); i++)
814     ;
815     if (i < end) {
816     final int beg = i;
817     final long[] deathRow = nBits(end - beg);
818     int deleted = 1;
819     deathRow[0] = 1L; // set bit 0
820     for (i = beg + 1; i < end; i++)
821     if (filter.test(elementAt(es, i))) {
822     setBit(deathRow, i - beg);
823     deleted++;
824 jsr166 1.1 }
825 jsr166 1.2 // Did filter reentrantly modify the list?
826     if (es != getArray())
827     throw new ConcurrentModificationException();
828     final Object[] newElts = Arrays.copyOf(es, es.length - deleted);
829     int w = beg;
830     for (i = beg; i < end; i++)
831     if (isClear(deathRow, i - beg))
832     newElts[w++] = es[i];
833     System.arraycopy(es, i, newElts, w, es.length - i);
834     setArray(newElts);
835     return true;
836     } else {
837     if (es != getArray())
838     throw new ConcurrentModificationException();
839     return false;
840 jsr166 1.1 }
841     }
842    
843     public void replaceAll(UnaryOperator<E> operator) {
844     if (operator == null) throw new NullPointerException();
845     synchronized (lock) {
846 jsr166 1.2 replaceAll(operator, 0, getArray().length);
847 jsr166 1.1 }
848     }
849    
850 jsr166 1.2 void replaceAll(UnaryOperator<E> operator, int i, int end) {
851     // assert Thread.holdsLock(lock);
852     final Object[] es = getArray().clone();
853     for (; i < end; i++)
854     es[i] = operator.apply(elementAt(es, i));
855     setArray(es);
856     }
857    
858 jsr166 1.1 public void sort(Comparator<? super E> c) {
859     synchronized (lock) {
860 jsr166 1.2 sort(c, 0, getArray().length);
861 jsr166 1.1 }
862     }
863    
864 jsr166 1.2 @SuppressWarnings("unchecked")
865     void sort(Comparator<? super E> c, int i, int end) {
866     // assert Thread.holdsLock(lock);
867     final Object[] es = getArray().clone();
868     Arrays.sort(es, i, end, (Comparator<Object>)c);
869     setArray(es);
870     }
871    
872 jsr166 1.1 /**
873     * Saves this list to a stream (that is, serializes it).
874     *
875     * @param s the stream
876     * @throws java.io.IOException if an I/O error occurs
877     * @serialData The length of the array backing the list is emitted
878     * (int), followed by all of its elements (each an Object)
879     * in the proper order.
880     */
881     private void writeObject(java.io.ObjectOutputStream s)
882     throws java.io.IOException {
883    
884     s.defaultWriteObject();
885    
886     Object[] elements = getArray();
887     // Write out array length
888     s.writeInt(elements.length);
889    
890     // Write out all elements in the proper order.
891     for (Object element : elements)
892     s.writeObject(element);
893     }
894    
895     /**
896     * Reconstitutes this list from a stream (that is, deserializes it).
897     * @param s the stream
898     * @throws ClassNotFoundException if the class of a serialized object
899     * could not be found
900     * @throws java.io.IOException if an I/O error occurs
901     */
902     private void readObject(java.io.ObjectInputStream s)
903     throws java.io.IOException, ClassNotFoundException {
904    
905     s.defaultReadObject();
906    
907     // bind to new lock
908     resetLock();
909    
910     // Read in array length and allocate array
911     int len = s.readInt();
912     Object[] elements = new Object[len];
913    
914     // Read in all elements in the proper order.
915     for (int i = 0; i < len; i++)
916     elements[i] = s.readObject();
917     setArray(elements);
918     }
919    
920     /**
921     * Returns a string representation of this list. The string
922     * representation consists of the string representations of the list's
923     * elements in the order they are returned by its iterator, enclosed in
924     * square brackets ({@code "[]"}). Adjacent elements are separated by
925     * the characters {@code ", "} (comma and space). Elements are
926     * converted to strings as by {@link String#valueOf(Object)}.
927     *
928     * @return a string representation of this list
929     */
930     public String toString() {
931     return Arrays.toString(getArray());
932     }
933    
934     /**
935     * Compares the specified object with this list for equality.
936     * Returns {@code true} if the specified object is the same object
937     * as this object, or if it is also a {@link List} and the sequence
938     * of elements returned by an {@linkplain List#iterator() iterator}
939     * over the specified list is the same as the sequence returned by
940     * an iterator over this list. The two sequences are considered to
941     * be the same if they have the same length and corresponding
942     * elements at the same position in the sequence are <em>equal</em>.
943     * Two elements {@code e1} and {@code e2} are considered
944     * <em>equal</em> if {@code Objects.equals(e1, e2)}.
945     *
946     * @param o the object to be compared for equality with this list
947     * @return {@code true} if the specified object is equal to this list
948     */
949     public boolean equals(Object o) {
950     if (o == this)
951     return true;
952     if (!(o instanceof List))
953     return false;
954    
955     List<?> list = (List<?>)o;
956     Iterator<?> it = list.iterator();
957     Object[] elements = getArray();
958     for (int i = 0, len = elements.length; i < len; i++)
959     if (!it.hasNext() || !Objects.equals(elements[i], it.next()))
960     return false;
961     if (it.hasNext())
962     return false;
963     return true;
964     }
965    
966     /**
967     * Returns the hash code value for this list.
968     *
969     * <p>This implementation uses the definition in {@link List#hashCode}.
970     *
971     * @return the hash code value for this list
972     */
973     public int hashCode() {
974     int hashCode = 1;
975     for (Object x : getArray())
976     hashCode = 31 * hashCode + (x == null ? 0 : x.hashCode());
977     return hashCode;
978     }
979    
980     /**
981     * Returns an iterator over the elements in this list in proper sequence.
982     *
983     * <p>The returned iterator provides a snapshot of the state of the list
984     * when the iterator was constructed. No synchronization is needed while
985     * traversing the iterator. The iterator does <em>NOT</em> support the
986     * {@code remove} method.
987     *
988     * @return an iterator over the elements in this list in proper sequence
989     */
990     public Iterator<E> iterator() {
991     return new COWIterator<E>(getArray(), 0);
992     }
993    
994     /**
995     * {@inheritDoc}
996     *
997     * <p>The returned iterator provides a snapshot of the state of the list
998     * when the iterator was constructed. No synchronization is needed while
999     * traversing the iterator. The iterator does <em>NOT</em> support the
1000     * {@code remove}, {@code set} or {@code add} methods.
1001     */
1002     public ListIterator<E> listIterator() {
1003     return new COWIterator<E>(getArray(), 0);
1004     }
1005    
1006     /**
1007     * {@inheritDoc}
1008     *
1009     * <p>The returned iterator provides a snapshot of the state of the list
1010     * when the iterator was constructed. No synchronization is needed while
1011     * traversing the iterator. The iterator does <em>NOT</em> support the
1012     * {@code remove}, {@code set} or {@code add} methods.
1013     *
1014     * @throws IndexOutOfBoundsException {@inheritDoc}
1015     */
1016     public ListIterator<E> listIterator(int index) {
1017     Object[] elements = getArray();
1018     int len = elements.length;
1019     if (index < 0 || index > len)
1020     throw new IndexOutOfBoundsException(outOfBounds(index, len));
1021    
1022     return new COWIterator<E>(elements, index);
1023     }
1024    
1025     /**
1026     * Returns a {@link Spliterator} over the elements in this list.
1027     *
1028     * <p>The {@code Spliterator} reports {@link Spliterator#IMMUTABLE},
1029     * {@link Spliterator#ORDERED}, {@link Spliterator#SIZED}, and
1030     * {@link Spliterator#SUBSIZED}.
1031     *
1032     * <p>The spliterator provides a snapshot of the state of the list
1033     * when the spliterator was constructed. No synchronization is needed while
1034     * operating on the spliterator.
1035     *
1036     * @return a {@code Spliterator} over the elements in this list
1037     * @since 1.8
1038     */
1039     public Spliterator<E> spliterator() {
1040     return Spliterators.spliterator
1041     (getArray(), Spliterator.IMMUTABLE | Spliterator.ORDERED);
1042     }
1043    
1044     static final class COWIterator<E> implements ListIterator<E> {
1045     /** Snapshot of the array */
1046     private final Object[] snapshot;
1047     /** Index of element to be returned by subsequent call to next. */
1048     private int cursor;
1049    
1050     COWIterator(Object[] elements, int initialCursor) {
1051     cursor = initialCursor;
1052     snapshot = elements;
1053     }
1054    
1055     public boolean hasNext() {
1056     return cursor < snapshot.length;
1057     }
1058    
1059     public boolean hasPrevious() {
1060     return cursor > 0;
1061     }
1062    
1063     @SuppressWarnings("unchecked")
1064     public E next() {
1065     if (! hasNext())
1066     throw new NoSuchElementException();
1067     return (E) snapshot[cursor++];
1068     }
1069    
1070     @SuppressWarnings("unchecked")
1071     public E previous() {
1072     if (! hasPrevious())
1073     throw new NoSuchElementException();
1074     return (E) snapshot[--cursor];
1075     }
1076    
1077     public int nextIndex() {
1078     return cursor;
1079     }
1080    
1081     public int previousIndex() {
1082     return cursor-1;
1083     }
1084    
1085     /**
1086     * Not supported. Always throws UnsupportedOperationException.
1087     * @throws UnsupportedOperationException always; {@code remove}
1088     * is not supported by this iterator.
1089     */
1090     public void remove() {
1091     throw new UnsupportedOperationException();
1092     }
1093    
1094     /**
1095     * Not supported. Always throws UnsupportedOperationException.
1096     * @throws UnsupportedOperationException always; {@code set}
1097     * is not supported by this iterator.
1098     */
1099     public void set(E e) {
1100     throw new UnsupportedOperationException();
1101     }
1102    
1103     /**
1104     * Not supported. Always throws UnsupportedOperationException.
1105     * @throws UnsupportedOperationException always; {@code add}
1106     * is not supported by this iterator.
1107     */
1108     public void add(E e) {
1109     throw new UnsupportedOperationException();
1110     }
1111    
1112     @Override
1113     @SuppressWarnings("unchecked")
1114     public void forEachRemaining(Consumer<? super E> action) {
1115     Objects.requireNonNull(action);
1116     final int size = snapshot.length;
1117     for (int i = cursor; i < size; i++) {
1118     action.accept((E) snapshot[i]);
1119     }
1120     cursor = size;
1121     }
1122     }
1123    
1124     /**
1125     * Returns a view of the portion of this list between
1126     * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.
1127     * The returned list is backed by this list, so changes in the
1128     * returned list are reflected in this list.
1129     *
1130     * <p>The semantics of the list returned by this method become
1131     * undefined if the backing list (i.e., this list) is modified in
1132     * any way other than via the returned list.
1133     *
1134     * @param fromIndex low endpoint (inclusive) of the subList
1135     * @param toIndex high endpoint (exclusive) of the subList
1136     * @return a view of the specified range within this list
1137     * @throws IndexOutOfBoundsException {@inheritDoc}
1138     */
1139     public List<E> subList(int fromIndex, int toIndex) {
1140     synchronized (lock) {
1141     Object[] elements = getArray();
1142     int len = elements.length;
1143     if (fromIndex < 0 || toIndex > len || fromIndex > toIndex)
1144     throw new IndexOutOfBoundsException();
1145     return new COWSubList<E>(this, fromIndex, toIndex);
1146     }
1147     }
1148    
1149     /**
1150     * Sublist for CopyOnWriteArrayList.
1151     */
1152     private static class COWSubList<E>
1153     extends AbstractList<E>
1154     implements RandomAccess
1155     {
1156     private final CopyOnWriteArrayList<E> l;
1157     private final int offset;
1158     private int size;
1159     private Object[] expectedArray;
1160    
1161     // only call this holding l's lock
1162     COWSubList(CopyOnWriteArrayList<E> list,
1163     int fromIndex, int toIndex) {
1164     // assert Thread.holdsLock(list.lock);
1165     l = list;
1166     expectedArray = l.getArray();
1167     offset = fromIndex;
1168     size = toIndex - fromIndex;
1169     }
1170    
1171     // only call this holding l's lock
1172     private void checkForComodification() {
1173     // assert Thread.holdsLock(l.lock);
1174     if (l.getArray() != expectedArray)
1175     throw new ConcurrentModificationException();
1176     }
1177    
1178 jsr166 1.2 private Object[] getArrayChecked() {
1179     // assert Thread.holdsLock(l.lock);
1180     Object[] a = l.getArray();
1181     if (a != expectedArray)
1182     throw new ConcurrentModificationException();
1183     return a;
1184     }
1185    
1186 jsr166 1.1 // only call this holding l's lock
1187     private void rangeCheck(int index) {
1188     // assert Thread.holdsLock(l.lock);
1189     if (index < 0 || index >= size)
1190     throw new IndexOutOfBoundsException(outOfBounds(index, size));
1191     }
1192    
1193     public E set(int index, E element) {
1194     synchronized (l.lock) {
1195     rangeCheck(index);
1196     checkForComodification();
1197 jsr166 1.2 E x = l.set(offset + index, element);
1198 jsr166 1.1 expectedArray = l.getArray();
1199     return x;
1200     }
1201     }
1202    
1203     public E get(int index) {
1204     synchronized (l.lock) {
1205     rangeCheck(index);
1206     checkForComodification();
1207 jsr166 1.2 return l.get(offset + index);
1208 jsr166 1.1 }
1209     }
1210    
1211     public int size() {
1212     synchronized (l.lock) {
1213     checkForComodification();
1214     return size;
1215     }
1216     }
1217    
1218 jsr166 1.2 public boolean add(E element) {
1219     synchronized (l.lock) {
1220     checkForComodification();
1221     l.add(offset + size, element);
1222     expectedArray = l.getArray();
1223     size++;
1224     }
1225     return true;
1226     }
1227    
1228 jsr166 1.1 public void add(int index, E element) {
1229     synchronized (l.lock) {
1230     checkForComodification();
1231     if (index < 0 || index > size)
1232     throw new IndexOutOfBoundsException
1233     (outOfBounds(index, size));
1234 jsr166 1.2 l.add(offset + index, element);
1235 jsr166 1.1 expectedArray = l.getArray();
1236     size++;
1237     }
1238     }
1239    
1240 jsr166 1.2 public boolean addAll(Collection<? extends E> c) {
1241     synchronized (l.lock) {
1242     final Object[] oldArray = getArrayChecked();
1243     boolean modified = l.addAll(offset + size, c);
1244     size += (expectedArray = l.getArray()).length - oldArray.length;
1245     return modified;
1246     }
1247     }
1248    
1249 jsr166 1.1 public void clear() {
1250     synchronized (l.lock) {
1251     checkForComodification();
1252 jsr166 1.2 l.removeRange(offset, offset + size);
1253 jsr166 1.1 expectedArray = l.getArray();
1254     size = 0;
1255     }
1256     }
1257    
1258     public E remove(int index) {
1259     synchronized (l.lock) {
1260     rangeCheck(index);
1261     checkForComodification();
1262 jsr166 1.2 E result = l.remove(offset + index);
1263 jsr166 1.1 expectedArray = l.getArray();
1264     size--;
1265     return result;
1266     }
1267     }
1268    
1269     public boolean remove(Object o) {
1270 jsr166 1.2 synchronized (l.lock) {
1271     checkForComodification();
1272     int index = indexOf(o);
1273     if (index == -1)
1274     return false;
1275     remove(index);
1276     return true;
1277     }
1278 jsr166 1.1 }
1279    
1280     public Iterator<E> iterator() {
1281     synchronized (l.lock) {
1282     checkForComodification();
1283     return new COWSubListIterator<E>(l, 0, offset, size);
1284     }
1285     }
1286    
1287     public ListIterator<E> listIterator(int index) {
1288     synchronized (l.lock) {
1289     checkForComodification();
1290     if (index < 0 || index > size)
1291     throw new IndexOutOfBoundsException
1292     (outOfBounds(index, size));
1293     return new COWSubListIterator<E>(l, index, offset, size);
1294     }
1295     }
1296    
1297     public List<E> subList(int fromIndex, int toIndex) {
1298     synchronized (l.lock) {
1299     checkForComodification();
1300     if (fromIndex < 0 || toIndex > size || fromIndex > toIndex)
1301     throw new IndexOutOfBoundsException();
1302     return new COWSubList<E>(l, fromIndex + offset,
1303     toIndex + offset);
1304     }
1305     }
1306    
1307     public void forEach(Consumer<? super E> action) {
1308     if (action == null) throw new NullPointerException();
1309 jsr166 1.2 int i, end; final Object[] es;
1310     synchronized (l.lock) {
1311     es = getArrayChecked();
1312     i = offset;
1313     end = i + size;
1314 jsr166 1.1 }
1315 jsr166 1.2 for (; i < end; i++)
1316     action.accept(elementAt(es, i));
1317 jsr166 1.1 }
1318    
1319     public void replaceAll(UnaryOperator<E> operator) {
1320     if (operator == null) throw new NullPointerException();
1321     synchronized (l.lock) {
1322 jsr166 1.2 checkForComodification();
1323     l.replaceAll(operator, offset, offset + size);
1324     expectedArray = l.getArray();
1325 jsr166 1.1 }
1326     }
1327    
1328     public void sort(Comparator<? super E> c) {
1329     synchronized (l.lock) {
1330 jsr166 1.2 checkForComodification();
1331     l.sort(c, offset, offset + size);
1332     expectedArray = l.getArray();
1333 jsr166 1.1 }
1334     }
1335    
1336     public boolean removeAll(Collection<?> c) {
1337 jsr166 1.2 Objects.requireNonNull(c);
1338     return bulkRemove(e -> c.contains(e));
1339 jsr166 1.1 }
1340    
1341     public boolean retainAll(Collection<?> c) {
1342 jsr166 1.2 Objects.requireNonNull(c);
1343     return bulkRemove(e -> !c.contains(e));
1344 jsr166 1.1 }
1345    
1346     public boolean removeIf(Predicate<? super E> filter) {
1347 jsr166 1.2 Objects.requireNonNull(filter);
1348     return bulkRemove(filter);
1349     }
1350    
1351     private boolean bulkRemove(Predicate<? super E> filter) {
1352 jsr166 1.1 synchronized (l.lock) {
1353 jsr166 1.2 final Object[] oldArray = getArrayChecked();
1354     boolean modified = l.bulkRemove(filter, offset, offset + size);
1355     size += (expectedArray = l.getArray()).length - oldArray.length;
1356     return modified;
1357 jsr166 1.1 }
1358     }
1359    
1360     public Spliterator<E> spliterator() {
1361 jsr166 1.2 synchronized (l.lock) {
1362     return Spliterators.spliterator(
1363     getArrayChecked(), offset, offset + size,
1364     Spliterator.IMMUTABLE | Spliterator.ORDERED);
1365     }
1366 jsr166 1.1 }
1367    
1368     }
1369    
1370     private static class COWSubListIterator<E> implements ListIterator<E> {
1371     private final ListIterator<E> it;
1372     private final int offset;
1373     private final int size;
1374    
1375     COWSubListIterator(List<E> l, int index, int offset, int size) {
1376     this.offset = offset;
1377     this.size = size;
1378     it = l.listIterator(index+offset);
1379     }
1380    
1381     public boolean hasNext() {
1382     return nextIndex() < size;
1383     }
1384    
1385     public E next() {
1386     if (hasNext())
1387     return it.next();
1388     else
1389     throw new NoSuchElementException();
1390     }
1391    
1392     public boolean hasPrevious() {
1393     return previousIndex() >= 0;
1394     }
1395    
1396     public E previous() {
1397     if (hasPrevious())
1398     return it.previous();
1399     else
1400     throw new NoSuchElementException();
1401     }
1402    
1403     public int nextIndex() {
1404     return it.nextIndex() - offset;
1405     }
1406    
1407     public int previousIndex() {
1408     return it.previousIndex() - offset;
1409     }
1410    
1411     public void remove() {
1412     throw new UnsupportedOperationException();
1413     }
1414    
1415     public void set(E e) {
1416     throw new UnsupportedOperationException();
1417     }
1418    
1419     public void add(E e) {
1420     throw new UnsupportedOperationException();
1421     }
1422    
1423     @Override
1424     @SuppressWarnings("unchecked")
1425     public void forEachRemaining(Consumer<? super E> action) {
1426     Objects.requireNonNull(action);
1427     while (nextIndex() < size) {
1428     action.accept(it.next());
1429     }
1430     }
1431     }
1432    
1433 jsr166 1.2 /** Initializes the lock; for use when deserializing or cloning. */
1434 jsr166 1.1 private void resetLock() {
1435 jsr166 1.2 Field lockField = java.security.AccessController.doPrivileged(
1436     (java.security.PrivilegedAction<Field>) () -> {
1437     try {
1438     Field f = CopyOnWriteArrayList.class
1439     .getDeclaredField("lock");
1440     f.setAccessible(true);
1441     return f;
1442     } catch (ReflectiveOperationException e) {
1443     throw new Error(e);
1444     }});
1445 jsr166 1.1 try {
1446 jsr166 1.2 lockField.set(this, new Object());
1447     } catch (IllegalAccessException e) {
1448 jsr166 1.1 throw new Error(e);
1449     }
1450     }
1451     }