[concurrency-interest] CopyOnWriteArrayList and snapshots

David M. Lloyd david.lloyd at redhat.com
Wed Mar 25 13:53:30 EDT 2009


Yeah, semantically, but toArray() makes a copy of the list data (not just 
the array ref) and then you've got a couple more layers of indirection as 
well.  I'm not sure what the absolute performance effect would be, but 
surely not copying should be better than copying in any case.

- DML

On 03/25/2009 12:40 PM, Sam Berlin wrote:
> Would it be possible to achieve much the same thing by calling code doing:
> 
>  List snapshot = Arrays.unmodifiableList(Arrays.asList(cowList.toArray()));
> 
> Sam
> 
> On Wed, Mar 25, 2009 at 1:10 PM, David M. Lloyd <david.lloyd at redhat.com> wrote:
>> I've run into a minor issue with CopyOnWriteArrayList and have come up with
>> a simple solution for it.  The issue is that you want to perform more than
>> one operation on the list (for instance, a size() followed by a get() with
>> index, which is otherwise not terribly useful on this class), and you need
>> the operations to be consistent with one another.  Using an iterator does
>> provide some ability to do this kind of thing, since it works on an
>> immutable snapshot of the array, but of course you are then limited to the
>> basic iterator operations, which do not include random access.  You can get
>> a copy of a snapshot using toArray(), but I thought it would be handy to
>> have a more generalized snapshot() method which doesn't do a copy of all the
>> list data.
>>
>> Here's a simple five-minute patch which adds a snapshot() method, which
>> returns an immutable List based on the array as it was.  Thoughts?
>>
>> diff -r dde3fe2e8164
>> src/share/classes/java/util/concurrent/CopyOnWriteArrayList.java
>> --- a/src/share/classes/java/util/concurrent/CopyOnWriteArrayList.java  Wed
>> Feb 25 14:32:01 2009 +0000
>> +++ b/src/share/classes/java/util/concurrent/CopyOnWriteArrayList.java  Wed
>> Mar 25 11:11:19 2009 -0500
>> @@ -988,6 +988,44 @@
>>         return new COWIterator<E>(elements, index);
>>     }
>>
>> +    /**
>> +     * Returns a snapshot view of this list.  The returned list provides
>> +     * a snapshot of the state of the list when the method was called.  No
>> +     * synchronization is needed while calling the list methods.  The list
>> +     * is read-only; any methods which modify the state of the list will
>> +     * throw <tt>UnsupportedOperationException</tt>.
>> +     *
>> +     * @return a snapshot of this list
>> +     */
>> +    public List<E> snapshot() {
>> +        final Object[] snapshot = getArray();
>> +        return new AbstractList<E>() {
>> +            public E get(final int index) {
>> +                return CopyOnWriteArrayList.this.get(snapshot, index);
>> +            }
>> +
>> +            public int size() {
>> +                return snapshot.length;
>> +            }
>> +
>> +            public Iterator<E> iterator() {
>> +                return new COWIterator<E>(snapshot, 0);
>> +            }
>> +
>> +            public ListIterator<E> listIterator() {
>> +                return new COWIterator<E>(snapshot, 0);
>> +            }
>> +
>> +            public ListIterator<E> listIterator(final int index) {
>> +                Object[] elements = snapshot;
>> +                int len = elements.length;
>> +                if (index<0 || index>len)
>> +                    throw new IndexOutOfBoundsException("Index: "+index);
>> +                return new COWIterator<E>(elements, index);
>> +            }
>> +        };
>> +    }
>> +
>>     private static class COWIterator<E> implements ListIterator<E> {
>>         /** Snapshot of the array **/
>>         private final Object[] snapshot;
>> _______________________________________________
>> Concurrency-interest mailing list
>> Concurrency-interest at cs.oswego.edu
>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>


More information about the Concurrency-interest mailing list