src/share/classes/java/util/concurrent/CopyOnWriteArrayList.java

Print this page
rev 6969 : [mq]: iterator


  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 
  36 package java.util.concurrent;
  37 import java.util.*;
  38 import java.util.concurrent.locks.ReentrantLock;

  39 
  40 /**
  41  * A thread-safe variant of {@link java.util.ArrayList} in which all mutative
  42  * operations (<tt>add</tt>, <tt>set</tt>, and so on) are implemented by
  43  * making a fresh copy of the underlying array.
  44  *
  45  * <p> This is ordinarily too costly, but may be <em>more</em> efficient
  46  * than alternatives when traversal operations vastly outnumber
  47  * mutations, and is useful when you cannot or don't want to
  48  * synchronize traversals, yet need to preclude interference among
  49  * concurrent threads.  The "snapshot" style iterator method uses a
  50  * reference to the state of the array at the point that the iterator
  51  * was created. This array never changes during the lifetime of the
  52  * iterator, so interference is impossible and the iterator is
  53  * guaranteed not to throw <tt>ConcurrentModificationException</tt>.
  54  * The iterator will not reflect additions, removals, or changes to
  55  * the list since the iterator was created.  Element-changing
  56  * operations on iterators themselves (<tt>remove</tt>, <tt>set</tt>, and
  57  * <tt>add</tt>) are not supported. These methods throw
  58  * <tt>UnsupportedOperationException</tt>.


1039             throw new UnsupportedOperationException();
1040         }
1041 
1042         /**
1043          * Not supported. Always throws UnsupportedOperationException.
1044          * @throws UnsupportedOperationException always; <tt>set</tt>
1045          *         is not supported by this iterator.
1046          */
1047         public void set(E e) {
1048             throw new UnsupportedOperationException();
1049         }
1050 
1051         /**
1052          * Not supported. Always throws UnsupportedOperationException.
1053          * @throws UnsupportedOperationException always; <tt>add</tt>
1054          *         is not supported by this iterator.
1055          */
1056         public void add(E e) {
1057             throw new UnsupportedOperationException();
1058         }










1059     }
1060 
1061     /**
1062      * Returns a view of the portion of this list between
1063      * <tt>fromIndex</tt>, inclusive, and <tt>toIndex</tt>, exclusive.
1064      * The returned list is backed by this list, so changes in the
1065      * returned list are reflected in this list.
1066      *
1067      * <p>The semantics of the list returned by this method become
1068      * undefined if the backing list (i.e., this list) is modified in
1069      * any way other than via the returned list.
1070      *
1071      * @param fromIndex low endpoint (inclusive) of the subList
1072      * @param toIndex high endpoint (exclusive) of the subList
1073      * @return a view of the specified range within this list
1074      * @throws IndexOutOfBoundsException {@inheritDoc}
1075      */
1076     public List<E> subList(int fromIndex, int toIndex) {
1077         final ReentrantLock lock = this.lock;
1078         lock.lock();


1297         }
1298 
1299         public int nextIndex() {
1300             return it.nextIndex() - offset;
1301         }
1302 
1303         public int previousIndex() {
1304             return it.previousIndex() - offset;
1305         }
1306 
1307         public void remove() {
1308             throw new UnsupportedOperationException();
1309         }
1310 
1311         public void set(E e) {
1312             throw new UnsupportedOperationException();
1313         }
1314 
1315         public void add(E e) {
1316             throw new UnsupportedOperationException();









1317         }
1318     }
1319 
1320     // Support for resetting lock while deserializing
1321     private void resetLock() {
1322         UNSAFE.putObjectVolatile(this, lockOffset, new ReentrantLock());
1323     }
1324     private static final sun.misc.Unsafe UNSAFE;
1325     private static final long lockOffset;
1326     static {
1327         try {
1328             UNSAFE = sun.misc.Unsafe.getUnsafe();
1329             Class<?> k = CopyOnWriteArrayList.class;
1330             lockOffset = UNSAFE.objectFieldOffset
1331                 (k.getDeclaredField("lock"));
1332         } catch (Exception e) {
1333             throw new Error(e);
1334         }
1335     }
1336 }


  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 
  36 package java.util.concurrent;
  37 import java.util.*;
  38 import java.util.concurrent.locks.ReentrantLock;
  39 import java.util.function.Consumer;
  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>.


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         @Override
1062         @SuppressWarnings("unchecked")
1063         public void forEachRemaining(Consumer<? super E> action) {
1064             Objects.requireNonNull(action);
1065             final int size = snapshot.length;
1066             for (int i=cursor; i < size; i++) {
1067                 action.accept((E) snapshot[i]);
1068             }
1069         }
1070     }
1071 
1072     /**
1073      * Returns a view of the portion of this list between
1074      * <tt>fromIndex</tt>, inclusive, and <tt>toIndex</tt>, exclusive.
1075      * The returned list is backed by this list, so changes in the
1076      * returned list are reflected in this list.
1077      *
1078      * <p>The semantics of the list returned by this method become
1079      * undefined if the backing list (i.e., this list) is modified in
1080      * any way other than via the returned list.
1081      *
1082      * @param fromIndex low endpoint (inclusive) of the subList
1083      * @param toIndex high endpoint (exclusive) of the subList
1084      * @return a view of the specified range within this list
1085      * @throws IndexOutOfBoundsException {@inheritDoc}
1086      */
1087     public List<E> subList(int fromIndex, int toIndex) {
1088         final ReentrantLock lock = this.lock;
1089         lock.lock();


1308         }
1309 
1310         public int nextIndex() {
1311             return it.nextIndex() - offset;
1312         }
1313 
1314         public int previousIndex() {
1315             return it.previousIndex() - offset;
1316         }
1317 
1318         public void remove() {
1319             throw new UnsupportedOperationException();
1320         }
1321 
1322         public void set(E e) {
1323             throw new UnsupportedOperationException();
1324         }
1325 
1326         public void add(E e) {
1327             throw new UnsupportedOperationException();
1328         }
1329 
1330         @Override
1331         @SuppressWarnings("unchecked")
1332         public void forEachRemaining(Consumer<? super E> action) {
1333             Objects.requireNonNull(action);
1334             while (nextIndex() < size) {
1335                 action.accept(it.next());
1336             }
1337         }
1338     }
1339 
1340     // Support for resetting lock while deserializing
1341     private void resetLock() {
1342         UNSAFE.putObjectVolatile(this, lockOffset, new ReentrantLock());
1343     }
1344     private static final sun.misc.Unsafe UNSAFE;
1345     private static final long lockOffset;
1346     static {
1347         try {
1348             UNSAFE = sun.misc.Unsafe.getUnsafe();
1349             Class<?> k = CopyOnWriteArrayList.class;
1350             lockOffset = UNSAFE.objectFieldOffset
1351                 (k.getDeclaredField("lock"));
1352         } catch (Exception e) {
1353             throw new Error(e);
1354         }
1355     }
1356 }