ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/CopyOnWriteArrayList.java
Revision: 1.144
Committed: Sun Oct 22 17:44:03 2017 UTC (6 years, 7 months ago) by jsr166
Branch: MAIN
Changes since 1.143: +2 -0 lines
Log Message:
sync 8174109: Better queuing priorities

File Contents

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