You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pc...@apache.org on 2006/07/01 00:37:29 UTC
svn commit: r418401 [15/32] - in /incubator/openjpa/trunk: openjpa-lib/
openjpa-lib/src/main/java/org/apache/openjpa/lib/ant/
openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/
openjpa-lib/src/main/java/org/apache/openjpa/lib/jdbc/ openjpa-lib/src/...
Modified: incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/Condition.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/Condition.java?rev=418401&r1=418400&r2=418401&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/Condition.java (original)
+++ incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/Condition.java Fri Jun 30 15:37:18 2006
@@ -1,19 +1,15 @@
/*
* Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
+ * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
/*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
@@ -23,33 +19,29 @@
import java.util.Date;
-
/**
* <tt>Condition</tt> factors out the <tt>Object</tt> monitor
- * methods ({@link Object#wait() wait}, {@link Object#notify notify}
+ * methods({@link Object#wait() wait}, {@link Object#notify notify}
* and {@link Object#notifyAll notifyAll}) into distinct objects to
* give the effect of having multiple wait-sets per object, by
* combining them with the use of arbitrary {@link Lock} implementations.
* Where a <tt>Lock</tt> replaces the use of <tt>synchronized</tt> methods
* and statements, a <tt>Condition</tt> replaces the use of the Object
* monitor methods.
- *
- * <p>Conditions (also known as <em>condition queues</em> or
+ * Conditions(also known as <em>condition queues</em> or
* <em>condition variables</em>) provide a means for one thread to
- * suspend execution (to "wait") until notified by another
- * thread that some state condition may now be true. Because access
+ * suspend execution(to "wait") until notified by another
+ * thread that some state condition may now be true. Because access
* to this shared state information occurs in different threads, it
* must be protected, so a lock of some form is associated with the
* condition. The key property that waiting for a condition provides
* is that it <em>atomically</em> releases the associated lock and
* suspends the current thread, just like <tt>Object.wait</tt>.
- *
- * <p>A <tt>Condition</tt> instance is intrinsically bound to a lock.
+ * A <tt>Condition</tt> instance is intrinsically bound to a lock.
* To obtain a <tt>Condition</tt> instance for a particular {@link Lock}
* instance use its {@link Lock#newCondition newCondition()} method.
- *
- * <p>As an example, suppose we have a bounded buffer which supports
- * <tt>put</tt> and <tt>take</tt> methods. If a
+ * As an example, suppose we have a bounded buffer which supports
+ * <tt>put</tt> and <tt>take</tt> methods. If a
* <tt>take</tt> is attempted on an empty buffer, then the thread will block
* until an item becomes available; if a <tt>put</tt> is attempted on a
* full buffer, then the thread will block until a space becomes available.
@@ -58,59 +50,35 @@
* only notifying a single thread at a time when items or spaces become
* available in the buffer. This can be achieved using two
* {@link Condition} instances.
- * <pre>
- * class BoundedBuffer {
- * <b>final Lock lock = new ReentrantLock();</b>
- * final Condition notFull = <b>lock.newCondition(); </b>
- * final Condition notEmpty = <b>lock.newCondition(); </b>
- *
- * final Object[] items = new Object[100];
- * int putptr, takeptr, count;
- *
- * public void put(Object x) throws InterruptedException {
- * <b>lock.lock();
- * try {</b>
- * while (count == items.length)
- * <b>notFull.await();</b>
- * items[putptr] = x;
- * if (++putptr == items.length) putptr = 0;
- * ++count;
- * <b>notEmpty.signal();</b>
- * <b>} finally {
- * lock.unlock();
- * }</b>
- * }
- *
- * public Object take() throws InterruptedException {
- * <b>lock.lock();
- * try {</b>
- * while (count == 0)
- * <b>notEmpty.await();</b>
- * Object x = items[takeptr];
- * if (++takeptr == items.length) takeptr = 0;
- * --count;
- * <b>notFull.signal();</b>
- * return x;
- * <b>} finally {
- * lock.unlock();
- * }</b>
- * }
- * }
+ * <pre> class BoundedBuffer {
+ * <b>final Lock lock = new ReentrantLock();</b>
+ * final Condition notFull = <b>lock.newCondition(); </b>
+ * final Condition notEmpty = <b>lock.newCondition(); </b>
+ * final Object[] items = new Object[100]; int putptr, takeptr, count;
+ * public void put(Object x) throws InterruptedException {
+ * <b>lock.lock(); try {</b> while (count == items.length)
+ * <b>notFull.await();</b> items[putptr] = x;
+ * if (++putptr == items.length) putptr = 0; ++count;
+ * <b>notEmpty.signal();</b>
+ * <b>} finally { lock.unlock(); }</b> }
+ * public Object take() throws InterruptedException {
+ * <b>lock.lock(); try {</b> while (count == 0)
+ * <b>notEmpty.await();</b> Object x = items[takeptr];
+ * if (++takeptr == items.length) takeptr = 0; --count;
+ * <b>notFull.signal();</b> return x;
+ * <b>} finally { lock.unlock(); }</b> } }
* </pre>
- *
+ *
* (The {@link edu.emory.mathcs.backport.java.util.concurrent.ArrayBlockingQueue} class provides
* this functionality, so there is no reason to implement this
* sample usage class.)
- *
- * <p>A <tt>Condition</tt> implementation can provide behavior and semantics
- * that is
- * different from that of the <tt>Object</tt> monitor methods, such as
+ * A <tt>Condition</tt> implementation can provide behavior and semantics
+ * that is different from that of the <tt>Object</tt> monitor methods, such as
* guaranteed ordering for notifications, or not requiring a lock to be held
* when performing notifications.
* If an implementation provides such specialized semantics then the
* implementation must document those semantics.
- *
- * <p>Note that <tt>Condition</tt> instances are just normal objects and can
+ * Note that <tt>Condition</tt> instances are just normal objects and can
* themselves be used as the target in a <tt>synchronized</tt> statement,
* and can have their own monitor {@link Object#wait wait} and
* {@link Object#notify notification} methods invoked.
@@ -120,53 +88,50 @@
* {@link #await waiting} and {@link #signal signalling} methods.
* It is recommended that to avoid confusion you never use <tt>Condition</tt>
* instances in this way, except perhaps within their own implementation.
- *
- * <p>Except where noted, passing a <tt>null</tt> value for any parameter
+ * Except where noted, passing a <tt>null</tt> value for any parameter
* will result in a {@link NullPointerException} being thrown.
- *
+ *
* <h3>Implementation Considerations</h3>
- *
- * <p>When waiting upon a <tt>Condition</tt>, a "<em>spurious
+ * When waiting upon a <tt>Condition</tt>, a "<em>spurious
* wakeup</em>" is permitted to occur, in
* general, as a concession to the underlying platform semantics.
* This has little practical impact on most application programs as a
* <tt>Condition</tt> should always be waited upon in a loop, testing
- * the state predicate that is being waited for. An implementation is
+ * the state predicate that is being waited for. An implementation is
* free to remove the possibility of spurious wakeups but it is
* recommended that applications programmers always assume that they can
* occur and so always wait in a loop.
- *
- * <p>The three forms of condition waiting
+ * The three forms of condition waiting
* (interruptible, non-interruptible, and timed) may differ in their ease of
* implementation on some platforms and in their performance characteristics.
* In particular, it may be difficult to provide these features and maintain
* specific semantics such as ordering guarantees.
* Further, the ability to interrupt the actual suspension of the thread may
* not always be feasible to implement on all platforms.
- * <p>Consequently, an implementation is not required to define exactly the
+ * Consequently, an implementation is not required to define exactly the
* same guarantees or semantics for all three forms of waiting, nor is it
* required to support interruption of the actual suspension of the thread.
- * <p>An implementation is required to
+ * An implementation is required to
* clearly document the semantics and guarantees provided by each of the
* waiting methods, and when an implementation does support interruption of
* thread suspension then it must obey the interruption semantics as defined
* in this interface.
- * <p>As interruption generally implies cancellation, and checks for
+ * As interruption generally implies cancellation, and checks for
* interruption are often infrequent, an implementation can favor responding
* to an interrupt over normal method return. This is true even if it can be
* shown that the interrupt occurred after another action may have unblocked
* the thread. An implementation should document this behavior.
- *
- *
+ *
+ *
* @since 1.5
* @author Doug Lea
*/
public interface Condition {
+
/**
* Causes the current thread to wait until it is signalled or
* {@link Thread#interrupt interrupted}.
- *
- * <p>The lock associated with this <tt>Condition</tt> is atomically
+ * The lock associated with this <tt>Condition</tt> is atomically
* released and the current thread becomes disabled for thread scheduling
* purposes and lies dormant until <em>one</em> of four things happens:
* <ul>
@@ -179,12 +144,10 @@
* thread, and interruption of thread suspension is supported; or
* <li>A "<em>spurious wakeup</em>" occurs
* </ul>
- *
- * <p>In all cases, before this method can return the current thread must
+ * In all cases, before this method can return the current thread must
* re-acquire the lock associated with this condition. When the
* thread returns it is <em>guaranteed</em> to hold this lock.
- *
- * <p>If the current thread:
+ * If the current thread:
* <ul>
* <li>has its interrupted status set on entry to this method; or
* <li>is {@link Thread#interrupt interrupted} while waiting
@@ -194,29 +157,27 @@
* interrupted status is cleared. It is not specified, in the first
* case, whether or not the test for interruption occurs before the lock
* is released.
- *
- * <p><b>Implementation Considerations</b>
- * <p>The current thread is assumed to hold the lock associated with this
+ *
+ * <b>Implementation Considerations</b>
+ * The current thread is assumed to hold the lock associated with this
* <tt>Condition</tt> when this method is called.
* It is up to the implementation to determine if this is
* the case and if not, how to respond. Typically, an exception will be
- * thrown (such as {@link IllegalMonitorStateException}) and the
+ * thrown(such as {@link IllegalMonitorStateException}) and the
* implementation must document that fact.
- *
- * <p>An implementation can favor responding to an interrupt over normal
+ * An implementation can favor responding to an interrupt over normal
* method return in response to a signal. In that case the implementation
* must ensure that the signal is redirected to another waiting thread, if
* there is one.
- *
- * @throws InterruptedException if the current thread is interrupted (and
+ *
+ * @throws InterruptedException if the current thread is interrupted(and
* interruption of thread suspension is supported).
*/
void await() throws InterruptedException;
/**
* Causes the current thread to wait until it is signalled.
- *
- * <p>The lock associated with this condition is atomically
+ * The lock associated with this condition is atomically
* released and the current thread becomes disabled for thread scheduling
* purposes and lies dormant until <em>one</em> of three things happens:
* <ul>
@@ -227,125 +188,121 @@
* <tt>Condition</tt>; or
* <li>A "<em>spurious wakeup</em>" occurs
* </ul>
- *
- * <p>In all cases, before this method can return the current thread must
+ * In all cases, before this method can return the current thread must
* re-acquire the lock associated with this condition. When the
* thread returns it is <em>guaranteed</em> to hold this lock.
- *
- * <p>If the current thread's interrupted status is set when it enters
+ * If the current thread's interrupted status is set when it enters
* this method, or it is {@link Thread#interrupt interrupted}
* while waiting, it will continue to wait until signalled. When it finally
- * returns from this method its interrupted status will still
- * be set.
- *
- * <p><b>Implementation Considerations</b>
- * <p>The current thread is assumed to hold the lock associated with this
+ * returns from this method its interrupted status will still be set.
+ *
+ * <b>Implementation Considerations</b>
+ * The current thread is assumed to hold the lock associated with this
* <tt>Condition</tt> when this method is called.
* It is up to the implementation to determine if this is
* the case and if not, how to respond. Typically, an exception will be
- * thrown (such as {@link IllegalMonitorStateException}) and the
+ * thrown(such as {@link IllegalMonitorStateException}) and the
* implementation must document that fact.
*/
void awaitUninterruptibly();
- // /**
- // * Causes the current thread to wait until it is signalled or interrupted,
- // * or the specified waiting time elapses.
- // *
- // * <p>The lock associated with this condition is atomically
- // * released and the current thread becomes disabled for thread scheduling
- // * purposes and lies dormant until <em>one</em> of five things happens:
- // * <ul>
- // * <li>Some other thread invokes the {@link #signal} method for this
- // * <tt>Condition</tt> and the current thread happens to be chosen as the
- // * thread to be awakened; or
- // * <li>Some other thread invokes the {@link #signalAll} method for this
- // * <tt>Condition</tt>; or
- // * <li>Some other thread {@link Thread#interrupt interrupts} the current
- // * thread, and interruption of thread suspension is supported; or
- // * <li>The specified waiting time elapses; or
- // * <li>A "<em>spurious wakeup</em>" occurs.
- // * </ul>
- // *
- // * <p>In all cases, before this method can return the current thread must
- // * re-acquire the lock associated with this condition. When the
- // * thread returns it is <em>guaranteed</em> to hold this lock.
- // *
- // * <p>If the current thread:
- // * <ul>
- // * <li>has its interrupted status set on entry to this method; or
- // * <li>is {@link Thread#interrupt interrupted} while waiting
- // * and interruption of thread suspension is supported,
- // * </ul>
- // * then {@link InterruptedException} is thrown and the current thread's
- // * interrupted status is cleared. It is not specified, in the first
- // * case, whether or not the test for interruption occurs before the lock
- // * is released.
- // *
- // * <p>The method returns an estimate of the number of nanoseconds
- // * remaining to wait given the supplied <tt>nanosTimeout</tt>
- // * value upon return, or a value less than or equal to zero if it
- // * timed out. This value can be used to determine whether and how
- // * long to re-wait in cases where the wait returns but an awaited
- // * condition still does not hold. Typical uses of this method take
- // * the following form:
- // *
- // * <pre>
- // * synchronized boolean aMethod(long timeout, TimeUnit unit) {
- // * long nanosTimeout = unit.toNanos(timeout);
- // * while (!conditionBeingWaitedFor) {
- // * if (nanosTimeout > 0)
- // * nanosTimeout = theCondition.awaitNanos(nanosTimeout);
- // * else
- // * return false;
- // * }
- // * // ...
- // * }
- // * </pre>
- // *
- // * <p> Design note: This method requires a nanosecond argument so
- // * as to avoid truncation errors in reporting remaining times.
- // * Such precision loss would make it difficult for programmers to
- // * ensure that total waiting times are not systematically shorter
- // * than specified when re-waits occur.
- // *
- // * <p><b>Implementation Considerations</b>
- // * <p>The current thread is assumed to hold the lock associated with this
- // * <tt>Condition</tt> when this method is called.
- // * It is up to the implementation to determine if this is
- // * the case and if not, how to respond. Typically, an exception will be
- // * thrown (such as {@link IllegalMonitorStateException}) and the
- // * implementation must document that fact.
- // *
- // * <p>An implementation can favor responding to an interrupt over normal
- // * method return in response to a signal, or over indicating the elapse
- // * of the specified waiting time. In either case the implementation
- // * must ensure that the signal is redirected to another waiting thread, if
- // * there is one.
- // *
- // * @param nanosTimeout the maximum time to wait, in nanoseconds
- // * @return A value less than or equal to zero if the wait has
- // * timed out; otherwise an estimate, that
- // * is strictly less than the <tt>nanosTimeout</tt> argument,
- // * of the time still remaining when this method returned.
- // *
- // * @throws InterruptedException if the current thread is interrupted (and
- // * interruption of thread suspension is supported).
- // */
- // long awaitNanos(long nanosTimeout) throws InterruptedException;
+// /**
+// * Causes the current thread to wait until it is signalled or interrupted,
+// * or the specified waiting time elapses.
+// *
+// * <p>The lock associated with this condition is atomically
+// * released and the current thread becomes disabled for thread scheduling
+// * purposes and lies dormant until <em>one</em> of five things happens:
+// * <ul>
+// * <li>Some other thread invokes the {@link #signal} method for this
+// * <tt>Condition</tt> and the current thread happens to be chosen as the
+// * thread to be awakened; or
+// * <li>Some other thread invokes the {@link #signalAll} method for this
+// * <tt>Condition</tt>; or
+// * <li>Some other thread {@link Thread#interrupt interrupts} the current
+// * thread, and interruption of thread suspension is supported; or
+// * <li>The specified waiting time elapses; or
+// * <li>A "<em>spurious wakeup</em>" occurs.
+// * </ul>
+// *
+// * <p>In all cases, before this method can return the current thread must
+// * re-acquire the lock associated with this condition. When the
+// * thread returns it is <em>guaranteed</em> to hold this lock.
+// *
+// * <p>If the current thread:
+// * <ul>
+// * <li>has its interrupted status set on entry to this method; or
+// * <li>is {@link Thread#interrupt interrupted} while waiting
+// * and interruption of thread suspension is supported,
+// * </ul>
+// * then {@link InterruptedException} is thrown and the current thread's
+// * interrupted status is cleared. It is not specified, in the first
+// * case, whether or not the test for interruption occurs before the lock
+// * is released.
+// *
+// * <p>The method returns an estimate of the number of nanoseconds
+// * remaining to wait given the supplied <tt>nanosTimeout</tt>
+// * value upon return, or a value less than or equal to zero if it
+// * timed out. This value can be used to determine whether and how
+// * long to re-wait in cases where the wait returns but an awaited
+// * condition still does not hold. Typical uses of this method take
+// * the following form:
+// *
+// * <pre>
+// * synchronized boolean aMethod(long timeout, TimeUnit unit) {
+// * long nanosTimeout = unit.toNanos(timeout);
+// * while (!conditionBeingWaitedFor) {
+// * if (nanosTimeout > 0)
+// * nanosTimeout = theCondition.awaitNanos(nanosTimeout);
+// * else
+// * return false;
+// * }
+// * // ...
+// * }
+// * </pre>
+// *
+// * <p> Design note: This method requires a nanosecond argument so
+// * as to avoid truncation errors in reporting remaining times.
+// * Such precision loss would make it difficult for programmers to
+// * ensure that total waiting times are not systematically shorter
+// * than specified when re-waits occur.
+// *
+// * <p><b>Implementation Considerations</b>
+// * <p>The current thread is assumed to hold the lock associated with this
+// * <tt>Condition</tt> when this method is called.
+// * It is up to the implementation to determine if this is
+// * the case and if not, how to respond. Typically, an exception will be
+// * thrown(such as {@link IllegalMonitorStateException}) and the
+// * implementation must document that fact.
+// *
+// * <p>An implementation can favor responding to an interrupt over normal
+// * method return in response to a signal, or over indicating the elapse
+// * of the specified waiting time. In either case the implementation
+// * must ensure that the signal is redirected to another waiting thread, if
+// * there is one.
+// *
+// * @param nanosTimeout the maximum time to wait, in nanoseconds
+// * @return A value less than or equal to zero if the wait has
+// * timed out; otherwise an estimate, that
+// * is strictly less than the <tt>nanosTimeout</tt> argument,
+// * of the time still remaining when this method returned.
+// *
+// * @throws InterruptedException if the current thread is interrupted(and
+// * interruption of thread suspension is supported).
+// */
+// long awaitNanos(long nanosTimeout) throws InterruptedException;
/**
* Causes the current thread to wait until it is signalled or interrupted,
* or the specified waiting time elapses. This method is behaviorally
* equivalent to:<br>
- * <pre>
- * awaitNanos(unit.toNanos(time)) > 0
+ * <pre> awaitNanos(unit.toNanos(time)) > 0
* </pre>
* @param time the maximum time to wait
* @param unit the time unit of the <tt>time</tt> argument.
* @return <tt>false</tt> if the waiting time detectably elapsed
* before return from the method, else <tt>true</tt>.
- * @throws InterruptedException if the current thread is interrupted (and
+ * @throws InterruptedException if the current thread is interrupted(and
* interruption of thread suspension is supported).
*/
boolean await(long time, TimeUnit unit) throws InterruptedException;
@@ -353,8 +310,7 @@
/**
* Causes the current thread to wait until it is signalled or interrupted,
* or the specified deadline elapses.
- *
- * <p>The lock associated with this condition is atomically
+ * The lock associated with this condition is atomically
* released and the current thread becomes disabled for thread scheduling
* purposes and lies dormant until <em>one</em> of five things happens:
* <ul>
@@ -368,13 +324,11 @@
* <li>The specified deadline elapses; or
* <li>A "<em>spurious wakeup</em>" occurs.
* </ul>
- *
- * <p>In all cases, before this method can return the current thread must
+ * In all cases, before this method can return the current thread must
* re-acquire the lock associated with this condition. When the
* thread returns it is <em>guaranteed</em> to hold this lock.
- *
- *
- * <p>If the current thread:
+ *
+ * If the current thread:
* <ul>
* <li>has its interrupted status set on entry to this method; or
* <li>is {@link Thread#interrupt interrupted} while waiting
@@ -384,51 +338,41 @@
* interrupted status is cleared. It is not specified, in the first
* case, whether or not the test for interruption occurs before the lock
* is released.
- *
- *
- * <p>The return value indicates whether the deadline has elapsed,
+ *
+ * The return value indicates whether the deadline has elapsed,
* which can be used as follows:
- * <pre>
- * synchronized boolean aMethod(Date deadline) {
- * boolean stillWaiting = true;
- * while (!conditionBeingWaitedFor) {
- * if (stillWaiting)
- * stillWaiting = theCondition.awaitUntil(deadline);
- * else
- * return false;
- * }
- * // ...
- * }
+ * <pre> synchronized boolean aMethod(Date deadline) {
+ * boolean stillWaiting = true; while (!conditionBeingWaitedFor) {
+ * if (stillWaiting) stillWaiting = theCondition.awaitUntil(deadline); else
+ * return false; } // ... }
* </pre>
- *
- * <p><b>Implementation Considerations</b>
- * <p>The current thread is assumed to hold the lock associated with this
+ *
+ * <b>Implementation Considerations</b>
+ * The current thread is assumed to hold the lock associated with this
* <tt>Condition</tt> when this method is called.
* It is up to the implementation to determine if this is
* the case and if not, how to respond. Typically, an exception will be
- * thrown (such as {@link IllegalMonitorStateException}) and the
+ * thrown(such as {@link IllegalMonitorStateException}) and the
* implementation must document that fact.
- *
- * <p>An implementation can favor responding to an interrupt over normal
+ * An implementation can favor responding to an interrupt over normal
* method return in response to a signal, or over indicating the passing
* of the specified deadline. In either case the implementation
* must ensure that the signal is redirected to another waiting thread, if
* there is one.
- *
- *
+ *
+ *
* @param deadline the absolute time to wait until
* @return <tt>false</tt> if the deadline has
* elapsed upon return, else <tt>true</tt>.
- *
- * @throws InterruptedException if the current thread is interrupted (and
+ *
+ * @throws InterruptedException if the current thread is interrupted(and
* interruption of thread suspension is supported).
*/
boolean awaitUntil(Date deadline) throws InterruptedException;
/**
* Wakes up one waiting thread.
- *
- * <p>If any threads are waiting on this condition then one
+ * If any threads are waiting on this condition then one
* is selected for waking up. That thread must then re-acquire the
* lock before returning from <tt>await</tt>.
*/
@@ -436,8 +380,7 @@
/**
* Wakes up all waiting threads.
- *
- * <p>If any threads are waiting on this condition then they are
+ * If any threads are waiting on this condition then they are
* all woken up. Each thread must re-acquire the lock before it can
* return from <tt>await</tt>.
*/
Modified: incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/CopyOnWriteArrayList.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/CopyOnWriteArrayList.java?rev=418401&r1=418400&r2=418401&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/CopyOnWriteArrayList.java (original)
+++ incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/CopyOnWriteArrayList.java Fri Jun 30 15:37:18 2006
@@ -1,19 +1,15 @@
/*
* Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
+ * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
/*
* Written by Dawid Kurzyniec, on the basis of public specifications and
* public domain sources from JSR 166, and released to the public domain,
@@ -25,19 +21,18 @@
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
-
import java.lang.reflect.Array;
-
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
-import java.util.List;
import java.util.ListIterator;
+import java.util.List;
import java.util.NoSuchElementException;
-
public class CopyOnWriteArrayList implements List, Cloneable, Serializable {
+
private static final long serialVersionUID = 8673264195747942595L;
+
private volatile transient Object[] array;
public CopyOnWriteArrayList() {
@@ -47,12 +42,10 @@
public CopyOnWriteArrayList(Collection c) {
// must deal with concurrent collections
Object[] array = c.toArray();
-
// make sure the array is Object[] type
if (array.getClass() != Object[].class) {
array = Arrays.copyOf(array, array.length, Object[].class);
}
-
// assume that c.toArray() has returned a new array instance, as
// required by the spec
setArray(array);
@@ -62,13 +55,9 @@
setArray(Arrays.copyOf(array, array.length, Object[].class));
}
- final Object[] getArray() {
- return array;
- }
+ final Object[] getArray() { return array; }
- final void setArray(Object[] array) {
- this.array = array;
- }
+ final void setArray(Object[] array) { this.array = array; }
public int size() {
return getArray().length;
@@ -78,21 +67,16 @@
return getArray().length == 0;
}
- private static int search(Object[] array, Object subject, int pos, int end) {
+ private static int search(Object[] array, Object subject, int pos, int end){
if (subject == null) {
- for (; pos < end; pos++) {
- if (array[pos] == null) {
- return pos;
- }
+ for (;pos < end; pos++) {
+ if (array[pos] == null) return pos;
}
} else {
- for (; pos < end; pos++) {
- if (subject.equals(array[pos])) {
- return pos;
- }
+ for (;pos < end; pos++) {
+ if (subject.equals(array[pos])) return pos;
}
}
-
return -1;
}
@@ -100,24 +84,18 @@
int pos) {
if (subject == null) {
for (pos--; pos >= start; pos--) {
- if (array[pos] == null) {
- return pos;
- }
+ if (array[pos] == null) return pos;
}
} else {
for (pos--; pos >= start; pos--) {
- if (subject.equals(array[pos])) {
- return pos;
- }
+ if (subject.equals(array[pos])) return pos;
}
}
-
return -1;
}
public boolean contains(Object o) {
Object[] array = getArray();
-
return search(array, o, 0, array.length) >= 0;
}
@@ -127,23 +105,17 @@
public Object[] toArray() {
Object[] array = getArray();
-
return Arrays.copyOf(array, array.length, Object[].class);
}
public Object[] toArray(Object[] a) {
Object[] array = getArray();
int length = array.length;
-
if (a.length < length) {
return Arrays.copyOf(array, length, a.getClass());
} else {
System.arraycopy(array, 0, a, 0, length);
-
- if (a.length > length) {
- a[length] = null;
- }
-
+ if (a.length > length) a[length] = null;
return a;
}
}
@@ -152,11 +124,10 @@
synchronized (this) {
Object[] oldarr = getArray();
int length = oldarr.length;
- Object[] newarr = new Object[length + 1];
+ Object[] newarr = new Object[length+1];
System.arraycopy(oldarr, 0, newarr, 0, length);
newarr[length] = o;
setArray(newarr);
-
return true;
}
}
@@ -165,51 +136,35 @@
synchronized (this) {
Object[] oldarr = getArray();
int length = oldarr.length;
-
- if (search(array, o, 0, length) >= 0) {
- return false;
- }
-
- Object[] newarr = new Object[length + 1];
+ if (search(array, o, 0, length) >= 0) return false;
+ Object[] newarr = new Object[length+1];
System.arraycopy(oldarr, 0, newarr, 0, length);
newarr[length] = o;
setArray(newarr);
-
return true;
}
}
public int addAllAbsent(Collection c) {
Object[] arr = c.toArray();
-
- if (arr.length == 0) {
- return 0;
- }
-
+ if (arr.length == 0) return 0;
synchronized (this) {
Object[] oldarr = getArray();
int oldlength = oldarr.length;
Object[] tmp = new Object[arr.length];
int added = 0;
-
- for (int i = 0; i < arr.length; i++) {
+ for (int i=0; i<arr.length; i++) {
Object o = arr[i];
-
- if ((search(oldarr, o, 0, oldlength) < 0) &&
- (search(tmp, o, 0, added) < 0)) {
+ if (search(oldarr, o, 0, oldlength) < 0
+ && search(tmp, o, 0, added) < 0) {
tmp[added++] = o;
}
}
-
- if (added == 0) {
- return 0;
- }
-
- Object[] newarr = new Object[oldlength + added];
+ if (added == 0) return 0;
+ Object[] newarr = new Object[oldlength+added];
System.arraycopy(oldarr, 0, newarr, 0, oldlength);
System.arraycopy(tmp, 0, newarr, oldlength, added);
setArray(newarr);
-
return added;
}
}
@@ -219,58 +174,36 @@
Object[] array = getArray();
int length = array.length;
int pos = search(array, o, 0, length);
-
- if (pos < 0) {
- return false;
- }
-
- Object[] newarr = new Object[length - 1];
- int moved = length - pos - 1;
-
- if (pos > 0) {
- System.arraycopy(array, 0, newarr, 0, pos);
- }
-
- if (moved > 0) {
- System.arraycopy(array, pos + 1, newarr, pos, moved);
- }
-
+ if (pos < 0) return false;
+ Object[] newarr = new Object[length-1];
+ int moved = length-pos-1;
+ if (pos > 0) System.arraycopy(array, 0, newarr, 0, pos);
+ if (moved > 0) System.arraycopy(array, pos+1, newarr, pos, moved);
setArray(newarr);
-
return true;
}
}
public boolean containsAll(Collection c) {
Object[] array = getArray();
-
for (Iterator itr = c.iterator(); itr.hasNext();) {
- if (search(array, itr.next(), 0, array.length) < 0) {
- return false;
- }
+ if (search(array, itr.next(), 0, array.length) < 0) return false;
}
-
return true;
}
public boolean addAll(Collection c) {
// must deal with concurrent collections
Object[] ca = c.toArray();
-
- if (ca.length == 0) {
- return false;
- }
-
+ if (ca.length == 0) return false;
synchronized (this) {
Object[] oldarr = getArray();
int length = oldarr.length;
Object[] newarr = new Object[length + ca.length];
System.arraycopy(oldarr, 0, newarr, 0, length);
-
int pos = length;
System.arraycopy(ca, 0, newarr, pos, ca.length);
setArray(newarr);
-
return true;
}
}
@@ -278,64 +211,42 @@
public boolean addAll(int index, Collection c) {
// must deal with concurrent collections
Object[] ca = c.toArray();
-
synchronized (this) {
Object[] oldarr = getArray();
int length = oldarr.length;
-
- if ((index < 0) || (index > length)) {
+ if (index < 0 || index > length) {
throw new IndexOutOfBoundsException("Index: " + index +
- ", Size: " + length);
- }
-
- if (ca.length == 0) {
- return false;
+ ", Size: " + length);
}
-
- Object[] newarr = new Object[length + ca.length];
- int moved = length - index;
+ if (ca.length == 0) return false;
+ Object[] newarr = new Object[length+ca.length];
+ int moved = length-index;
System.arraycopy(oldarr, 0, newarr, 0, index);
-
int pos = length;
System.arraycopy(ca, 0, newarr, index, ca.length);
-
if (moved > 0) {
- System.arraycopy(oldarr, index, newarr, index + ca.length, moved);
+ System.arraycopy(oldarr, index, newarr, index+ca.length, moved);
}
-
setArray(newarr);
-
return true;
}
}
public boolean removeAll(Collection c) {
- if (c.isEmpty()) {
- return false;
- }
-
+ if (c.isEmpty()) return false;
synchronized (this) {
Object[] array = getArray();
int length = array.length;
Object[] tmp = new Object[length];
- int newlen = 0;
-
- for (int i = 0; i < length; i++) {
+ int newlen=0;
+ for (int i=0; i<length; i++) {
Object o = array[i];
-
- if (!c.contains(o)) {
- tmp[newlen++] = o;
- }
- }
-
- if (newlen == length) {
- return false;
+ if (!c.contains(o)) tmp[newlen++] = o;
}
-
+ if (newlen == length) return false;
Object[] newarr = new Object[newlen];
System.arraycopy(tmp, 0, newarr, 0, newlen);
setArray(newarr);
-
return true;
}
}
@@ -345,24 +256,15 @@
Object[] array = getArray();
int length = array.length;
Object[] tmp = new Object[length];
- int newlen = 0;
-
- for (int i = 0; i < length; i++) {
+ int newlen=0;
+ for (int i=0; i<length; i++) {
Object o = array[i];
-
- if (c.contains(o)) {
- tmp[newlen++] = o;
- }
+ if (c.contains(o)) tmp[newlen++] = o;
}
-
- if (newlen == length) {
- return false;
- }
-
+ if (newlen == length) return false;
Object[] newarr = new Object[newlen];
System.arraycopy(tmp, 0, newarr, 0, newlen);
setArray(newarr);
-
return true;
}
}
@@ -372,49 +274,33 @@
}
public Object clone() {
- try {
- return super.clone();
- } catch (CloneNotSupportedException e) {
- throw new InternalError();
- }
+ try { return super.clone(); } catch (CloneNotSupportedException e) { throw new InternalError(); }
}
public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
-
- if (!(o instanceof List)) {
- return false;
- }
+ if (o == this) return true;
+ if (!(o instanceof List)) return false;
- ListIterator itr = ((List) o).listIterator();
+ ListIterator itr = ((List)o).listIterator();
Object[] array = getArray();
int length = array.length;
- int idx = 0;
-
- while ((idx < length) && itr.hasNext()) {
+ int idx=0;
+ while(idx < length && itr.hasNext()) {
Object o1 = array[idx++];
Object o2 = itr.next();
-
- if (!eq(o1, o2)) {
- return false;
- }
+ if (!eq(o1, o2)) return false;
}
-
- return ((idx == length) && !itr.hasNext());
+ return(idx == length && !itr.hasNext());
}
public int hashCode() {
int hashCode = 1;
Object[] array = getArray();
int length = array.length;
-
- for (int i = 0; i < length; i++) {
+ for (int i=0; i<length; i++) {
Object o = array[i];
- hashCode = (31 * hashCode) + ((o == null) ? 0 : o.hashCode());
+ hashCode = 31*hashCode + (o == null ? 0 : o.hashCode());
}
-
return hashCode;
}
@@ -426,10 +312,8 @@
synchronized (this) {
Object[] oldarr = getArray();
int length = oldarr.length;
-
// piggyback the array bounds check
Object oldVal = oldarr[index];
-
if (oldVal == element) {
setArray(oldarr);
} else {
@@ -438,7 +322,6 @@
newarr[index] = element;
setArray(newarr);
}
-
return oldVal;
}
}
@@ -447,21 +330,17 @@
synchronized (this) {
Object[] oldarr = getArray();
int length = oldarr.length;
-
- if ((index < 0) || (index > length)) {
+ if (index < 0 || index > length) {
throw new IndexOutOfBoundsException("Index: " + index +
- ", Size: " + length);
+ ", Size: " + length);
}
-
- Object[] newarr = new Object[length + 1];
- int moved = length - index;
+ Object[] newarr = new Object[length+1];
+ int moved = length-index;
System.arraycopy(oldarr, 0, newarr, 0, index);
newarr[index] = element;
-
if (moved > 0) {
- System.arraycopy(oldarr, index, newarr, index + 1, moved);
+ System.arraycopy(oldarr, index, newarr, index+1, moved);
}
-
setArray(newarr);
}
}
@@ -470,51 +349,37 @@
synchronized (this) {
Object[] array = getArray();
int length = array.length;
-
- if ((index < 0) || (index >= length)) {
+ if (index < 0 || index >= length) {
throw new IndexOutOfBoundsException("Index: " + index +
- ", Size: " + length);
+ ", Size: " + length);
}
-
Object result = array[index];
- Object[] newarr = new Object[length - 1];
- int moved = length - index - 1;
-
- if (index > 0) {
- System.arraycopy(array, 0, newarr, 0, index);
- }
-
- if (moved > 0) {
- System.arraycopy(array, index + 1, newarr, index, moved);
- }
-
+ Object[] newarr = new Object[length-1];
+ int moved = length-index-1;
+ if (index > 0) System.arraycopy(array, 0, newarr, 0, index);
+ if (moved > 0) System.arraycopy(array, index+1, newarr, index, moved);
setArray(newarr);
-
return result;
}
}
public int indexOf(Object o) {
Object[] array = getArray();
-
return search(array, o, 0, array.length);
}
public int indexOf(Object o, int index) {
Object[] array = getArray();
-
return search(array, o, index, array.length);
}
public int lastIndexOf(Object o) {
Object[] array = getArray();
-
return reverseSearch(array, o, 0, array.length);
}
public int lastIndexOf(Object o, int index) {
Object[] array = getArray();
-
return reverseSearch(array, o, 0, index);
}
@@ -524,33 +389,26 @@
public ListIterator listIterator(int index) {
Object[] array = getArray();
-
- if ((index < 0) || (index > array.length)) {
- throw new IndexOutOfBoundsException("Index: " + index + ", Size: " +
- array.length);
+ if (index < 0 || index > array.length) {
+ throw new IndexOutOfBoundsException("Index: " + index +
+ ", Size: " + array.length);
}
-
return new COWIterator(array, index);
}
public List subList(int fromIndex, int toIndex) {
Object[] array = getArray();
-
- if ((fromIndex < 0) || (toIndex > array.length) ||
- (fromIndex > toIndex)) {
+ if (fromIndex < 0 || toIndex > array.length || fromIndex > toIndex) {
throw new IndexOutOfBoundsException();
}
-
- return new COWSubList(fromIndex, toIndex - fromIndex);
+ return new COWSubList(fromIndex, toIndex-fromIndex);
}
private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
-
Object[] array = getArray();
int length = array.length;
out.writeInt(length);
-
for (int i = 0; i < length; i++)
out.writeObject(array[i]);
}
@@ -558,14 +416,11 @@
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException {
in.defaultReadObject();
-
int length = in.readInt();
Object[] array = new Object[length];
-
for (int i = 0; i < length; i++) {
array[i] = in.readObject();
}
-
setArray(array);
}
@@ -574,77 +429,43 @@
int length = array.length;
StringBuffer buf = new StringBuffer();
buf.append('[');
-
- for (int i = 0; i < length; i++) {
- if (i > 0) {
- buf.append(", ");
- }
-
+ for (int i=0; i<length; i++) {
+ if (i>0) buf.append(", ");
buf.append(array[i]);
}
-
buf.append(']');
-
return buf.toString();
}
- private static boolean eq(Object o1, Object o2) {
- return ((o1 == null) ? (o2 == null) : o1.equals(o2));
- }
-
static class COWIterator implements ListIterator {
final Object[] array;
int cursor;
-
COWIterator(Object[] array, int cursor) {
this.array = array;
this.cursor = cursor;
}
-
- public boolean hasNext() {
- return cursor < array.length;
- }
-
- public boolean hasPrevious() {
- return cursor > 0;
- }
-
- public int nextIndex() {
- return cursor;
- }
-
+ public boolean hasNext() { return cursor < array.length; }
+ public boolean hasPrevious() { return cursor > 0; }
+ public int nextIndex() { return cursor; }
public Object next() {
- try {
- return array[cursor++];
- } catch (IndexOutOfBoundsException e) {
+ try { return array[cursor++]; } catch (IndexOutOfBoundsException e) {
throw new NoSuchElementException();
}
-
// todo: should decrement cursor on failure?...
}
-
- public int previousIndex() {
- return cursor - 1;
- }
-
+ public int previousIndex() { return cursor-1; }
public Object previous() {
- try {
- return array[--cursor];
- } catch (IndexOutOfBoundsException e) {
+ try { return array[--cursor]; } catch (IndexOutOfBoundsException e) {
throw new NoSuchElementException();
}
-
// todo: should decrement cursor on failure?...
}
-
public void add(Object val) {
throw new UnsupportedOperationException();
}
-
public void set(Object val) {
throw new UnsupportedOperationException();
}
-
public void remove() {
throw new UnsupportedOperationException();
}
@@ -670,7 +491,7 @@
}
public boolean contains(Object o) {
- return search(getArray(), o, offset, offset + length) >= 0;
+ return search(getArray(), o, offset, offset+length) >= 0;
}
public Iterator iterator() {
@@ -681,77 +502,53 @@
Object[] array = getArray();
Object[] newarr = new Object[length];
System.arraycopy(array, offset, newarr, 0, length);
-
return newarr;
}
public Object[] toArray(Object[] a) {
Object[] array = getArray();
-
if (a.length < length) {
- a = (Object[]) Array.newInstance(a.getClass().getComponentType(),
- length);
+ a = (Object[])Array.newInstance(a.getClass().getComponentType(),
+ length);
System.arraycopy(array, offset, a, 0, length);
} else {
System.arraycopy(array, offset, a, 0, length);
-
- if (a.length > length) {
- a[length] = null;
- }
+ if (a.length > length) a[length] = null;
}
-
return a;
}
public boolean add(Object o) {
add(length, o);
-
return true;
}
public boolean remove(Object o) {
synchronized (CopyOnWriteArrayList.this) {
Object[] array = getArray();
-
- if (array != expectedArray) {
+ if (array != expectedArray)
throw new ConcurrentModificationException();
- }
-
int fullLength = array.length;
int pos = search(array, o, offset, length);
-
- if (pos < 0) {
- return false;
- }
-
- Object[] newarr = new Object[fullLength - 1];
- int moved = length - pos - 1;
-
- if (pos > 0) {
+ if (pos < 0) return false;
+ Object[] newarr = new Object[fullLength-1];
+ int moved = length-pos-1;
+ if (pos > 0)
System.arraycopy(array, 0, newarr, 0, pos);
- }
-
- if (moved > 0) {
- System.arraycopy(array, pos + 1, newarr, pos, moved);
- }
-
+ if (moved > 0)
+ System.arraycopy(array, pos+1, newarr, pos, moved);
setArray(newarr);
expectedArray = newarr;
length--;
-
return true;
}
}
public boolean containsAll(Collection c) {
Object[] array = getArray();
-
for (Iterator itr = c.iterator(); itr.hasNext();) {
- if (search(array, itr.next(), offset, length) < 0) {
- return false;
- }
+ if (search(array, itr.next(), offset, length) < 0) return false;
}
-
return true;
}
@@ -761,95 +558,57 @@
public boolean addAll(int index, Collection c) {
int added = c.size();
-
synchronized (CopyOnWriteArrayList.this) {
- if ((index < 0) || (index >= length)) {
+ if (index < 0 || index >= length) {
throw new IndexOutOfBoundsException("Index: " + index +
- ", Size: " + length);
+ ", Size: " + length);
}
-
Object[] oldarr = getArray();
-
- if (oldarr != expectedArray) {
+ if (oldarr != expectedArray)
throw new ConcurrentModificationException();
- }
-
- if (added == 0) {
- return false;
- }
-
+ if (added == 0) return false;
int fullLength = oldarr.length;
Object[] newarr = new Object[fullLength + added];
- int pos = offset + index;
+ int pos = offset+index;
int newpos = pos;
System.arraycopy(oldarr, 0, newarr, 0, pos);
-
- int rem = fullLength - pos;
-
- for (Iterator itr = c.iterator(); itr.hasNext();) {
+ int rem = fullLength-pos;
+ for (Iterator itr = c.iterator(); itr.hasNext(); ) {
newarr[newpos++] = itr.next();
}
-
- if (rem > 0) {
- System.arraycopy(oldarr, pos, newarr, newpos, rem);
- }
-
+ if (rem > 0) System.arraycopy(oldarr, pos, newarr, newpos, rem);
setArray(newarr);
expectedArray = newarr;
length += added;
-
return true;
}
}
public boolean removeAll(Collection c) {
- if (c.isEmpty()) {
- return false;
- }
-
+ if (c.isEmpty()) return false;
synchronized (CopyOnWriteArrayList.this) {
Object[] array = getArray();
-
- if (array != expectedArray) {
+ if (array != expectedArray)
throw new ConcurrentModificationException();
- }
-
int fullLength = array.length;
Object[] tmp = new Object[length];
- int retained = 0;
-
- for (int i = offset; i < (offset + length); i++) {
+ int retained=0;
+ for (int i=offset; i<offset+length; i++) {
Object o = array[i];
-
- if (!c.contains(o)) {
- tmp[retained++] = o;
- }
+ if (!c.contains(o)) tmp[retained++] = o;
}
-
- if (retained == length) {
- return false;
- }
-
- Object[] newarr = new Object[(fullLength + retained) - length];
+ if (retained == length) return false;
+ Object[] newarr = new Object[fullLength + retained-length];
int moved = fullLength - offset - length;
-
- if (offset > 0) {
- System.arraycopy(array, 0, newarr, 0, offset);
- }
-
- if (retained > 0) {
+ if (offset > 0) System.arraycopy(array, 0, newarr, 0, offset);
+ if (retained > 0)
System.arraycopy(tmp, 0, newarr, offset, retained);
- }
-
- if (moved > 0) {
- System.arraycopy(array, offset + length, newarr,
- offset + retained, moved);
- }
-
+ if (moved > 0)
+ System.arraycopy(array, offset+length, newarr,
+ offset+retained, moved);
setArray(newarr);
expectedArray = newarr;
length = retained;
-
return true;
}
}
@@ -857,47 +616,28 @@
public boolean retainAll(Collection c) {
synchronized (CopyOnWriteArrayList.this) {
Object[] array = getArray();
-
- if (array != expectedArray) {
+ if (array != expectedArray)
throw new ConcurrentModificationException();
- }
-
int fullLength = array.length;
Object[] tmp = new Object[length];
- int retained = 0;
-
- for (int i = offset; i < (offset + length); i++) {
+ int retained=0;
+ for (int i=offset; i<offset+length; i++) {
Object o = array[i];
-
- if (c.contains(o)) {
- tmp[retained++] = o;
- }
- }
-
- if (retained == length) {
- return false;
+ if (c.contains(o)) tmp[retained++] = o;
}
-
- Object[] newarr = new Object[(fullLength + retained) - length];
+ if (retained == length) return false;
+ Object[] newarr = new Object[fullLength + retained-length];
int moved = fullLength - offset - length;
-
- if (offset > 0) {
+ if (offset > 0)
System.arraycopy(array, 0, newarr, 0, offset);
- }
-
- if (retained > 0) {
+ if (retained > 0)
System.arraycopy(tmp, 0, newarr, offset, retained);
- }
-
- if (moved > 0) {
- System.arraycopy(array, offset + length, newarr,
- offset + retained, moved);
- }
-
+ if (moved > 0)
+ System.arraycopy(array, offset+length, newarr,
+ offset+retained, moved);
setArray(newarr);
expectedArray = newarr;
length = retained;
-
return true;
}
}
@@ -905,24 +645,15 @@
public void clear() {
synchronized (CopyOnWriteArrayList.this) {
Object[] array = getArray();
-
- if (array != expectedArray) {
+ if (array != expectedArray)
throw new ConcurrentModificationException();
- }
-
int fullLength = array.length;
- Object[] newarr = new Object[fullLength - length];
+ Object[] newarr = new Object[fullLength-length];
int moved = fullLength - offset - length;
-
- if (offset > 0) {
- System.arraycopy(array, 0, newarr, 0, offset);
- }
-
- if (moved > 0) {
- System.arraycopy(array, offset + length, newarr, offset,
+ if (offset > 0) System.arraycopy(array, 0, newarr, 0, offset);
+ if (moved > 0)
+ System.arraycopy(array, offset+length, newarr, offset,
moved);
- }
-
setArray(newarr);
expectedArray = newarr;
length = 0;
@@ -930,125 +661,90 @@
}
public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
-
- if (!(o instanceof List)) {
- return false;
- }
-
+ if (o == this) return true;
+ if (!(o instanceof List)) return false;
Object[] array;
int last;
-
synchronized (CopyOnWriteArrayList.this) {
array = getArray();
-
- if (array != expectedArray) {
+ if (array != expectedArray)
throw new ConcurrentModificationException();
- }
-
- last = offset + length;
+ last = offset+length;
}
-
- ListIterator itr = ((List) o).listIterator();
- int idx = offset;
-
- while ((idx < last) && itr.hasNext()) {
+ ListIterator itr = ((List)o).listIterator();
+ int idx=offset;
+ while(idx < last && itr.hasNext()) {
Object o1 = array[idx];
Object o2 = itr.next();
-
- if (!eq(o1, o2)) {
- return false;
- }
+ if (!eq(o1, o2)) return false;
}
-
- return ((idx == last) && !itr.hasNext());
+ return(idx == last && !itr.hasNext());
}
public int hashCode() {
int hashCode = 1;
Object[] array;
int last;
-
synchronized (CopyOnWriteArrayList.this) {
array = getArray();
-
- if (array != expectedArray) {
+ if (array != expectedArray)
throw new ConcurrentModificationException();
- }
-
- last = offset + length;
+ last = offset+length;
}
-
- for (int i = offset; i < last; i++) {
+ for (int i=offset; i<last; i++) {
Object o = array[i];
- hashCode = (31 * hashCode) + ((o == null) ? 0 : o.hashCode());
+ hashCode = 31*hashCode + (o == null ? 0 : o.hashCode());
}
-
return hashCode;
}
public Object get(int index) {
- return getArray()[offset + index];
+ return getArray()[offset+index];
}
public Object set(int index, Object element) {
synchronized (CopyOnWriteArrayList.this) {
- if ((index < 0) || (index >= length)) {
+ if (index < 0 || index >= length) {
throw new IndexOutOfBoundsException("Index: " + index +
- ", Size: " + length);
+ ", Size: " + length);
}
-
Object[] oldarr = getArray();
-
- if (oldarr != expectedArray) {
+ if (oldarr != expectedArray)
throw new ConcurrentModificationException();
- }
-
int fullLength = oldarr.length;
-
// piggyback the array bounds check
- Object oldVal = oldarr[offset + index];
-
+ Object oldVal = oldarr[offset+index];
if (oldVal == element) {
setArray(oldarr);
} else {
Object[] newarr = new Object[fullLength];
System.arraycopy(oldarr, 0, newarr, 0, fullLength);
- newarr[offset + index] = element;
+ newarr[offset+index] = element;
setArray(newarr);
expectedArray = newarr;
}
-
return oldVal;
}
}
public void add(int index, Object element) {
synchronized (CopyOnWriteArrayList.this) {
- if ((index < 0) || (index > length)) {
+ if (index < 0 || index > length) {
throw new IndexOutOfBoundsException("Index: " + index +
- ", Size: " + length);
+ ", Size: " + length);
}
-
Object[] oldarr = getArray();
-
- if (oldarr != expectedArray) {
+ if (oldarr != expectedArray)
throw new ConcurrentModificationException();
- }
-
int fullLength = oldarr.length;
- Object[] newarr = new Object[fullLength + 1];
- int pos = offset + index;
- int moved = fullLength - pos;
+ Object[] newarr = new Object[fullLength+1];
+ int pos = offset+index;
+ int moved = fullLength-pos;
System.arraycopy(oldarr, 0, newarr, 0, pos);
newarr[pos] = element;
-
if (moved > 0) {
- System.arraycopy(oldarr, pos, newarr, pos + 1, moved);
+ System.arraycopy(oldarr, pos, newarr, pos+1, moved);
}
-
setArray(newarr);
expectedArray = newarr;
length++;
@@ -1057,133 +753,98 @@
public Object remove(int index) {
synchronized (CopyOnWriteArrayList.this) {
- if ((index < 0) || (index >= length)) {
+ if (index < 0 || index >= length) {
throw new IndexOutOfBoundsException("Index: " + index +
", Size: " + length);
}
-
Object[] array = getArray();
-
- if (array != expectedArray) {
+ if (array != expectedArray)
throw new ConcurrentModificationException();
- }
-
int fullLength = array.length;
- int pos = offset + index;
+ int pos = offset+index;
Object result = array[pos];
- Object[] newarr = new Object[fullLength - 1];
- int moved = fullLength - pos - 1;
-
- if (index > 0) {
+ Object[] newarr = new Object[fullLength-1];
+ int moved = fullLength-pos-1;
+ if (index > 0)
System.arraycopy(array, 0, newarr, 0, pos);
- }
-
- if (moved > 0) {
- System.arraycopy(array, pos + 1, newarr, pos, moved);
- }
-
+ if (moved > 0)
+ System.arraycopy(array, pos+1, newarr, pos, moved);
setArray(newarr);
expectedArray = newarr;
length--;
-
return result;
}
}
public int indexOf(Object o) {
- int pos = search(getArray(), o, offset, offset + length);
-
- return (pos >= 0) ? (pos - offset) : (-1);
+ int pos = search(getArray(), o, offset, offset+length);
+ return pos >= 0 ? pos-offset : -1;
}
public int indexOf(Object o, int index) {
- int pos = search(getArray(), o, offset + index, offset + length) -
- offset;
-
- return (pos >= 0) ? (pos - offset) : (-1);
+ int pos = search(getArray(), o, offset+index, offset+length)-offset;
+ return pos >= 0 ? pos-offset : -1;
}
public int lastIndexOf(Object o) {
- int pos = reverseSearch(getArray(), o, offset, offset + length) -
- offset;
-
- return (pos >= 0) ? (pos - offset) : (-1);
+ int pos = reverseSearch(getArray(), o, offset, offset+length)
+ -offset;
+ return pos >= 0 ? pos-offset : -1;
}
public int lastIndexOf(Object o, int index) {
- int pos = reverseSearch(getArray(), o, offset, offset + index) -
- offset;
-
- return (pos >= 0) ? (pos - offset) : (-1);
+ int pos = reverseSearch(getArray(), o, offset, offset+index)-offset;
+ return pos >= 0 ? pos-offset : -1;
}
public ListIterator listIterator() {
// must synchronize to atomically obtain the array and length
synchronized (CopyOnWriteArrayList.this) {
Object[] array = getArray();
-
- if (array != expectedArray) {
+ if (array != expectedArray)
throw new ConcurrentModificationException();
- }
-
- return new COWSubIterator(array, offset, offset + length, offset);
+ return new COWSubIterator(array, offset, offset+length, offset);
}
}
public ListIterator listIterator(int index) {
// must synchronize to atomically obtain the array and length
synchronized (CopyOnWriteArrayList.this) {
- if ((index < 0) || (index >= length)) {
+ if (index < 0 || index >= length) {
throw new IndexOutOfBoundsException("Index: " + index +
- ", Size: " + length);
+ ", Size: " + length);
}
-
Object[] array = getArray();
-
- if (array != expectedArray) {
+ if (array != expectedArray)
throw new ConcurrentModificationException();
- }
-
- return new COWSubIterator(array, offset, offset + length,
- offset + index);
+ return new COWSubIterator(array, offset, offset+length,
+ offset+index);
}
}
public List subList(int fromIndex, int toIndex) {
- if ((fromIndex < 0) || (toIndex > length) || (fromIndex > toIndex)) {
+ if (fromIndex < 0 || toIndex > length || fromIndex > toIndex) {
throw new IndexOutOfBoundsException();
}
-
- return new COWSubList(offset + fromIndex, toIndex - fromIndex);
+ return new COWSubList(offset+fromIndex, toIndex-fromIndex);
}
public String toString() {
Object[] array;
int last;
-
synchronized (CopyOnWriteArrayList.this) {
array = getArray();
-
- if (array != expectedArray) {
+ if (array != expectedArray)
throw new ConcurrentModificationException();
- }
-
- last = offset + length;
+ last = offset+length;
}
-
StringBuffer buf = new StringBuffer();
buf.append('[');
-
- for (int i = offset; i < last; i++) {
- if (i > offset) {
- buf.append(", ");
- }
-
+ for (int i=offset; i<last; i++) {
+ if (i>offset) buf.append(", ");
buf.append(array[i]);
}
-
buf.append(']');
-
return buf.toString();
}
}
@@ -1191,8 +852,7 @@
static class COWSubIterator implements ListIterator {
final Object[] array;
int cursor;
- int first;
- int last;
+ int first, last;
COWSubIterator(Object[] array, int first, int last, int cursor) {
this.array = array;
@@ -1201,35 +861,21 @@
this.cursor = cursor;
}
- public boolean hasNext() {
- return cursor < last;
- }
+ public boolean hasNext() { return cursor < last; }
- public boolean hasPrevious() {
- return cursor > first;
- }
+ public boolean hasPrevious() { return cursor > first; }
- public int nextIndex() {
- return cursor - first;
- }
+ public int nextIndex() { return cursor-first; }
public Object next() {
- if (cursor == last) {
- throw new NoSuchElementException();
- }
-
+ if (cursor == last) throw new NoSuchElementException();
return array[cursor++];
}
- public int previousIndex() {
- return cursor - first - 1;
- }
+ public int previousIndex() { return cursor-first-1; }
public Object previous() {
- if (cursor == first) {
- throw new NoSuchElementException();
- }
-
+ if (cursor == first) throw new NoSuchElementException();
return array[--cursor];
}
@@ -1244,5 +890,9 @@
public void remove() {
throw new UnsupportedOperationException();
}
+ }
+
+ private static boolean eq(Object o1, Object o2) {
+ return(o1 == null ? o2 == null : o1.equals(o2));
}
}