[concurrency-interest] CopyOnWriteArrayList and snapshots

Jim Andreou jim.andreou at gmail.com
Wed Mar 25 14:25:52 EDT 2009


This doesn't solve the possible inconsistency between size() and get(int),
since the underlying cowList may change.
I actually think David's fix makes sense. The culprit is depending on
toArray methods to get snapshots, which return arrays, which are mutable and
force the copying.

2009/3/25 Shaffer, Darron <Darron_Shaffer at stercomm.com>

> Or even:
>
>  List snapshot = Collections.unmodifiableList(cowList);
>
> -----Original Message-----
> From: concurrency-interest-bounces at cs.oswego.edu [mailto:
> concurrency-interest-bounces at cs.oswego.edu] On Behalf Of Sam Berlin
> Sent: Wednesday, March 25, 2009 12:41 PM
> To: David M. Lloyd
> Cc: concurrency-interest
> Subject: Re: [concurrency-interest] CopyOnWriteArrayList and snapshots
>
> 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
> >
>
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20090325/67dcc756/attachment.html>


More information about the Concurrency-interest mailing list