CopyOnWriteArrayList.java revision 51b1b6997fd3f980076b8081f7f1165ccc2a4008
1/*
2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26/*
27 * Written by Doug Lea with assistance from members of JCP JSR-166
28 * Expert Group.  Adapted and released, under explicit permission,
29 * from JDK ArrayList.java which carries the following copyright:
30 *
31 * Copyright 1997 by Sun Microsystems, Inc.,
32 * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
33 * All rights reserved.
34 */
35
36package java.util.concurrent;
37import java.util.*;
38import java.util.concurrent.locks.*;
39import sun.misc.Unsafe;
40
41/**
42 * A thread-safe variant of {@link java.util.ArrayList} in which all mutative
43 * operations (<tt>add</tt>, <tt>set</tt>, and so on) are implemented by
44 * making a fresh copy of the underlying array.
45 *
46 * <p> This is ordinarily too costly, but may be <em>more</em> efficient
47 * than alternatives when traversal operations vastly outnumber
48 * mutations, and is useful when you cannot or don't want to
49 * synchronize traversals, yet need to preclude interference among
50 * concurrent threads.  The "snapshot" style iterator method uses a
51 * reference to the state of the array at the point that the iterator
52 * was created. This array never changes during the lifetime of the
53 * iterator, so interference is impossible and the iterator is
54 * guaranteed not to throw <tt>ConcurrentModificationException</tt>.
55 * The iterator will not reflect additions, removals, or changes to
56 * the list since the iterator was created.  Element-changing
57 * operations on iterators themselves (<tt>remove</tt>, <tt>set</tt>, and
58 * <tt>add</tt>) are not supported. These methods throw
59 * <tt>UnsupportedOperationException</tt>.
60 *
61 * <p>All elements are permitted, including <tt>null</tt>.
62 *
63 * <p>Memory consistency effects: As with other concurrent
64 * collections, actions in a thread prior to placing an object into a
65 * {@code CopyOnWriteArrayList}
66 * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
67 * actions subsequent to the access or removal of that element from
68 * the {@code CopyOnWriteArrayList} in another thread.
69 *
70 * <p>This class is a member of the
71 * <a href="{@docRoot}/../technotes/guides/collections/index.html">
72 * Java Collections Framework</a>.
73 *
74 * @since 1.5
75 * @author Doug Lea
76 * @param <E> the type of elements held in this collection
77 */
78public class CopyOnWriteArrayList<E>
79    implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
80    private static final long serialVersionUID = 8673264195747942595L;
81
82    /** The lock protecting all mutators */
83    transient final ReentrantLock lock = new ReentrantLock();
84
85    /** The array, accessed only via getArray/setArray. */
86    private volatile transient 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 = c.toArray();
120        // c.toArray might (incorrectly) not return Object[] (see 6260652)
121        if (elements.getClass() != Object[].class)
122            elements = Arrays.copyOf(elements, elements.length, Object[].class);
123        setArray(elements);
124    }
125
126    /**
127     * Creates a list holding a copy of the given array.
128     *
129     * @param toCopyIn the array (a copy of this array is used as the
130     *        internal array)
131     * @throws NullPointerException if the specified array is null
132     */
133    public CopyOnWriteArrayList(E[] toCopyIn) {
134        setArray(Arrays.copyOf(toCopyIn, toCopyIn.length, Object[].class));
135    }
136
137    /**
138     * Returns the number of elements in this list.
139     *
140     * @return the number of elements in this list
141     */
142    public int size() {
143        return getArray().length;
144    }
145
146    /**
147     * Returns <tt>true</tt> if this list contains no elements.
148     *
149     * @return <tt>true</tt> if this list contains no elements
150     */
151    public boolean isEmpty() {
152        return size() == 0;
153    }
154
155    /**
156     * Test for equality, coping with nulls.
157     */
158    private static boolean eq(Object o1, Object o2) {
159        return (o1 == null ? o2 == null : o1.equals(o2));
160    }
161
162    /**
163     * static version of indexOf, to allow repeated calls without
164     * needing to re-acquire array each time.
165     * @param o element to search for
166     * @param elements the array
167     * @param index first index to search
168     * @param fence one past last index to search
169     * @return index of element, or -1 if absent
170     */
171    private static int indexOf(Object o, Object[] elements,
172                               int index, int fence) {
173        if (o == null) {
174            for (int i = index; i < fence; i++)
175                if (elements[i] == null)
176                    return i;
177        } else {
178            for (int i = index; i < fence; i++)
179                if (o.equals(elements[i]))
180                    return i;
181        }
182        return -1;
183    }
184
185    /**
186     * static version of lastIndexOf.
187     * @param o element to search for
188     * @param elements the array
189     * @param index first index to search
190     * @return index of element, or -1 if absent
191     */
192    private static int lastIndexOf(Object o, Object[] elements, int index) {
193        if (o == null) {
194            for (int i = index; i >= 0; i--)
195                if (elements[i] == null)
196                    return i;
197        } else {
198            for (int i = index; i >= 0; i--)
199                if (o.equals(elements[i]))
200                    return i;
201        }
202        return -1;
203    }
204
205    /**
206     * Returns <tt>true</tt> if this list contains the specified element.
207     * More formally, returns <tt>true</tt> if and only if this list contains
208     * at least one element <tt>e</tt> such that
209     * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
210     *
211     * @param o element whose presence in this list is to be tested
212     * @return <tt>true</tt> if this list contains the specified element
213     */
214    public boolean contains(Object o) {
215        Object[] elements = getArray();
216        return indexOf(o, elements, 0, elements.length) >= 0;
217    }
218
219    /**
220     * {@inheritDoc}
221     */
222    public int indexOf(Object o) {
223        Object[] elements = getArray();
224        return indexOf(o, elements, 0, elements.length);
225    }
226
227    /**
228     * Returns the index of the first occurrence of the specified element in
229     * this list, searching forwards from <tt>index</tt>, or returns -1 if
230     * the element is not found.
231     * More formally, returns the lowest index <tt>i</tt> such that
232     * <tt>(i&nbsp;&gt;=&nbsp;index&nbsp;&amp;&amp;&nbsp;(e==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;e.equals(get(i))))</tt>,
233     * or -1 if there is no such index.
234     *
235     * @param e element to search for
236     * @param index index to start searching from
237     * @return the index of the first occurrence of the element in
238     *         this list at position <tt>index</tt> or later in the list;
239     *         <tt>-1</tt> if the element is not found.
240     * @throws IndexOutOfBoundsException if the specified index is negative
241     */
242    public int indexOf(E e, int index) {
243        Object[] elements = getArray();
244        return indexOf(e, elements, index, elements.length);
245    }
246
247    /**
248     * {@inheritDoc}
249     */
250    public int lastIndexOf(Object o) {
251        Object[] elements = getArray();
252        return lastIndexOf(o, elements, elements.length - 1);
253    }
254
255    /**
256     * Returns the index of the last occurrence of the specified element in
257     * this list, searching backwards from <tt>index</tt>, or returns -1 if
258     * the element is not found.
259     * More formally, returns the highest index <tt>i</tt> such that
260     * <tt>(i&nbsp;&lt;=&nbsp;index&nbsp;&amp;&amp;&nbsp;(e==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;e.equals(get(i))))</tt>,
261     * or -1 if there is no such index.
262     *
263     * @param e element to search for
264     * @param index index to start searching backwards from
265     * @return the index of the last occurrence of the element at position
266     *         less than or equal to <tt>index</tt> in this list;
267     *         -1 if the element is not found.
268     * @throws IndexOutOfBoundsException if the specified index is greater
269     *         than or equal to the current size of this list
270     */
271    public int lastIndexOf(E e, int index) {
272        Object[] elements = getArray();
273        return lastIndexOf(e, elements, index);
274    }
275
276    /**
277     * Returns a shallow copy of this list.  (The elements themselves
278     * are not copied.)
279     *
280     * @return a clone of this list
281     */
282    public Object clone() {
283        try {
284            CopyOnWriteArrayList c = (CopyOnWriteArrayList)(super.clone());
285            c.resetLock();
286            return c;
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     * <tt>null</tt>.  (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 <tt>x</tt> 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 <tt>String</tt>:
334     *
335     * <pre>
336     *     String[] y = x.toArray(new String[0]);</pre>
337     *
338     * Note that <tt>toArray(new Object[0])</tt> is identical in function to
339     * <tt>toArray()</tt>.
340     *
341     * @param a the array into which the elements of the list are to
342     *          be stored, if it is big enough; otherwise, a new array of the
343     *          same runtime type is allocated for this purpose.
344     * @return an array containing all the elements in this list
345     * @throws ArrayStoreException if the runtime type of the specified array
346     *         is not a supertype of the runtime type of every element in
347     *         this list
348     * @throws NullPointerException if the specified array is null
349     */
350    @SuppressWarnings("unchecked")
351    public <T> T[] toArray(T a[]) {
352        Object[] elements = getArray();
353        int len = elements.length;
354        if (a.length < len)
355            return (T[]) Arrays.copyOf(elements, len, a.getClass());
356        else {
357            System.arraycopy(elements, 0, a, 0, len);
358            if (a.length > len)
359                a[len] = null;
360            return a;
361        }
362    }
363
364    // Positional Access Operations
365
366    @SuppressWarnings("unchecked")
367    private E get(Object[] a, int index) {
368        return (E) a[index];
369    }
370
371    /**
372     * {@inheritDoc}
373     *
374     * @throws IndexOutOfBoundsException {@inheritDoc}
375     */
376    public E get(int index) {
377        return get(getArray(), index);
378    }
379
380    /**
381     * Replaces the element at the specified position in this list with the
382     * specified element.
383     *
384     * @throws IndexOutOfBoundsException {@inheritDoc}
385     */
386    public E set(int index, E element) {
387        final ReentrantLock lock = this.lock;
388        lock.lock();
389        try {
390            Object[] elements = getArray();
391            E oldValue = get(elements, index);
392
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        } finally {
404            lock.unlock();
405        }
406    }
407
408    /**
409     * Appends the specified element to the end of this list.
410     *
411     * @param e element to be appended to this list
412     * @return <tt>true</tt> (as specified by {@link Collection#add})
413     */
414    public boolean add(E e) {
415        final ReentrantLock lock = this.lock;
416        lock.lock();
417        try {
418            Object[] elements = getArray();
419            int len = elements.length;
420            Object[] newElements = Arrays.copyOf(elements, len + 1);
421            newElements[len] = e;
422            setArray(newElements);
423            return true;
424        } finally {
425            lock.unlock();
426        }
427    }
428
429    /**
430     * Inserts the specified element at the specified position in this
431     * list. Shifts the element currently at that position (if any) and
432     * any subsequent elements to the right (adds one to their indices).
433     *
434     * @throws IndexOutOfBoundsException {@inheritDoc}
435     */
436    public void add(int index, E element) {
437        final ReentrantLock lock = this.lock;
438        lock.lock();
439        try {
440            Object[] elements = getArray();
441            int len = elements.length;
442            if (index > len || index < 0)
443                throw new IndexOutOfBoundsException("Index: "+index+
444                                                    ", Size: "+len);
445            Object[] newElements;
446            int numMoved = len - index;
447            if (numMoved == 0)
448                newElements = Arrays.copyOf(elements, len + 1);
449            else {
450                newElements = new Object[len + 1];
451                System.arraycopy(elements, 0, newElements, 0, index);
452                System.arraycopy(elements, index, newElements, index + 1,
453                                 numMoved);
454            }
455            newElements[index] = element;
456            setArray(newElements);
457        } finally {
458            lock.unlock();
459        }
460    }
461
462    /**
463     * Removes the element at the specified position in this list.
464     * Shifts any subsequent elements to the left (subtracts one from their
465     * indices).  Returns the element that was removed from the list.
466     *
467     * @throws IndexOutOfBoundsException {@inheritDoc}
468     */
469    public E remove(int index) {
470        final ReentrantLock lock = this.lock;
471        lock.lock();
472        try {
473            Object[] elements = getArray();
474            int len = elements.length;
475            E oldValue = get(elements, index);
476            int numMoved = len - index - 1;
477            if (numMoved == 0)
478                setArray(Arrays.copyOf(elements, len - 1));
479            else {
480                Object[] newElements = new Object[len - 1];
481                System.arraycopy(elements, 0, newElements, 0, index);
482                System.arraycopy(elements, index + 1, newElements, index,
483                                 numMoved);
484                setArray(newElements);
485            }
486            return oldValue;
487        } finally {
488            lock.unlock();
489        }
490    }
491
492    /**
493     * Removes the first occurrence of the specified element from this list,
494     * if it is present.  If this list does not contain the element, it is
495     * unchanged.  More formally, removes the element with the lowest index
496     * <tt>i</tt> such that
497     * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>
498     * (if such an element exists).  Returns <tt>true</tt> if this list
499     * contained the specified element (or equivalently, if this list
500     * changed as a result of the call).
501     *
502     * @param o element to be removed from this list, if present
503     * @return <tt>true</tt> if this list contained the specified element
504     */
505    public boolean remove(Object o) {
506        final ReentrantLock lock = this.lock;
507        lock.lock();
508        try {
509            Object[] elements = getArray();
510            int len = elements.length;
511            if (len != 0) {
512                // Copy while searching for element to remove
513                // This wins in the normal case of element being present
514                int newlen = len - 1;
515                Object[] newElements = new Object[newlen];
516
517                for (int i = 0; i < newlen; ++i) {
518                    if (eq(o, elements[i])) {
519                        // found one;  copy remaining and exit
520                        for (int k = i + 1; k < len; ++k)
521                            newElements[k-1] = elements[k];
522                        setArray(newElements);
523                        return true;
524                    } else
525                        newElements[i] = elements[i];
526                }
527
528                // special handling for last cell
529                if (eq(o, elements[newlen])) {
530                    setArray(newElements);
531                    return true;
532                }
533            }
534            return false;
535        } finally {
536            lock.unlock();
537        }
538    }
539
540    /**
541     * Removes from this list all of the elements whose index is between
542     * <tt>fromIndex</tt>, inclusive, and <tt>toIndex</tt>, exclusive.
543     * Shifts any succeeding elements to the left (reduces their index).
544     * This call shortens the list by <tt>(toIndex - fromIndex)</tt> elements.
545     * (If <tt>toIndex==fromIndex</tt>, this operation has no effect.)
546     *
547     * @param fromIndex index of first element to be removed
548     * @param toIndex index after last element to be removed
549     * @throws IndexOutOfBoundsException if fromIndex or toIndex out of range
550     *         ({@code{fromIndex < 0 || toIndex > size() || toIndex < fromIndex})
551     */
552    private void removeRange(int fromIndex, int toIndex) {
553        final ReentrantLock lock = this.lock;
554        lock.lock();
555        try {
556            Object[] elements = getArray();
557            int len = elements.length;
558
559            if (fromIndex < 0 || toIndex > len || toIndex < fromIndex)
560                throw new IndexOutOfBoundsException();
561            int newlen = len - (toIndex - fromIndex);
562            int numMoved = len - toIndex;
563            if (numMoved == 0)
564                setArray(Arrays.copyOf(elements, newlen));
565            else {
566                Object[] newElements = new Object[newlen];
567                System.arraycopy(elements, 0, newElements, 0, fromIndex);
568                System.arraycopy(elements, toIndex, newElements,
569                                 fromIndex, numMoved);
570                setArray(newElements);
571            }
572        } finally {
573            lock.unlock();
574        }
575    }
576
577    /**
578     * Append the element if not present.
579     *
580     * @param e element to be added to this list, if absent
581     * @return <tt>true</tt> if the element was added
582     */
583    public boolean addIfAbsent(E e) {
584        final ReentrantLock lock = this.lock;
585        lock.lock();
586        try {
587            // Copy while checking if already present.
588            // This wins in the most common case where it is not present
589            Object[] elements = getArray();
590            int len = elements.length;
591            Object[] newElements = new Object[len + 1];
592            for (int i = 0; i < len; ++i) {
593                if (eq(e, elements[i]))
594                    return false; // exit, throwing away copy
595                else
596                    newElements[i] = elements[i];
597            }
598            newElements[len] = e;
599            setArray(newElements);
600            return true;
601        } finally {
602            lock.unlock();
603        }
604    }
605
606    /**
607     * Returns <tt>true</tt> if this list contains all of the elements of the
608     * specified collection.
609     *
610     * @param c collection to be checked for containment in this list
611     * @return <tt>true</tt> if this list contains all of the elements of the
612     *         specified collection
613     * @throws NullPointerException if the specified collection is null
614     * @see #contains(Object)
615     */
616    public boolean containsAll(Collection<?> c) {
617        Object[] elements = getArray();
618        int len = elements.length;
619        for (Object e : c) {
620            if (indexOf(e, elements, 0, len) < 0)
621                return false;
622        }
623        return true;
624    }
625
626    /**
627     * Removes from this list all of its elements that are contained in
628     * the specified collection. This is a particularly expensive operation
629     * in this class because of the need for an internal temporary array.
630     *
631     * @param c collection containing elements to be removed from this list
632     * @return <tt>true</tt> if this list changed as a result of the call
633     * @throws ClassCastException if the class of an element of this list
634     *         is incompatible with the specified collection
635     *         (<a href="../Collection.html#optional-restrictions">optional</a>)
636     * @throws NullPointerException if this list contains a null element and the
637     *         specified collection does not permit null elements
638     *         (<a href="../Collection.html#optional-restrictions">optional</a>),
639     *         or if the specified collection is null
640     * @see #remove(Object)
641     */
642    public boolean removeAll(Collection<?> c) {
643        final ReentrantLock lock = this.lock;
644        lock.lock();
645        try {
646            Object[] elements = getArray();
647            int len = elements.length;
648            if (len != 0) {
649                // temp array holds those elements we know we want to keep
650                int newlen = 0;
651                Object[] temp = new Object[len];
652                for (int i = 0; i < len; ++i) {
653                    Object element = elements[i];
654                    if (!c.contains(element))
655                        temp[newlen++] = element;
656                }
657                if (newlen != len) {
658                    setArray(Arrays.copyOf(temp, newlen));
659                    return true;
660                }
661            }
662            return false;
663        } finally {
664            lock.unlock();
665        }
666    }
667
668    /**
669     * Retains only the elements in this list that are contained in the
670     * specified collection.  In other words, removes from this list all of
671     * its elements that are not contained in the specified collection.
672     *
673     * @param c collection containing elements to be retained in this list
674     * @return <tt>true</tt> if this list changed as a result of the call
675     * @throws ClassCastException if the class of an element of this list
676     *         is incompatible with the specified collection
677     *         (<a href="../Collection.html#optional-restrictions">optional</a>)
678     * @throws NullPointerException if this list contains a null element and the
679     *         specified collection does not permit null elements
680     *         (<a href="../Collection.html#optional-restrictions">optional</a>),
681     *         or if the specified collection is null
682     * @see #remove(Object)
683     */
684    public boolean retainAll(Collection<?> c) {
685        final ReentrantLock lock = this.lock;
686        lock.lock();
687        try {
688            Object[] elements = getArray();
689            int len = elements.length;
690            if (len != 0) {
691                // temp array holds those elements we know we want to keep
692                int newlen = 0;
693                Object[] temp = new Object[len];
694                for (int i = 0; i < len; ++i) {
695                    Object element = elements[i];
696                    if (c.contains(element))
697                        temp[newlen++] = element;
698                }
699                if (newlen != len) {
700                    setArray(Arrays.copyOf(temp, newlen));
701                    return true;
702                }
703            }
704            return false;
705        } finally {
706            lock.unlock();
707        }
708    }
709
710    /**
711     * Appends all of the elements in the specified collection that
712     * are not already contained in this list, to the end of
713     * this list, in the order that they are returned by the
714     * specified collection's iterator.
715     *
716     * @param c collection containing elements to be added to this list
717     * @return the number of elements added
718     * @throws NullPointerException if the specified collection is null
719     * @see #addIfAbsent(Object)
720     */
721    public int addAllAbsent(Collection<? extends E> c) {
722        Object[] cs = c.toArray();
723        if (cs.length == 0)
724            return 0;
725        Object[] uniq = new Object[cs.length];
726        final ReentrantLock lock = this.lock;
727        lock.lock();
728        try {
729            Object[] elements = getArray();
730            int len = elements.length;
731            int added = 0;
732            for (int i = 0; i < cs.length; ++i) { // scan for duplicates
733                Object e = cs[i];
734                if (indexOf(e, elements, 0, len) < 0 &&
735                    indexOf(e, uniq, 0, added) < 0)
736                    uniq[added++] = e;
737            }
738            if (added > 0) {
739                Object[] newElements = Arrays.copyOf(elements, len + added);
740                System.arraycopy(uniq, 0, newElements, len, added);
741                setArray(newElements);
742            }
743            return added;
744        } finally {
745            lock.unlock();
746        }
747    }
748
749    /**
750     * Removes all of the elements from this list.
751     * The list will be empty after this call returns.
752     */
753    public void clear() {
754        final ReentrantLock lock = this.lock;
755        lock.lock();
756        try {
757            setArray(new Object[0]);
758        } finally {
759            lock.unlock();
760        }
761    }
762
763    /**
764     * Appends all of the elements in the specified collection to the end
765     * of this list, in the order that they are returned by the specified
766     * collection's iterator.
767     *
768     * @param c collection containing elements to be added to this list
769     * @return <tt>true</tt> if this list changed as a result of the call
770     * @throws NullPointerException if the specified collection is null
771     * @see #add(Object)
772     */
773    public boolean addAll(Collection<? extends E> c) {
774        Object[] cs = c.toArray();
775        if (cs.length == 0)
776            return false;
777        final ReentrantLock lock = this.lock;
778        lock.lock();
779        try {
780            Object[] elements = getArray();
781            int len = elements.length;
782            Object[] newElements = Arrays.copyOf(elements, len + cs.length);
783            System.arraycopy(cs, 0, newElements, len, cs.length);
784            setArray(newElements);
785            return true;
786        } finally {
787            lock.unlock();
788        }
789    }
790
791    /**
792     * Inserts all of the elements in the specified collection into this
793     * list, starting at the specified position.  Shifts the element
794     * currently at that position (if any) and any subsequent elements to
795     * the right (increases their indices).  The new elements will appear
796     * in this list in the order that they are returned by the
797     * specified collection's iterator.
798     *
799     * @param index index at which to insert the first element
800     *        from the specified collection
801     * @param c collection containing elements to be added to this list
802     * @return <tt>true</tt> if this list changed as a result of the call
803     * @throws IndexOutOfBoundsException {@inheritDoc}
804     * @throws NullPointerException if the specified collection is null
805     * @see #add(int,Object)
806     */
807    public boolean addAll(int index, Collection<? extends E> c) {
808        Object[] cs = c.toArray();
809        final ReentrantLock lock = this.lock;
810        lock.lock();
811        try {
812            Object[] elements = getArray();
813            int len = elements.length;
814            if (index > len || index < 0)
815                throw new IndexOutOfBoundsException("Index: "+index+
816                                                    ", Size: "+len);
817            if (cs.length == 0)
818                return false;
819            int numMoved = len - index;
820            Object[] newElements;
821            if (numMoved == 0)
822                newElements = Arrays.copyOf(elements, len + cs.length);
823            else {
824                newElements = new Object[len + cs.length];
825                System.arraycopy(elements, 0, newElements, 0, index);
826                System.arraycopy(elements, index,
827                                 newElements, index + cs.length,
828                                 numMoved);
829            }
830            System.arraycopy(cs, 0, newElements, index, cs.length);
831            setArray(newElements);
832            return true;
833        } finally {
834            lock.unlock();
835        }
836    }
837
838    /**
839     * Saves the state of the list to a stream (that is, serializes it).
840     *
841     * @serialData The length of the array backing the list is emitted
842     *               (int), followed by all of its elements (each an Object)
843     *               in the proper order.
844     * @param s the stream
845     */
846    private void writeObject(java.io.ObjectOutputStream s)
847        throws java.io.IOException{
848
849        s.defaultWriteObject();
850
851        Object[] elements = getArray();
852        // Write out array length
853        s.writeInt(elements.length);
854
855        // Write out all elements in the proper order.
856        for (Object element : elements)
857            s.writeObject(element);
858    }
859
860    /**
861     * Reconstitutes the list from a stream (that is, deserializes it).
862     *
863     * @param s the stream
864     */
865    private void readObject(java.io.ObjectInputStream s)
866        throws java.io.IOException, ClassNotFoundException {
867
868        s.defaultReadObject();
869
870        // bind to new lock
871        resetLock();
872
873        // Read in array length and allocate array
874        int len = s.readInt();
875        Object[] elements = new Object[len];
876
877        // Read in all elements in the proper order.
878        for (int i = 0; i < len; i++)
879            elements[i] = s.readObject();
880        setArray(elements);
881    }
882
883    /**
884     * Returns a string representation of this list.  The string
885     * representation consists of the string representations of the list's
886     * elements in the order they are returned by its iterator, enclosed in
887     * square brackets (<tt>"[]"</tt>).  Adjacent elements are separated by
888     * the characters <tt>", "</tt> (comma and space).  Elements are
889     * converted to strings as by {@link String#valueOf(Object)}.
890     *
891     * @return a string representation of this list
892     */
893    public String toString() {
894        return Arrays.toString(getArray());
895    }
896
897    /**
898     * Compares the specified object with this list for equality.
899     * Returns {@code true} if the specified object is the same object
900     * as this object, or if it is also a {@link List} and the sequence
901     * of elements returned by an {@linkplain List#iterator() iterator}
902     * over the specified list is the same as the sequence returned by
903     * an iterator over this list.  The two sequences are considered to
904     * be the same if they have the same length and corresponding
905     * elements at the same position in the sequence are <em>equal</em>.
906     * Two elements {@code e1} and {@code e2} are considered
907     * <em>equal</em> if {@code (e1==null ? e2==null : e1.equals(e2))}.
908     *
909     * @param o the object to be compared for equality with this list
910     * @return {@code true} if the specified object is equal to this list
911     */
912    public boolean equals(Object o) {
913        if (o == this)
914            return true;
915        if (!(o instanceof List))
916            return false;
917
918        List<?> list = (List<?>)(o);
919        Iterator<?> it = list.iterator();
920        Object[] elements = getArray();
921        int len = elements.length;
922        for (int i = 0; i < len; ++i)
923            if (!it.hasNext() || !eq(elements[i], it.next()))
924                return false;
925        if (it.hasNext())
926            return false;
927        return true;
928    }
929
930    /**
931     * Returns the hash code value for this list.
932     *
933     * <p>This implementation uses the definition in {@link List#hashCode}.
934     *
935     * @return the hash code value for this list
936     */
937    public int hashCode() {
938        int hashCode = 1;
939        Object[] elements = getArray();
940        int len = elements.length;
941        for (int i = 0; i < len; ++i) {
942            Object obj = elements[i];
943            hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
944        }
945        return hashCode;
946    }
947
948    /**
949     * Returns an iterator over the elements in this list in proper sequence.
950     *
951     * <p>The returned iterator provides a snapshot of the state of the list
952     * when the iterator was constructed. No synchronization is needed while
953     * traversing the iterator. The iterator does <em>NOT</em> support the
954     * <tt>remove</tt> method.
955     *
956     * @return an iterator over the elements in this list in proper sequence
957     */
958    public Iterator<E> iterator() {
959        return new COWIterator<E>(getArray(), 0);
960    }
961
962    /**
963     * {@inheritDoc}
964     *
965     * <p>The returned iterator provides a snapshot of the state of the list
966     * when the iterator was constructed. No synchronization is needed while
967     * traversing the iterator. The iterator does <em>NOT</em> support the
968     * <tt>remove</tt>, <tt>set</tt> or <tt>add</tt> methods.
969     */
970    public ListIterator<E> listIterator() {
971        return new COWIterator<E>(getArray(), 0);
972    }
973
974    /**
975     * {@inheritDoc}
976     *
977     * <p>The returned iterator provides a snapshot of the state of the list
978     * when the iterator was constructed. No synchronization is needed while
979     * traversing the iterator. The iterator does <em>NOT</em> support the
980     * <tt>remove</tt>, <tt>set</tt> or <tt>add</tt> methods.
981     *
982     * @throws IndexOutOfBoundsException {@inheritDoc}
983     */
984    public ListIterator<E> listIterator(final int index) {
985        Object[] elements = getArray();
986        int len = elements.length;
987        if (index<0 || index>len)
988            throw new IndexOutOfBoundsException("Index: "+index);
989
990        return new COWIterator<E>(elements, index);
991    }
992
993    private static class COWIterator<E> implements ListIterator<E> {
994        /** Snapshot of the array */
995        private final Object[] snapshot;
996        /** Index of element to be returned by subsequent call to next.  */
997        private int cursor;
998
999        private COWIterator(Object[] elements, int initialCursor) {
1000            cursor = initialCursor;
1001            snapshot = elements;
1002        }
1003
1004        public boolean hasNext() {
1005            return cursor < snapshot.length;
1006        }
1007
1008        public boolean hasPrevious() {
1009            return cursor > 0;
1010        }
1011
1012        @SuppressWarnings("unchecked")
1013        public E next() {
1014            if (! hasNext())
1015                throw new NoSuchElementException();
1016            return (E) snapshot[cursor++];
1017        }
1018
1019        @SuppressWarnings("unchecked")
1020        public E previous() {
1021            if (! hasPrevious())
1022                throw new NoSuchElementException();
1023            return (E) snapshot[--cursor];
1024        }
1025
1026        public int nextIndex() {
1027            return cursor;
1028        }
1029
1030        public int previousIndex() {
1031            return cursor-1;
1032        }
1033
1034        /**
1035         * Not supported. Always throws UnsupportedOperationException.
1036         * @throws UnsupportedOperationException always; <tt>remove</tt>
1037         *         is not supported by this iterator.
1038         */
1039        public void remove() {
1040            throw new UnsupportedOperationException();
1041        }
1042
1043        /**
1044         * Not supported. Always throws UnsupportedOperationException.
1045         * @throws UnsupportedOperationException always; <tt>set</tt>
1046         *         is not supported by this iterator.
1047         */
1048        public void set(E e) {
1049            throw new UnsupportedOperationException();
1050        }
1051
1052        /**
1053         * Not supported. Always throws UnsupportedOperationException.
1054         * @throws UnsupportedOperationException always; <tt>add</tt>
1055         *         is not supported by this iterator.
1056         */
1057        public void add(E e) {
1058            throw new UnsupportedOperationException();
1059        }
1060    }
1061
1062    /**
1063     * Returns a view of the portion of this list between
1064     * <tt>fromIndex</tt>, inclusive, and <tt>toIndex</tt>, exclusive.
1065     * The returned list is backed by this list, so changes in the
1066     * returned list are reflected in this list.
1067     *
1068     * <p>The semantics of the list returned by this method become
1069     * undefined if the backing list (i.e., this list) is modified in
1070     * any way other than via the returned list.
1071     *
1072     * @param fromIndex low endpoint (inclusive) of the subList
1073     * @param toIndex high endpoint (exclusive) of the subList
1074     * @return a view of the specified range within this list
1075     * @throws IndexOutOfBoundsException {@inheritDoc}
1076     */
1077    public List<E> subList(int fromIndex, int toIndex) {
1078        final ReentrantLock lock = this.lock;
1079        lock.lock();
1080        try {
1081            Object[] elements = getArray();
1082            int len = elements.length;
1083            if (fromIndex < 0 || toIndex > len || fromIndex > toIndex)
1084                throw new IndexOutOfBoundsException();
1085            return new COWSubList<E>(this, fromIndex, toIndex);
1086        } finally {
1087            lock.unlock();
1088        }
1089    }
1090
1091    /**
1092     * Sublist for CopyOnWriteArrayList.
1093     * This class extends AbstractList merely for convenience, to
1094     * avoid having to define addAll, etc. This doesn't hurt, but
1095     * is wasteful.  This class does not need or use modCount
1096     * mechanics in AbstractList, but does need to check for
1097     * concurrent modification using similar mechanics.  On each
1098     * operation, the array that we expect the backing list to use
1099     * is checked and updated.  Since we do this for all of the
1100     * base operations invoked by those defined in AbstractList,
1101     * all is well.  While inefficient, this is not worth
1102     * improving.  The kinds of list operations inherited from
1103     * AbstractList are already so slow on COW sublists that
1104     * adding a bit more space/time doesn't seem even noticeable.
1105     */
1106    private static class COWSubList<E>
1107        extends AbstractList<E>
1108        implements RandomAccess
1109    {
1110        private final CopyOnWriteArrayList<E> l;
1111        private final int offset;
1112        private int size;
1113        private Object[] expectedArray;
1114
1115        // only call this holding l's lock
1116        COWSubList(CopyOnWriteArrayList<E> list,
1117                   int fromIndex, int toIndex) {
1118            l = list;
1119            expectedArray = l.getArray();
1120            offset = fromIndex;
1121            size = toIndex - fromIndex;
1122        }
1123
1124        // only call this holding l's lock
1125        private void checkForComodification() {
1126            if (l.getArray() != expectedArray)
1127                throw new ConcurrentModificationException();
1128        }
1129
1130        // only call this holding l's lock
1131        private void rangeCheck(int index) {
1132            if (index<0 || index>=size)
1133                throw new IndexOutOfBoundsException("Index: "+index+
1134                                                    ",Size: "+size);
1135        }
1136
1137        public E set(int index, E element) {
1138            final ReentrantLock lock = l.lock;
1139            lock.lock();
1140            try {
1141                rangeCheck(index);
1142                checkForComodification();
1143                E x = l.set(index+offset, element);
1144                expectedArray = l.getArray();
1145                return x;
1146            } finally {
1147                lock.unlock();
1148            }
1149        }
1150
1151        public E get(int index) {
1152            final ReentrantLock lock = l.lock;
1153            lock.lock();
1154            try {
1155                rangeCheck(index);
1156                checkForComodification();
1157                return l.get(index+offset);
1158            } finally {
1159                lock.unlock();
1160            }
1161        }
1162
1163        public int size() {
1164            final ReentrantLock lock = l.lock;
1165            lock.lock();
1166            try {
1167                checkForComodification();
1168                return size;
1169            } finally {
1170                lock.unlock();
1171            }
1172        }
1173
1174        public void add(int index, E element) {
1175            final ReentrantLock lock = l.lock;
1176            lock.lock();
1177            try {
1178                checkForComodification();
1179                if (index<0 || index>size)
1180                    throw new IndexOutOfBoundsException();
1181                l.add(index+offset, element);
1182                expectedArray = l.getArray();
1183                size++;
1184            } finally {
1185                lock.unlock();
1186            }
1187        }
1188
1189        public void clear() {
1190            final ReentrantLock lock = l.lock;
1191            lock.lock();
1192            try {
1193                checkForComodification();
1194                l.removeRange(offset, offset+size);
1195                expectedArray = l.getArray();
1196                size = 0;
1197            } finally {
1198                lock.unlock();
1199            }
1200        }
1201
1202        public E remove(int index) {
1203            final ReentrantLock lock = l.lock;
1204            lock.lock();
1205            try {
1206                rangeCheck(index);
1207                checkForComodification();
1208                E result = l.remove(index+offset);
1209                expectedArray = l.getArray();
1210                size--;
1211                return result;
1212            } finally {
1213                lock.unlock();
1214            }
1215        }
1216
1217        public boolean remove(Object o) {
1218            int index = indexOf(o);
1219            if (index == -1)
1220                return false;
1221            remove(index);
1222            return true;
1223        }
1224
1225        public Iterator<E> iterator() {
1226            final ReentrantLock lock = l.lock;
1227            lock.lock();
1228            try {
1229                checkForComodification();
1230                return new COWSubListIterator<E>(l, 0, offset, size);
1231            } finally {
1232                lock.unlock();
1233            }
1234        }
1235
1236        public ListIterator<E> listIterator(final int index) {
1237            final ReentrantLock lock = l.lock;
1238            lock.lock();
1239            try {
1240                checkForComodification();
1241                if (index<0 || index>size)
1242                    throw new IndexOutOfBoundsException("Index: "+index+
1243                                                        ", Size: "+size);
1244                return new COWSubListIterator<E>(l, index, offset, size);
1245            } finally {
1246                lock.unlock();
1247            }
1248        }
1249
1250        public List<E> subList(int fromIndex, int toIndex) {
1251            final ReentrantLock lock = l.lock;
1252            lock.lock();
1253            try {
1254                checkForComodification();
1255                if (fromIndex<0 || toIndex>size)
1256                    throw new IndexOutOfBoundsException();
1257                return new COWSubList<E>(l, fromIndex + offset,
1258                                         toIndex + offset);
1259            } finally {
1260                lock.unlock();
1261            }
1262        }
1263
1264    }
1265
1266
1267    private static class COWSubListIterator<E> implements ListIterator<E> {
1268        private final ListIterator<E> i;
1269        private final int index;
1270        private final int offset;
1271        private final int size;
1272
1273        COWSubListIterator(List<E> l, int index, int offset,
1274                           int size) {
1275            this.index = index;
1276            this.offset = offset;
1277            this.size = size;
1278            i = l.listIterator(index+offset);
1279        }
1280
1281        public boolean hasNext() {
1282            return nextIndex() < size;
1283        }
1284
1285        public E next() {
1286            if (hasNext())
1287                return i.next();
1288            else
1289                throw new NoSuchElementException();
1290        }
1291
1292        public boolean hasPrevious() {
1293            return previousIndex() >= 0;
1294        }
1295
1296        public E previous() {
1297            if (hasPrevious())
1298                return i.previous();
1299            else
1300                throw new NoSuchElementException();
1301        }
1302
1303        public int nextIndex() {
1304            return i.nextIndex() - offset;
1305        }
1306
1307        public int previousIndex() {
1308            return i.previousIndex() - offset;
1309        }
1310
1311        public void remove() {
1312            throw new UnsupportedOperationException();
1313        }
1314
1315        public void set(E e) {
1316            throw new UnsupportedOperationException();
1317        }
1318
1319        public void add(E e) {
1320            throw new UnsupportedOperationException();
1321        }
1322    }
1323
1324    // Support for resetting lock while deserializing
1325    private void resetLock() {
1326        UNSAFE.putObjectVolatile(this, lockOffset, new ReentrantLock());
1327    }
1328    private static final sun.misc.Unsafe UNSAFE;
1329    private static final long lockOffset;
1330    static {
1331        try {
1332            UNSAFE = sun.misc.Unsafe.getUnsafe();
1333            Class k = CopyOnWriteArrayList.class;
1334            lockOffset = UNSAFE.objectFieldOffset
1335                (k.getDeclaredField("lock"));
1336        } catch (Exception e) {
1337            throw new Error(e);
1338        }
1339    }
1340}
1341