summaryrefslogtreecommitdiffstats
path: root/concurrent/src/main/java
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2008-10-21 07:00:00 -0700
committerThe Android Open Source Project <initial-contribution@android.com>2008-10-21 07:00:00 -0700
commitfdb2704414a9ed92394ada0d1395e4db86889465 (patch)
tree9b591a4a50054274a197f02b3ccb51313681879f /concurrent/src/main/java
downloadlibcore-fdb2704414a9ed92394ada0d1395e4db86889465.zip
libcore-fdb2704414a9ed92394ada0d1395e4db86889465.tar.gz
libcore-fdb2704414a9ed92394ada0d1395e4db86889465.tar.bz2
Initial Contribution
Diffstat (limited to 'concurrent/src/main/java')
-rw-r--r--concurrent/src/main/java/java/util/concurrent/AbstractExecutorService.java223
-rw-r--r--concurrent/src/main/java/java/util/concurrent/ArrayBlockingQueue.java682
-rw-r--r--concurrent/src/main/java/java/util/concurrent/BlockingQueue.java227
-rw-r--r--concurrent/src/main/java/java/util/concurrent/BrokenBarrierException.java38
-rw-r--r--concurrent/src/main/java/java/util/concurrent/Callable.java36
-rw-r--r--concurrent/src/main/java/java/util/concurrent/CancellationException.java34
-rw-r--r--concurrent/src/main/java/java/util/concurrent/CompletionService.java92
-rw-r--r--concurrent/src/main/java/java/util/concurrent/ConcurrentHashMap.java1354
-rw-r--r--concurrent/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java481
-rw-r--r--concurrent/src/main/java/java/util/concurrent/ConcurrentMap.java118
-rw-r--r--concurrent/src/main/java/java/util/concurrent/CopyOnWriteArrayList.java1189
-rw-r--r--concurrent/src/main/java/java/util/concurrent/CopyOnWriteArraySet.java105
-rw-r--r--concurrent/src/main/java/java/util/concurrent/CountDownLatch.java280
-rw-r--r--concurrent/src/main/java/java/util/concurrent/CyclicBarrier.java430
-rw-r--r--concurrent/src/main/java/java/util/concurrent/DelayQueue.java365
-rw-r--r--concurrent/src/main/java/java/util/concurrent/Delayed.java32
-rw-r--r--concurrent/src/main/java/java/util/concurrent/Exchanger.java247
-rw-r--r--concurrent/src/main/java/java/util/concurrent/ExecutionException.java65
-rw-r--r--concurrent/src/main/java/java/util/concurrent/Executor.java107
-rw-r--r--concurrent/src/main/java/java/util/concurrent/ExecutorCompletionService.java148
-rw-r--r--concurrent/src/main/java/java/util/concurrent/ExecutorService.java285
-rw-r--r--concurrent/src/main/java/java/util/concurrent/Executors.java659
-rw-r--r--concurrent/src/main/java/java/util/concurrent/Future.java133
-rw-r--r--concurrent/src/main/java/java/util/concurrent/FutureTask.java276
-rw-r--r--concurrent/src/main/java/java/util/concurrent/LinkedBlockingQueue.java720
-rw-r--r--concurrent/src/main/java/java/util/concurrent/PriorityBlockingQueue.java455
-rw-r--r--concurrent/src/main/java/java/util/concurrent/RejectedExecutionException.java62
-rw-r--r--concurrent/src/main/java/java/util/concurrent/RejectedExecutionHandler.java33
-rw-r--r--concurrent/src/main/java/java/util/concurrent/ScheduledExecutorService.java145
-rw-r--r--concurrent/src/main/java/java/util/concurrent/ScheduledFuture.java19
-rw-r--r--concurrent/src/main/java/java/util/concurrent/ScheduledThreadPoolExecutor.java541
-rw-r--r--concurrent/src/main/java/java/util/concurrent/Semaphore.java665
-rw-r--r--concurrent/src/main/java/java/util/concurrent/SynchronousQueue.java684
-rw-r--r--concurrent/src/main/java/java/util/concurrent/ThreadFactory.java40
-rw-r--r--concurrent/src/main/java/java/util/concurrent/ThreadPoolExecutor.java1513
-rw-r--r--concurrent/src/main/java/java/util/concurrent/TimeUnit.java238
-rw-r--r--concurrent/src/main/java/java/util/concurrent/TimeoutException.java38
-rw-r--r--concurrent/src/main/java/java/util/concurrent/atomic/AtomicBoolean.java127
-rw-r--r--concurrent/src/main/java/java/util/concurrent/atomic/AtomicInteger.java223
-rw-r--r--concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerArray.java246
-rw-r--r--concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java261
-rw-r--r--concurrent/src/main/java/java/util/concurrent/atomic/AtomicLong.java235
-rw-r--r--concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java243
-rw-r--r--concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java323
-rw-r--r--concurrent/src/main/java/java/util/concurrent/atomic/AtomicMarkableReference.java163
-rw-r--r--concurrent/src/main/java/java/util/concurrent/atomic/AtomicReference.java115
-rw-r--r--concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceArray.java152
-rw-r--r--concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java198
-rw-r--r--concurrent/src/main/java/java/util/concurrent/atomic/AtomicStampedReference.java167
-rw-r--r--concurrent/src/main/java/java/util/concurrent/atomic/UnsafeAccess.java34
-rw-r--r--concurrent/src/main/java/java/util/concurrent/atomic/package.html133
-rw-r--r--concurrent/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java2064
-rw-r--r--concurrent/src/main/java/java/util/concurrent/locks/Condition.java439
-rw-r--r--concurrent/src/main/java/java/util/concurrent/locks/Lock.java329
-rw-r--r--concurrent/src/main/java/java/util/concurrent/locks/LockSupport.java178
-rw-r--r--concurrent/src/main/java/java/util/concurrent/locks/ReadWriteLock.java97
-rw-r--r--concurrent/src/main/java/java/util/concurrent/locks/ReentrantLock.java727
-rw-r--r--concurrent/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java1119
-rw-r--r--concurrent/src/main/java/java/util/concurrent/locks/UnsafeAccess.java34
-rw-r--r--concurrent/src/main/java/java/util/concurrent/locks/package.html45
-rw-r--r--concurrent/src/main/java/java/util/concurrent/package.html126
61 files changed, 20537 insertions, 0 deletions
diff --git a/concurrent/src/main/java/java/util/concurrent/AbstractExecutorService.java b/concurrent/src/main/java/java/util/concurrent/AbstractExecutorService.java
new file mode 100644
index 0000000..ed4ce4f
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/AbstractExecutorService.java
@@ -0,0 +1,223 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+
+import java.util.*;
+
+/**
+ * Provides default implementation of {@link ExecutorService}
+ * execution methods. This class implements the <tt>submit</tt>,
+ * <tt>invokeAny</tt> and <tt>invokeAll</tt> methods using the default
+ * {@link FutureTask} class provided in this package. For example,
+ * the implementation of <tt>submit(Runnable)</tt> creates an
+ * associated <tt>FutureTask</tt> that is executed and
+ * returned. Subclasses overriding these methods to use different
+ * {@link Future} implementations should do so consistently for each
+ * of these methods.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ */
+public abstract class AbstractExecutorService implements ExecutorService {
+
+ public Future<?> submit(Runnable task) {
+ if (task == null) throw new NullPointerException();
+ FutureTask<Object> ftask = new FutureTask<Object>(task, null);
+ execute(ftask);
+ return ftask;
+ }
+
+ public <T> Future<T> submit(Runnable task, T result) {
+ if (task == null) throw new NullPointerException();
+ FutureTask<T> ftask = new FutureTask<T>(task, result);
+ execute(ftask);
+ return ftask;
+ }
+
+ public <T> Future<T> submit(Callable<T> task) {
+ if (task == null) throw new NullPointerException();
+ FutureTask<T> ftask = new FutureTask<T>(task);
+ execute(ftask);
+ return ftask;
+ }
+
+ /**
+ * the main mechanics of invokeAny.
+ */
+ private <T> T doInvokeAny(Collection<Callable<T>> tasks,
+ boolean timed, long nanos)
+ throws InterruptedException, ExecutionException, TimeoutException {
+ if (tasks == null)
+ throw new NullPointerException();
+ int ntasks = tasks.size();
+ if (ntasks == 0)
+ throw new IllegalArgumentException();
+ List<Future<T>> futures= new ArrayList<Future<T>>(ntasks);
+ ExecutorCompletionService<T> ecs =
+ new ExecutorCompletionService<T>(this);
+
+ // For efficiency, especially in executors with limited
+ // parallelism, check to see if previously submitted tasks are
+ // done before submitting more of them. This interleaving
+ // plus the exception mechanics account for messiness of main
+ // loop.
+
+ try {
+ // Record exceptions so that if we fail to obtain any
+ // result, we can throw the last exception we got.
+ ExecutionException ee = null;
+ long lastTime = (timed)? System.nanoTime() : 0;
+ Iterator<Callable<T>> it = tasks.iterator();
+
+ // Start one task for sure; the rest incrementally
+ futures.add(ecs.submit(it.next()));
+ --ntasks;
+ int active = 1;
+
+ for (;;) {
+ Future<T> f = ecs.poll();
+ if (f == null) {
+ if (ntasks > 0) {
+ --ntasks;
+ futures.add(ecs.submit(it.next()));
+ ++active;
+ }
+ else if (active == 0)
+ break;
+ else if (timed) {
+ f = ecs.poll(nanos, TimeUnit.NANOSECONDS);
+ if (f == null)
+ throw new TimeoutException();
+ long now = System.nanoTime();
+ nanos -= now - lastTime;
+ lastTime = now;
+ }
+ else
+ f = ecs.take();
+ }
+ if (f != null) {
+ --active;
+ try {
+ return f.get();
+ } catch(InterruptedException ie) {
+ throw ie;
+ } catch(ExecutionException eex) {
+ ee = eex;
+ } catch(RuntimeException rex) {
+ ee = new ExecutionException(rex);
+ }
+ }
+ }
+
+ if (ee == null)
+ ee = new ExecutionException();
+ throw ee;
+
+ } finally {
+ for (Future<T> f : futures)
+ f.cancel(true);
+ }
+ }
+
+ public <T> T invokeAny(Collection<Callable<T>> tasks)
+ throws InterruptedException, ExecutionException {
+ try {
+ return doInvokeAny(tasks, false, 0);
+ } catch (TimeoutException cannotHappen) {
+ assert false;
+ return null;
+ }
+ }
+
+ public <T> T invokeAny(Collection<Callable<T>> tasks,
+ long timeout, TimeUnit unit)
+ throws InterruptedException, ExecutionException, TimeoutException {
+ return doInvokeAny(tasks, true, unit.toNanos(timeout));
+ }
+
+ public <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks)
+ throws InterruptedException {
+ if (tasks == null)
+ throw new NullPointerException();
+ List<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
+ boolean done = false;
+ try {
+ for (Callable<T> t : tasks) {
+ FutureTask<T> f = new FutureTask<T>(t);
+ futures.add(f);
+ execute(f);
+ }
+ for (Future<T> f : futures) {
+ if (!f.isDone()) {
+ try {
+ f.get();
+ } catch(CancellationException ignore) {
+ } catch(ExecutionException ignore) {
+ }
+ }
+ }
+ done = true;
+ return futures;
+ } finally {
+ if (!done)
+ for (Future<T> f : futures)
+ f.cancel(true);
+ }
+ }
+
+ public <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks,
+ long timeout, TimeUnit unit)
+ throws InterruptedException {
+ if (tasks == null || unit == null)
+ throw new NullPointerException();
+ long nanos = unit.toNanos(timeout);
+ List<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
+ boolean done = false;
+ try {
+ for (Callable<T> t : tasks)
+ futures.add(new FutureTask<T>(t));
+
+ long lastTime = System.nanoTime();
+
+ // Interleave time checks and calls to execute in case
+ // executor doesn't have any/much parallelism.
+ Iterator<Future<T>> it = futures.iterator();
+ while (it.hasNext()) {
+ execute((Runnable)(it.next()));
+ long now = System.nanoTime();
+ nanos -= now - lastTime;
+ lastTime = now;
+ if (nanos <= 0)
+ return futures;
+ }
+
+ for (Future<T> f : futures) {
+ if (!f.isDone()) {
+ if (nanos <= 0)
+ return futures;
+ try {
+ f.get(nanos, TimeUnit.NANOSECONDS);
+ } catch(CancellationException ignore) {
+ } catch(ExecutionException ignore) {
+ } catch(TimeoutException toe) {
+ return futures;
+ }
+ long now = System.nanoTime();
+ nanos -= now - lastTime;
+ lastTime = now;
+ }
+ }
+ done = true;
+ return futures;
+ } finally {
+ if (!done)
+ for (Future<T> f : futures)
+ f.cancel(true);
+ }
+ }
+
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/ArrayBlockingQueue.java b/concurrent/src/main/java/java/util/concurrent/ArrayBlockingQueue.java
new file mode 100644
index 0000000..88a0858
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/ArrayBlockingQueue.java
@@ -0,0 +1,682 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+import java.util.concurrent.locks.*;
+import java.util.*;
+
+// BEGIN android-note
+// removed link to collections framework docs
+// END android-note
+
+/**
+ * A bounded {@linkplain BlockingQueue blocking queue} backed by an
+ * array. This queue orders elements FIFO (first-in-first-out). The
+ * <em>head</em> of the queue is that element that has been on the
+ * queue the longest time. The <em>tail</em> of the queue is that
+ * element that has been on the queue the shortest time. New elements
+ * are inserted at the tail of the queue, and the queue retrieval
+ * operations obtain elements at the head of the queue.
+ *
+ * <p>This is a classic &quot;bounded buffer&quot;, in which a
+ * fixed-sized array holds elements inserted by producers and
+ * extracted by consumers. Once created, the capacity cannot be
+ * increased. Attempts to offer an element to a full queue will
+ * result in the offer operation blocking; attempts to retrieve an
+ * element from an empty queue will similarly block.
+ *
+ * <p> This class supports an optional fairness policy for ordering
+ * waiting producer and consumer threads. By default, this ordering
+ * is not guaranteed. However, a queue constructed with fairness set
+ * to <tt>true</tt> grants threads access in FIFO order. Fairness
+ * generally decreases throughput but reduces variability and avoids
+ * starvation.
+ *
+ * <p>This class implements all of the <em>optional</em> methods
+ * of the {@link Collection} and {@link Iterator} interfaces.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ * @param <E> the type of elements held in this collection
+ */
+public class ArrayBlockingQueue<E> extends AbstractQueue<E>
+ implements BlockingQueue<E>, java.io.Serializable {
+
+ /**
+ * Serialization ID. This class relies on default serialization
+ * even for the items array, which is default-serialized, even if
+ * it is empty. Otherwise it could not be declared final, which is
+ * necessary here.
+ */
+ private static final long serialVersionUID = -817911632652898426L;
+
+ /** The queued items */
+ private final E[] items;
+ /** items index for next take, poll or remove */
+ private transient int takeIndex;
+ /** items index for next put, offer, or add. */
+ private transient int putIndex;
+ /** Number of items in the queue */
+ private int count;
+
+ /*
+ * Concurrency control uses the classic two-condition algorithm
+ * found in any textbook.
+ */
+
+ /** Main lock guarding all access */
+ private final ReentrantLock lock;
+ /** Condition for waiting takes */
+ private final Condition notEmpty;
+ /** Condition for waiting puts */
+ private final Condition notFull;
+
+ // Internal helper methods
+
+ /**
+ * Circularly increment i.
+ */
+ final int inc(int i) {
+ return (++i == items.length)? 0 : i;
+ }
+
+ /**
+ * Insert element at current put position, advance, and signal.
+ * Call only when holding lock.
+ */
+ private void insert(E x) {
+ items[putIndex] = x;
+ putIndex = inc(putIndex);
+ ++count;
+ notEmpty.signal();
+ }
+
+ /**
+ * Extract element at current take position, advance, and signal.
+ * Call only when holding lock.
+ */
+ private E extract() {
+ final E[] items = this.items;
+ E x = items[takeIndex];
+ items[takeIndex] = null;
+ takeIndex = inc(takeIndex);
+ --count;
+ notFull.signal();
+ return x;
+ }
+
+ /**
+ * Utility for remove and iterator.remove: Delete item at position i.
+ * Call only when holding lock.
+ */
+ void removeAt(int i) {
+ final E[] items = this.items;
+ // if removing front item, just advance
+ if (i == takeIndex) {
+ items[takeIndex] = null;
+ takeIndex = inc(takeIndex);
+ } else {
+ // slide over all others up through putIndex.
+ for (;;) {
+ int nexti = inc(i);
+ if (nexti != putIndex) {
+ items[i] = items[nexti];
+ i = nexti;
+ } else {
+ items[i] = null;
+ putIndex = i;
+ break;
+ }
+ }
+ }
+ --count;
+ notFull.signal();
+ }
+
+ /**
+ * Creates an <tt>ArrayBlockingQueue</tt> with the given (fixed)
+ * capacity and default access policy.
+ * @param capacity the capacity of this queue
+ * @throws IllegalArgumentException if <tt>capacity</tt> is less than 1
+ */
+ public ArrayBlockingQueue(int capacity) {
+ this(capacity, false);
+ }
+
+ /**
+ * Creates an <tt>ArrayBlockingQueue</tt> with the given (fixed)
+ * capacity and the specified access policy.
+ * @param capacity the capacity of this queue
+ * @param fair if <tt>true</tt> then queue accesses for threads blocked
+ * on insertion or removal, are processed in FIFO order; if <tt>false</tt>
+ * the access order is unspecified.
+ * @throws IllegalArgumentException if <tt>capacity</tt> is less than 1
+ */
+ public ArrayBlockingQueue(int capacity, boolean fair) {
+ if (capacity <= 0)
+ throw new IllegalArgumentException();
+ this.items = (E[]) new Object[capacity];
+ lock = new ReentrantLock(fair);
+ notEmpty = lock.newCondition();
+ notFull = lock.newCondition();
+ }
+
+ /**
+ * Creates an <tt>ArrayBlockingQueue</tt> with the given (fixed)
+ * capacity, the specified access policy and initially containing the
+ * elements of the given collection,
+ * added in traversal order of the collection's iterator.
+ * @param capacity the capacity of this queue
+ * @param fair if <tt>true</tt> then queue accesses for threads blocked
+ * on insertion or removal, are processed in FIFO order; if <tt>false</tt>
+ * the access order is unspecified.
+ * @param c the collection of elements to initially contain
+ * @throws IllegalArgumentException if <tt>capacity</tt> is less than
+ * <tt>c.size()</tt>, or less than 1.
+ * @throws NullPointerException if <tt>c</tt> or any element within it
+ * is <tt>null</tt>
+ */
+ public ArrayBlockingQueue(int capacity, boolean fair,
+ Collection<? extends E> c) {
+ this(capacity, fair);
+ if (capacity < c.size())
+ throw new IllegalArgumentException();
+
+ for (Iterator<? extends E> it = c.iterator(); it.hasNext();)
+ add(it.next());
+ }
+
+ /**
+ * Inserts the specified element at the tail of this queue if possible,
+ * returning immediately if this queue is full.
+ *
+ * @param o the element to add.
+ * @return <tt>true</tt> if it was possible to add the element to
+ * this queue, else <tt>false</tt>
+ * @throws NullPointerException if the specified element is <tt>null</tt>
+ */
+ public boolean offer(E o) {
+ if (o == null) throw new NullPointerException();
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ if (count == items.length)
+ return false;
+ else {
+ insert(o);
+ return true;
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Inserts the specified element at the tail of this queue, waiting if
+ * necessary up to the specified wait time for space to become available.
+ * @param o the element to add
+ * @param timeout how long to wait before giving up, in units of
+ * <tt>unit</tt>
+ * @param unit a <tt>TimeUnit</tt> determining how to interpret the
+ * <tt>timeout</tt> parameter
+ * @return <tt>true</tt> if successful, or <tt>false</tt> if
+ * the specified waiting time elapses before space is available.
+ * @throws InterruptedException if interrupted while waiting.
+ * @throws NullPointerException if the specified element is <tt>null</tt>.
+ */
+ public boolean offer(E o, long timeout, TimeUnit unit)
+ throws InterruptedException {
+
+ if (o == null) throw new NullPointerException();
+ final ReentrantLock lock = this.lock;
+ lock.lockInterruptibly();
+ try {
+ long nanos = unit.toNanos(timeout);
+ for (;;) {
+ if (count != items.length) {
+ insert(o);
+ return true;
+ }
+ if (nanos <= 0)
+ return false;
+ try {
+ nanos = notFull.awaitNanos(nanos);
+ } catch (InterruptedException ie) {
+ notFull.signal(); // propagate to non-interrupted thread
+ throw ie;
+ }
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public E poll() {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ if (count == 0)
+ return null;
+ E x = extract();
+ return x;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public E poll(long timeout, TimeUnit unit) throws InterruptedException {
+ final ReentrantLock lock = this.lock;
+ lock.lockInterruptibly();
+ try {
+ long nanos = unit.toNanos(timeout);
+ for (;;) {
+ if (count != 0) {
+ E x = extract();
+ return x;
+ }
+ if (nanos <= 0)
+ return null;
+ try {
+ nanos = notEmpty.awaitNanos(nanos);
+ } catch (InterruptedException ie) {
+ notEmpty.signal(); // propagate to non-interrupted thread
+ throw ie;
+ }
+
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public boolean remove(Object o) {
+ if (o == null) return false;
+ final E[] items = this.items;
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ int i = takeIndex;
+ int k = 0;
+ for (;;) {
+ if (k++ >= count)
+ return false;
+ if (o.equals(items[i])) {
+ removeAt(i);
+ return true;
+ }
+ i = inc(i);
+ }
+
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public E peek() {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ return (count == 0) ? null : items[takeIndex];
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public E take() throws InterruptedException {
+ final ReentrantLock lock = this.lock;
+ lock.lockInterruptibly();
+ try {
+ try {
+ while (count == 0)
+ notEmpty.await();
+ } catch (InterruptedException ie) {
+ notEmpty.signal(); // propagate to non-interrupted thread
+ throw ie;
+ }
+ E x = extract();
+ return x;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Adds the specified element to the tail of this queue, waiting if
+ * necessary for space to become available.
+ * @param o the element to add
+ * @throws InterruptedException if interrupted while waiting.
+ * @throws NullPointerException if the specified element is <tt>null</tt>.
+ */
+ public void put(E o) throws InterruptedException {
+ if (o == null) throw new NullPointerException();
+ final E[] items = this.items;
+ final ReentrantLock lock = this.lock;
+ lock.lockInterruptibly();
+ try {
+ try {
+ while (count == items.length)
+ notFull.await();
+ } catch (InterruptedException ie) {
+ notFull.signal(); // propagate to non-interrupted thread
+ throw ie;
+ }
+ insert(o);
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ // this doc comment is overridden to remove the reference to collections
+ // greater in size than Integer.MAX_VALUE
+ /**
+ * Returns the number of elements in this queue.
+ *
+ * @return the number of elements in this queue.
+ */
+ public int size() {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ return count;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ // this doc comment is a modified copy of the inherited doc comment,
+ // without the reference to unlimited queues.
+ /**
+ * Returns the number of elements that this queue can ideally (in
+ * the absence of memory or resource constraints) accept without
+ * blocking. This is always equal to the initial capacity of this queue
+ * less the current <tt>size</tt> of this queue.
+ * <p>Note that you <em>cannot</em> always tell if
+ * an attempt to <tt>add</tt> an element will succeed by
+ * inspecting <tt>remainingCapacity</tt> because it may be the
+ * case that a waiting consumer is ready to <tt>take</tt> an
+ * element out of an otherwise full queue.
+ *
+ * @return the remaining capacity
+ */
+ public int remainingCapacity() {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ return items.length - count;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public boolean contains(Object o) {
+ if (o == null) return false;
+ final E[] items = this.items;
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ int i = takeIndex;
+ int k = 0;
+ while (k++ < count) {
+ if (o.equals(items[i]))
+ return true;
+ i = inc(i);
+ }
+ return false;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public Object[] toArray() {
+ final E[] items = this.items;
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ Object[] a = new Object[count];
+ int k = 0;
+ int i = takeIndex;
+ while (k < count) {
+ a[k++] = items[i];
+ i = inc(i);
+ }
+ return a;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public <T> T[] toArray(T[] a) {
+ final E[] items = this.items;
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ if (a.length < count)
+ a = (T[])java.lang.reflect.Array.newInstance(
+ a.getClass().getComponentType(),
+ count
+ );
+
+ int k = 0;
+ int i = takeIndex;
+ while (k < count) {
+ a[k++] = (T)items[i];
+ i = inc(i);
+ }
+ if (a.length > count)
+ a[count] = null;
+ return a;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public String toString() {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ return super.toString();
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public void clear() {
+ final E[] items = this.items;
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ int i = takeIndex;
+ int k = count;
+ while (k-- > 0) {
+ items[i] = null;
+ i = inc(i);
+ }
+ count = 0;
+ putIndex = 0;
+ takeIndex = 0;
+ notFull.signalAll();
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public int drainTo(Collection<? super E> c) {
+ if (c == null)
+ throw new NullPointerException();
+ if (c == this)
+ throw new IllegalArgumentException();
+ final E[] items = this.items;
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ int i = takeIndex;
+ int n = 0;
+ int max = count;
+ while (n < max) {
+ c.add(items[i]);
+ items[i] = null;
+ i = inc(i);
+ ++n;
+ }
+ if (n > 0) {
+ count = 0;
+ putIndex = 0;
+ takeIndex = 0;
+ notFull.signalAll();
+ }
+ return n;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public int drainTo(Collection<? super E> c, int maxElements) {
+ if (c == null)
+ throw new NullPointerException();
+ if (c == this)
+ throw new IllegalArgumentException();
+ if (maxElements <= 0)
+ return 0;
+ final E[] items = this.items;
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ int i = takeIndex;
+ int n = 0;
+ int sz = count;
+ int max = (maxElements < count)? maxElements : count;
+ while (n < max) {
+ c.add(items[i]);
+ items[i] = null;
+ i = inc(i);
+ ++n;
+ }
+ if (n > 0) {
+ count -= n;
+ takeIndex = i;
+ notFull.signalAll();
+ }
+ return n;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+
+ /**
+ * Returns an iterator over the elements in this queue in proper sequence.
+ * The returned <tt>Iterator</tt> is a "weakly consistent" iterator that
+ * will never throw {@link java.util.ConcurrentModificationException},
+ * and guarantees to traverse elements as they existed upon
+ * construction of the iterator, and may (but is not guaranteed to)
+ * reflect any modifications subsequent to construction.
+ *
+ * @return an iterator over the elements in this queue in proper sequence.
+ */
+ public Iterator<E> iterator() {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ return new Itr();
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Iterator for ArrayBlockingQueue
+ */
+ private class Itr implements Iterator<E> {
+ /**
+ * Index of element to be returned by next,
+ * or a negative number if no such.
+ */
+ private int nextIndex;
+
+ /**
+ * nextItem holds on to item fields because once we claim
+ * that an element exists in hasNext(), we must return it in
+ * the following next() call even if it was in the process of
+ * being removed when hasNext() was called.
+ **/
+ private E nextItem;
+
+ /**
+ * Index of element returned by most recent call to next.
+ * Reset to -1 if this element is deleted by a call to remove.
+ */
+ private int lastRet;
+
+ Itr() {
+ lastRet = -1;
+ if (count == 0)
+ nextIndex = -1;
+ else {
+ nextIndex = takeIndex;
+ nextItem = items[takeIndex];
+ }
+ }
+
+ public boolean hasNext() {
+ /*
+ * No sync. We can return true by mistake here
+ * only if this iterator passed across threads,
+ * which we don't support anyway.
+ */
+ return nextIndex >= 0;
+ }
+
+ /**
+ * Check whether nextIndex is valid; if so setting nextItem.
+ * Stops iterator when either hits putIndex or sees null item.
+ */
+ private void checkNext() {
+ if (nextIndex == putIndex) {
+ nextIndex = -1;
+ nextItem = null;
+ } else {
+ nextItem = items[nextIndex];
+ if (nextItem == null)
+ nextIndex = -1;
+ }
+ }
+
+ public E next() {
+ final ReentrantLock lock = ArrayBlockingQueue.this.lock;
+ lock.lock();
+ try {
+ if (nextIndex < 0)
+ throw new NoSuchElementException();
+ lastRet = nextIndex;
+ E x = nextItem;
+ nextIndex = inc(nextIndex);
+ checkNext();
+ return x;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public void remove() {
+ final ReentrantLock lock = ArrayBlockingQueue.this.lock;
+ lock.lock();
+ try {
+ int i = lastRet;
+ if (i == -1)
+ throw new IllegalStateException();
+ lastRet = -1;
+
+ int ti = takeIndex;
+ removeAt(i);
+ // back up cursor (reset to front if was first element)
+ nextIndex = (i == ti) ? takeIndex : i;
+ checkNext();
+ } finally {
+ lock.unlock();
+ }
+ }
+ }
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/BlockingQueue.java b/concurrent/src/main/java/java/util/concurrent/BlockingQueue.java
new file mode 100644
index 0000000..ddb7d77
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/BlockingQueue.java
@@ -0,0 +1,227 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+
+import java.util.Collection;
+import java.util.Queue;
+
+// BEGIN android-note
+// removed link to collections framework docs
+// END android-note
+
+/**
+ * A {@link java.util.Queue} that additionally supports operations
+ * that wait for the queue to become non-empty when retrieving an element,
+ * and wait for space to become available in the queue when storing an
+ * element.
+ *
+ * <p>A <tt>BlockingQueue</tt> does not accept <tt>null</tt> elements.
+ * Implementations throw <tt>NullPointerException</tt> on attempts
+ * to <tt>add</tt>, <tt>put</tt> or <tt>offer</tt> a <tt>null</tt>. A
+ * <tt>null</tt> is used as a sentinel value to indicate failure of
+ * <tt>poll</tt> operations.
+ *
+ * <p>A <tt>BlockingQueue</tt> may be capacity bounded. At any given
+ * time it may have a <tt>remainingCapacity</tt> beyond which no
+ * additional elements can be <tt>put</tt> without blocking.
+ * A <tt>BlockingQueue</tt> without any intrinsic capacity constraints always
+ * reports a remaining capacity of <tt>Integer.MAX_VALUE</tt>.
+ *
+ * <p> While <tt>BlockingQueue</tt> is designed to be used primarily
+ * for producer-consumer queues, it additionally supports the {@link
+ * java.util.Collection} interface. So, for example, it is possible
+ * to remove an arbitrary element from a queue using
+ * <tt>remove(x)</tt>. However, such operations are in general
+ * <em>not</em> performed very efficiently, and are intended for only
+ * occasional use, such as when a queued message is cancelled. Also,
+ * the bulk Collection operations, most notably <tt>addAll</tt>, are
+ * <em>not</em> necessarily performed atomically, so it is possible
+ * for <tt>addAll(c)</tt> to fail (throwing an exception) after adding
+ * only some of the elements in <tt>c</tt>.
+ *
+ * <p>A <tt>BlockingQueue</tt> does <em>not</em> intrinsically support
+ * any kind of &quot;close&quot; or &quot;shutdown&quot; operation to
+ * indicate that no more items will be added. The needs and usage of
+ * such features tend to be implementation-dependent. For example, a
+ * common tactic is for producers to insert special
+ * <em>end-of-stream</em> or <em>poison</em> objects, that are
+ * interpreted accordingly when taken by consumers.
+ *
+ * <p>
+ * Usage example, based on a typical producer-consumer scenario.
+ * Note that a <tt>BlockingQueue</tt> can safely be used with multiple
+ * producers and multiple consumers.
+ * <pre>
+ * class Producer implements Runnable {
+ * private final BlockingQueue queue;
+ * Producer(BlockingQueue q) { queue = q; }
+ * public void run() {
+ * try {
+ * while(true) { queue.put(produce()); }
+ * } catch (InterruptedException ex) { ... handle ...}
+ * }
+ * Object produce() { ... }
+ * }
+ *
+ * class Consumer implements Runnable {
+ * private final BlockingQueue queue;
+ * Consumer(BlockingQueue q) { queue = q; }
+ * public void run() {
+ * try {
+ * while(true) { consume(queue.take()); }
+ * } catch (InterruptedException ex) { ... handle ...}
+ * }
+ * void consume(Object x) { ... }
+ * }
+ *
+ * class Setup {
+ * void main() {
+ * BlockingQueue q = new SomeQueueImplementation();
+ * Producer p = new Producer(q);
+ * Consumer c1 = new Consumer(q);
+ * Consumer c2 = new Consumer(q);
+ * new Thread(p).start();
+ * new Thread(c1).start();
+ * new Thread(c2).start();
+ * }
+ * }
+ * </pre>
+ *
+ * @since 1.5
+ * @author Doug Lea
+ * @param <E> the type of elements held in this collection
+ */
+public interface BlockingQueue<E> extends Queue<E> {
+
+ /**
+ * Inserts the specified element into this queue, if possible. When
+ * using queues that may impose insertion restrictions (for
+ * example capacity bounds), method <tt>offer</tt> is generally
+ * preferable to method {@link Collection#add}, which can fail to
+ * insert an element only by throwing an exception.
+ *
+ * @param o the element to add.
+ * @return <tt>true</tt> if it was possible to add the element to
+ * this queue, else <tt>false</tt>
+ * @throws NullPointerException if the specified element is <tt>null</tt>
+ */
+ boolean offer(E o);
+
+ /**
+ * Inserts the specified element into this queue, waiting if necessary
+ * up to the specified wait time for space to become available.
+ * @param o the element to add
+ * @param timeout how long to wait before giving up, in units of
+ * <tt>unit</tt>
+ * @param unit a <tt>TimeUnit</tt> determining how to interpret the
+ * <tt>timeout</tt> parameter
+ * @return <tt>true</tt> if successful, or <tt>false</tt> if
+ * the specified waiting time elapses before space is available.
+ * @throws InterruptedException if interrupted while waiting.
+ * @throws NullPointerException if the specified element is <tt>null</tt>.
+ */
+ boolean offer(E o, long timeout, TimeUnit unit)
+ throws InterruptedException;
+
+ /**
+ * Retrieves and removes the head of this queue, waiting
+ * if necessary up to the specified wait time if no elements are
+ * present on this queue.
+ * @param timeout how long to wait before giving up, in units of
+ * <tt>unit</tt>
+ * @param unit a <tt>TimeUnit</tt> determining how to interpret the
+ * <tt>timeout</tt> parameter
+ * @return the head of this queue, or <tt>null</tt> if the
+ * specified waiting time elapses before an element is present.
+ * @throws InterruptedException if interrupted while waiting.
+ */
+ E poll(long timeout, TimeUnit unit)
+ throws InterruptedException;
+
+ /**
+ * Retrieves and removes the head of this queue, waiting
+ * if no elements are present on this queue.
+ * @return the head of this queue
+ * @throws InterruptedException if interrupted while waiting.
+ */
+ E take() throws InterruptedException;
+
+ /**
+ * Adds the specified element to this queue, waiting if necessary for
+ * space to become available.
+ * @param o the element to add
+ * @throws InterruptedException if interrupted while waiting.
+ * @throws NullPointerException if the specified element is <tt>null</tt>.
+ */
+ void put(E o) throws InterruptedException;
+
+ /**
+ * Returns the number of elements that this queue can ideally (in
+ * the absence of memory or resource constraints) accept without
+ * blocking, or <tt>Integer.MAX_VALUE</tt> if there is no
+ * intrinsic limit.
+ * <p>Note that you <em>cannot</em> always tell if
+ * an attempt to <tt>add</tt> an element will succeed by
+ * inspecting <tt>remainingCapacity</tt> because it may be the
+ * case that a waiting consumer is ready to <tt>take</tt> an
+ * element out of an otherwise full queue.
+ * @return the remaining capacity
+ */
+ int remainingCapacity();
+
+ /**
+ * Adds the specified element to this queue if it is possible to
+ * do so immediately, returning <tt>true</tt> upon success, else
+ * throwing an IllegalStateException.
+ * @param o the element
+ * @return <tt>true</tt> (as per the general contract of
+ * <tt>Collection.add</tt>).
+ *
+ * @throws NullPointerException if the specified element is <tt>null</tt>
+ * @throws IllegalStateException if element cannot be added
+ */
+ boolean add(E o);
+
+ /**
+ * Removes all available elements from this queue and adds them
+ * into the given collection. This operation may be more
+ * efficient than repeatedly polling this queue. A failure
+ * encountered while attempting to <tt>add</tt> elements to
+ * collection <tt>c</tt> may result in elements being in neither,
+ * either or both collections when the associated exception is
+ * thrown. Attempts to drain a queue to itself result in
+ * <tt>IllegalArgumentException</tt>. Further, the behavior of
+ * this operation is undefined if the specified collection is
+ * modified while the operation is in progress.
+ *
+ * @param c the collection to transfer elements into
+ * @return the number of elements transferred.
+ * @throws NullPointerException if c is null
+ * @throws IllegalArgumentException if c is this queue
+ *
+ */
+ int drainTo(Collection<? super E> c);
+
+ /**
+ * Removes at most the given number of available elements from
+ * this queue and adds them into the given collection. A failure
+ * encountered while attempting to <tt>add</tt> elements to
+ * collection <tt>c</tt> may result in elements being in neither,
+ * either or both collections when the associated exception is
+ * thrown. Attempts to drain a queue to itself result in
+ * <tt>IllegalArgumentException</tt>. Further, the behavior of
+ * this operation is undefined if the specified collection is
+ * modified while the operation is in progress.
+ *
+ * @param c the collection to transfer elements into
+ * @param maxElements the maximum number of elements to transfer
+ * @return the number of elements transferred.
+ * @throws NullPointerException if c is null
+ * @throws IllegalArgumentException if c is this queue
+ */
+ int drainTo(Collection<? super E> c, int maxElements);
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/BrokenBarrierException.java b/concurrent/src/main/java/java/util/concurrent/BrokenBarrierException.java
new file mode 100644
index 0000000..3f93fbb
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/BrokenBarrierException.java
@@ -0,0 +1,38 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+
+/**
+ * Exception thrown when a thread tries to wait upon a barrier that is
+ * in a broken state, or which enters the broken state while the thread
+ * is waiting.
+ *
+ * @see CyclicBarrier
+ *
+ * @since 1.5
+ * @author Doug Lea
+ *
+ */
+public class BrokenBarrierException extends Exception {
+ private static final long serialVersionUID = 7117394618823254244L;
+
+ /**
+ * Constructs a <tt>BrokenBarrierException</tt> with no specified detail
+ * message.
+ */
+ public BrokenBarrierException() {}
+
+ /**
+ * Constructs a <tt>BrokenBarrierException</tt> with the specified
+ * detail message.
+ *
+ * @param message the detail message
+ */
+ public BrokenBarrierException(String message) {
+ super(message);
+ }
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/Callable.java b/concurrent/src/main/java/java/util/concurrent/Callable.java
new file mode 100644
index 0000000..abc4d04
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/Callable.java
@@ -0,0 +1,36 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+
+/**
+ * A task that returns a result and may throw an exception.
+ * Implementors define a single method with no arguments called
+ * <tt>call</tt>.
+ *
+ * <p>The <tt>Callable</tt> interface is similar to {@link
+ * java.lang.Runnable}, in that both are designed for classes whose
+ * instances are potentially executed by another thread. A
+ * <tt>Runnable</tt>, however, does not return a result and cannot
+ * throw a checked exception.
+ *
+ * <p> The {@link Executors} class contains utility methods to
+ * convert from other common forms to <tt>Callable</tt> classes.
+ *
+ * @see Executor
+ * @since 1.5
+ * @author Doug Lea
+ * @param <V> the result type of method <tt>call</tt>
+ */
+public interface Callable<V> {
+ /**
+ * Computes a result, or throws an exception if unable to do so.
+ *
+ * @return computed result
+ * @throws Exception if unable to compute a result
+ */
+ V call() throws Exception;
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/CancellationException.java b/concurrent/src/main/java/java/util/concurrent/CancellationException.java
new file mode 100644
index 0000000..2c29544
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/CancellationException.java
@@ -0,0 +1,34 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+
+/**
+ * Exception indicating that the result of a value-producing task,
+ * such as a {@link FutureTask}, cannot be retrieved because the task
+ * was cancelled.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ */
+public class CancellationException extends IllegalStateException {
+ private static final long serialVersionUID = -9202173006928992231L;
+
+ /**
+ * Constructs a <tt>CancellationException</tt> with no detail message.
+ */
+ public CancellationException() {}
+
+ /**
+ * Constructs a <tt>CancellationException</tt> with the specified detail
+ * message.
+ *
+ * @param message the detail message
+ */
+ public CancellationException(String message) {
+ super(message);
+ }
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/CompletionService.java b/concurrent/src/main/java/java/util/concurrent/CompletionService.java
new file mode 100644
index 0000000..e349e5f
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/CompletionService.java
@@ -0,0 +1,92 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+
+/**
+ * A service that decouples the production of new asynchronous tasks
+ * from the consumption of the results of completed tasks. Producers
+ * <tt>submit</tt> tasks for execution. Consumers <tt>take</tt>
+ * completed tasks and process their results in the order they
+ * complete. A <tt>CompletionService</tt> can for example be used to
+ * manage asynchronous IO, in which tasks that perform reads are
+ * submitted in one part of a program or system, and then acted upon
+ * in a different part of the program when the reads complete,
+ * possibly in a different order than they were requested.
+
+ * <p>
+ *
+ * Typically, a <tt>CompletionService</tt> relies on a separate {@link
+ * Executor} to actually execute the tasks, in which case the
+ * <tt>CompletionService</tt> only manages an internal completion
+ * queue. The {@link ExecutorCompletionService} class provides an
+ * implementation of this approach.
+ *
+ */
+public interface CompletionService<V> {
+ /**
+ * Submits a value-returning task for execution and returns a Future
+ * representing the pending results of the task. Upon completion,
+ * this task may be taken or polled.
+ *
+ * @param task the task to submit
+ * @return a Future representing pending completion of the task
+ * @throws RejectedExecutionException if task cannot be scheduled
+ * for execution
+ * @throws NullPointerException if task null
+ */
+ Future<V> submit(Callable<V> task);
+
+
+ /**
+ * Submits a Runnable task for execution and returns a Future
+ * representing that task. Upon completion,
+ * this task may be taken or polled.
+ *
+ * @param task the task to submit
+ * @param result the result to return upon successful completion
+ * @return a Future representing pending completion of the task,
+ * and whose <tt>get()</tt> method will return the given result value
+ * upon completion
+ * @throws RejectedExecutionException if task cannot be scheduled
+ * for execution
+ * @throws NullPointerException if task null
+ */
+ Future<V> submit(Runnable task, V result);
+
+ /**
+ * Retrieves and removes the Future representing the next
+ * completed task, waiting if none are yet present.
+ * @return the Future representing the next completed task
+ * @throws InterruptedException if interrupted while waiting.
+ */
+ Future<V> take() throws InterruptedException;
+
+
+ /**
+ * Retrieves and removes the Future representing the next
+ * completed task or <tt>null</tt> if none are present.
+ *
+ * @return the Future representing the next completed task, or
+ * <tt>null</tt> if none are present.
+ */
+ Future<V> poll();
+
+ /**
+ * Retrieves and removes the Future representing the next
+ * completed task, waiting if necessary up to the specified wait
+ * time if none are yet present.
+ * @param timeout how long to wait before giving up, in units of
+ * <tt>unit</tt>
+ * @param unit a <tt>TimeUnit</tt> determining how to interpret the
+ * <tt>timeout</tt> parameter
+ * @return the Future representing the next completed task or
+ * <tt>null</tt> if the specified waiting time elapses before one
+ * is present.
+ * @throws InterruptedException if interrupted while waiting.
+ */
+ Future<V> poll(long timeout, TimeUnit unit) throws InterruptedException;
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/ConcurrentHashMap.java b/concurrent/src/main/java/java/util/concurrent/ConcurrentHashMap.java
new file mode 100644
index 0000000..ce0bb19
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/ConcurrentHashMap.java
@@ -0,0 +1,1354 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+import java.util.concurrent.locks.*;
+import java.util.*;
+import java.io.Serializable;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+// BEGIN android-note
+// removed link to collections framework docs
+// removed cloneable interface from ConcurrentMap interface
+// END android-note
+
+/**
+ * A hash table supporting full concurrency of retrievals and
+ * adjustable expected concurrency for updates. This class obeys the
+ * same functional specification as {@link java.util.Hashtable}, and
+ * includes versions of methods corresponding to each method of
+ * <tt>Hashtable</tt>. However, even though all operations are
+ * thread-safe, retrieval operations do <em>not</em> entail locking,
+ * and there is <em>not</em> any support for locking the entire table
+ * in a way that prevents all access. This class is fully
+ * interoperable with <tt>Hashtable</tt> in programs that rely on its
+ * thread safety but not on its synchronization details.
+ *
+ * <p> Retrieval operations (including <tt>get</tt>) generally do not
+ * block, so may overlap with update operations (including
+ * <tt>put</tt> and <tt>remove</tt>). Retrievals reflect the results
+ * of the most recently <em>completed</em> update operations holding
+ * upon their onset. For aggregate operations such as <tt>putAll</tt>
+ * and <tt>clear</tt>, concurrent retrievals may reflect insertion or
+ * removal of only some entries. Similarly, Iterators and
+ * Enumerations return elements reflecting the state of the hash table
+ * at some point at or since the creation of the iterator/enumeration.
+ * They do <em>not</em> throw
+ * {@link ConcurrentModificationException}. However, iterators are
+ * designed to be used by only one thread at a time.
+ *
+ * <p> The allowed concurrency among update operations is guided by
+ * the optional <tt>concurrencyLevel</tt> constructor argument
+ * (default 16), which is used as a hint for internal sizing. The
+ * table is internally partitioned to try to permit the indicated
+ * number of concurrent updates without contention. Because placement
+ * in hash tables is essentially random, the actual concurrency will
+ * vary. Ideally, you should choose a value to accommodate as many
+ * threads as will ever concurrently modify the table. Using a
+ * significantly higher value than you need can waste space and time,
+ * and a significantly lower value can lead to thread contention. But
+ * overestimates and underestimates within an order of magnitude do
+ * not usually have much noticeable impact. A value of one is
+ * appropriate when it is known that only one thread will modify
+ * and all others will only read.
+ *
+ * <p>This class implements all of the <em>optional</em> methods
+ * of the {@link Map} and {@link Iterator} interfaces.
+ *
+ * <p> Like {@link java.util.Hashtable} but unlike {@link
+ * java.util.HashMap}, this class does NOT allow <tt>null</tt> to be
+ * used as a key or value.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ * @param <K> the type of keys maintained by this map
+ * @param <V> the type of mapped values
+ */
+public class ConcurrentHashMap<K, V> extends AbstractMap<K, V>
+ implements ConcurrentMap<K, V>, Serializable {
+ private static final long serialVersionUID = 7249069246763182397L;
+
+ /*
+ * The basic strategy is to subdivide the table among Segments,
+ * each of which itself is a concurrently readable hash table.
+ */
+
+ /* ---------------- Constants -------------- */
+
+ /**
+ * The default initial number of table slots for this table.
+ * Used when not otherwise specified in constructor.
+ */
+ static int DEFAULT_INITIAL_CAPACITY = 16;
+
+ /**
+ * The maximum capacity, used if a higher value is implicitly
+ * specified by either of the constructors with arguments. MUST
+ * be a power of two <= 1<<30 to ensure that entries are indexible
+ * using ints.
+ */
+ static final int MAXIMUM_CAPACITY = 1 << 30;
+
+ /**
+ * The default load factor for this table. Used when not
+ * otherwise specified in constructor.
+ */
+ static final float DEFAULT_LOAD_FACTOR = 0.75f;
+
+ /**
+ * The default number of concurrency control segments.
+ **/
+ static final int DEFAULT_SEGMENTS = 16;
+
+ /**
+ * The maximum number of segments to allow; used to bound
+ * constructor arguments.
+ */
+ static final int MAX_SEGMENTS = 1 << 16; // slightly conservative
+
+ /* ---------------- Fields -------------- */
+
+ /**
+ * Mask value for indexing into segments. The upper bits of a
+ * key's hash code are used to choose the segment.
+ **/
+ final int segmentMask;
+
+ /**
+ * Shift value for indexing within segments.
+ **/
+ final int segmentShift;
+
+ /**
+ * The segments, each of which is a specialized hash table
+ */
+ final Segment[] segments;
+
+ transient Set<K> keySet;
+ transient Set<Map.Entry<K,V>> entrySet;
+ transient Collection<V> values;
+
+ /* ---------------- Small Utilities -------------- */
+
+ /**
+ * Returns a hash code for non-null Object x.
+ * Uses the same hash code spreader as most other java.util hash tables.
+ * @param x the object serving as a key
+ * @return the hash code
+ */
+ static int hash(Object x) {
+ int h = x.hashCode();
+ h += ~(h << 9);
+ h ^= (h >>> 14);
+ h += (h << 4);
+ h ^= (h >>> 10);
+ return h;
+ }
+
+ /**
+ * Returns the segment that should be used for key with given hash
+ * @param hash the hash code for the key
+ * @return the segment
+ */
+ final Segment<K,V> segmentFor(int hash) {
+ return (Segment<K,V>) segments[(hash >>> segmentShift) & segmentMask];
+ }
+
+ /* ---------------- Inner Classes -------------- */
+
+ /**
+ * Segments are specialized versions of hash tables. This
+ * subclasses from ReentrantLock opportunistically, just to
+ * simplify some locking and avoid separate construction.
+ **/
+ static final class Segment<K,V> extends ReentrantLock implements Serializable {
+ /*
+ * Segments maintain a table of entry lists that are ALWAYS
+ * kept in a consistent state, so can be read without locking.
+ * Next fields of nodes are immutable (final). All list
+ * additions are performed at the front of each bin. This
+ * makes it easy to check changes, and also fast to traverse.
+ * When nodes would otherwise be changed, new nodes are
+ * created to replace them. This works well for hash tables
+ * since the bin lists tend to be short. (The average length
+ * is less than two for the default load factor threshold.)
+ *
+ * Read operations can thus proceed without locking, but rely
+ * on a memory barrier to ensure that completed write
+ * operations performed by other threads are
+ * noticed. Conveniently, the "count" field, tracking the
+ * number of elements, can also serve as the volatile variable
+ * providing proper read/write barriers. This is convenient
+ * because this field needs to be read in many read operations
+ * anyway.
+ *
+ * Implementors note. The basic rules for all this are:
+ *
+ * - All unsynchronized read operations must first read the
+ * "count" field, and should not look at table entries if
+ * it is 0.
+ *
+ * - All synchronized write operations should write to
+ * the "count" field after updating. The operations must not
+ * take any action that could even momentarily cause
+ * a concurrent read operation to see inconsistent
+ * data. This is made easier by the nature of the read
+ * operations in Map. For example, no operation
+ * can reveal that the table has grown but the threshold
+ * has not yet been updated, so there are no atomicity
+ * requirements for this with respect to reads.
+ *
+ * As a guide, all critical volatile reads and writes are marked
+ * in code comments.
+ */
+
+ private static final long serialVersionUID = 2249069246763182397L;
+
+ /**
+ * The number of elements in this segment's region.
+ **/
+ transient volatile int count;
+
+ /**
+ * Number of updates; used for checking lack of modifications
+ * in bulk-read methods.
+ */
+ transient int modCount;
+
+ /**
+ * The table is rehashed when its size exceeds this threshold.
+ * (The value of this field is always (int)(capacity *
+ * loadFactor).)
+ */
+ transient int threshold;
+
+ /**
+ * The per-segment table
+ */
+ transient HashEntry[] table;
+
+ /**
+ * The load factor for the hash table. Even though this value
+ * is same for all segments, it is replicated to avoid needing
+ * links to outer object.
+ * @serial
+ */
+ final float loadFactor;
+
+ Segment(int initialCapacity, float lf) {
+ loadFactor = lf;
+ setTable(new HashEntry[initialCapacity]);
+ }
+
+ /**
+ * Set table to new HashEntry array.
+ * Call only while holding lock or in constructor.
+ **/
+ void setTable(HashEntry[] newTable) {
+ table = newTable;
+ threshold = (int)(newTable.length * loadFactor);
+ count = count; // write-volatile
+ }
+
+ /* Specialized implementations of map methods */
+
+ V get(Object key, int hash) {
+ if (count != 0) { // read-volatile
+ HashEntry[] tab = table;
+ int index = hash & (tab.length - 1);
+ HashEntry<K,V> e = (HashEntry<K,V>) tab[index];
+ while (e != null) {
+ if (e.hash == hash && key.equals(e.key))
+ return e.value;
+ e = e.next;
+ }
+ }
+ return null;
+ }
+
+ boolean containsKey(Object key, int hash) {
+ if (count != 0) { // read-volatile
+ HashEntry[] tab = table;
+ int index = hash & (tab.length - 1);
+ HashEntry<K,V> e = (HashEntry<K,V>) tab[index];
+ while (e != null) {
+ if (e.hash == hash && key.equals(e.key))
+ return true;
+ e = e.next;
+ }
+ }
+ return false;
+ }
+
+ boolean containsValue(Object value) {
+ if (count != 0) { // read-volatile
+ HashEntry[] tab = table;
+ int len = tab.length;
+ for (int i = 0 ; i < len; i++)
+ for (HashEntry<K,V> e = (HashEntry<K,V>)tab[i] ; e != null ; e = e.next)
+ if (value.equals(e.value))
+ return true;
+ }
+ return false;
+ }
+
+ boolean replace(K key, int hash, V oldValue, V newValue) {
+ lock();
+ try {
+ int c = count;
+ HashEntry[] tab = table;
+ int index = hash & (tab.length - 1);
+ HashEntry<K,V> first = (HashEntry<K,V>) tab[index];
+ HashEntry<K,V> e = first;
+ for (;;) {
+ if (e == null)
+ return false;
+ if (e.hash == hash && key.equals(e.key))
+ break;
+ e = e.next;
+ }
+
+ V v = e.value;
+ if (v == null || !oldValue.equals(v))
+ return false;
+
+ e.value = newValue;
+ count = c; // write-volatile
+ return true;
+
+ } finally {
+ unlock();
+ }
+ }
+
+ V replace(K key, int hash, V newValue) {
+ lock();
+ try {
+ int c = count;
+ HashEntry[] tab = table;
+ int index = hash & (tab.length - 1);
+ HashEntry<K,V> first = (HashEntry<K,V>) tab[index];
+ HashEntry<K,V> e = first;
+ for (;;) {
+ if (e == null)
+ return null;
+ if (e.hash == hash && key.equals(e.key))
+ break;
+ e = e.next;
+ }
+
+ V v = e.value;
+ e.value = newValue;
+ count = c; // write-volatile
+ return v;
+
+ } finally {
+ unlock();
+ }
+ }
+
+
+ V put(K key, int hash, V value, boolean onlyIfAbsent) {
+ lock();
+ try {
+ int c = count;
+ HashEntry[] tab = table;
+ int index = hash & (tab.length - 1);
+ HashEntry<K,V> first = (HashEntry<K,V>) tab[index];
+
+ for (HashEntry<K,V> e = first; e != null; e = (HashEntry<K,V>) e.next) {
+ if (e.hash == hash && key.equals(e.key)) {
+ V oldValue = e.value;
+ if (!onlyIfAbsent)
+ e.value = value;
+ ++modCount;
+ count = c; // write-volatile
+ return oldValue;
+ }
+ }
+
+ tab[index] = new HashEntry<K,V>(hash, key, value, first);
+ ++modCount;
+ ++c;
+ count = c; // write-volatile
+ if (c > threshold)
+ setTable(rehash(tab));
+ return null;
+ } finally {
+ unlock();
+ }
+ }
+
+ HashEntry[] rehash(HashEntry[] oldTable) {
+ int oldCapacity = oldTable.length;
+ if (oldCapacity >= MAXIMUM_CAPACITY)
+ return oldTable;
+
+ /*
+ * Reclassify nodes in each list to new Map. Because we are
+ * using power-of-two expansion, the elements from each bin
+ * must either stay at same index, or move with a power of two
+ * offset. We eliminate unnecessary node creation by catching
+ * cases where old nodes can be reused because their next
+ * fields won't change. Statistically, at the default
+ * threshold, only about one-sixth of them need cloning when
+ * a table doubles. The nodes they replace will be garbage
+ * collectable as soon as they are no longer referenced by any
+ * reader thread that may be in the midst of traversing table
+ * right now.
+ */
+
+ HashEntry[] newTable = new HashEntry[oldCapacity << 1];
+ int sizeMask = newTable.length - 1;
+ for (int i = 0; i < oldCapacity ; i++) {
+ // We need to guarantee that any existing reads of old Map can
+ // proceed. So we cannot yet null out each bin.
+ HashEntry<K,V> e = (HashEntry<K,V>)oldTable[i];
+
+ if (e != null) {
+ HashEntry<K,V> next = e.next;
+ int idx = e.hash & sizeMask;
+
+ // Single node on list
+ if (next == null)
+ newTable[idx] = e;
+
+ else {
+ // Reuse trailing consecutive sequence at same slot
+ HashEntry<K,V> lastRun = e;
+ int lastIdx = idx;
+ for (HashEntry<K,V> last = next;
+ last != null;
+ last = last.next) {
+ int k = last.hash & sizeMask;
+ if (k != lastIdx) {
+ lastIdx = k;
+ lastRun = last;
+ }
+ }
+ newTable[lastIdx] = lastRun;
+
+ // Clone all remaining nodes
+ for (HashEntry<K,V> p = e; p != lastRun; p = p.next) {
+ int k = p.hash & sizeMask;
+ newTable[k] = new HashEntry<K,V>(p.hash,
+ p.key,
+ p.value,
+ (HashEntry<K,V>) newTable[k]);
+ }
+ }
+ }
+ }
+ return newTable;
+ }
+
+ /**
+ * Remove; match on key only if value null, else match both.
+ */
+ V remove(Object key, int hash, Object value) {
+ lock();
+ try {
+ int c = count;
+ HashEntry[] tab = table;
+ int index = hash & (tab.length - 1);
+ HashEntry<K,V> first = (HashEntry<K,V>)tab[index];
+
+ HashEntry<K,V> e = first;
+ for (;;) {
+ if (e == null)
+ return null;
+ if (e.hash == hash && key.equals(e.key))
+ break;
+ e = e.next;
+ }
+
+ V oldValue = e.value;
+ if (value != null && !value.equals(oldValue))
+ return null;
+
+ // All entries following removed node can stay in list, but
+ // all preceding ones need to be cloned.
+ HashEntry<K,V> newFirst = e.next;
+ for (HashEntry<K,V> p = first; p != e; p = p.next)
+ newFirst = new HashEntry<K,V>(p.hash, p.key,
+ p.value, newFirst);
+ tab[index] = newFirst;
+ ++modCount;
+ count = c-1; // write-volatile
+ return oldValue;
+ } finally {
+ unlock();
+ }
+ }
+
+ void clear() {
+ lock();
+ try {
+ HashEntry[] tab = table;
+ for (int i = 0; i < tab.length ; i++)
+ tab[i] = null;
+ ++modCount;
+ count = 0; // write-volatile
+ } finally {
+ unlock();
+ }
+ }
+ }
+
+ /**
+ * ConcurrentHashMap list entry. Note that this is never exported
+ * out as a user-visible Map.Entry
+ */
+ static final class HashEntry<K,V> {
+ final K key;
+ V value;
+ final int hash;
+ final HashEntry<K,V> next;
+
+ HashEntry(int hash, K key, V value, HashEntry<K,V> next) {
+ this.value = value;
+ this.hash = hash;
+ this.key = key;
+ this.next = next;
+ }
+ }
+
+
+ /* ---------------- Public operations -------------- */
+
+ /**
+ * Creates a new, empty map with the specified initial
+ * capacity and the specified load factor.
+ *
+ * @param initialCapacity the initial capacity. The implementation
+ * performs internal sizing to accommodate this many elements.
+ * @param loadFactor the load factor threshold, used to control resizing.
+ * @param concurrencyLevel the estimated number of concurrently
+ * updating threads. The implementation performs internal sizing
+ * to try to accommodate this many threads.
+ * @throws IllegalArgumentException if the initial capacity is
+ * negative or the load factor or concurrencyLevel are
+ * nonpositive.
+ */
+ public ConcurrentHashMap(int initialCapacity,
+ float loadFactor, int concurrencyLevel) {
+ if (!(loadFactor > 0) || initialCapacity < 0 || concurrencyLevel <= 0)
+ throw new IllegalArgumentException();
+
+ if (concurrencyLevel > MAX_SEGMENTS)
+ concurrencyLevel = MAX_SEGMENTS;
+
+ // Find power-of-two sizes best matching arguments
+ int sshift = 0;
+ int ssize = 1;
+ while (ssize < concurrencyLevel) {
+ ++sshift;
+ ssize <<= 1;
+ }
+ segmentShift = 32 - sshift;
+ segmentMask = ssize - 1;
+ this.segments = new Segment[ssize];
+
+ if (initialCapacity > MAXIMUM_CAPACITY)
+ initialCapacity = MAXIMUM_CAPACITY;
+ int c = initialCapacity / ssize;
+ if (c * ssize < initialCapacity)
+ ++c;
+ int cap = 1;
+ while (cap < c)
+ cap <<= 1;
+
+ for (int i = 0; i < this.segments.length; ++i)
+ this.segments[i] = new Segment<K,V>(cap, loadFactor);
+ }
+
+ /**
+ * Creates a new, empty map with the specified initial
+ * capacity, and with default load factor and concurrencyLevel.
+ *
+ * @param initialCapacity The implementation performs internal
+ * sizing to accommodate this many elements.
+ * @throws IllegalArgumentException if the initial capacity of
+ * elements is negative.
+ */
+ public ConcurrentHashMap(int initialCapacity) {
+ this(initialCapacity, DEFAULT_LOAD_FACTOR, DEFAULT_SEGMENTS);
+ }
+
+ /**
+ * Creates a new, empty map with a default initial capacity,
+ * load factor, and concurrencyLevel.
+ */
+ public ConcurrentHashMap() {
+ this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_SEGMENTS);
+ }
+
+ /**
+ * Creates a new map with the same mappings as the given map. The
+ * map is created with a capacity of twice the number of mappings in
+ * the given map or 11 (whichever is greater), and a default load factor.
+ * @param t the map
+ */
+ public ConcurrentHashMap(Map<? extends K, ? extends V> t) {
+ this(Math.max((int) (t.size() / DEFAULT_LOAD_FACTOR) + 1,
+ 11),
+ DEFAULT_LOAD_FACTOR, DEFAULT_SEGMENTS);
+ putAll(t);
+ }
+
+ public boolean isEmpty() {
+ final Segment[] segments = this.segments;
+ /*
+ * We need to keep track of per-segment modCounts to avoid ABA
+ * problems in which an element in one segment was added and
+ * in another removed during traversal, in which case the
+ * table was never actually empty at any point. Note the
+ * similar use of modCounts in the size() and containsValue()
+ * methods, which are the only other methods also susceptible
+ * to ABA problems.
+ */
+ int[] mc = new int[segments.length];
+ int mcsum = 0;
+ for (int i = 0; i < segments.length; ++i) {
+ if (segments[i].count != 0)
+ return false;
+ else
+ mcsum += mc[i] = segments[i].modCount;
+ }
+ // If mcsum happens to be zero, then we know we got a snapshot
+ // before any modifications at all were made. This is
+ // probably common enough to bother tracking.
+ if (mcsum != 0) {
+ for (int i = 0; i < segments.length; ++i) {
+ if (segments[i].count != 0 ||
+ mc[i] != segments[i].modCount)
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public int size() {
+ final Segment[] segments = this.segments;
+ int[] mc = new int[segments.length];
+ for (;;) {
+ long sum = 0;
+ int mcsum = 0;
+ for (int i = 0; i < segments.length; ++i) {
+ sum += segments[i].count;
+ mcsum += mc[i] = segments[i].modCount;
+ }
+ int check = 0;
+ if (mcsum != 0) {
+ for (int i = 0; i < segments.length; ++i) {
+ check += segments[i].count;
+ if (mc[i] != segments[i].modCount) {
+ check = -1; // force retry
+ break;
+ }
+ }
+ }
+ if (check == sum) {
+ if (sum > Integer.MAX_VALUE)
+ return Integer.MAX_VALUE;
+ else
+ return (int)sum;
+ }
+ }
+ }
+
+
+ /**
+ * Returns the value to which the specified key is mapped in this table.
+ *
+ * @param key a key in the table.
+ * @return the value to which the key is mapped in this table;
+ * <tt>null</tt> if the key is not mapped to any value in
+ * this table.
+ * @throws NullPointerException if the key is
+ * <tt>null</tt>.
+ */
+ public V get(Object key) {
+ int hash = hash(key); // throws NullPointerException if key null
+ return segmentFor(hash).get(key, hash);
+ }
+
+ /**
+ * Tests if the specified object is a key in this table.
+ *
+ * @param key possible key.
+ * @return <tt>true</tt> if and only if the specified object
+ * is a key in this table, as determined by the
+ * <tt>equals</tt> method; <tt>false</tt> otherwise.
+ * @throws NullPointerException if the key is
+ * <tt>null</tt>.
+ */
+ public boolean containsKey(Object key) {
+ int hash = hash(key); // throws NullPointerException if key null
+ return segmentFor(hash).containsKey(key, hash);
+ }
+
+ /**
+ * Returns <tt>true</tt> if this map maps one or more keys to the
+ * specified value. Note: This method requires a full internal
+ * traversal of the hash table, and so is much slower than
+ * method <tt>containsKey</tt>.
+ *
+ * @param value value whose presence in this map is to be tested.
+ * @return <tt>true</tt> if this map maps one or more keys to the
+ * specified value.
+ * @throws NullPointerException if the value is <tt>null</tt>.
+ */
+ public boolean containsValue(Object value) {
+ if (value == null)
+ throw new NullPointerException();
+
+ final Segment[] segments = this.segments;
+ int[] mc = new int[segments.length];
+ for (;;) {
+ int sum = 0;
+ int mcsum = 0;
+ for (int i = 0; i < segments.length; ++i) {
+ int c = segments[i].count;
+ mcsum += mc[i] = segments[i].modCount;
+ if (segments[i].containsValue(value))
+ return true;
+ }
+ boolean cleanSweep = true;
+ if (mcsum != 0) {
+ for (int i = 0; i < segments.length; ++i) {
+ int c = segments[i].count;
+ if (mc[i] != segments[i].modCount) {
+ cleanSweep = false;
+ break;
+ }
+ }
+ }
+ if (cleanSweep)
+ return false;
+ }
+ }
+
+ /**
+ * Legacy method testing if some key maps into the specified value
+ * in this table. This method is identical in functionality to
+ * {@link #containsValue}, and exists solely to ensure
+ * full compatibility with class {@link java.util.Hashtable},
+ * which supported this method prior to introduction of the
+ * Java Collections framework.
+
+ * @param value a value to search for.
+ * @return <tt>true</tt> if and only if some key maps to the
+ * <tt>value</tt> argument in this table as
+ * determined by the <tt>equals</tt> method;
+ * <tt>false</tt> otherwise.
+ * @throws NullPointerException if the value is <tt>null</tt>.
+ */
+ public boolean contains(Object value) {
+ return containsValue(value);
+ }
+
+ /**
+ * Maps the specified <tt>key</tt> to the specified
+ * <tt>value</tt> in this table. Neither the key nor the
+ * value can be <tt>null</tt>.
+ *
+ * <p> The value can be retrieved by calling the <tt>get</tt> method
+ * with a key that is equal to the original key.
+ *
+ * @param key the table key.
+ * @param value the value.
+ * @return the previous value of the specified key in this table,
+ * or <tt>null</tt> if it did not have one.
+ * @throws NullPointerException if the key or value is
+ * <tt>null</tt>.
+ */
+ public V put(K key, V value) {
+ if (value == null)
+ throw new NullPointerException();
+ int hash = hash(key);
+ return segmentFor(hash).put(key, hash, value, false);
+ }
+
+ /**
+ * If the specified key is not already associated
+ * with a value, associate it with the given value.
+ * This is equivalent to
+ * <pre>
+ * if (!map.containsKey(key))
+ * return map.put(key, value);
+ * else
+ * return map.get(key);
+ * </pre>
+ * Except that the action is performed atomically.
+ * @param key key with which the specified value is to be associated.
+ * @param value value to be associated with the specified key.
+ * @return previous value associated with specified key, or <tt>null</tt>
+ * if there was no mapping for key. A <tt>null</tt> return can
+ * also indicate that the map previously associated <tt>null</tt>
+ * with the specified key, if the implementation supports
+ * <tt>null</tt> values.
+ *
+ * @throws UnsupportedOperationException if the <tt>put</tt> operation is
+ * not supported by this map.
+ * @throws ClassCastException if the class of the specified key or value
+ * prevents it from being stored in this map.
+ * @throws NullPointerException if the specified key or value is
+ * <tt>null</tt>.
+ *
+ **/
+ public V putIfAbsent(K key, V value) {
+ if (value == null)
+ throw new NullPointerException();
+ int hash = hash(key);
+ return segmentFor(hash).put(key, hash, value, true);
+ }
+
+
+ /**
+ * Copies all of the mappings from the specified map to this one.
+ *
+ * These mappings replace any mappings that this map had for any of the
+ * keys currently in the specified Map.
+ *
+ * @param t Mappings to be stored in this map.
+ */
+ public void putAll(Map<? extends K, ? extends V> t) {
+ for (Iterator<? extends Map.Entry<? extends K, ? extends V>> it = (Iterator<? extends Map.Entry<? extends K, ? extends V>>) t.entrySet().iterator(); it.hasNext(); ) {
+ Entry<? extends K, ? extends V> e = it.next();
+ put(e.getKey(), e.getValue());
+ }
+ }
+
+ /**
+ * Removes the key (and its corresponding value) from this
+ * table. This method does nothing if the key is not in the table.
+ *
+ * @param key the key that needs to be removed.
+ * @return the value to which the key had been mapped in this table,
+ * or <tt>null</tt> if the key did not have a mapping.
+ * @throws NullPointerException if the key is
+ * <tt>null</tt>.
+ */
+ public V remove(Object key) {
+ int hash = hash(key);
+ return segmentFor(hash).remove(key, hash, null);
+ }
+
+ /**
+ * Remove entry for key only if currently mapped to given value.
+ * Acts as
+ * <pre>
+ * if (map.get(key).equals(value)) {
+ * map.remove(key);
+ * return true;
+ * } else return false;
+ * </pre>
+ * except that the action is performed atomically.
+ * @param key key with which the specified value is associated.
+ * @param value value associated with the specified key.
+ * @return true if the value was removed
+ * @throws NullPointerException if the specified key is
+ * <tt>null</tt>.
+ */
+ public boolean remove(Object key, Object value) {
+ int hash = hash(key);
+ return segmentFor(hash).remove(key, hash, value) != null;
+ }
+
+
+ /**
+ * Replace entry for key only if currently mapped to given value.
+ * Acts as
+ * <pre>
+ * if (map.get(key).equals(oldValue)) {
+ * map.put(key, newValue);
+ * return true;
+ * } else return false;
+ * </pre>
+ * except that the action is performed atomically.
+ * @param key key with which the specified value is associated.
+ * @param oldValue value expected to be associated with the specified key.
+ * @param newValue value to be associated with the specified key.
+ * @return true if the value was replaced
+ * @throws NullPointerException if the specified key or values are
+ * <tt>null</tt>.
+ */
+ public boolean replace(K key, V oldValue, V newValue) {
+ if (oldValue == null || newValue == null)
+ throw new NullPointerException();
+ int hash = hash(key);
+ return segmentFor(hash).replace(key, hash, oldValue, newValue);
+ }
+
+ /**
+ * Replace entry for key only if currently mapped to some value.
+ * Acts as
+ * <pre>
+ * if ((map.containsKey(key)) {
+ * return map.put(key, value);
+ * } else return null;
+ * </pre>
+ * except that the action is performed atomically.
+ * @param key key with which the specified value is associated.
+ * @param value value to be associated with the specified key.
+ * @return previous value associated with specified key, or <tt>null</tt>
+ * if there was no mapping for key.
+ * @throws NullPointerException if the specified key or value is
+ * <tt>null</tt>.
+ */
+ public V replace(K key, V value) {
+ if (value == null)
+ throw new NullPointerException();
+ int hash = hash(key);
+ return segmentFor(hash).replace(key, hash, value);
+ }
+
+
+ /**
+ * Removes all mappings from this map.
+ */
+ public void clear() {
+ for (int i = 0; i < segments.length; ++i)
+ segments[i].clear();
+ }
+
+
+// BEGIN android-changed
+// /**
+// * Returns a shallow copy of this
+// * <tt>ConcurrentHashMap</tt> instance: the keys and
+// * values themselves are not cloned.
+// *
+// * @return a shallow copy of this map.
+// */
+// public Object clone() {
+// // We cannot call super.clone, since it would share final
+// // segments array, and there's no way to reassign finals.
+//
+// float lf = segments[0].loadFactor;
+// int segs = segments.length;
+// int cap = (int)(size() / lf);
+// if (cap < segs) cap = segs;
+// ConcurrentHashMap<K,V> t = new ConcurrentHashMap<K,V>(cap, lf, segs);
+// t.putAll(this);
+// return t;
+// }
+// END android-changed
+
+ /**
+ * Returns a set view of the keys contained in this map. The set is
+ * backed by the map, so changes to the map are reflected in the set, and
+ * vice-versa. The set supports element removal, which removes the
+ * corresponding mapping from this map, via the <tt>Iterator.remove</tt>,
+ * <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt>, and
+ * <tt>clear</tt> operations. It does not support the <tt>add</tt> or
+ * <tt>addAll</tt> operations.
+ * The returned <tt>iterator</tt> is a "weakly consistent" iterator that
+ * will never throw {@link java.util.ConcurrentModificationException},
+ * and guarantees to traverse elements as they existed upon
+ * construction of the iterator, and may (but is not guaranteed to)
+ * reflect any modifications subsequent to construction.
+ *
+ * @return a set view of the keys contained in this map.
+ */
+ public Set<K> keySet() {
+ Set<K> ks = keySet;
+ return (ks != null) ? ks : (keySet = new KeySet());
+ }
+
+
+ /**
+ * Returns a collection view of the values contained in this map. The
+ * collection is backed by the map, so changes to the map are reflected in
+ * the collection, and vice-versa. The collection supports element
+ * removal, which removes the corresponding mapping from this map, via the
+ * <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
+ * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
+ * It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
+ * The returned <tt>iterator</tt> is a "weakly consistent" iterator that
+ * will never throw {@link java.util.ConcurrentModificationException},
+ * and guarantees to traverse elements as they existed upon
+ * construction of the iterator, and may (but is not guaranteed to)
+ * reflect any modifications subsequent to construction.
+ *
+ * @return a collection view of the values contained in this map.
+ */
+ public Collection<V> values() {
+ Collection<V> vs = values;
+ return (vs != null) ? vs : (values = new Values());
+ }
+
+
+ /**
+ * Returns a collection view of the mappings contained in this map. Each
+ * element in the returned collection is a <tt>Map.Entry</tt>. The
+ * collection is backed by the map, so changes to the map are reflected in
+ * the collection, and vice-versa. The collection supports element
+ * removal, which removes the corresponding mapping from the map, via the
+ * <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
+ * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
+ * It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
+ * The returned <tt>iterator</tt> is a "weakly consistent" iterator that
+ * will never throw {@link java.util.ConcurrentModificationException},
+ * and guarantees to traverse elements as they existed upon
+ * construction of the iterator, and may (but is not guaranteed to)
+ * reflect any modifications subsequent to construction.
+ *
+ * @return a collection view of the mappings contained in this map.
+ */
+ public Set<Map.Entry<K,V>> entrySet() {
+ Set<Map.Entry<K,V>> es = entrySet;
+ return (es != null) ? es : (entrySet = (Set<Map.Entry<K,V>>) (Set) new EntrySet());
+ }
+
+
+ /**
+ * Returns an enumeration of the keys in this table.
+ *
+ * @return an enumeration of the keys in this table.
+ * @see #keySet
+ */
+ public Enumeration<K> keys() {
+ return new KeyIterator();
+ }
+
+ /**
+ * Returns an enumeration of the values in this table.
+ *
+ * @return an enumeration of the values in this table.
+ * @see #values
+ */
+ public Enumeration<V> elements() {
+ return new ValueIterator();
+ }
+
+ /* ---------------- Iterator Support -------------- */
+
+ abstract class HashIterator {
+ int nextSegmentIndex;
+ int nextTableIndex;
+ HashEntry[] currentTable;
+ HashEntry<K, V> nextEntry;
+ HashEntry<K, V> lastReturned;
+
+ HashIterator() {
+ nextSegmentIndex = segments.length - 1;
+ nextTableIndex = -1;
+ advance();
+ }
+
+ public boolean hasMoreElements() { return hasNext(); }
+
+ final void advance() {
+ if (nextEntry != null && (nextEntry = nextEntry.next) != null)
+ return;
+
+ while (nextTableIndex >= 0) {
+ if ( (nextEntry = (HashEntry<K,V>)currentTable[nextTableIndex--]) != null)
+ return;
+ }
+
+ while (nextSegmentIndex >= 0) {
+ Segment<K,V> seg = (Segment<K,V>)segments[nextSegmentIndex--];
+ if (seg.count != 0) {
+ currentTable = seg.table;
+ for (int j = currentTable.length - 1; j >= 0; --j) {
+ if ( (nextEntry = (HashEntry<K,V>)currentTable[j]) != null) {
+ nextTableIndex = j - 1;
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ public boolean hasNext() { return nextEntry != null; }
+
+ HashEntry<K,V> nextEntry() {
+ if (nextEntry == null)
+ throw new NoSuchElementException();
+ lastReturned = nextEntry;
+ advance();
+ return lastReturned;
+ }
+
+ public void remove() {
+ if (lastReturned == null)
+ throw new IllegalStateException();
+ ConcurrentHashMap.this.remove(lastReturned.key);
+ lastReturned = null;
+ }
+ }
+
+ final class KeyIterator extends HashIterator implements Iterator<K>, Enumeration<K> {
+ public K next() { return super.nextEntry().key; }
+ public K nextElement() { return super.nextEntry().key; }
+ }
+
+ final class ValueIterator extends HashIterator implements Iterator<V>, Enumeration<V> {
+ public V next() { return super.nextEntry().value; }
+ public V nextElement() { return super.nextEntry().value; }
+ }
+
+
+
+ /**
+ * Entry iterator. Exported Entry objects must write-through
+ * changes in setValue, even if the nodes have been cloned. So we
+ * cannot return internal HashEntry objects. Instead, the iterator
+ * itself acts as a forwarding pseudo-entry.
+ */
+ final class EntryIterator extends HashIterator implements Map.Entry<K,V>, Iterator<Entry<K,V>> {
+ public Map.Entry<K,V> next() {
+ nextEntry();
+ return this;
+ }
+
+ public K getKey() {
+ if (lastReturned == null)
+ throw new IllegalStateException("Entry was removed");
+ return lastReturned.key;
+ }
+
+ public V getValue() {
+ if (lastReturned == null)
+ throw new IllegalStateException("Entry was removed");
+ return ConcurrentHashMap.this.get(lastReturned.key);
+ }
+
+ public V setValue(V value) {
+ if (lastReturned == null)
+ throw new IllegalStateException("Entry was removed");
+ return ConcurrentHashMap.this.put(lastReturned.key, value);
+ }
+
+ public boolean equals(Object o) {
+ // If not acting as entry, just use default.
+ if (lastReturned == null)
+ return super.equals(o);
+ if (!(o instanceof Map.Entry))
+ return false;
+ Map.Entry e = (Map.Entry)o;
+ return eq(getKey(), e.getKey()) && eq(getValue(), e.getValue());
+ }
+
+ public int hashCode() {
+ // If not acting as entry, just use default.
+ if (lastReturned == null)
+ return super.hashCode();
+
+ Object k = getKey();
+ Object v = getValue();
+ return ((k == null) ? 0 : k.hashCode()) ^
+ ((v == null) ? 0 : v.hashCode());
+ }
+
+ public String toString() {
+ // If not acting as entry, just use default.
+ if (lastReturned == null)
+ return super.toString();
+ else
+ return getKey() + "=" + getValue();
+ }
+
+ boolean eq(Object o1, Object o2) {
+ return (o1 == null ? o2 == null : o1.equals(o2));
+ }
+
+ }
+
+ final class KeySet extends AbstractSet<K> {
+ public Iterator<K> iterator() {
+ return new KeyIterator();
+ }
+ public int size() {
+ return ConcurrentHashMap.this.size();
+ }
+ public boolean contains(Object o) {
+ return ConcurrentHashMap.this.containsKey(o);
+ }
+ public boolean remove(Object o) {
+ return ConcurrentHashMap.this.remove(o) != null;
+ }
+ public void clear() {
+ ConcurrentHashMap.this.clear();
+ }
+ }
+
+ final class Values extends AbstractCollection<V> {
+ public Iterator<V> iterator() {
+ return new ValueIterator();
+ }
+ public int size() {
+ return ConcurrentHashMap.this.size();
+ }
+ public boolean contains(Object o) {
+ return ConcurrentHashMap.this.containsValue(o);
+ }
+ public void clear() {
+ ConcurrentHashMap.this.clear();
+ }
+ }
+
+ final class EntrySet extends AbstractSet<Map.Entry<K,V>> {
+ public Iterator<Map.Entry<K,V>> iterator() {
+ return new EntryIterator();
+ }
+ public boolean contains(Object o) {
+ if (!(o instanceof Map.Entry))
+ return false;
+ Map.Entry<K,V> e = (Map.Entry<K,V>)o;
+ V v = ConcurrentHashMap.this.get(e.getKey());
+ return v != null && v.equals(e.getValue());
+ }
+ public boolean remove(Object o) {
+ if (!(o instanceof Map.Entry))
+ return false;
+ Map.Entry<K,V> e = (Map.Entry<K,V>)o;
+ return ConcurrentHashMap.this.remove(e.getKey(), e.getValue());
+ }
+ public int size() {
+ return ConcurrentHashMap.this.size();
+ }
+ public void clear() {
+ ConcurrentHashMap.this.clear();
+ }
+ public Object[] toArray() {
+ // Since we don't ordinarily have distinct Entry objects, we
+ // must pack elements using exportable SimpleEntry
+ Collection<Map.Entry<K,V>> c = new ArrayList<Map.Entry<K,V>>(size());
+ for (Iterator<Map.Entry<K,V>> i = iterator(); i.hasNext(); )
+ c.add(new SimpleEntry<K,V>(i.next()));
+ return c.toArray();
+ }
+ public <T> T[] toArray(T[] a) {
+ Collection<Map.Entry<K,V>> c = new ArrayList<Map.Entry<K,V>>(size());
+ for (Iterator<Map.Entry<K,V>> i = iterator(); i.hasNext(); )
+ c.add(new SimpleEntry<K,V>(i.next()));
+ return c.toArray(a);
+ }
+
+ }
+
+ /**
+ * This duplicates java.util.AbstractMap.SimpleEntry until this class
+ * is made accessible.
+ */
+ static final class SimpleEntry<K,V> implements Entry<K,V> {
+ K key;
+ V value;
+
+ public SimpleEntry(K key, V value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public SimpleEntry(Entry<K,V> e) {
+ this.key = e.getKey();
+ this.value = e.getValue();
+ }
+
+ public K getKey() {
+ return key;
+ }
+
+ public V getValue() {
+ return value;
+ }
+
+ public V setValue(V value) {
+ V oldValue = this.value;
+ this.value = value;
+ return oldValue;
+ }
+
+ public boolean equals(Object o) {
+ if (!(o instanceof Map.Entry))
+ return false;
+ Map.Entry e = (Map.Entry)o;
+ return eq(key, e.getKey()) && eq(value, e.getValue());
+ }
+
+ public int hashCode() {
+ return ((key == null) ? 0 : key.hashCode()) ^
+ ((value == null) ? 0 : value.hashCode());
+ }
+
+ public String toString() {
+ return key + "=" + value;
+ }
+
+ static boolean eq(Object o1, Object o2) {
+ return (o1 == null ? o2 == null : o1.equals(o2));
+ }
+ }
+
+ /* ---------------- Serialization Support -------------- */
+
+ /**
+ * Save the state of the <tt>ConcurrentHashMap</tt>
+ * instance to a stream (i.e.,
+ * serialize it).
+ * @param s the stream
+ * @serialData
+ * the key (Object) and value (Object)
+ * for each key-value mapping, followed by a null pair.
+ * The key-value mappings are emitted in no particular order.
+ */
+ private void writeObject(java.io.ObjectOutputStream s) throws IOException {
+ s.defaultWriteObject();
+
+ for (int k = 0; k < segments.length; ++k) {
+ Segment<K,V> seg = (Segment<K,V>)segments[k];
+ seg.lock();
+ try {
+ HashEntry[] tab = seg.table;
+ for (int i = 0; i < tab.length; ++i) {
+ for (HashEntry<K,V> e = (HashEntry<K,V>)tab[i]; e != null; e = e.next) {
+ s.writeObject(e.key);
+ s.writeObject(e.value);
+ }
+ }
+ } finally {
+ seg.unlock();
+ }
+ }
+ s.writeObject(null);
+ s.writeObject(null);
+ }
+
+ /**
+ * Reconstitute the <tt>ConcurrentHashMap</tt>
+ * instance from a stream (i.e.,
+ * deserialize it).
+ * @param s the stream
+ */
+ private void readObject(java.io.ObjectInputStream s)
+ throws IOException, ClassNotFoundException {
+ s.defaultReadObject();
+
+ // Initialize each segment to be minimally sized, and let grow.
+ for (int i = 0; i < segments.length; ++i) {
+ segments[i].setTable(new HashEntry[1]);
+ }
+
+ // Read the keys and values, and put the mappings in the table
+ for (;;) {
+ K key = (K) s.readObject();
+ V value = (V) s.readObject();
+ if (key == null)
+ break;
+ put(key, value);
+ }
+ }
+}
+
+
+
+
diff --git a/concurrent/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java b/concurrent/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java
new file mode 100644
index 0000000..794142d
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java
@@ -0,0 +1,481 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+import java.util.*;
+import java.util.concurrent.atomic.*;
+
+
+// BEGIN android-note
+// removed link to collections framework docs
+// END android-note
+
+/**
+ * An unbounded thread-safe {@linkplain Queue queue} based on linked nodes.
+ * This queue orders elements FIFO (first-in-first-out).
+ * The <em>head</em> of the queue is that element that has been on the
+ * queue the longest time.
+ * The <em>tail</em> of the queue is that element that has been on the
+ * queue the shortest time. New elements
+ * are inserted at the tail of the queue, and the queue retrieval
+ * operations obtain elements at the head of the queue.
+ * A <tt>ConcurrentLinkedQueue</tt> is an appropriate choice when
+ * many threads will share access to a common collection.
+ * This queue does not permit <tt>null</tt> elements.
+ *
+ * <p>This implementation employs an efficient &quot;wait-free&quot;
+ * algorithm based on one described in <a
+ * href="http://www.cs.rochester.edu/u/michael/PODC96.html"> Simple,
+ * Fast, and Practical Non-Blocking and Blocking Concurrent Queue
+ * Algorithms</a> by Maged M. Michael and Michael L. Scott.
+ *
+ * <p>Beware that, unlike in most collections, the <tt>size</tt> method
+ * is <em>NOT</em> a constant-time operation. Because of the
+ * asynchronous nature of these queues, determining the current number
+ * of elements requires a traversal of the elements.
+ *
+ * <p>This class implements all of the <em>optional</em> methods
+ * of the {@link Collection} and {@link Iterator} interfaces.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ * @param <E> the type of elements held in this collection
+ *
+ */
+public class ConcurrentLinkedQueue<E> extends AbstractQueue<E>
+ implements Queue<E>, java.io.Serializable {
+ private static final long serialVersionUID = 196745693267521676L;
+
+ /*
+ * This is a straight adaptation of Michael & Scott algorithm.
+ * For explanation, read the paper. The only (minor) algorithmic
+ * difference is that this version supports lazy deletion of
+ * internal nodes (method remove(Object)) -- remove CAS'es item
+ * fields to null. The normal queue operations unlink but then
+ * pass over nodes with null item fields. Similarly, iteration
+ * methods ignore those with nulls.
+ */
+
+ private static class Node<E> {
+ private volatile E item;
+ private volatile Node<E> next;
+
+ private static final
+ AtomicReferenceFieldUpdater<Node, Node>
+ nextUpdater =
+ AtomicReferenceFieldUpdater.newUpdater
+ (Node.class, Node.class, "next");
+ private static final
+ AtomicReferenceFieldUpdater<Node, Object>
+ itemUpdater =
+ AtomicReferenceFieldUpdater.newUpdater
+ (Node.class, Object.class, "item");
+
+ Node(E x) { item = x; }
+
+ Node(E x, Node<E> n) { item = x; next = n; }
+
+ E getItem() {
+ return item;
+ }
+
+ boolean casItem(E cmp, E val) {
+ return itemUpdater.compareAndSet(this, cmp, val);
+ }
+
+ void setItem(E val) {
+ itemUpdater.set(this, val);
+ }
+
+ Node<E> getNext() {
+ return next;
+ }
+
+ boolean casNext(Node<E> cmp, Node<E> val) {
+ return nextUpdater.compareAndSet(this, cmp, val);
+ }
+
+ void setNext(Node<E> val) {
+ nextUpdater.set(this, val);
+ }
+
+ }
+
+ private static final
+ AtomicReferenceFieldUpdater<ConcurrentLinkedQueue, Node>
+ tailUpdater =
+ AtomicReferenceFieldUpdater.newUpdater
+ (ConcurrentLinkedQueue.class, Node.class, "tail");
+ private static final
+ AtomicReferenceFieldUpdater<ConcurrentLinkedQueue, Node>
+ headUpdater =
+ AtomicReferenceFieldUpdater.newUpdater
+ (ConcurrentLinkedQueue.class, Node.class, "head");
+
+ private boolean casTail(Node<E> cmp, Node<E> val) {
+ return tailUpdater.compareAndSet(this, cmp, val);
+ }
+
+ private boolean casHead(Node<E> cmp, Node<E> val) {
+ return headUpdater.compareAndSet(this, cmp, val);
+ }
+
+
+ /**
+ * Pointer to header node, initialized to a dummy node. The first
+ * actual node is at head.getNext().
+ */
+ private transient volatile Node<E> head = new Node<E>(null, null);
+
+ /** Pointer to last node on list **/
+ private transient volatile Node<E> tail = head;
+
+
+ /**
+ * Creates a <tt>ConcurrentLinkedQueue</tt> that is initially empty.
+ */
+ public ConcurrentLinkedQueue() {}
+
+ /**
+ * Creates a <tt>ConcurrentLinkedQueue</tt>
+ * initially containing the elements of the given collection,
+ * added in traversal order of the collection's iterator.
+ * @param c the collection of elements to initially contain
+ * @throws NullPointerException if <tt>c</tt> or any element within it
+ * is <tt>null</tt>
+ */
+ public ConcurrentLinkedQueue(Collection<? extends E> c) {
+ for (Iterator<? extends E> it = c.iterator(); it.hasNext();)
+ add(it.next());
+ }
+
+ // Have to override just to update the javadoc
+
+ /**
+ * Adds the specified element to the tail of this queue.
+ * @param o the element to add.
+ * @return <tt>true</tt> (as per the general contract of
+ * <tt>Collection.add</tt>).
+ *
+ * @throws NullPointerException if the specified element is <tt>null</tt>
+ */
+ public boolean add(E o) {
+ return offer(o);
+ }
+
+ /**
+ * Inserts the specified element to the tail of this queue.
+ *
+ * @param o the element to add.
+ * @return <tt>true</tt> (as per the general contract of
+ * <tt>Queue.offer</tt>).
+ * @throws NullPointerException if the specified element is <tt>null</tt>
+ */
+ public boolean offer(E o) {
+ if (o == null) throw new NullPointerException();
+ Node<E> n = new Node<E>(o, null);
+ for(;;) {
+ Node<E> t = tail;
+ Node<E> s = t.getNext();
+ if (t == tail) {
+ if (s == null) {
+ if (t.casNext(s, n)) {
+ casTail(t, n);
+ return true;
+ }
+ } else {
+ casTail(t, s);
+ }
+ }
+ }
+ }
+
+ public E poll() {
+ for (;;) {
+ Node<E> h = head;
+ Node<E> t = tail;
+ Node<E> first = h.getNext();
+ if (h == head) {
+ if (h == t) {
+ if (first == null)
+ return null;
+ else
+ casTail(t, first);
+ } else if (casHead(h, first)) {
+ E item = first.getItem();
+ if (item != null) {
+ first.setItem(null);
+ return item;
+ }
+ // else skip over deleted item, continue loop,
+ }
+ }
+ }
+ }
+
+ public E peek() { // same as poll except don't remove item
+ for (;;) {
+ Node<E> h = head;
+ Node<E> t = tail;
+ Node<E> first = h.getNext();
+ if (h == head) {
+ if (h == t) {
+ if (first == null)
+ return null;
+ else
+ casTail(t, first);
+ } else {
+ E item = first.getItem();
+ if (item != null)
+ return item;
+ else // remove deleted node and continue
+ casHead(h, first);
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the first actual (non-header) node on list. This is yet
+ * another variant of poll/peek; here returning out the first
+ * node, not element (so we cannot collapse with peek() without
+ * introducing race.)
+ */
+ Node<E> first() {
+ for (;;) {
+ Node<E> h = head;
+ Node<E> t = tail;
+ Node<E> first = h.getNext();
+ if (h == head) {
+ if (h == t) {
+ if (first == null)
+ return null;
+ else
+ casTail(t, first);
+ } else {
+ if (first.getItem() != null)
+ return first;
+ else // remove deleted node and continue
+ casHead(h, first);
+ }
+ }
+ }
+ }
+
+
+ public boolean isEmpty() {
+ return first() == null;
+ }
+
+ /**
+ * Returns the number of elements in this queue. If this queue
+ * contains more than <tt>Integer.MAX_VALUE</tt> elements, returns
+ * <tt>Integer.MAX_VALUE</tt>.
+ *
+ * <p>Beware that, unlike in most collections, this method is
+ * <em>NOT</em> a constant-time operation. Because of the
+ * asynchronous nature of these queues, determining the current
+ * number of elements requires an O(n) traversal.
+ *
+ * @return the number of elements in this queue.
+ */
+ public int size() {
+ int count = 0;
+ for (Node<E> p = first(); p != null; p = p.getNext()) {
+ if (p.getItem() != null) {
+ // Collections.size() spec says to max out
+ if (++count == Integer.MAX_VALUE)
+ break;
+ }
+ }
+ return count;
+ }
+
+ public boolean contains(Object o) {
+ if (o == null) return false;
+ for (Node<E> p = first(); p != null; p = p.getNext()) {
+ E item = p.getItem();
+ if (item != null &&
+ o.equals(item))
+ return true;
+ }
+ return false;
+ }
+
+ public boolean remove(Object o) {
+ if (o == null) return false;
+ for (Node<E> p = first(); p != null; p = p.getNext()) {
+ E item = p.getItem();
+ if (item != null &&
+ o.equals(item) &&
+ p.casItem(item, null))
+ return true;
+ }
+ return false;
+ }
+
+ public Object[] toArray() {
+ // Use ArrayList to deal with resizing.
+ ArrayList<E> al = new ArrayList<E>();
+ for (Node<E> p = first(); p != null; p = p.getNext()) {
+ E item = p.getItem();
+ if (item != null)
+ al.add(item);
+ }
+ return al.toArray();
+ }
+
+ public <T> T[] toArray(T[] a) {
+ // try to use sent-in array
+ int k = 0;
+ Node<E> p;
+ for (p = first(); p != null && k < a.length; p = p.getNext()) {
+ E item = p.getItem();
+ if (item != null)
+ a[k++] = (T)item;
+ }
+ if (p == null) {
+ if (k < a.length)
+ a[k] = null;
+ return a;
+ }
+
+ // If won't fit, use ArrayList version
+ ArrayList<E> al = new ArrayList<E>();
+ for (Node<E> q = first(); q != null; q = q.getNext()) {
+ E item = q.getItem();
+ if (item != null)
+ al.add(item);
+ }
+ return (T[])al.toArray(a);
+ }
+
+ /**
+ * Returns an iterator over the elements in this queue in proper sequence.
+ * The returned iterator is a "weakly consistent" iterator that
+ * will never throw {@link java.util.ConcurrentModificationException},
+ * and guarantees to traverse elements as they existed upon
+ * construction of the iterator, and may (but is not guaranteed to)
+ * reflect any modifications subsequent to construction.
+ *
+ * @return an iterator over the elements in this queue in proper sequence.
+ */
+ public Iterator<E> iterator() {
+ return new Itr();
+ }
+
+ private class Itr implements Iterator<E> {
+ /**
+ * Next node to return item for.
+ */
+ private Node<E> nextNode;
+
+ /**
+ * nextItem holds on to item fields because once we claim
+ * that an element exists in hasNext(), we must return it in
+ * the following next() call even if it was in the process of
+ * being removed when hasNext() was called.
+ **/
+ private E nextItem;
+
+ /**
+ * Node of the last returned item, to support remove.
+ */
+ private Node<E> lastRet;
+
+ Itr() {
+ advance();
+ }
+
+ /**
+ * Moves to next valid node and returns item to return for
+ * next(), or null if no such.
+ */
+ private E advance() {
+ lastRet = nextNode;
+ E x = nextItem;
+
+ Node<E> p = (nextNode == null)? first() : nextNode.getNext();
+ for (;;) {
+ if (p == null) {
+ nextNode = null;
+ nextItem = null;
+ return x;
+ }
+ E item = p.getItem();
+ if (item != null) {
+ nextNode = p;
+ nextItem = item;
+ return x;
+ } else // skip over nulls
+ p = p.getNext();
+ }
+ }
+
+ public boolean hasNext() {
+ return nextNode != null;
+ }
+
+ public E next() {
+ if (nextNode == null) throw new NoSuchElementException();
+ return advance();
+ }
+
+ public void remove() {
+ Node<E> l = lastRet;
+ if (l == null) throw new IllegalStateException();
+ // rely on a future traversal to relink.
+ l.setItem(null);
+ lastRet = null;
+ }
+ }
+
+ /**
+ * Save the state to a stream (that is, serialize it).
+ *
+ * @serialData All of the elements (each an <tt>E</tt>) in
+ * the proper order, followed by a null
+ * @param s the stream
+ */
+ private void writeObject(java.io.ObjectOutputStream s)
+ throws java.io.IOException {
+
+ // Write out any hidden stuff
+ s.defaultWriteObject();
+
+ // Write out all elements in the proper order.
+ for (Node<E> p = first(); p != null; p = p.getNext()) {
+ Object item = p.getItem();
+ if (item != null)
+ s.writeObject(item);
+ }
+
+ // Use trailing null as sentinel
+ s.writeObject(null);
+ }
+
+ /**
+ * Reconstitute the Queue instance from a stream (that is,
+ * deserialize it).
+ * @param s the stream
+ */
+ private void readObject(java.io.ObjectInputStream s)
+ throws java.io.IOException, ClassNotFoundException {
+ // Read in capacity, and any hidden stuff
+ s.defaultReadObject();
+ head = new Node<E>(null, null);
+ tail = head;
+ // Read in all elements and place in queue
+ for (;;) {
+ E item = (E)s.readObject();
+ if (item == null)
+ break;
+ else
+ offer(item);
+ }
+ }
+
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/ConcurrentMap.java b/concurrent/src/main/java/java/util/concurrent/ConcurrentMap.java
new file mode 100644
index 0000000..32dc000
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/ConcurrentMap.java
@@ -0,0 +1,118 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+import java.util.Map;
+
+// BEGIN android-note
+// removed link to collections framework docs
+// END android-note
+
+/**
+ * A {@link java.util.Map} providing additional atomic
+ * <tt>putIfAbsent</tt>, <tt>remove</tt>, and <tt>replace</tt> methods.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ * @param <K> the type of keys maintained by this map
+ * @param <V> the type of mapped values
+ */
+public interface ConcurrentMap<K, V> extends Map<K, V> {
+ /**
+ * If the specified key is not already associated
+ * with a value, associate it with the given value.
+ * This is equivalent to
+ * <pre>
+ * if (!map.containsKey(key))
+ * return map.put(key, value);
+ * else
+ * return map.get(key);
+ * </pre>
+ * Except that the action is performed atomically.
+ * @param key key with which the specified value is to be associated.
+ * @param value value to be associated with the specified key.
+ * @return previous value associated with specified key, or <tt>null</tt>
+ * if there was no mapping for key. A <tt>null</tt> return can
+ * also indicate that the map previously associated <tt>null</tt>
+ * with the specified key, if the implementation supports
+ * <tt>null</tt> values.
+ *
+ * @throws UnsupportedOperationException if the <tt>put</tt> operation is
+ * not supported by this map.
+ * @throws ClassCastException if the class of the specified key or value
+ * prevents it from being stored in this map.
+ * @throws IllegalArgumentException if some aspect of this key or value
+ * prevents it from being stored in this map.
+ * @throws NullPointerException if this map does not permit <tt>null</tt>
+ * keys or values, and the specified key or value is
+ * <tt>null</tt>.
+ *
+ */
+ V putIfAbsent(K key, V value);
+
+ /**
+ * Remove entry for key only if currently mapped to given value.
+ * Acts as
+ * <pre>
+ * if ((map.containsKey(key) && map.get(key).equals(value)) {
+ * map.remove(key);
+ * return true;
+ * } else return false;
+ * </pre>
+ * except that the action is performed atomically.
+ * @param key key with which the specified value is associated.
+ * @param value value associated with the specified key.
+ * @return true if the value was removed, false otherwise
+ * @throws NullPointerException if this map does not permit <tt>null</tt>
+ * keys or values, and the specified key or value is
+ * <tt>null</tt>.
+ */
+ boolean remove(Object key, Object value);
+
+
+ /**
+ * Replace entry for key only if currently mapped to given value.
+ * Acts as
+ * <pre>
+ * if ((map.containsKey(key) && map.get(key).equals(oldValue)) {
+ * map.put(key, newValue);
+ * return true;
+ * } else return false;
+ * </pre>
+ * except that the action is performed atomically.
+ * @param key key with which the specified value is associated.
+ * @param oldValue value expected to be associated with the specified key.
+ * @param newValue value to be associated with the specified key.
+ * @return true if the value was replaced
+ * @throws NullPointerException if this map does not permit <tt>null</tt>
+ * keys or values, and the specified key or value is
+ * <tt>null</tt>.
+ */
+ boolean replace(K key, V oldValue, V newValue);
+
+ /**
+ * Replace entry for key only if currently mapped to some value.
+ * Acts as
+ * <pre>
+ * if ((map.containsKey(key)) {
+ * return map.put(key, value);
+ * } else return null;
+ * </pre>
+ * except that the action is performed atomically.
+ * @param key key with which the specified value is associated.
+ * @param value value to be associated with the specified key.
+ * @return previous value associated with specified key, or <tt>null</tt>
+ * if there was no mapping for key. A <tt>null</tt> return can
+ * also indicate that the map previously associated <tt>null</tt>
+ * with the specified key, if the implementation supports
+ * <tt>null</tt> values.
+ * @throws NullPointerException if this map does not permit <tt>null</tt>
+ * keys or values, and the specified key or value is
+ * <tt>null</tt>.
+ */
+ V replace(K key, V value);
+
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/CopyOnWriteArrayList.java b/concurrent/src/main/java/java/util/concurrent/CopyOnWriteArrayList.java
new file mode 100644
index 0000000..26165de
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/CopyOnWriteArrayList.java
@@ -0,0 +1,1189 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to you 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
+ * 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.
+ */
+
+package java.util.concurrent;
+
+import java.io.IOException;
+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.NoSuchElementException;
+import java.util.RandomAccess;
+import java.util.concurrent.locks.ReentrantLock;
+
+// BEGIN android-added
+/**
+ * Implements a {@link java.util.ArrayList} variant that is thread-safe. All
+ * write operation result in a new copy of the underlying data being created.
+ * Iterators reflect the state of the CopyOnWriteArrayList at the time they were
+ * created. They are not updated to reflect subsequent changes to the list. In
+ * addition, these iterators cannot be used for modifying the underlying
+ * CopyOnWriteArrayList.
+ *
+ * @param <E> the element type
+ */
+// END android-added
+public class CopyOnWriteArrayList<E> implements List<E>, RandomAccess, Cloneable, Serializable {
+
+ private static final long serialVersionUID = 8673264195747942595L;
+
+ private transient volatile E[] arr;
+
+ /**
+ * Lock for the queue write methods
+ */
+ private final transient ReentrantLock lock = new ReentrantLock();
+
+ // BEGIN android-added
+ /**
+ * Creates a new, empty instance of CopyOnWriteArrayList.
+ */
+ // END android-added
+ public CopyOnWriteArrayList() {
+ }
+
+ // BEGIN android-added
+ /**
+ * Creates a new instance of CopyOnWriteArrayList and fills it with the
+ * contents of a given Collection.
+ *
+ * @param c the collection the elements of which are to be copied into
+ * the new instance.
+ */
+ // END android-added
+ public CopyOnWriteArrayList(Collection<? extends E> c) {
+ this((E[]) c.toArray());
+ }
+
+ // BEGIN android-added
+ /**
+ * Creates a new instance of CopyOnWriteArrayList and fills it with the
+ * contents of a given array.
+ *
+ * @param array the array the elements of which are to be copied into the
+ * new instance.
+ */
+ // END android-added
+ public CopyOnWriteArrayList(E[] array) {
+ int size = array.length;
+ E[] data = newElementArray(size);
+ for (int i = 0; i < size; i++) {
+ data[i] = array[i];
+ }
+ arr = data;
+ }
+
+ public boolean add(E e) {
+ lock.lock();
+ try {
+ E[] data;
+ E[] old = getData();
+ int size = old.length;
+ data = newElementArray(size + 1);
+ System.arraycopy(old, 0, data, 0, size);
+ data[size] = e;
+ setData(data);
+ return true;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public void add(int index, E e) {
+ lock.lock();
+ try {
+ E[] data;
+ E[] old = getData();
+ int size = old.length;
+ checkIndexInclusive(index, size);
+ data = newElementArray(size+1);
+ System.arraycopy(old, 0, data, 0, index);
+ data[index] = e;
+ if (size > index) {
+ System.arraycopy(old, index, data, index + 1, size - index);
+ }
+ setData(data);
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public boolean addAll(Collection<? extends E> c) {
+ Iterator it = c.iterator();
+ int ssize = c.size();
+ lock.lock();
+ try {
+ int size = size();
+ E[] data;
+ E[] old = getData();
+ int nSize = size + ssize;
+ data = newElementArray(nSize);
+ System.arraycopy(old, 0, data, 0, size);
+ while (it.hasNext()) {
+ data[size++] = (E) it.next();
+ }
+ setData(data);
+ } finally {
+ lock.unlock();
+ }
+ return true;
+ }
+
+ public boolean addAll(int index, Collection<? extends E> c) {
+ Iterator it = c.iterator();
+ int ssize = c.size();
+ lock.lock();
+ try {
+ int size = size();
+ checkIndexInclusive(index, size);
+ E[] data;
+ E[] old = getData();
+ int nSize = size + ssize;
+ data = newElementArray(nSize);
+ System.arraycopy(old, 0, data, 0, index);
+ int i = index;
+ while (it.hasNext()) {
+ data[i++] = (E) it.next();
+ }
+ if (size > index) {
+ System.arraycopy(old, index, data, index + ssize, size - index);
+ }
+ setData(data);
+ } finally {
+ lock.unlock();
+ }
+ return true;
+ }
+
+ // BEGIN android-added
+ /**
+ * Adds to this CopyOnWriteArrayList all those elements from a given
+ * collection that are not yet part of the list.
+ *
+ * @param c the collection from which the potential new elements are
+ * taken.
+ *
+ * @return the number of elements actually added to this list.
+ */
+ // END android-added
+ public int addAllAbsent(Collection<? extends E> c) {
+ if (c.size() == 0) {
+ return 0;
+ }
+ lock.lock();
+ try {
+ E[] old = getData();
+ int size = old.length;
+ E[] toAdd = newElementArray(c.size());
+ int i = 0;
+ for (Iterator it = c.iterator(); it.hasNext();) {
+ E o = (E) it.next();
+ if (indexOf(o) < 0) {
+ toAdd[i++] = o;
+ }
+ }
+ E[] data = newElementArray(size + i);
+ System.arraycopy(old, 0, data, 0, size);
+ System.arraycopy(toAdd, 0, data, size, i);
+ setData(data);
+ return i;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ // BEGIN android-added
+ /**
+ * Adds to this CopyOnWriteArrayList another element, given that this
+ * element is not yet part of the list.
+ *
+ * @param e the potential new element.
+ *
+ * @return true if the element was added, or false otherwise.
+ */
+ // END android-added
+ public boolean addIfAbsent(E e) {
+ lock.lock();
+ try {
+ E[] data;
+ E[] old = getData();
+ int size = old.length;
+ if (size != 0) {
+ if (indexOf(e) >= 0) {
+ return false;
+ }
+ }
+ data = newElementArray(size + 1);
+ System.arraycopy(old, 0, data, 0, size);
+ data[size] = e;
+ setData(data);
+ return true;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public void clear() {
+ lock.lock();
+ try {
+ setData(newElementArray(0));
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ @Override
+ public Object clone() {
+ try {
+ CopyOnWriteArrayList thisClone = (CopyOnWriteArrayList) super.clone();
+ thisClone.setData(this.getData());
+ return thisClone;
+ } catch (CloneNotSupportedException e) {
+ throw new RuntimeException("CloneNotSupportedException is not expected here");
+ }
+ }
+
+ public boolean contains(Object o) {
+ return indexOf(o) >= 0;
+ }
+
+ public boolean containsAll(Collection<?> c) {
+ E[] data = getData();
+ return containsAll(c, data, 0, data.length);
+ }
+
+ public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (!(o instanceof List)) {
+ return false;
+ }
+ List l = (List) o;
+ Iterator it = l.listIterator();
+ Iterator ourIt = listIterator();
+ while (it.hasNext()) {
+ if (!ourIt.hasNext()) {
+ return false;
+ }
+ Object thisListElem = it.next();
+ Object anotherListElem = ourIt.next();
+ if (!(thisListElem == null ? anotherListElem == null : thisListElem
+ .equals(anotherListElem))) {
+ return false;
+ }
+ }
+ if (ourIt.hasNext()) {
+ return false;
+ }
+ return true;
+ }
+
+ public E get(int index) {
+ E[] data = getData();
+ return data[index];
+ }
+
+ public int hashCode() {
+ int hashCode = 1;
+ Iterator it = listIterator();
+ while (it.hasNext()) {
+ Object obj = it.next();
+ hashCode = 31 * hashCode + (obj == null ? 0 : obj.hashCode());
+ }
+ return hashCode;
+ }
+
+ // BEGIN android-added
+ /**
+ * Returns the index of a given element, starting the search from a given
+ * position in the list.
+ *
+ * @param e the element to search.
+ * @param index the index at which to start the search.
+ *
+ * @return the index of the element or null, if the element has not been
+ * found at or beyond the given start index.
+ */
+ // END android-added
+ public int indexOf(E e, int index) {
+ E[] data = getData();
+ return indexOf(e, data, index, data.length - index);
+ }
+
+ public int indexOf(Object o) {
+ E[] data = getData();
+ return indexOf(o, data, 0, data.length);
+ }
+
+ public boolean isEmpty() {
+ return size() == 0;
+ }
+
+ public Iterator<E> iterator() {
+ return new ListIteratorImpl(getData(), 0);
+ }
+
+ // BEGIN android-added
+ /**
+ * Returns the last index of a given element, starting the search from
+ * a given position in the list and going backwards.
+ *
+ * @param e the element to search.
+ * @param index the index at which to start the search.
+ *
+ * @return the index of the element or null, if the element has not been
+ * found at or before the given start index.
+ */
+ // END android-added
+ public int lastIndexOf(E e, int index) {
+ E[] data = getData();
+ return lastIndexOf(e, data, 0, index);
+ }
+
+ public int lastIndexOf(Object o) {
+ E[] data = getData();
+ return lastIndexOf(o, data, 0, data.length);
+ }
+
+ public ListIterator<E> listIterator() {
+ return new ListIteratorImpl(getData(), 0);
+ }
+
+ public ListIterator<E> listIterator(int index) {
+ E[] data = getData();
+ checkIndexInclusive(index, data.length);
+ return new ListIteratorImpl(data, index);
+ }
+
+ public E remove(int index) {
+ return removeRange(index, 1);
+ }
+
+ public boolean remove(Object o) {
+ lock.lock();
+ try {
+ int index = indexOf(o);
+ if (index == -1) {
+ return false;
+ }
+ remove(index);
+ return true;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public boolean removeAll(Collection<?> c) {
+ lock.lock();
+ try {
+ return removeAll(c, 0, getData().length) != 0;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public boolean retainAll(Collection<?> c) {
+ if (c == null) {
+ throw new NullPointerException();
+ }
+ lock.lock();
+ try {
+ return retainAll(c, 0, getData().length) != 0;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public E set(int index, E e) {
+ lock.lock();
+ try {
+ int size = size();
+ checkIndexExlusive(index, size);
+ E[] data;
+ data = newElementArray(size);
+ E[] oldArr = getData();
+ System.arraycopy(oldArr, 0, data, 0, size);
+ E old = data[index];
+ data[index] = e;
+ setData(data);
+ return old;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public int size() {
+ return getData().length;
+ }
+
+ public List<E> subList(int fromIndex, int toIndex) {
+ return new SubList(this, fromIndex, toIndex);
+ }
+
+ public Object[] toArray() {
+ E[] data = getData();
+ return toArray(data, 0, data.length);
+ }
+
+ public <T> T[] toArray(T[] a) {
+ E[] data = getData();
+ return (T[]) toArray(a, data, 0, data.length);
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer("[");
+
+ Iterator it = listIterator();
+ while (it.hasNext()) {
+ sb.append(String.valueOf(it.next()));
+ sb.append(", ");
+ }
+ if (sb.length() > 1) {
+ sb.setLength(sb.length() - 2);
+ }
+ sb.append("]");
+ return sb.toString();
+ }
+
+ // private and package private methods
+
+ @SuppressWarnings("unchecked")
+ private final E[] newElementArray(int size) {
+ return (E[])new Object[size];
+ }
+
+ /**
+ * sets the internal data array
+ *
+ * @param data array to set
+ */
+ private final void setData(E[] data) {
+ arr = data;
+ }
+
+ /**
+ * gets the internal data array
+ *
+ * @return the data array
+ */
+ final E[] getData() {
+ if (arr == null) {
+ return newElementArray(0);
+ }
+ return arr;
+ }
+
+ /**
+ * Removes from the specified range of this list
+ * all the elements that are contained in the specified collection
+ * <p/>
+ * !should be called under lock
+ *
+ * @return Returns the number of removed elements
+ */
+ final int removeAll(Collection c, int start, int size) {
+ int ssize = c.size();
+ if (ssize == 0) {
+ return 0;
+ }
+ Object[] old = getData();
+ int arrsize = old.length;
+ if (arrsize == 0) {
+ return 0;
+ }
+ Object[] data = new Object[size];
+ int j = 0;
+ for (int i = start; i < (start + size); i++) {
+ if (!c.contains(old[i])) {
+ data[j++] = old[i];
+ }
+ }
+ if (j != size) {
+ E[] result = newElementArray(arrsize - (size - j));
+ System.arraycopy(old, 0, result, 0, start);
+ System.arraycopy(data, 0, result, start, j);
+ System.arraycopy(old, start + size, result, start + j, arrsize
+ - (start + size));
+ setData(result);
+ return (size - j);
+ }
+ return 0;
+ }
+
+ /**
+ * Retains only the elements in the specified range of this list
+ * that are contained in the specified collection
+ *
+ * @return Returns the number of removed elements
+ */
+ // should be called under lock
+ int retainAll(Collection c, int start, int size) {
+ Object[] old = getData();
+ if (size == 0) {
+ return 0;
+ }
+ if (c.size() == 0) {
+ E[] data;
+ if (size == old.length) {
+ data = newElementArray(0);
+ } else {
+ data = newElementArray(old.length - size);
+ System.arraycopy(old, 0, data, 0, start);
+ System.arraycopy(old, start + size, data, start, old.length
+ - start - size);
+ }
+ setData(data);
+ return size;
+ }
+ Object[] temp = new Object[size];
+ int pos = 0;
+ for (int i = start; i < (start + size); i++) {
+ if (c.contains(old[i])) {
+ temp[pos++] = old[i];
+ }
+ }
+ if (pos == size) {
+ return 0;
+ }
+ E[] data = newElementArray(pos + old.length - size);
+ System.arraycopy(old, 0, data, 0, start);
+ System.arraycopy(temp, 0, data, start, pos);
+ System.arraycopy(old, start + size, data, start + pos, old.length
+ - start - size);
+ setData(data);
+ return (size - pos);
+ }
+
+ /**
+ * Removes specified range from this list
+ */
+ E removeRange(int start, int size) {
+ lock.lock();
+ try {
+ int sizeArr = size();
+ checkIndexExlusive(start, sizeArr);
+ checkIndexInclusive(start + size, sizeArr);
+ E[] data;
+ data = newElementArray(sizeArr - size);
+ E[] oldArr = getData();
+ System.arraycopy(oldArr, 0, data, 0, start);
+ E old = oldArr[start];
+ if (sizeArr > (start + size)) {
+ System.arraycopy(oldArr, start + size, data, start, sizeArr
+ - (start + size));
+ }
+ setData(data);
+ return old;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ // some util static functions to use by iterators and methods
+ /**
+ * Returns an array containing all of the elements
+ * in the specified range of the array in proper sequence
+ */
+ static Object[] toArray(Object[] data, int start, int size) {
+ Object[] result = new Object[size];
+ System.arraycopy(data, start, result, 0, size);
+ return result;
+ }
+
+ /**
+ * Returns an array containing all of the elements
+ * in the specified range of the array in proper sequence,
+ * stores the result in the array, specified by first parameter
+ * (as for public instance method toArray(Object[] to)
+ */
+ static Object[] toArray(Object[] to, Object[] data, int start, int size) {
+ int l = data.length;
+ if (to.length < l) {
+ to = (Object[]) Array.newInstance(to.getClass().getComponentType(),
+ l);
+ } else {
+ if (to.length > l) {
+ to[l] = null;
+ }
+ }
+ System.arraycopy(data, start, to, 0, size);
+ return to;
+ }
+
+ /**
+ * Checks if the specified range of the
+ * array contains all of the elements in the collection
+ *
+ * @param c collection with elements
+ * @param data array where to search the elements
+ * @param start start index
+ * @param size size of the range
+ */
+ static final boolean containsAll(Collection c, Object[] data, int start,
+ int size) {
+ if (size == 0) {
+ return false;
+ }
+ Iterator it = c.iterator();
+ while (it.hasNext()) {
+ Object next = it.next();
+ if (indexOf(next, data, start, size) < 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Returns the index in the specified range of the data array
+ * of the last occurrence of the specified element
+ *
+ * @param o element to search
+ * @param data array where to search
+ * @param start start index
+ * @param size size of the range
+ * @return
+ */
+ static final int lastIndexOf(Object o, Object[] data, int start, int size) {
+ if (size == 0) {
+ return -1;
+ }
+ if (o != null) {
+ for (int i = start + size - 1; i > start - 1; i--) {
+ if (o.equals(data[i])) {
+ return i;
+ }
+ }
+ } else {
+ for (int i = start + size - 1; i > start - 1; i--) {
+ if (data[i] == null) {
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Returns the index in the specified range of the data array
+ * of the first occurrence of the specified element
+ *
+ * @param o element to search
+ * @param data array where to search
+ * @param start start index
+ * @param size end index
+ * @return
+ */
+ static final int indexOf(Object o, Object[] data, int start, int size) {
+ if (size == 0) {
+ return -1;
+ }
+ if (o == null) {
+ for (int i = start; i < start + size; i++) {
+ if (data[i] == null) {
+ return i;
+ }
+ }
+ } else {
+ for (int i = start; i < start + size; i++) {
+ if (o.equals(data[i])) {
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Throws <code>IndexOutOfBoundsException</code> if <code>index</code>
+ * is out of the list bounds.
+ *
+ * @param index element index to check.
+ */
+ static final void checkIndexInclusive(int index, int size) {
+ if (index < 0 || index > size) {
+ throw new IndexOutOfBoundsException("Index is " + index + ", size is " + size);
+ }
+ }
+
+ /**
+ * Throws <code>IndexOutOfBoundsException</code> if <code>index</code>
+ * is out of the list bounds. Excluding the last element.
+ *
+ * @param index element index to check.
+ */
+ static final void checkIndexExlusive(int index, int size) {
+ if (index < 0 || index >= size) {
+ throw new IndexOutOfBoundsException("Index is " + index + ", size is " + size);
+ }
+ }
+
+ /**
+ * list iterator implementation,
+ * when created gets snapshot of the list,
+ * so never throws ConcurrentModificationException
+ */
+ private static class ListIteratorImpl implements ListIterator {
+ private final Object[] arr;
+
+ private int current;
+
+ private final int size;
+
+ final int size() {
+ return size;
+ }
+
+ public ListIteratorImpl(Object[] data, int current) {
+ this.current = current;
+ arr = data;
+ size = data.length;
+ }
+
+ public void add(Object o) {
+ throw new UnsupportedOperationException("Unsupported operation add");
+ }
+
+ public boolean hasNext() {
+ if (current < size) {
+ return true;
+ }
+ return false;
+ }
+
+ public boolean hasPrevious() {
+ return current > 0;
+ }
+
+ public Object next() {
+ if (hasNext()) {
+ return arr[current++];
+ }
+ throw new NoSuchElementException("pos is " + current + ", size is " + size);
+ }
+
+ public int nextIndex() {
+ return current;
+ }
+
+ public Object previous() {
+ if (hasPrevious()) {
+ return arr[--current];
+ }
+ throw new NoSuchElementException("pos is " + (current-1) + ", size is " + size);
+ }
+
+ public int previousIndex() {
+ return current - 1;
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException("Unsupported operation remove");
+ }
+
+ public void set(Object o) {
+ throw new UnsupportedOperationException("Unsupported operation set");
+ }
+
+ }
+
+ /**
+ * Keeps a state of sublist implementation,
+ * size and array declared as final,
+ * so we'll never get the unconsistent state
+ */
+ static final class SubListReadData {
+ final int size;
+
+ final Object[] data;
+
+ SubListReadData(int size, Object[] data) {
+ this.size = size;
+ this.data = data;
+ }
+ }
+
+ /**
+ * Represents a list returned by <code>sublist()</code>.
+ */
+ static class SubList implements List {
+ private final CopyOnWriteArrayList list;
+
+ private volatile SubListReadData read;
+
+ private final int start;
+
+ /**
+ * Sublist constructor.
+ *
+ * @param list backing list.
+ * @param fromIdx startingIndex, inclusive
+ * @param toIdx endIndex, exclusive
+ */
+ public SubList(CopyOnWriteArrayList list, int fromIdx, int toIdx) {
+ this.list = list;
+ Object[] data = list.getData();
+ int size = toIdx - fromIdx;
+ checkIndexExlusive(fromIdx, data.length);
+ checkIndexInclusive(toIdx, data.length);
+ read = new SubListReadData(size, list.getData());
+ start = fromIdx;
+ }
+
+ /**
+ * throws ConcurrentModificationException when the list
+ * is structurally modified in the other way other than via this subList
+ * <p/>
+ * Should be called under lock!
+ */
+ private void checkModifications() {
+ if (read.data != list.getData()) {
+ throw new ConcurrentModificationException();
+ }
+ }
+
+ /**
+ * @see java.util.List#listIterator(int)
+ */
+ public ListIterator listIterator(int startIdx) {
+ return new SubListIterator(startIdx, read);
+ }
+
+ /**
+ * @see java.util.List#set(int, java.lang.Object)
+ */
+ public Object set(int index, Object obj) {
+ list.lock.lock();
+ try {
+ checkIndexExlusive(index, read.size);
+ checkModifications();
+ Object result = list.set(index + start, obj);
+ read = new SubListReadData(read.size, list.getData());
+ return result;
+ } finally {
+ list.lock.unlock();
+ }
+ }
+
+ /**
+ * @see java.util.List#get(int)
+ */
+ public Object get(int index) {
+ SubListReadData data = read;
+ if (data.data != list.getData()) {
+ list.lock.lock();
+ try {
+ data = read;
+ if (data.data != list.getData()) {
+ throw new ConcurrentModificationException();
+ }
+ } finally {
+ list.lock.unlock();
+ }
+ }
+ checkIndexExlusive(index, data.size);
+ return data.data[index + start];
+ }
+
+ /**
+ * @see java.util.Collection#size()
+ */
+ public int size() {
+ return read.size;
+ }
+
+ /**
+ * @see java.util.List#remove(int)
+ */
+ public Object remove(int index) {
+ list.lock.lock();
+ try {
+ checkIndexExlusive(index, read.size);
+ checkModifications();
+ Object obj = list.remove(index + start);
+ read = new SubListReadData(read.size - 1, list.getData());
+ return obj;
+ } finally {
+ list.lock.unlock();
+ }
+ }
+
+ /**
+ * @see java.util.List#add(int, java.lang.Object)
+ */
+ public void add(int index, Object object) {
+ list.lock.lock();
+ try {
+ checkIndexInclusive(index, read.size);
+ checkModifications();
+ list.add(index + start, object);
+ read = new SubListReadData(read.size + 1, list.getData());
+ } finally {
+ list.lock.unlock();
+ }
+ }
+
+ public boolean add(Object o) {
+ list.lock.lock();
+ try {
+ checkModifications();
+ list.add(start + read.size, o);
+ read = new SubListReadData(read.size + 1, list.getData());
+ return true;
+ } finally {
+ list.lock.unlock();
+ }
+ }
+
+ public boolean addAll(Collection c) {
+ list.lock.lock();
+ try {
+ checkModifications();
+ int d = list.size();
+ list.addAll(start + read.size, c);
+ read = new SubListReadData(read.size + (list.size() - d), list
+ .getData());
+ return true;
+ } finally {
+ list.lock.unlock();
+ }
+ }
+
+ public void clear() {
+ list.lock.lock();
+ try {
+ checkModifications();
+ list.removeRange(start, read.size);
+ read = new SubListReadData(0, list.getData());
+ } finally {
+ list.lock.unlock();
+ }
+ }
+
+ public boolean contains(Object o) {
+ return indexOf(o) != -1;
+ }
+
+ public boolean containsAll(Collection c) {
+ SubListReadData b = read;
+ return CopyOnWriteArrayList.containsAll(c, b.data, start, b.size);
+ }
+
+ public int indexOf(Object o) {
+ SubListReadData b = read;
+ int ind = CopyOnWriteArrayList.indexOf(o, b.data, start, b.size)
+ - start;
+ return ind < 0 ? -1 : ind;
+ }
+
+ public boolean isEmpty() {
+ return read.size == 0;
+ }
+
+ public Iterator iterator() {
+ return new SubListIterator(0, read);
+ }
+
+ public int lastIndexOf(Object o) {
+ SubListReadData b = read;
+ int ind = CopyOnWriteArrayList
+ .lastIndexOf(o, b.data, start, b.size)
+ - start;
+ return ind < 0 ? -1 : ind;
+ }
+
+ public ListIterator listIterator() {
+ return new SubListIterator(0, read);
+ }
+
+ public boolean remove(Object o) {
+ list.lock.lock();
+ try {
+ checkModifications();
+ int i = indexOf(o);
+ if (i == -1) {
+ return false;
+ }
+ boolean result = list.remove(i + start) != null;
+ if (result) {
+ read = new SubListReadData(read.size - 1, list.getData());
+ }
+ return result;
+ } finally {
+ list.lock.unlock();
+ }
+ }
+
+ public boolean removeAll(Collection c) {
+ list.lock.lock();
+ try {
+ checkModifications();
+ int removed = list.removeAll(c, start, read.size);
+ if (removed > 0) {
+ read = new SubListReadData(read.size - removed, list
+ .getData());
+ return true;
+ }
+ } finally {
+ list.lock.unlock();
+ }
+ return false;
+ }
+
+ public boolean retainAll(Collection c) {
+ list.lock.lock();
+ try {
+ checkModifications();
+ int removed = list.retainAll(c, start, read.size);
+ if (removed > 0) {
+ read = new SubListReadData(read.size - removed, list
+ .getData());
+ return true;
+ }
+ return false;
+ } finally {
+ list.lock.unlock();
+ }
+ }
+
+ public List subList(int fromIndex, int toIndex) {
+ return new SubList(list, start + fromIndex, start + toIndex);
+ }
+
+ public Object[] toArray() {
+ SubListReadData r = read;
+ return CopyOnWriteArrayList.toArray(r.data, start, r.size);
+ }
+
+ public Object[] toArray(Object[] a) {
+ SubListReadData r = read;
+ return CopyOnWriteArrayList.toArray(a, r.data, start, r.size);
+ }
+
+ /**
+ * @see java.util.List#addAll(int, java.util.Collection)
+ */
+ public boolean addAll(int index, Collection collection) {
+ list.lock.lock();
+ try {
+ checkIndexInclusive(index, read.size);
+ checkModifications();
+ int d = list.size();
+ boolean rt = list.addAll(index + start, collection);
+ read = new SubListReadData(read.size + list.size() - d, list
+ .getData());
+ return rt;
+ } finally {
+ list.lock.unlock();
+ }
+ }
+
+ /**
+ * Implementation of <code>ListIterator</code> for the
+ * <code>SubList</code>
+ * gets a snapshot of the sublist,
+ * never throws ConcurrentModificationException
+ */
+ private class SubListIterator extends ListIteratorImpl {
+ private final SubListReadData dataR;
+
+ /**
+ * Constructs an iterator starting with the given index
+ *
+ * @param index index of the first element to iterate.
+ */
+ private SubListIterator(int index, SubListReadData d) {
+ super(d.data, index + start);
+ this.dataR = d;
+ }
+
+ /**
+ * @see java.util.ListIterator#nextIndex()
+ */
+ public int nextIndex() {
+ return super.nextIndex() - start;
+ }
+
+ /**
+ * @see java.util.ListIterator#previousIndex()
+ */
+ public int previousIndex() {
+ return super.previousIndex() - start;
+ }
+
+ /**
+ * @see java.util.Iterator#hasNext()
+ */
+ public boolean hasNext() {
+ return nextIndex() < dataR.size;
+ }
+
+ /**
+ * @see java.util.ListIterator#hasPrevious()
+ */
+ public boolean hasPrevious() {
+ return previousIndex() > -1;
+ }
+ }
+
+ }
+
+ //serialization support
+ /**
+ * Writes the object state to the ObjectOutputStream.
+ *
+ * @param oos ObjectOutputStream to write object to.
+ * @throws IOException if an I/O error occur.
+ */
+ private void writeObject(ObjectOutputStream oos) throws IOException {
+ E[] back = getData();
+ int size = back.length;
+ oos.defaultWriteObject();
+ oos.writeInt(size);
+ for (int i = 0; i < size; i++) {
+ oos.writeObject(back[i]);
+ }
+ }
+
+ /**
+ * Reads the object state from the ObjectOutputStream.
+ *
+ * @param ois ObjectInputStream to read object from.
+ * @throws IOException if an I/O error occur.
+ */
+ private void readObject(ObjectInputStream ois) throws IOException,
+ ClassNotFoundException {
+ ois.defaultReadObject();
+ int length = ois.readInt();
+ if (length == 0) {
+ setData(newElementArray(0));
+ } else {
+ E[] back = newElementArray(length);
+ for (int i = 0; i < back.length; i++) {
+ back[i] = (E) ois.readObject();
+ }
+ setData(back);
+ }
+ }
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/CopyOnWriteArraySet.java b/concurrent/src/main/java/java/util/concurrent/CopyOnWriteArraySet.java
new file mode 100644
index 0000000..23b228b
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/CopyOnWriteArraySet.java
@@ -0,0 +1,105 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain. Use, modify, and
+ * redistribute this code in any way without acknowledgement.
+ */
+
+package java.util.concurrent;
+import java.util.*;
+
+// BEGIN android-note
+// removed link to collections framework docs
+// Removed clonable interface to be closer to the RI.
+// END android-note
+
+/**
+ * A {@link java.util.Set} that uses {@link
+ * java.util.concurrent.CopyOnWriteArrayList} for all of its
+ * operations. Thus, it shares the same basic properties:
+ * <ul>
+ * <li>It is best suited for applications in which set sizes generally
+ * stay small, read-only operations
+ * vastly outnumber mutative operations, and you need
+ * to prevent interference among threads during traversal.
+ * <li>Mutative operations(add, set, remove, etc) are expensive
+ * since they usually entail copying the entire underlying array.
+ * <li>Iterators do not support the mutative remove operation
+ * <li>Traversal via iterators is very fast and cannot ever encounter
+ * interference from other threads. Iterators rely on
+ * unchanging snapshots of the array at the time the iterators were
+ * constructed.
+ * </ul>
+ * <p>
+ * <b>Sample Usage.</b> Probably the main application
+ * of copy-on-write sets are classes that maintain
+ * sets of Handler objects
+ * that must be multicasted to upon an update command. This
+ * is a classic case where you do not want to be holding a
+ * lock while sending a message, and where traversals normally
+ * vastly overwhelm additions.
+ * <pre>
+ * class Handler { void handle(); ... }
+ *
+ * class X {
+ * private final CopyOnWriteArraySet&lt;Handler&gt; handlers = new CopyOnWriteArraySet&lt;Handler&gt;();
+ * public void addHandler(Handler h) { handlers.add(h); }
+ *
+ * private long internalState;
+ * private synchronized void changeState() { internalState = ...; }
+ *
+ * public void update() {
+ * changeState();
+ * Iterator it = handlers.iterator();
+ * while (it.hasNext())
+ * it.next().handle();
+ * }
+ * }
+ * </pre>
+ * @see CopyOnWriteArrayList
+ *
+ * @since 1.5
+ * @author Doug Lea
+ * @param <E> the type of elements held in this collection
+ */
+public class CopyOnWriteArraySet<E> extends AbstractSet<E>
+ // BEGIN android-changed
+ // removed Cloneable from list of implemented interfaces
+ // implements Cloneable, java.io.Serializable {
+ implements java.io.Serializable {
+ // END android-changed
+ private static final long serialVersionUID = 5457747651344034263L;
+
+ private final CopyOnWriteArrayList<E> al;
+
+ /**
+ * Creates an empty set.
+ */
+ public CopyOnWriteArraySet() {
+ al = new CopyOnWriteArrayList<E>();
+ }
+
+ /**
+ * Creates a set containing all of the elements of the specified
+ * Collection.
+ * @param c the collection
+ */
+ public CopyOnWriteArraySet(Collection<? extends E> c) {
+ al = new CopyOnWriteArrayList<E>();
+ al.addAllAbsent(c);
+ }
+
+ public int size() { return al.size(); }
+ public boolean isEmpty() { return al.isEmpty(); }
+ public boolean contains(Object o) { return al.contains(o); }
+ public Object[] toArray() { return al.toArray(); }
+ public <T> T[] toArray(T[] a) { return al.toArray(a); }
+ public void clear() { al.clear(); }
+ public Iterator<E> iterator() { return al.iterator(); }
+ public boolean remove(Object o) { return al.remove(o); }
+ public boolean add(E o) { return al.addIfAbsent(o); }
+ public boolean containsAll(Collection<?> c) { return al.containsAll(c); }
+ public boolean addAll(Collection<? extends E> c) { return al.addAllAbsent(c) > 0; }
+ public boolean removeAll(Collection<?> c) { return al.removeAll(c); }
+ public boolean retainAll(Collection<?> c) { return al.retainAll(c); }
+
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/CountDownLatch.java b/concurrent/src/main/java/java/util/concurrent/CountDownLatch.java
new file mode 100644
index 0000000..721744c
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/CountDownLatch.java
@@ -0,0 +1,280 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+import java.util.concurrent.locks.*;
+import java.util.concurrent.atomic.*;
+
+/**
+ * A synchronization aid that allows one or more threads to wait until
+ * a set of operations being performed in other threads completes.
+ *
+ * <p>A <tt>CountDownLatch</tt> is initialized with a given
+ * <em>count</em>. The {@link #await await} methods block until the current
+ * {@link #getCount count} reaches zero due to invocations of the
+ * {@link #countDown} method, after which all waiting threads are
+ * released and any subsequent invocations of {@link #await await} return
+ * immediately. This is a one-shot phenomenon -- the count cannot be
+ * reset. If you need a version that resets the count, consider using
+ * a {@link CyclicBarrier}.
+ *
+ * <p>A <tt>CountDownLatch</tt> is a versatile synchronization tool
+ * and can be used for a number of purposes. A
+ * <tt>CountDownLatch</tt> initialized with a count of one serves as a
+ * simple on/off latch, or gate: all threads invoking {@link #await await}
+ * wait at the gate until it is opened by a thread invoking {@link
+ * #countDown}. A <tt>CountDownLatch</tt> initialized to <em>N</em>
+ * can be used to make one thread wait until <em>N</em> threads have
+ * completed some action, or some action has been completed N times.
+ * <p>A useful property of a <tt>CountDownLatch</tt> is that it
+ * doesn't require that threads calling <tt>countDown</tt> wait for
+ * the count to reach zero before proceeding, it simply prevents any
+ * thread from proceeding past an {@link #await await} until all
+ * threads could pass.
+ *
+ * <p><b>Sample usage:</b> Here is a pair of classes in which a group
+ * of worker threads use two countdown latches:
+ * <ul>
+ * <li>The first is a start signal that prevents any worker from proceeding
+ * until the driver is ready for them to proceed;
+ * <li>The second is a completion signal that allows the driver to wait
+ * until all workers have completed.
+ * </ul>
+ *
+ * <pre>
+ * class Driver { // ...
+ * void main() throws InterruptedException {
+ * CountDownLatch startSignal = new CountDownLatch(1);
+ * CountDownLatch doneSignal = new CountDownLatch(N);
+ *
+ * for (int i = 0; i < N; ++i) // create and start threads
+ * new Thread(new Worker(startSignal, doneSignal)).start();
+ *
+ * doSomethingElse(); // don't let run yet
+ * startSignal.countDown(); // let all threads proceed
+ * doSomethingElse();
+ * doneSignal.await(); // wait for all to finish
+ * }
+ * }
+ *
+ * class Worker implements Runnable {
+ * private final CountDownLatch startSignal;
+ * private final CountDownLatch doneSignal;
+ * Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
+ * this.startSignal = startSignal;
+ * this.doneSignal = doneSignal;
+ * }
+ * public void run() {
+ * try {
+ * startSignal.await();
+ * doWork();
+ * doneSignal.countDown();
+ * } catch (InterruptedException ex) {} // return;
+ * }
+ *
+ * void doWork() { ... }
+ * }
+ *
+ * </pre>
+ *
+ * <p>Another typical usage would be to divide a problem into N parts,
+ * describe each part with a Runnable that executes that portion and
+ * counts down on the latch, and queue all the Runnables to an
+ * Executor. When all sub-parts are complete, the coordinating thread
+ * will be able to pass through await. (When threads must repeatedly
+ * count down in this way, instead use a {@link CyclicBarrier}.)
+ *
+ * <pre>
+ * class Driver2 { // ...
+ * void main() throws InterruptedException {
+ * CountDownLatch doneSignal = new CountDownLatch(N);
+ * Executor e = ...
+ *
+ * for (int i = 0; i < N; ++i) // create and start threads
+ * e.execute(new WorkerRunnable(doneSignal, i));
+ *
+ * doneSignal.await(); // wait for all to finish
+ * }
+ * }
+ *
+ * class WorkerRunnable implements Runnable {
+ * private final CountDownLatch doneSignal;
+ * private final int i;
+ * WorkerRunnable(CountDownLatch doneSignal, int i) {
+ * this.doneSignal = doneSignal;
+ * this.i = i;
+ * }
+ * public void run() {
+ * try {
+ * doWork(i);
+ * doneSignal.countDown();
+ * } catch (InterruptedException ex) {} // return;
+ * }
+ *
+ * void doWork() { ... }
+ * }
+ *
+ * </pre>
+ *
+ * @since 1.5
+ * @author Doug Lea
+ */
+public class CountDownLatch {
+ /**
+ * Synchronization control For CountDownLatch.
+ * Uses AQS state to represent count.
+ */
+ private static final class Sync extends AbstractQueuedSynchronizer {
+ Sync(int count) {
+ setState(count);
+ }
+
+ int getCount() {
+ return getState();
+ }
+
+ public int tryAcquireShared(int acquires) {
+ return getState() == 0? 1 : -1;
+ }
+
+ public boolean tryReleaseShared(int releases) {
+ // Decrement count; signal when transition to zero
+ for (;;) {
+ int c = getState();
+ if (c == 0)
+ return false;
+ int nextc = c-1;
+ if (compareAndSetState(c, nextc))
+ return nextc == 0;
+ }
+ }
+ }
+
+ private final Sync sync;
+ /**
+ * Constructs a <tt>CountDownLatch</tt> initialized with the given
+ * count.
+ *
+ * @param count the number of times {@link #countDown} must be invoked
+ * before threads can pass through {@link #await}.
+ *
+ * @throws IllegalArgumentException if <tt>count</tt> is less than zero.
+ */
+ public CountDownLatch(int count) {
+ if (count < 0) throw new IllegalArgumentException("count < 0");
+ this.sync = new Sync(count);
+ }
+
+ /**
+ * Causes the current thread to wait until the latch has counted down to
+ * zero, unless the thread is {@link Thread#interrupt interrupted}.
+ *
+ * <p>If the current {@link #getCount count} is zero then this method
+ * returns immediately.
+ * <p>If the current {@link #getCount count} is greater than zero then
+ * the current thread becomes disabled for thread scheduling
+ * purposes and lies dormant until one of two things happen:
+ * <ul>
+ * <li>The count reaches zero due to invocations of the
+ * {@link #countDown} method; or
+ * <li>Some other thread {@link Thread#interrupt interrupts} the current
+ * thread.
+ * </ul>
+ * <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,
+ * </ul>
+ * then {@link InterruptedException} is thrown and the current thread's
+ * interrupted status is cleared.
+ *
+ * @throws InterruptedException if the current thread is interrupted
+ * while waiting.
+ */
+ public void await() throws InterruptedException {
+ sync.acquireSharedInterruptibly(1);
+ }
+
+ /**
+ * Causes the current thread to wait until the latch has counted down to
+ * zero, unless the thread is {@link Thread#interrupt interrupted},
+ * or the specified waiting time elapses.
+ *
+ * <p>If the current {@link #getCount count} is zero then this method
+ * returns immediately with the value <tt>true</tt>.
+ *
+ * <p>If the current {@link #getCount count} is greater than zero then
+ * the current thread becomes disabled for thread scheduling
+ * purposes and lies dormant until one of three things happen:
+ * <ul>
+ * <li>The count reaches zero due to invocations of the
+ * {@link #countDown} method; or
+ * <li>Some other thread {@link Thread#interrupt interrupts} the current
+ * thread; or
+ * <li>The specified waiting time elapses.
+ * </ul>
+ * <p>If the count reaches zero then the method returns with the
+ * value <tt>true</tt>.
+ * <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,
+ * </ul>
+ * then {@link InterruptedException} is thrown and the current thread's
+ * interrupted status is cleared.
+ *
+ * <p>If the specified waiting time elapses then the value <tt>false</tt>
+ * is returned.
+ * If the time is
+ * less than or equal to zero, the method will not wait at all.
+ *
+ * @param timeout the maximum time to wait
+ * @param unit the time unit of the <tt>timeout</tt> argument.
+ * @return <tt>true</tt> if the count reached zero and <tt>false</tt>
+ * if the waiting time elapsed before the count reached zero.
+ *
+ * @throws InterruptedException if the current thread is interrupted
+ * while waiting.
+ */
+ public boolean await(long timeout, TimeUnit unit)
+ throws InterruptedException {
+ return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
+ }
+
+ /**
+ * Decrements the count of the latch, releasing all waiting threads if
+ * the count reaches zero.
+ * <p>If the current {@link #getCount count} is greater than zero then
+ * it is decremented. If the new count is zero then all waiting threads
+ * are re-enabled for thread scheduling purposes.
+ * <p>If the current {@link #getCount count} equals zero then nothing
+ * happens.
+ */
+ public void countDown() {
+ sync.releaseShared(1);
+ }
+
+ /**
+ * Returns the current count.
+ * <p>This method is typically used for debugging and testing purposes.
+ * @return the current count.
+ */
+ public long getCount() {
+ return sync.getCount();
+ }
+
+ /**
+ * Returns a string identifying this latch, as well as its state.
+ * The state, in brackets, includes the String
+ * &quot;Count =&quot; followed by the current count.
+ * @return a string identifying this latch, as well as its
+ * state
+ */
+ public String toString() {
+ return super.toString() + "[Count = " + sync.getCount() + "]";
+ }
+
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/CyclicBarrier.java b/concurrent/src/main/java/java/util/concurrent/CyclicBarrier.java
new file mode 100644
index 0000000..d70c4c7
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/CyclicBarrier.java
@@ -0,0 +1,430 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+import java.util.concurrent.locks.*;
+
+/**
+ * A synchronization aid that allows a set of threads to all wait for
+ * each other to reach a common barrier point. CyclicBarriers are
+ * useful in programs involving a fixed sized party of threads that
+ * must occasionally wait for each other. The barrier is called
+ * <em>cyclic</em> because it can be re-used after the waiting threads
+ * are released.
+ *
+ * <p>A <tt>CyclicBarrier</tt> supports an optional {@link Runnable} command
+ * that is run once per barrier point, after the last thread in the party
+ * arrives, but before any threads are released.
+ * This <em>barrier action</em> is useful
+ * for updating shared-state before any of the parties continue.
+ *
+ * <p><b>Sample usage:</b> Here is an example of
+ * using a barrier in a parallel decomposition design:
+ * <pre>
+ * class Solver {
+ * final int N;
+ * final float[][] data;
+ * final CyclicBarrier barrier;
+ *
+ * class Worker implements Runnable {
+ * int myRow;
+ * Worker(int row) { myRow = row; }
+ * public void run() {
+ * while (!done()) {
+ * processRow(myRow);
+ *
+ * try {
+ * barrier.await();
+ * } catch (InterruptedException ex) {
+ * return;
+ * } catch (BrokenBarrierException ex) {
+ * return;
+ * }
+ * }
+ * }
+ * }
+ *
+ * public Solver(float[][] matrix) {
+ * data = matrix;
+ * N = matrix.length;
+ * barrier = new CyclicBarrier(N,
+ * new Runnable() {
+ * public void run() {
+ * mergeRows(...);
+ * }
+ * });
+ * for (int i = 0; i < N; ++i)
+ * new Thread(new Worker(i)).start();
+ *
+ * waitUntilDone();
+ * }
+ * }
+ * </pre>
+ * Here, each worker thread processes a row of the matrix then waits at the
+ * barrier until all rows have been processed. When all rows are processed
+ * the supplied {@link Runnable} barrier action is executed and merges the
+ * rows. If the merger
+ * determines that a solution has been found then <tt>done()</tt> will return
+ * <tt>true</tt> and each worker will terminate.
+ *
+ * <p>If the barrier action does not rely on the parties being suspended when
+ * it is executed, then any of the threads in the party could execute that
+ * action when it is released. To facilitate this, each invocation of
+ * {@link #await} returns the arrival index of that thread at the barrier.
+ * You can then choose which thread should execute the barrier action, for
+ * example:
+ * <pre> if (barrier.await() == 0) {
+ * // log the completion of this iteration
+ * }</pre>
+ *
+ * <p>The <tt>CyclicBarrier</tt> uses a fast-fail all-or-none breakage
+ * model for failed synchronization attempts: If a thread leaves a
+ * barrier point prematurely because of interruption, failure, or
+ * timeout, all other threads, even those that have not yet resumed
+ * from a previous {@link #await}. will also leave abnormally via
+ * {@link BrokenBarrierException} (or <tt>InterruptedException</tt> if
+ * they too were interrupted at about the same time).
+ *
+ * @since 1.5
+ * @see CountDownLatch
+ *
+ * @author Doug Lea
+ */
+public class CyclicBarrier {
+ /** The lock for guarding barrier entry */
+ private final ReentrantLock lock = new ReentrantLock();
+ /** Condition to wait on until tripped */
+ private final Condition trip = lock.newCondition();
+ /** The number of parties */
+ private final int parties;
+ /* The command to run when tripped */
+ private final Runnable barrierCommand;
+
+ /**
+ * The generation number. Incremented upon barrier trip.
+ * Retracted upon reset.
+ */
+ private long generation;
+
+ /**
+ * Breakage indicator.
+ */
+ private boolean broken;
+
+ /**
+ * Number of parties still waiting. Counts down from parties to 0
+ * on each cycle.
+ */
+ private int count;
+
+ /**
+ * Updates state on barrier trip and wake up everyone.
+ */
+ private void nextGeneration() {
+ count = parties;
+ ++generation;
+ trip.signalAll();
+ }
+
+ /**
+ * Sets barrier as broken and wake up everyone
+ */
+ private void breakBarrier() {
+ broken = true;
+ trip.signalAll();
+ }
+
+ /**
+ * Main barrier code, covering the various policies.
+ */
+ private int dowait(boolean timed, long nanos)
+ throws InterruptedException, BrokenBarrierException, TimeoutException {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ int index = --count;
+ long g = generation;
+
+ if (broken)
+ throw new BrokenBarrierException();
+
+ if (Thread.interrupted()) {
+ breakBarrier();
+ throw new InterruptedException();
+ }
+
+ if (index == 0) { // tripped
+ nextGeneration();
+ boolean ranAction = false;
+ try {
+ Runnable command = barrierCommand;
+ if (command != null)
+ command.run();
+ ranAction = true;
+ return 0;
+ } finally {
+ if (!ranAction)
+ breakBarrier();
+ }
+ }
+
+ for (;;) {
+ try {
+ if (!timed)
+ trip.await();
+ else if (nanos > 0L)
+ nanos = trip.awaitNanos(nanos);
+ } catch (InterruptedException ie) {
+ breakBarrier();
+ throw ie;
+ }
+
+ if (broken ||
+ g > generation) // true if a reset occurred while waiting
+ throw new BrokenBarrierException();
+
+ if (g < generation)
+ return index;
+
+ if (timed && nanos <= 0L) {
+ breakBarrier();
+ throw new TimeoutException();
+ }
+ }
+
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Creates a new <tt>CyclicBarrier</tt> that will trip when the
+ * given number of parties (threads) are waiting upon it, and which
+ * will execute the given barrier action when the barrier is tripped,
+ * performed by the last thread entering the barrier.
+ *
+ * @param parties the number of threads that must invoke {@link #await}
+ * before the barrier is tripped.
+ * @param barrierAction the command to execute when the barrier is
+ * tripped, or <tt>null</tt> if there is no action.
+ *
+ * @throws IllegalArgumentException if <tt>parties</tt> is less than 1.
+ */
+ public CyclicBarrier(int parties, Runnable barrierAction) {
+ if (parties <= 0) throw new IllegalArgumentException();
+ this.parties = parties;
+ this.count = parties;
+ this.barrierCommand = barrierAction;
+ }
+
+ /**
+ * Creates a new <tt>CyclicBarrier</tt> that will trip when the
+ * given number of parties (threads) are waiting upon it, and
+ * does not perform a predefined action upon each barrier.
+ *
+ * @param parties the number of threads that must invoke {@link #await}
+ * before the barrier is tripped.
+ *
+ * @throws IllegalArgumentException if <tt>parties</tt> is less than 1.
+ */
+ public CyclicBarrier(int parties) {
+ this(parties, null);
+ }
+
+ /**
+ * Returns the number of parties required to trip this barrier.
+ * @return the number of parties required to trip this barrier.
+ **/
+ public int getParties() {
+ return parties;
+ }
+
+ /**
+ * Waits until all {@link #getParties parties} have invoked <tt>await</tt>
+ * on this barrier.
+ *
+ * <p>If the current thread is not the last to arrive then it is
+ * disabled for thread scheduling purposes and lies dormant until
+ * one of following things happens:
+ * <ul>
+ * <li>The last thread arrives; or
+ * <li>Some other thread {@link Thread#interrupt interrupts} the current
+ * thread; or
+ * <li>Some other thread {@link Thread#interrupt interrupts} one of the
+ * other waiting threads; or
+ * <li>Some other thread times out while waiting for barrier; or
+ * <li>Some other thread invokes {@link #reset} on this barrier.
+ * </ul>
+ * <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
+ * </ul>
+ * then {@link InterruptedException} is thrown and the current thread's
+ * interrupted status is cleared.
+ *
+ * <p>If the barrier is {@link #reset} while any thread is waiting, or if
+ * the barrier {@link #isBroken is broken} when <tt>await</tt> is invoked,
+ * or while any thread is waiting,
+ * then {@link BrokenBarrierException} is thrown.
+ *
+ * <p>If any thread is {@link Thread#interrupt interrupted} while waiting,
+ * then all other waiting threads will throw
+ * {@link BrokenBarrierException} and the barrier is placed in the broken
+ * state.
+ *
+ * <p>If the current thread is the last thread to arrive, and a
+ * non-null barrier action was supplied in the constructor, then the
+ * current thread runs the action before allowing the other threads to
+ * continue.
+ * If an exception occurs during the barrier action then that exception
+ * will be propagated in the current thread and the barrier is placed in
+ * the broken state.
+ *
+ * @return the arrival index of the current thread, where index
+ * <tt>{@link #getParties()} - 1</tt> indicates the first to arrive and
+ * zero indicates the last to arrive.
+ *
+ * @throws InterruptedException if the current thread was interrupted
+ * while waiting
+ * @throws BrokenBarrierException if <em>another</em> thread was
+ * interrupted while the current thread was waiting, or the barrier was
+ * reset, or the barrier was broken when <tt>await</tt> was called,
+ * or the barrier action (if present) failed due an exception.
+ */
+ public int await() throws InterruptedException, BrokenBarrierException {
+ try {
+ return dowait(false, 0L);
+ } catch (TimeoutException toe) {
+ throw new Error(toe); // cannot happen;
+ }
+ }
+
+ /**
+ * Waits until all {@link #getParties parties} have invoked <tt>await</tt>
+ * on this barrier.
+ *
+ * <p>If the current thread is not the last to arrive then it is
+ * disabled for thread scheduling purposes and lies dormant until
+ * one of the following things happens:
+ * <ul>
+ * <li>The last thread arrives; or
+ * <li>The specified timeout elapses; or
+ * <li>Some other thread {@link Thread#interrupt interrupts} the current
+ * thread; or
+ * <li>Some other thread {@link Thread#interrupt interrupts} one of the
+ * other waiting threads; or
+ * <li>Some other thread times out while waiting for barrier; or
+ * <li>Some other thread invokes {@link #reset} on this barrier.
+ * </ul>
+ * <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
+ * </ul>
+ * then {@link InterruptedException} is thrown and the current thread's
+ * interrupted status is cleared.
+ *
+ * <p>If the barrier is {@link #reset} while any thread is waiting, or if
+ * the barrier {@link #isBroken is broken} when <tt>await</tt> is invoked,
+ * or while any thread is waiting,
+ * then {@link BrokenBarrierException} is thrown.
+ *
+ * <p>If any thread is {@link Thread#interrupt interrupted} while waiting,
+ * then all other waiting threads will throw
+ * {@link BrokenBarrierException} and the barrier is placed in the broken
+ * state.
+ *
+ * <p>If the current thread is the last thread to arrive, and a
+ * non-null barrier action was supplied in the constructor, then the
+ * current thread runs the action before allowing the other threads to
+ * continue.
+ * If an exception occurs during the barrier action then that exception
+ * will be propagated in the current thread and the barrier is placed in
+ * the broken state.
+ *
+ * @param timeout the time to wait for the barrier
+ * @param unit the time unit of the timeout parameter
+ * @return the arrival index of the current thread, where index
+ * <tt>{@link #getParties()} - 1</tt> indicates the first to arrive and
+ * zero indicates the last to arrive.
+ *
+ * @throws InterruptedException if the current thread was interrupted
+ * while waiting
+ * @throws TimeoutException if the specified timeout elapses.
+ * @throws BrokenBarrierException if <em>another</em> thread was
+ * interrupted while the current thread was waiting, or the barrier was
+ * reset, or the barrier was broken when <tt>await</tt> was called,
+ * or the barrier action (if present) failed due an exception.
+ */
+ public int await(long timeout, TimeUnit unit)
+ throws InterruptedException,
+ BrokenBarrierException,
+ TimeoutException {
+ return dowait(true, unit.toNanos(timeout));
+ }
+
+ /**
+ * Queries if this barrier is in a broken state.
+ * @return <tt>true</tt> if one or more parties broke out of this
+ * barrier due to interruption or timeout since construction or
+ * the last reset, or a barrier action failed due to an exception;
+ * and <tt>false</tt> otherwise.
+ */
+ public boolean isBroken() {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ return broken;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Resets the barrier to its initial state. If any parties are
+ * currently waiting at the barrier, they will return with a
+ * {@link BrokenBarrierException}. Note that resets <em>after</em>
+ * a breakage has occurred for other reasons can be complicated to
+ * carry out; threads need to re-synchronize in some other way,
+ * and choose one to perform the reset. It may be preferable to
+ * instead create a new barrier for subsequent use.
+ */
+ public void reset() {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ /*
+ * Retract generation number enough to cover threads
+ * currently waiting on current and still resuming from
+ * previous generation, plus similarly accommodating spans
+ * after the reset.
+ */
+ generation -= 4;
+ broken = false;
+ trip.signalAll();
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Returns the number of parties currently waiting at the barrier.
+ * This method is primarily useful for debugging and assertions.
+ *
+ * @return the number of parties currently blocked in {@link #await}
+ **/
+ public int getNumberWaiting() {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ return parties - count;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/DelayQueue.java b/concurrent/src/main/java/java/util/concurrent/DelayQueue.java
new file mode 100644
index 0000000..88c4280
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/DelayQueue.java
@@ -0,0 +1,365 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+
+package java.util.concurrent;
+import java.util.concurrent.locks.*;
+import java.util.*;
+
+// BEGIN android-note
+// removed link to collections framework docs
+// END android-note
+
+/**
+ * An unbounded {@linkplain BlockingQueue blocking queue} of <tt>Delayed</tt>
+ * elements, in which an element can only be taken when its delay has expired.
+ * The <em>head</em> of the queue is that <tt>Delayed</tt> element whose delay
+ * expired furthest in the past - if no delay has expired there is no head and
+ * <tt>poll</tt> will return <tt>null</tt>.
+ * This queue does not permit <tt>null</tt> elements.
+ * <p>This class implements all of the <em>optional</em> methods
+ * of the {@link Collection} and {@link Iterator} interfaces.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ * @param <E> the type of elements held in this collection
+ */
+
+public class DelayQueue<E extends Delayed> extends AbstractQueue<E>
+ implements BlockingQueue<E> {
+
+ private transient final ReentrantLock lock = new ReentrantLock();
+ private transient final Condition available = lock.newCondition();
+ private final PriorityQueue<E> q = new PriorityQueue<E>();
+
+ /**
+ * Creates a new <tt>DelayQueue</tt> that is initially empty.
+ */
+ public DelayQueue() {}
+
+ /**
+ * Creates a <tt>DelayQueue</tt> initially containing the elements of the
+ * given collection of {@link Delayed} instances.
+ *
+ * @param c the collection
+ * @throws NullPointerException if <tt>c</tt> or any element within it
+ * is <tt>null</tt>
+ *
+ */
+ public DelayQueue(Collection<? extends E> c) {
+ this.addAll(c);
+ }
+
+ /**
+ * Inserts the specified element into this delay queue.
+ *
+ * @param o the element to add
+ * @return <tt>true</tt>
+ * @throws NullPointerException if the specified element is <tt>null</tt>.
+ */
+ public boolean offer(E o) {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ E first = q.peek();
+ q.offer(o);
+ if (first == null || o.compareTo(first) < 0)
+ available.signalAll();
+ return true;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+
+ /**
+ * Adds the specified element to this delay queue. As the queue is
+ * unbounded this method will never block.
+ * @param o the element to add
+ * @throws NullPointerException if the specified element is <tt>null</tt>.
+ */
+ public void put(E o) {
+ offer(o);
+ }
+
+ /**
+ * Inserts the specified element into this delay queue. As the queue is
+ * unbounded this method will never block.
+ * @param o the element to add
+ * @param timeout This parameter is ignored as the method never blocks
+ * @param unit This parameter is ignored as the method never blocks
+ * @return <tt>true</tt>
+ * @throws NullPointerException if the specified element is <tt>null</tt>.
+ */
+ public boolean offer(E o, long timeout, TimeUnit unit) {
+ return offer(o);
+ }
+
+ /**
+ * Adds the specified element to this queue.
+ * @param o the element to add
+ * @return <tt>true</tt> (as per the general contract of
+ * <tt>Collection.add</tt>).
+ *
+ * @throws NullPointerException if the specified element is <tt>null</tt>.
+ */
+ public boolean add(E o) {
+ return offer(o);
+ }
+
+ public E take() throws InterruptedException {
+ final ReentrantLock lock = this.lock;
+ lock.lockInterruptibly();
+ try {
+ for (;;) {
+ E first = q.peek();
+ if (first == null) {
+ available.await();
+ } else {
+ long delay = first.getDelay(TimeUnit.NANOSECONDS);
+ if (delay > 0) {
+ long tl = available.awaitNanos(delay);
+ } else {
+ E x = q.poll();
+ assert x != null;
+ if (q.size() != 0)
+ available.signalAll(); // wake up other takers
+ return x;
+
+ }
+ }
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public E poll(long time, TimeUnit unit) throws InterruptedException {
+ final ReentrantLock lock = this.lock;
+ lock.lockInterruptibly();
+ long nanos = unit.toNanos(time);
+ try {
+ for (;;) {
+ E first = q.peek();
+ if (first == null) {
+ if (nanos <= 0)
+ return null;
+ else
+ nanos = available.awaitNanos(nanos);
+ } else {
+ long delay = first.getDelay(TimeUnit.NANOSECONDS);
+ if (delay > 0) {
+ if (delay > nanos)
+ delay = nanos;
+ long timeLeft = available.awaitNanos(delay);
+ nanos -= delay - timeLeft;
+ } else {
+ E x = q.poll();
+ assert x != null;
+ if (q.size() != 0)
+ available.signalAll();
+ return x;
+ }
+ }
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public E poll() {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ E first = q.peek();
+ if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
+ return null;
+ else {
+ E x = q.poll();
+ assert x != null;
+ if (q.size() != 0)
+ available.signalAll();
+ return x;
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public E peek() {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ return q.peek();
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public int size() {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ return q.size();
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public int drainTo(Collection<? super E> c) {
+ if (c == null)
+ throw new NullPointerException();
+ if (c == this)
+ throw new IllegalArgumentException();
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ int n = 0;
+ for (;;) {
+ E first = q.peek();
+ if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
+ break;
+ c.add(q.poll());
+ ++n;
+ }
+ if (n > 0)
+ available.signalAll();
+ return n;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public int drainTo(Collection<? super E> c, int maxElements) {
+ if (c == null)
+ throw new NullPointerException();
+ if (c == this)
+ throw new IllegalArgumentException();
+ if (maxElements <= 0)
+ return 0;
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ int n = 0;
+ while (n < maxElements) {
+ E first = q.peek();
+ if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
+ break;
+ c.add(q.poll());
+ ++n;
+ }
+ if (n > 0)
+ available.signalAll();
+ return n;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Atomically removes all of the elements from this delay queue.
+ * The queue will be empty after this call returns.
+ */
+ public void clear() {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ q.clear();
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Always returns <tt>Integer.MAX_VALUE</tt> because
+ * a <tt>DelayQueue</tt> is not capacity constrained.
+ * @return <tt>Integer.MAX_VALUE</tt>
+ */
+ public int remainingCapacity() {
+ return Integer.MAX_VALUE;
+ }
+
+ public Object[] toArray() {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ return q.toArray();
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public <T> T[] toArray(T[] array) {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ return q.toArray(array);
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public boolean remove(Object o) {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ return q.remove(o);
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Returns an iterator over the elements in this queue. The iterator
+ * does not return the elements in any particular order. The
+ * returned iterator is a thread-safe "fast-fail" iterator that will
+ * throw {@link java.util.ConcurrentModificationException}
+ * upon detected interference.
+ *
+ * @return an iterator over the elements in this queue.
+ */
+ public Iterator<E> iterator() {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ return new Itr(q.iterator());
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ private class Itr<E> implements Iterator<E> {
+ private final Iterator<E> iter;
+ Itr(Iterator<E> i) {
+ iter = i;
+ }
+
+ public boolean hasNext() {
+ return iter.hasNext();
+ }
+
+ public E next() {
+ final ReentrantLock lock = DelayQueue.this.lock;
+ lock.lock();
+ try {
+ return iter.next();
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public void remove() {
+ final ReentrantLock lock = DelayQueue.this.lock;
+ lock.lock();
+ try {
+ iter.remove();
+ } finally {
+ lock.unlock();
+ }
+ }
+ }
+
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/Delayed.java b/concurrent/src/main/java/java/util/concurrent/Delayed.java
new file mode 100644
index 0000000..62f7568
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/Delayed.java
@@ -0,0 +1,32 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+
+import java.util.*;
+
+/**
+ * A mix-in style interface for marking objects that should be
+ * acted upon after a given delay.
+ *
+ * <p>An implementation of this interface must define a
+ * <tt>compareTo</tt> method that provides an ordering consistent with
+ * its <tt>getDelay</tt> method.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ */
+public interface Delayed extends Comparable<Delayed> {
+
+ /**
+ * Returns the delay associated with this object, in the given time unit.
+ *
+ * @param unit the time unit
+ * @return the delay; zero or negative values indicate that the
+ * delay has already elapsed
+ */
+ long getDelay(TimeUnit unit);
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/Exchanger.java b/concurrent/src/main/java/java/util/concurrent/Exchanger.java
new file mode 100644
index 0000000..da8c815
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/Exchanger.java
@@ -0,0 +1,247 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+import java.util.concurrent.locks.*;
+
+/**
+ * A synchronization point at which two threads can exchange objects.
+ * Each thread presents some object on entry to the {@link #exchange
+ * exchange} method, and receives the object presented by the other
+ * thread on return.
+ *
+ * <p><b>Sample Usage:</b>
+ * Here are the highlights of a class that uses an <tt>Exchanger</tt> to
+ * swap buffers between threads so that the thread filling the
+ * buffer gets a freshly
+ * emptied one when it needs it, handing off the filled one to
+ * the thread emptying the buffer.
+ * <pre>
+ * class FillAndEmpty {
+ * Exchanger&lt;DataBuffer&gt; exchanger = new Exchanger();
+ * DataBuffer initialEmptyBuffer = ... a made-up type
+ * DataBuffer initialFullBuffer = ...
+ *
+ * class FillingLoop implements Runnable {
+ * public void run() {
+ * DataBuffer currentBuffer = initialEmptyBuffer;
+ * try {
+ * while (currentBuffer != null) {
+ * addToBuffer(currentBuffer);
+ * if (currentBuffer.full())
+ * currentBuffer = exchanger.exchange(currentBuffer);
+ * }
+ * } catch (InterruptedException ex) { ... handle ... }
+ * }
+ * }
+ *
+ * class EmptyingLoop implements Runnable {
+ * public void run() {
+ * DataBuffer currentBuffer = initialFullBuffer;
+ * try {
+ * while (currentBuffer != null) {
+ * takeFromBuffer(currentBuffer);
+ * if (currentBuffer.empty())
+ * currentBuffer = exchanger.exchange(currentBuffer);
+ * }
+ * } catch (InterruptedException ex) { ... handle ...}
+ * }
+ * }
+ *
+ * void start() {
+ * new Thread(new FillingLoop()).start();
+ * new Thread(new EmptyingLoop()).start();
+ * }
+ * }
+ * </pre>
+ *
+ * @since 1.5
+ * @author Doug Lea
+ * @param <V> The type of objects that may be exchanged
+ */
+public class Exchanger<V> {
+ private final ReentrantLock lock = new ReentrantLock();
+ private final Condition taken = lock.newCondition();
+
+ /** Holder for the item being exchanged */
+ private V item;
+
+ /**
+ * Arrival count transitions from 0 to 1 to 2 then back to 0
+ * during an exchange.
+ */
+ private int arrivalCount;
+
+ /**
+ * Main exchange function, handling the different policy variants.
+ */
+ private V doExchange(V x, boolean timed, long nanos) throws InterruptedException, TimeoutException {
+ lock.lock();
+ try {
+ V other;
+
+ // If arrival count already at two, we must wait for
+ // a previous pair to finish and reset the count;
+ while (arrivalCount == 2) {
+ if (!timed)
+ taken.await();
+ else if (nanos > 0)
+ nanos = taken.awaitNanos(nanos);
+ else
+ throw new TimeoutException();
+ }
+
+ int count = ++arrivalCount;
+
+ // If item is already waiting, replace it and signal other thread
+ if (count == 2) {
+ other = item;
+ item = x;
+ taken.signal();
+ return other;
+ }
+
+ // Otherwise, set item and wait for another thread to
+ // replace it and signal us.
+
+ item = x;
+ InterruptedException interrupted = null;
+ try {
+ while (arrivalCount != 2) {
+ if (!timed)
+ taken.await();
+ else if (nanos > 0)
+ nanos = taken.awaitNanos(nanos);
+ else
+ break; // timed out
+ }
+ } catch (InterruptedException ie) {
+ interrupted = ie;
+ }
+
+ // Get and reset item and count after the wait.
+ // (We need to do this even if wait was aborted.)
+ other = item;
+ item = null;
+ count = arrivalCount;
+ arrivalCount = 0;
+ taken.signal();
+
+ // If the other thread replaced item, then we must
+ // continue even if cancelled.
+ if (count == 2) {
+ if (interrupted != null)
+ Thread.currentThread().interrupt();
+ return other;
+ }
+
+ // If no one is waiting for us, we can back out
+ if (interrupted != null)
+ throw interrupted;
+ else // must be timeout
+ throw new TimeoutException();
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Create a new Exchanger.
+ **/
+ public Exchanger() {
+ }
+
+ /**
+ * Waits for another thread to arrive at this exchange point (unless
+ * it is {@link Thread#interrupt interrupted}),
+ * and then transfers the given object to it, receiving its object
+ * in return.
+ * <p>If another thread is already waiting at the exchange point then
+ * it is resumed for thread scheduling purposes and receives the object
+ * passed in by the current thread. The current thread returns immediately,
+ * receiving the object passed to the exchange by that other thread.
+ * <p>If no other thread is already waiting at the exchange then the
+ * current thread is disabled for thread scheduling purposes and lies
+ * dormant until one of two things happens:
+ * <ul>
+ * <li>Some other thread enters the exchange; or
+ * <li>Some other thread {@link Thread#interrupt interrupts} the current
+ * thread.
+ * </ul>
+ * <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
+ * for the exchange,
+ * </ul>
+ * then {@link InterruptedException} is thrown and the current thread's
+ * interrupted status is cleared.
+ *
+ * @param x the object to exchange
+ * @return the object provided by the other thread.
+ * @throws InterruptedException if current thread was interrupted
+ * while waiting
+ **/
+ public V exchange(V x) throws InterruptedException {
+ try {
+ return doExchange(x, false, 0);
+ } catch (TimeoutException cannotHappen) {
+ throw new Error(cannotHappen);
+ }
+ }
+
+ /**
+ * Waits for another thread to arrive at this exchange point (unless
+ * it is {@link Thread#interrupt interrupted}, or the specified waiting
+ * time elapses),
+ * and then transfers the given object to it, receiving its object
+ * in return.
+ *
+ * <p>If another thread is already waiting at the exchange point then
+ * it is resumed for thread scheduling purposes and receives the object
+ * passed in by the current thread. The current thread returns immediately,
+ * receiving the object passed to the exchange by that other thread.
+ *
+ * <p>If no other thread is already waiting at the exchange then the
+ * current thread is disabled for thread scheduling purposes and lies
+ * dormant until one of three things happens:
+ * <ul>
+ * <li>Some other thread enters the exchange; or
+ * <li>Some other thread {@link Thread#interrupt interrupts} the current
+ * thread; or
+ * <li>The specified waiting time elapses.
+ * </ul>
+ * <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
+ * for the exchange,
+ * </ul>
+ * then {@link InterruptedException} is thrown and the current thread's
+ * interrupted status is cleared.
+ *
+ * <p>If the specified waiting time elapses then {@link TimeoutException}
+ * is thrown.
+ * If the time is
+ * less than or equal to zero, the method will not wait at all.
+ *
+ * @param x the object to exchange
+ * @param timeout the maximum time to wait
+ * @param unit the time unit of the <tt>timeout</tt> argument.
+ * @return the object provided by the other thread.
+ * @throws InterruptedException if current thread was interrupted
+ * while waiting
+ * @throws TimeoutException if the specified waiting time elapses before
+ * another thread enters the exchange.
+ **/
+ public V exchange(V x, long timeout, TimeUnit unit)
+ throws InterruptedException, TimeoutException {
+ return doExchange(x, true, unit.toNanos(timeout));
+ }
+
+}
+
+
diff --git a/concurrent/src/main/java/java/util/concurrent/ExecutionException.java b/concurrent/src/main/java/java/util/concurrent/ExecutionException.java
new file mode 100644
index 0000000..8f0e448
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/ExecutionException.java
@@ -0,0 +1,65 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+
+/**
+ * Exception thrown when attempting to retrieve the result of a task
+ * that aborted by throwing an exception. This exception can be
+ * inspected using the {@link #getCause()} method.
+ *
+ * @see Future
+ * @since 1.5
+ * @author Doug Lea
+ */
+public class ExecutionException extends Exception {
+ private static final long serialVersionUID = 7830266012832686185L;
+
+ /**
+ * Constructs a <tt>ExecutionException</tt> with no detail message.
+ * The cause is not initialized, and may subsequently be
+ * initialized by a call to {@link #initCause(Throwable) initCause}.
+ */
+ protected ExecutionException() { }
+
+ /**
+ * Constructs a <tt>ExecutionException</tt> with the specified detail
+ * message. The cause is not initialized, and may subsequently be
+ * initialized by a call to {@link #initCause(Throwable) initCause}.
+ *
+ * @param message the detail message
+ */
+ protected ExecutionException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs a <tt>ExecutionException</tt> with the specified detail
+ * message and cause.
+ *
+ * @param message the detail message
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method)
+ */
+ public ExecutionException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Constructs a <tt>ExecutionException</tt> with the specified cause.
+ * The detail message is set to:
+ * <pre>
+ * (cause == null ? null : cause.toString())</pre>
+ * (which typically contains the class and detail message of
+ * <tt>cause</tt>).
+ *
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method)
+ */
+ public ExecutionException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/Executor.java b/concurrent/src/main/java/java/util/concurrent/Executor.java
new file mode 100644
index 0000000..60fe193
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/Executor.java
@@ -0,0 +1,107 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+
+/**
+ * An object that executes submitted {@link Runnable} tasks. This
+ * interface provides a way of decoupling task submission from the
+ * mechanics of how each task will be run, including details of thread
+ * use, scheduling, etc. An <tt>Executor</tt> is normally used
+ * instead of explicitly creating threads. For example, rather than
+ * invoking <tt>new Thread(new(RunnableTask())).start()</tt> for each
+ * of a set of tasks, you might use:
+ *
+ * <pre>
+ * Executor executor = <em>anExecutor</em>;
+ * executor.execute(new RunnableTask1());
+ * executor.execute(new RunnableTask2());
+ * ...
+ * </pre>
+ *
+ * However, the <tt>Executor</tt> interface does not strictly
+ * require that execution be asynchronous. In the simplest case, an
+ * executor can run the submitted task immediately in the caller's
+ * thread:
+ *
+ * <pre>
+ * class DirectExecutor implements Executor {
+ * public void execute(Runnable r) {
+ * r.run();
+ * }
+ * }</pre>
+ *
+ * More typically, tasks are executed in some thread other
+ * than the caller's thread. The executor below spawns a new thread
+ * for each task.
+ *
+ * <pre>
+ * class ThreadPerTaskExecutor implements Executor {
+ * public void execute(Runnable r) {
+ * new Thread(r).start();
+ * }
+ * }</pre>
+ *
+ * Many <tt>Executor</tt> implementations impose some sort of
+ * limitation on how and when tasks are scheduled. The executor below
+ * serializes the submission of tasks to a second executor,
+ * illustrating a composite executor.
+ *
+ * <pre>
+ * class SerialExecutor implements Executor {
+ * final Queue&lt;Runnable&gt; tasks = new LinkedBlockingQueue&lt;Runnable&gt;();
+ * final Executor executor;
+ * Runnable active;
+ *
+ * SerialExecutor(Executor executor) {
+ * this.executor = executor;
+ * }
+ *
+ * public synchronized void execute(final Runnable r) {
+ * tasks.offer(new Runnable() {
+ * public void run() {
+ * try {
+ * r.run();
+ * } finally {
+ * scheduleNext();
+ * }
+ * }
+ * });
+ * if (active == null) {
+ * scheduleNext();
+ * }
+ * }
+ *
+ * protected synchronized void scheduleNext() {
+ * if ((active = tasks.poll()) != null) {
+ * executor.execute(active);
+ * }
+ * }
+ * }</pre>
+ *
+ * The <tt>Executor</tt> implementations provided in this package
+ * implement {@link ExecutorService}, which is a more extensive
+ * interface. The {@link ThreadPoolExecutor} class provides an
+ * extensible thread pool implementation. The {@link Executors} class
+ * provides convenient factory methods for these Executors.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ */
+public interface Executor {
+
+ /**
+ * Executes the given command at some time in the future. The command
+ * may execute in a new thread, in a pooled thread, or in the calling
+ * thread, at the discretion of the <tt>Executor</tt> implementation.
+ *
+ * @param command the runnable task
+ * @throws RejectedExecutionException if this task cannot be
+ * accepted for execution.
+ * @throws NullPointerException if command is null
+ */
+ void execute(Runnable command);
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/ExecutorCompletionService.java b/concurrent/src/main/java/java/util/concurrent/ExecutorCompletionService.java
new file mode 100644
index 0000000..4f9c9d9
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/ExecutorCompletionService.java
@@ -0,0 +1,148 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+
+
+/**
+ * A {@link CompletionService} that uses a supplied {@link Executor}
+ * to execute tasks. This class arranges that submitted tasks are,
+ * upon completion, placed on a queue accessible using <tt>take</tt>.
+ * The class is lightweight enough to be suitable for transient use
+ * when processing groups of tasks.
+ *
+ * <p>
+ *
+ * <b>Usage Examples.</b>
+ *
+ * Suppose you have a set of solvers for a certain problem, each
+ * returning a value of some type <tt>Result</tt>, and would like to
+ * run them concurrently, processing the results of each of them that
+ * return a non-null value, in some method <tt>use(Result r)</tt>. You
+ * could write this as:
+ *
+ * <pre>
+ * void solve(Executor e, Collection&lt;Callable&lt;Result&gt;&gt; solvers)
+ * throws InterruptedException, ExecutionException {
+ * CompletionService&lt;Result&gt; ecs = new ExecutorCompletionService&lt;Result&gt;(e);
+ * for (Callable&lt;Result&gt; s : solvers)
+ * ecs.submit(s);
+ * int n = solvers.size();
+ * for (int i = 0; i &lt; n; ++i) {
+ * Result r = ecs.take().get();
+ * if (r != null)
+ * use(r);
+ * }
+ * }
+ * </pre>
+ *
+ * Suppose instead that you would like to use the first non-null result
+ * of the set of tasks, ignoring any that encounter exceptions,
+ * and cancelling all other tasks when the first one is ready:
+ *
+ * <pre>
+ * void solve(Executor e, Collection&lt;Callable&lt;Result&gt;&gt; solvers)
+ * throws InterruptedException {
+ * CompletionService&lt;Result&gt; ecs = new ExecutorCompletionService&lt;Result&gt;(e);
+ * int n = solvers.size();
+ * List&lt;Future&lt;Result&gt;&gt; futures = new ArrayList&lt;Future&lt;Result&gt;&gt;(n);
+ * Result result = null;
+ * try {
+ * for (Callable&lt;Result&gt; s : solvers)
+ * futures.add(ecs.submit(s));
+ * for (int i = 0; i &lt; n; ++i) {
+ * try {
+ * Result r = ecs.take().get();
+ * if (r != null) {
+ * result = r;
+ * break;
+ * }
+ * } catch(ExecutionException ignore) {}
+ * }
+ * }
+ * finally {
+ * for (Future&lt;Result&gt; f : futures)
+ * f.cancel(true);
+ * }
+ *
+ * if (result != null)
+ * use(result);
+ * }
+ * </pre>
+ */
+public class ExecutorCompletionService<V> implements CompletionService<V> {
+ private final Executor executor;
+ private final BlockingQueue<Future<V>> completionQueue;
+
+ /**
+ * FutureTask extension to enqueue upon completion
+ */
+ private class QueueingFuture extends FutureTask<V> {
+ QueueingFuture(Callable<V> c) { super(c); }
+ QueueingFuture(Runnable t, V r) { super(t, r); }
+ protected void done() { completionQueue.add(this); }
+ }
+
+ /**
+ * Creates an ExecutorCompletionService using the supplied
+ * executor for base task execution and a
+ * {@link LinkedBlockingQueue} as a completion queue.
+ * @param executor the executor to use
+ * @throws NullPointerException if executor is <tt>null</tt>
+ */
+ public ExecutorCompletionService(Executor executor) {
+ if (executor == null)
+ throw new NullPointerException();
+ this.executor = executor;
+ this.completionQueue = new LinkedBlockingQueue<Future<V>>();
+ }
+
+ /**
+ * Creates an ExecutorCompletionService using the supplied
+ * executor for base task execution and the supplied queue as its
+ * completion queue.
+ * @param executor the executor to use
+ * @param completionQueue the queue to use as the completion queue
+ * normally one dedicated for use by this service
+ * @throws NullPointerException if executor or completionQueue are <tt>null</tt>
+ */
+ public ExecutorCompletionService(Executor executor,
+ BlockingQueue<Future<V>> completionQueue) {
+ if (executor == null || completionQueue == null)
+ throw new NullPointerException();
+ this.executor = executor;
+ this.completionQueue = completionQueue;
+ }
+
+ public Future<V> submit(Callable<V> task) {
+ if (task == null) throw new NullPointerException();
+ QueueingFuture f = new QueueingFuture(task);
+ executor.execute(f);
+ return f;
+ }
+
+ public Future<V> submit(Runnable task, V result) {
+ if (task == null) throw new NullPointerException();
+ QueueingFuture f = new QueueingFuture(task, result);
+ executor.execute(f);
+ return f;
+ }
+
+ public Future<V> take() throws InterruptedException {
+ return completionQueue.take();
+ }
+
+ public Future<V> poll() {
+ return completionQueue.poll();
+ }
+
+ public Future<V> poll(long timeout, TimeUnit unit) throws InterruptedException {
+ return completionQueue.poll(timeout, unit);
+ }
+
+}
+
+
diff --git a/concurrent/src/main/java/java/util/concurrent/ExecutorService.java b/concurrent/src/main/java/java/util/concurrent/ExecutorService.java
new file mode 100644
index 0000000..f0a6346
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/ExecutorService.java
@@ -0,0 +1,285 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+
+import java.util.List;
+import java.util.Collection;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedExceptionAction;
+
+/**
+ * An {@link Executor} that provides methods to manage termination and
+ * methods that can produce a {@link Future} for tracking progress of
+ * one or more asynchronous tasks.
+ *
+ * <p>
+ * An <tt>ExecutorService</tt> can be shut down, which will cause it
+ * to stop accepting new tasks. After being shut down, the executor
+ * will eventually terminate, at which point no tasks are actively
+ * executing, no tasks are awaiting execution, and no new tasks can be
+ * submitted.
+ *
+ * <p> Method <tt>submit</tt> extends base method {@link
+ * Executor#execute} by creating and returning a {@link Future} that
+ * can be used to cancel execution and/or wait for completion.
+ * Methods <tt>invokeAny</tt> and <tt>invokeAll</tt> perform the most
+ * commonly useful forms of bulk execution, executing a collection of
+ * tasks and then waiting for at least one, or all, to
+ * complete. (Class {@link ExecutorCompletionService} can be used to
+ * write customized variants of these methods.)
+ *
+ * <p>The {@link Executors} class provides factory methods for the
+ * executor services provided in this package.
+ *
+ * <h3>Usage Example</h3>
+ *
+ * Here is a sketch of a network service in which threads in a thread
+ * pool service incoming requests. It uses the preconfigured {@link
+ * Executors#newFixedThreadPool} factory method:
+ *
+ * <pre>
+ * class NetworkService {
+ * private final ServerSocket serverSocket;
+ * private final ExecutorService pool;
+ *
+ * public NetworkService(int port, int poolSize) throws IOException {
+ * serverSocket = new ServerSocket(port);
+ * pool = Executors.newFixedThreadPool(poolSize);
+ * }
+ *
+ * public void serve() {
+ * try {
+ * for (;;) {
+ * pool.execute(new Handler(serverSocket.accept()));
+ * }
+ * } catch (IOException ex) {
+ * pool.shutdown();
+ * }
+ * }
+ * }
+ *
+ * class Handler implements Runnable {
+ * private final Socket socket;
+ * Handler(Socket socket) { this.socket = socket; }
+ * public void run() {
+ * // read and service request
+ * }
+ * }
+ * </pre>
+ * @since 1.5
+ * @author Doug Lea
+ */
+public interface ExecutorService extends Executor {
+
+ /**
+ * Initiates an orderly shutdown in which previously submitted
+ * tasks are executed, but no new tasks will be
+ * accepted. Invocation has no additional effect if already shut
+ * down.
+ * @throws SecurityException if a security manager exists and
+ * shutting down this ExecutorService may manipulate threads that
+ * the caller is not permitted to modify because it does not hold
+ * {@link java.lang.RuntimePermission}<tt>("modifyThread")</tt>,
+ * or the security manager's <tt>checkAccess</tt> method denies access.
+ */
+ void shutdown();
+
+ /**
+ * Attempts to stop all actively executing tasks, halts the
+ * processing of waiting tasks, and returns a list of the tasks that were
+ * awaiting execution.
+ *
+ * <p>There are no guarantees beyond best-effort attempts to stop
+ * processing actively executing tasks. For example, typical
+ * implementations will cancel via {@link Thread#interrupt}, so if any
+ * tasks mask or fail to respond to interrupts, they may never terminate.
+ *
+ * @return list of tasks that never commenced execution
+ * @throws SecurityException if a security manager exists and
+ * shutting down this ExecutorService may manipulate threads that
+ * the caller is not permitted to modify because it does not hold
+ * {@link java.lang.RuntimePermission}<tt>("modifyThread")</tt>,
+ * or the security manager's <tt>checkAccess</tt> method denies access.
+ */
+ List<Runnable> shutdownNow();
+
+ /**
+ * Returns <tt>true</tt> if this executor has been shut down.
+ *
+ * @return <tt>true</tt> if this executor has been shut down
+ */
+ boolean isShutdown();
+
+ /**
+ * Returns <tt>true</tt> if all tasks have completed following shut down.
+ * Note that <tt>isTerminated</tt> is never <tt>true</tt> unless
+ * either <tt>shutdown</tt> or <tt>shutdownNow</tt> was called first.
+ *
+ * @return <tt>true</tt> if all tasks have completed following shut down
+ */
+ boolean isTerminated();
+
+ /**
+ * Blocks until all tasks have completed execution after a shutdown
+ * request, or the timeout occurs, or the current thread is
+ * interrupted, whichever happens first.
+ *
+ * @param timeout the maximum time to wait
+ * @param unit the time unit of the timeout argument
+ * @return <tt>true</tt> if this executor terminated and <tt>false</tt>
+ * if the timeout elapsed before termination
+ * @throws InterruptedException if interrupted while waiting
+ */
+ boolean awaitTermination(long timeout, TimeUnit unit)
+ throws InterruptedException;
+
+
+ /**
+ * Submits a value-returning task for execution and returns a Future
+ * representing the pending results of the task.
+ *
+ * <p>
+ * If you would like to immediately block waiting
+ * for a task, you can use constructions of the form
+ * <tt>result = exec.submit(aCallable).get();</tt>
+ *
+ * <p> Note: The {@link Executors} class includes a set of methods
+ * that can convert some other common closure-like objects,
+ * for example, {@link java.security.PrivilegedAction} to
+ * {@link Callable} form so they can be submitted.
+ *
+ * @param task the task to submit
+ * @return a Future representing pending completion of the task
+ * @throws RejectedExecutionException if task cannot be scheduled
+ * for execution
+ * @throws NullPointerException if task null
+ */
+ <T> Future<T> submit(Callable<T> task);
+
+ /**
+ * Submits a Runnable task for execution and returns a Future
+ * representing that task that will upon completion return
+ * the given result.
+ *
+ * @param task the task to submit
+ * @param result the result to return
+ * @return a Future representing pending completion of the task,
+ * and whose <tt>get()</tt> method will return the given result
+ * upon completion.
+ * @throws RejectedExecutionException if task cannot be scheduled
+ * for execution
+ * @throws NullPointerException if task null
+ */
+ <T> Future<T> submit(Runnable task, T result);
+
+ /**
+ * Submits a Runnable task for execution and returns a Future
+ * representing that task.
+ *
+ * @param task the task to submit
+ * @return a Future representing pending completion of the task,
+ * and whose <tt>get()</tt> method will return <tt>null</tt>
+ * upon completion.
+ * @throws RejectedExecutionException if task cannot be scheduled
+ * for execution
+ * @throws NullPointerException if task null
+ */
+ Future<?> submit(Runnable task);
+
+ /**
+ * Executes the given tasks, returning their results
+ * when all complete.
+ * Note that a <em>completed</em> task could have
+ * terminated either normally or by throwing an exception.
+ * The results of this method are undefined if the given
+ * collection is modified while this operation is in progress.
+ * @param tasks the collection of tasks
+ * @return A list of Futures representing the tasks, in the same
+ * sequential order as produced by the iterator for the given task
+ * list, each of which has completed.
+ * @throws InterruptedException if interrupted while waiting, in
+ * which case unfinished tasks are cancelled.
+ * @throws NullPointerException if tasks or any of its elements are <tt>null</tt>
+ * @throws RejectedExecutionException if any task cannot be scheduled
+ * for execution
+ */
+ <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks)
+ throws InterruptedException;
+
+ /**
+ * Executes the given tasks, returning their results
+ * when all complete or the timeout expires, whichever happens first.
+ * Upon return, tasks that have not completed are cancelled.
+ * Note that a <em>completed</em> task could have
+ * terminated either normally or by throwing an exception.
+ * The results of this method are undefined if the given
+ * collection is modified while this operation is in progress.
+ * @param tasks the collection of tasks
+ * @param timeout the maximum time to wait
+ * @param unit the time unit of the timeout argument
+ * @return A list of Futures representing the tasks, in the same
+ * sequential order as produced by the iterator for the given
+ * task list. If the operation did not time out, each task will
+ * have completed. If it did time out, some of thiese tasks will
+ * not have completed.
+ * @throws InterruptedException if interrupted while waiting, in
+ * which case unfinished tasks are cancelled.
+ * @throws NullPointerException if tasks, any of its elements, or
+ * unit are <tt>null</tt>
+ * @throws RejectedExecutionException if any task cannot be scheduled
+ * for execution
+ */
+ <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks,
+ long timeout, TimeUnit unit)
+ throws InterruptedException;
+
+ /**
+ * Executes the given tasks, returning the result
+ * of one that has completed successfully (i.e., without throwing
+ * an exception), if any do. Upon normal or exceptional return,
+ * tasks that have not completed are cancelled.
+ * The results of this method are undefined if the given
+ * collection is modified while this operation is in progress.
+ * @param tasks the collection of tasks
+ * @return The result returned by one of the tasks.
+ * @throws InterruptedException if interrupted while waiting
+ * @throws NullPointerException if tasks or any of its elements
+ * are <tt>null</tt>
+ * @throws IllegalArgumentException if tasks empty
+ * @throws ExecutionException if no task successfully completes
+ * @throws RejectedExecutionException if tasks cannot be scheduled
+ * for execution
+ */
+ <T> T invokeAny(Collection<Callable<T>> tasks)
+ throws InterruptedException, ExecutionException;
+
+ /**
+ * Executes the given tasks, returning the result
+ * of one that has completed successfully (i.e., without throwing
+ * an exception), if any do before the given timeout elapses.
+ * Upon normal or exceptional return, tasks that have not
+ * completed are cancelled.
+ * The results of this method are undefined if the given
+ * collection is modified while this operation is in progress.
+ * @param tasks the collection of tasks
+ * @param timeout the maximum time to wait
+ * @param unit the time unit of the timeout argument
+ * @return The result returned by one of the tasks.
+ * @throws InterruptedException if interrupted while waiting
+ * @throws NullPointerException if tasks, any of its elements, or
+ * unit are <tt>null</tt>
+ * @throws TimeoutException if the given timeout elapses before
+ * any task successfully completes
+ * @throws ExecutionException if no task successfully completes
+ * @throws RejectedExecutionException if tasks cannot be scheduled
+ * for execution
+ */
+ <T> T invokeAny(Collection<Callable<T>> tasks,
+ long timeout, TimeUnit unit)
+ throws InterruptedException, ExecutionException, TimeoutException;
+
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/Executors.java b/concurrent/src/main/java/java/util/concurrent/Executors.java
new file mode 100644
index 0000000..23f1b75
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/Executors.java
@@ -0,0 +1,659 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedExceptionAction;
+import java.security.AccessControlException;
+
+/**
+ * Factory and utility methods for {@link Executor}, {@link
+ * ExecutorService}, {@link ScheduledExecutorService}, {@link
+ * ThreadFactory}, and {@link Callable} classes defined in this
+ * package. This class supports the following kinds of methods:
+ *
+ * <ul>
+ * <li> Methods that create and return an {@link ExecutorService}
+ * set up with commonly useful configuration settings.
+ * <li> Methods that create and return a {@link ScheduledExecutorService}
+ * set up with commonly useful configuration settings.
+ * <li> Methods that create and return a "wrapped" ExecutorService, that
+ * disables reconfiguration by making implementation-specific methods
+ * inaccessible.
+ * <li> Methods that create and return a {@link ThreadFactory}
+ * that sets newly created threads to a known state.
+ * <li> Methods that create and return a {@link Callable}
+ * out of other closure-like forms, so they can be used
+ * in execution methods requiring <tt>Callable</tt>.
+ * </ul>
+ *
+ * @since 1.5
+ * @author Doug Lea
+ */
+public class Executors {
+
+ /**
+ * Creates a thread pool that reuses a fixed set of threads
+ * operating off a shared unbounded queue. If any thread
+ * terminates due to a failure during execution prior to shutdown,
+ * a new one will take its place if needed to execute subsequent
+ * tasks.
+ *
+ * @param nThreads the number of threads in the pool
+ * @return the newly created thread pool
+ */
+ public static ExecutorService newFixedThreadPool(int nThreads) {
+ return new ThreadPoolExecutor(nThreads, nThreads,
+ 0L, TimeUnit.MILLISECONDS,
+ new LinkedBlockingQueue<Runnable>());
+ }
+
+ /**
+ * Creates a thread pool that reuses a fixed set of threads
+ * operating off a shared unbounded queue, using the provided
+ * ThreadFactory to create new threads when needed.
+ *
+ * @param nThreads the number of threads in the pool
+ * @param threadFactory the factory to use when creating new threads
+ * @return the newly created thread pool
+ */
+ public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
+ return new ThreadPoolExecutor(nThreads, nThreads,
+ 0L, TimeUnit.MILLISECONDS,
+ new LinkedBlockingQueue<Runnable>(),
+ threadFactory);
+ }
+
+ /**
+ * Creates an Executor that uses a single worker thread operating
+ * off an unbounded queue. (Note however that if this single
+ * thread terminates due to a failure during execution prior to
+ * shutdown, a new one will take its place if needed to execute
+ * subsequent tasks.) Tasks are guaranteed to execute
+ * sequentially, and no more than one task will be active at any
+ * given time. Unlike the otherwise equivalent
+ * <tt>newFixedThreadPool(1)</tt> the returned executor is
+ * guaranteed not to be reconfigurable to use additional threads.
+ *
+ * @return the newly created single-threaded Executor
+ */
+ public static ExecutorService newSingleThreadExecutor() {
+ return new DelegatedExecutorService
+ (new ThreadPoolExecutor(1, 1,
+ 0L, TimeUnit.MILLISECONDS,
+ new LinkedBlockingQueue<Runnable>()));
+ }
+
+ /**
+ * Creates an Executor that uses a single worker thread operating
+ * off an unbounded queue, and uses the provided ThreadFactory to
+ * create a new thread when needed. Unlike the otherwise
+ * equivalent <tt>newFixedThreadPool(1, threadFactory)</tt> the returned executor
+ * is guaranteed not to be reconfigurable to use additional
+ * threads.
+ *
+ * @param threadFactory the factory to use when creating new
+ * threads
+ *
+ * @return the newly created single-threaded Executor
+ */
+ public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
+ return new DelegatedExecutorService
+ (new ThreadPoolExecutor(1, 1,
+ 0L, TimeUnit.MILLISECONDS,
+ new LinkedBlockingQueue<Runnable>(),
+ threadFactory));
+ }
+
+ /**
+ * Creates a thread pool that creates new threads as needed, but
+ * will reuse previously constructed threads when they are
+ * available. These pools will typically improve the performance
+ * of programs that execute many short-lived asynchronous tasks.
+ * Calls to <tt>execute</tt> will reuse previously constructed
+ * threads if available. If no existing thread is available, a new
+ * thread will be created and added to the pool. Threads that have
+ * not been used for sixty seconds are terminated and removed from
+ * the cache. Thus, a pool that remains idle for long enough will
+ * not consume any resources. Note that pools with similar
+ * properties but different details (for example, timeout parameters)
+ * may be created using {@link ThreadPoolExecutor} constructors.
+ *
+ * @return the newly created thread pool
+ */
+ public static ExecutorService newCachedThreadPool() {
+ return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
+ 60L, TimeUnit.SECONDS,
+ new SynchronousQueue<Runnable>());
+ }
+
+ /**
+ * Creates a thread pool that creates new threads as needed, but
+ * will reuse previously constructed threads when they are
+ * available, and uses the provided
+ * ThreadFactory to create new threads when needed.
+ * @param threadFactory the factory to use when creating new threads
+ * @return the newly created thread pool
+ */
+ public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
+ return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
+ 60L, TimeUnit.SECONDS,
+ new SynchronousQueue<Runnable>(),
+ threadFactory);
+ }
+
+ /**
+ * Creates a single-threaded executor that can schedule commands
+ * to run after a given delay, or to execute periodically.
+ * (Note however that if this single
+ * thread terminates due to a failure during execution prior to
+ * shutdown, a new one will take its place if needed to execute
+ * subsequent tasks.) Tasks are guaranteed to execute
+ * sequentially, and no more than one task will be active at any
+ * given time. Unlike the otherwise equivalent
+ * <tt>newScheduledThreadPool(1)</tt> the returned executor is
+ * guaranteed not to be reconfigurable to use additional threads.
+ * @return the newly created scheduled executor
+ */
+ public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
+ return new DelegatedScheduledExecutorService
+ (new ScheduledThreadPoolExecutor(1));
+ }
+
+ /**
+ * Creates a single-threaded executor that can schedule commands
+ * to run after a given delay, or to execute periodically. (Note
+ * however that if this single thread terminates due to a failure
+ * during execution prior to shutdown, a new one will take its
+ * place if needed to execute subsequent tasks.) Tasks are
+ * guaranteed to execute sequentially, and no more than one task
+ * will be active at any given time. Unlike the otherwise
+ * equivalent <tt>newScheduledThreadPool(1, threadFactory)</tt>
+ * the returned executor is guaranteed not to be reconfigurable to
+ * use additional threads.
+ * @param threadFactory the factory to use when creating new
+ * threads
+ * @return a newly created scheduled executor
+ */
+ public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) {
+ return new DelegatedScheduledExecutorService
+ (new ScheduledThreadPoolExecutor(1, threadFactory));
+ }
+
+ /**
+ * Creates a thread pool that can schedule commands to run after a
+ * given delay, or to execute periodically.
+ * @param corePoolSize the number of threads to keep in the pool,
+ * even if they are idle.
+ * @return a newly created scheduled thread pool
+ */
+ public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
+ return new ScheduledThreadPoolExecutor(corePoolSize);
+ }
+
+ /**
+ * Creates a thread pool that can schedule commands to run after a
+ * given delay, or to execute periodically.
+ * @param corePoolSize the number of threads to keep in the pool,
+ * even if they are idle.
+ * @param threadFactory the factory to use when the executor
+ * creates a new thread.
+ * @return a newly created scheduled thread pool
+ */
+ public static ScheduledExecutorService newScheduledThreadPool(
+ int corePoolSize, ThreadFactory threadFactory) {
+ return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
+ }
+
+
+ /**
+ * Returns an object that delegates all defined {@link
+ * ExecutorService} methods to the given executor, but not any
+ * other methods that might otherwise be accessible using
+ * casts. This provides a way to safely "freeze" configuration and
+ * disallow tuning of a given concrete implementation.
+ * @param executor the underlying implementation
+ * @return an <tt>ExecutorService</tt> instance
+ * @throws NullPointerException if executor null
+ */
+ public static ExecutorService unconfigurableExecutorService(ExecutorService executor) {
+ if (executor == null)
+ throw new NullPointerException();
+ return new DelegatedExecutorService(executor);
+ }
+
+ /**
+ * Returns an object that delegates all defined {@link
+ * ScheduledExecutorService} methods to the given executor, but
+ * not any other methods that might otherwise be accessible using
+ * casts. This provides a way to safely "freeze" configuration and
+ * disallow tuning of a given concrete implementation.
+ * @param executor the underlying implementation
+ * @return a <tt>ScheduledExecutorService</tt> instance
+ * @throws NullPointerException if executor null
+ */
+ public static ScheduledExecutorService unconfigurableScheduledExecutorService(ScheduledExecutorService executor) {
+ if (executor == null)
+ throw new NullPointerException();
+ return new DelegatedScheduledExecutorService(executor);
+ }
+
+ /**
+ * Returns a default thread factory used to create new threads.
+ * This factory creates all new threads used by an Executor in the
+ * same {@link ThreadGroup}. If there is a {@link
+ * java.lang.SecurityManager}, it uses the group of {@link
+ * System#getSecurityManager}, else the group of the thread
+ * invoking this <tt>defaultThreadFactory</tt> method. Each new
+ * thread is created as a non-daemon thread with priority
+ * <tt>Thread.NORM_PRIORITY</tt>. New threads have names
+ * accessible via {@link Thread#getName} of
+ * <em>pool-N-thread-M</em>, where <em>N</em> is the sequence
+ * number of this factory, and <em>M</em> is the sequence number
+ * of the thread created by this factory.
+ * @return a thread factory
+ */
+ public static ThreadFactory defaultThreadFactory() {
+ return new DefaultThreadFactory();
+ }
+
+ /**
+ * Returns a thread factory used to create new threads that
+ * have the same permissions as the current thread.
+ * This factory creates threads with the same settings as {@link
+ * Executors#defaultThreadFactory}, additionally setting the
+ * AccessControlContext and contextClassLoader of new threads to
+ * be the same as the thread invoking this
+ * <tt>privilegedThreadFactory</tt> method. A new
+ * <tt>privilegedThreadFactory</tt> can be created within an
+ * {@link AccessController#doPrivileged} action setting the
+ * current thread's access control context to create threads with
+ * the selected permission settings holding within that action.
+ *
+ * <p> Note that while tasks running within such threads will have
+ * the same access control and class loader settings as the
+ * current thread, they need not have the same {@link
+ * java.lang.ThreadLocal} or {@link
+ * java.lang.InheritableThreadLocal} values. If necessary,
+ * particular values of thread locals can be set or reset before
+ * any task runs in {@link ThreadPoolExecutor} subclasses using
+ * {@link ThreadPoolExecutor#beforeExecute}. Also, if it is
+ * necessary to initialize worker threads to have the same
+ * InheritableThreadLocal settings as some other designated
+ * thread, you can create a custom ThreadFactory in which that
+ * thread waits for and services requests to create others that
+ * will inherit its values.
+ *
+ * @return a thread factory
+ * @throws AccessControlException if the current access control
+ * context does not have permission to both get and set context
+ * class loader.
+ */
+ public static ThreadFactory privilegedThreadFactory() {
+ return new PrivilegedThreadFactory();
+ }
+
+ /**
+ * Returns a {@link Callable} object that, when
+ * called, runs the given task and returns the given result. This
+ * can be useful when applying methods requiring a
+ * <tt>Callable</tt> to an otherwise resultless action.
+ * @param task the task to run
+ * @param result the result to return
+ * @throws NullPointerException if task null
+ * @return a callable object
+ */
+ public static <T> Callable<T> callable(Runnable task, T result) {
+ if (task == null)
+ throw new NullPointerException();
+ return new RunnableAdapter<T>(task, result);
+ }
+
+ /**
+ * Returns a {@link Callable} object that, when
+ * called, runs the given task and returns <tt>null</tt>.
+ * @param task the task to run
+ * @return a callable object
+ * @throws NullPointerException if task null
+ */
+ public static Callable<Object> callable(Runnable task) {
+ if (task == null)
+ throw new NullPointerException();
+ return new RunnableAdapter<Object>(task, null);
+ }
+
+ /**
+ * Returns a {@link Callable} object that, when
+ * called, runs the given privileged action and returns its result.
+ * @param action the privileged action to run
+ * @return a callable object
+ * @throws NullPointerException if action null
+ */
+ public static Callable<Object> callable(PrivilegedAction action) {
+ if (action == null)
+ throw new NullPointerException();
+ return new PrivilegedActionAdapter(action);
+ }
+
+ /**
+ * Returns a {@link Callable} object that, when
+ * called, runs the given privileged exception action and returns
+ * its result.
+ * @param action the privileged exception action to run
+ * @return a callable object
+ * @throws NullPointerException if action null
+ */
+ public static Callable<Object> callable(PrivilegedExceptionAction action) {
+ if (action == null)
+ throw new NullPointerException();
+ return new PrivilegedExceptionActionAdapter(action);
+ }
+
+ /**
+ * Returns a {@link Callable} object that will, when
+ * called, execute the given <tt>callable</tt> under the current
+ * access control context. This method should normally be
+ * invoked within an {@link AccessController#doPrivileged} action
+ * to create callables that will, if possible, execute under the
+ * selected permission settings holding within that action; or if
+ * not possible, throw an associated {@link
+ * AccessControlException}.
+ * @param callable the underlying task
+ * @return a callable object
+ * @throws NullPointerException if callable null
+ *
+ */
+ public static <T> Callable<T> privilegedCallable(Callable<T> callable) {
+ if (callable == null)
+ throw new NullPointerException();
+ return new PrivilegedCallable(callable);
+ }
+
+ /**
+ * Returns a {@link Callable} object that will, when
+ * called, execute the given <tt>callable</tt> under the current
+ * access control context, with the current context class loader
+ * as the context class loader. This method should normally be
+ * invoked within an {@link AccessController#doPrivileged} action
+ * to create callables that will, if possible, execute under the
+ * selected permission settings holding within that action; or if
+ * not possible, throw an associated {@link
+ * AccessControlException}.
+ * @param callable the underlying task
+ *
+ * @return a callable object
+ * @throws NullPointerException if callable null
+ * @throws AccessControlException if the current access control
+ * context does not have permission to both set and get context
+ * class loader.
+ */
+ public static <T> Callable<T> privilegedCallableUsingCurrentClassLoader(Callable<T> callable) {
+ if (callable == null)
+ throw new NullPointerException();
+ return new PrivilegedCallableUsingCurrentClassLoader(callable);
+ }
+
+ // Non-public classes supporting the public methods
+
+ /**
+ * A callable that runs given task and returns given result
+ */
+ static final class RunnableAdapter<T> implements Callable<T> {
+ final Runnable task;
+ final T result;
+ RunnableAdapter(Runnable task, T result) {
+ this.task = task;
+ this.result = result;
+ }
+ public T call() {
+ task.run();
+ return result;
+ }
+ }
+
+ /**
+ * A callable that runs given privileged action and returns its result
+ */
+ static final class PrivilegedActionAdapter implements Callable<Object> {
+ PrivilegedActionAdapter(PrivilegedAction action) {
+ this.action = action;
+ }
+ public Object call () {
+ return action.run();
+ }
+ private final PrivilegedAction action;
+ }
+
+ /**
+ * A callable that runs given privileged exception action and returns its result
+ */
+ static final class PrivilegedExceptionActionAdapter implements Callable<Object> {
+ PrivilegedExceptionActionAdapter(PrivilegedExceptionAction action) {
+ this.action = action;
+ }
+ public Object call () throws Exception {
+ return action.run();
+ }
+ private final PrivilegedExceptionAction action;
+ }
+
+
+ /**
+ * A callable that runs under established access control settings
+ */
+ static final class PrivilegedCallable<T> implements Callable<T> {
+ private final AccessControlContext acc;
+ private final Callable<T> task;
+ private T result;
+ private Exception exception;
+ PrivilegedCallable(Callable<T> task) {
+ this.task = task;
+ this.acc = AccessController.getContext();
+ }
+
+ public T call() throws Exception {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ try {
+ result = task.call();
+ } catch(Exception ex) {
+ exception = ex;
+ }
+ return null;
+ }
+ }, acc);
+ if (exception != null)
+ throw exception;
+ else
+ return result;
+ }
+ }
+
+ /**
+ * A callable that runs under established access control settings and
+ * current ClassLoader
+ */
+ static final class PrivilegedCallableUsingCurrentClassLoader<T> implements Callable<T> {
+ private final ClassLoader ccl;
+ private final AccessControlContext acc;
+ private final Callable<T> task;
+ private T result;
+ private Exception exception;
+ PrivilegedCallableUsingCurrentClassLoader(Callable<T> task) {
+ this.task = task;
+ this.ccl = Thread.currentThread().getContextClassLoader();
+ this.acc = AccessController.getContext();
+ acc.checkPermission(new RuntimePermission("getContextClassLoader"));
+ acc.checkPermission(new RuntimePermission("setContextClassLoader"));
+ }
+
+ public T call() throws Exception {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ ClassLoader savedcl = null;
+ Thread t = Thread.currentThread();
+ try {
+ ClassLoader cl = t.getContextClassLoader();
+ if (ccl != cl) {
+ t.setContextClassLoader(ccl);
+ savedcl = cl;
+ }
+ result = task.call();
+ } catch(Exception ex) {
+ exception = ex;
+ } finally {
+ if (savedcl != null)
+ t.setContextClassLoader(savedcl);
+ }
+ return null;
+ }
+ }, acc);
+ if (exception != null)
+ throw exception;
+ else
+ return result;
+ }
+ }
+
+ /**
+ * The default thread factory
+ */
+ static class DefaultThreadFactory implements ThreadFactory {
+ static final AtomicInteger poolNumber = new AtomicInteger(1);
+ final ThreadGroup group;
+ final AtomicInteger threadNumber = new AtomicInteger(1);
+ final String namePrefix;
+
+ DefaultThreadFactory() {
+ SecurityManager s = System.getSecurityManager();
+ group = (s != null)? s.getThreadGroup() :
+ Thread.currentThread().getThreadGroup();
+ namePrefix = "pool-" +
+ poolNumber.getAndIncrement() +
+ "-thread-";
+ }
+
+ public Thread newThread(Runnable r) {
+ Thread t = new Thread(group, r,
+ namePrefix + threadNumber.getAndIncrement(),
+ 0);
+ if (t.isDaemon())
+ t.setDaemon(false);
+ if (t.getPriority() != Thread.NORM_PRIORITY)
+ t.setPriority(Thread.NORM_PRIORITY);
+ return t;
+ }
+ }
+
+ /**
+ * Thread factory capturing access control and class loader
+ */
+ static class PrivilegedThreadFactory extends DefaultThreadFactory {
+ private final ClassLoader ccl;
+ private final AccessControlContext acc;
+
+ PrivilegedThreadFactory() {
+ super();
+ this.ccl = Thread.currentThread().getContextClassLoader();
+ this.acc = AccessController.getContext();
+ acc.checkPermission(new RuntimePermission("setContextClassLoader"));
+ }
+
+ public Thread newThread(final Runnable r) {
+ return super.newThread(new Runnable() {
+ public void run() {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ Thread.currentThread().setContextClassLoader(ccl);
+ r.run();
+ return null;
+ }
+ }, acc);
+ }
+ });
+ }
+
+ }
+
+ /**
+ * A wrapper class that exposes only the ExecutorService methods
+ * of an implementation.
+ */
+ static class DelegatedExecutorService extends AbstractExecutorService {
+ private final ExecutorService e;
+ DelegatedExecutorService(ExecutorService executor) { e = executor; }
+ public void execute(Runnable command) { e.execute(command); }
+ public void shutdown() { e.shutdown(); }
+ public List<Runnable> shutdownNow() { return e.shutdownNow(); }
+ public boolean isShutdown() { return e.isShutdown(); }
+ public boolean isTerminated() { return e.isTerminated(); }
+ public boolean awaitTermination(long timeout, TimeUnit unit)
+ throws InterruptedException {
+ return e.awaitTermination(timeout, unit);
+ }
+ public Future<?> submit(Runnable task) {
+ return e.submit(task);
+ }
+ public <T> Future<T> submit(Callable<T> task) {
+ return e.submit(task);
+ }
+ public <T> Future<T> submit(Runnable task, T result) {
+ return e.submit(task, result);
+ }
+ public <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks)
+ throws InterruptedException {
+ return e.invokeAll(tasks);
+ }
+ public <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks,
+ long timeout, TimeUnit unit)
+ throws InterruptedException {
+ return e.invokeAll(tasks, timeout, unit);
+ }
+ public <T> T invokeAny(Collection<Callable<T>> tasks)
+ throws InterruptedException, ExecutionException {
+ return e.invokeAny(tasks);
+ }
+ public <T> T invokeAny(Collection<Callable<T>> tasks,
+ long timeout, TimeUnit unit)
+ throws InterruptedException, ExecutionException, TimeoutException {
+ return e.invokeAny(tasks, timeout, unit);
+ }
+ }
+
+ /**
+ * A wrapper class that exposes only the ExecutorService and
+ * ScheduleExecutor methods of a ScheduledExecutorService implementation.
+ */
+ static class DelegatedScheduledExecutorService
+ extends DelegatedExecutorService
+ implements ScheduledExecutorService {
+ private final ScheduledExecutorService e;
+ DelegatedScheduledExecutorService(ScheduledExecutorService executor) {
+ super(executor);
+ e = executor;
+ }
+ public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
+ return e.schedule(command, delay, unit);
+ }
+ public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) {
+ return e.schedule(callable, delay, unit);
+ }
+ public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) {
+ return e.scheduleAtFixedRate(command, initialDelay, period, unit);
+ }
+ public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) {
+ return e.scheduleWithFixedDelay(command, initialDelay, delay, unit);
+ }
+ }
+
+
+ /** Cannot instantiate. */
+ private Executors() {}
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/Future.java b/concurrent/src/main/java/java/util/concurrent/Future.java
new file mode 100644
index 0000000..38fa8c6
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/Future.java
@@ -0,0 +1,133 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+
+/**
+ * A <tt>Future</tt> represents the result of an asynchronous
+ * computation. Methods are provided to check if the computation is
+ * complete, to wait for its completion, and to retrieve the result of
+ * the computation. The result can only be retrieved using method
+ * <tt>get</tt> when the computation has completed, blocking if
+ * necessary until it is ready. Cancellation is performed by the
+ * <tt>cancel</tt> method. Additional methods are provided to
+ * determine if the task completed normally or was cancelled. Once a
+ * computation has completed, the computation cannot be cancelled.
+ * If you would like to use a <tt>Future</tt> for the sake
+ * of cancellability but not provide a usable result, you can
+ * declare types of the form <tt>Future&lt;?&gt;</tt> and
+ * return <tt>null</tt> as a result of the underlying task.
+ *
+ * <p>
+ * <b>Sample Usage</b> (Note that the following classes are all
+ * made-up.) <p>
+ * <pre>
+ * interface ArchiveSearcher { String search(String target); }
+ * class App {
+ * ExecutorService executor = ...
+ * ArchiveSearcher searcher = ...
+ * void showSearch(final String target) throws InterruptedException {
+ * Future&lt;String&gt; future = executor.submit(new Callable&lt;String&gt;() {
+ * public String call() { return searcher.search(target); }
+ * });
+ * displayOtherThings(); // do other things while searching
+ * try {
+ * displayText(future.get()); // use future
+ * } catch (ExecutionException ex) { cleanup(); return; }
+ * }
+ * }
+ * </pre>
+ *
+ * The {@link FutureTask} class is an implementation of <tt>Future</tt> that
+ * implements <tt>Runnable</tt>, and so may be executed by an <tt>Executor</tt>.
+ * For example, the above construction with <tt>submit</tt> could be replaced by:
+ * <pre>
+ * FutureTask&lt;String&gt; future =
+ * new FutureTask&lt;String&gt;(new Callable&lt;String&gt;() {
+ * public String call() {
+ * return searcher.search(target);
+ * }});
+ * executor.execute(future);
+ * </pre>
+ * @see FutureTask
+ * @see Executor
+ * @since 1.5
+ * @author Doug Lea
+ * @param <V> The result type returned by this Future's <tt>get</tt> method
+ */
+public interface Future<V> {
+
+ /**
+ * Attempts to cancel execution of this task. This attempt will
+ * fail if the task has already completed, already been cancelled,
+ * or could not be cancelled for some other reason. If successful,
+ * and this task has not started when <tt>cancel</tt> is called,
+ * this task should never run. If the task has already started,
+ * then the <tt>mayInterruptIfRunning</tt> parameter determines
+ * whether the thread executing this task should be interrupted in
+ * an attempt to stop the task.
+ *
+ * @param mayInterruptIfRunning <tt>true</tt> if the thread executing this
+ * task should be interrupted; otherwise, in-progress tasks are allowed
+ * to complete
+ * @return <tt>false</tt> if the task could not be cancelled,
+ * typically because it has already completed normally;
+ * <tt>true</tt> otherwise
+ */
+ boolean cancel(boolean mayInterruptIfRunning);
+
+ /**
+ * Returns <tt>true</tt> if this task was cancelled before it completed
+ * normally.
+ *
+ * @return <tt>true</tt> if task was cancelled before it completed
+ */
+ boolean isCancelled();
+
+ /**
+ * Returns <tt>true</tt> if this task completed.
+ *
+ * Completion may be due to normal termination, an exception, or
+ * cancellation -- in all of these cases, this method will return
+ * <tt>true</tt>.
+ *
+ * @return <tt>true</tt> if this task completed.
+ */
+ boolean isDone();
+
+ /**
+ * Waits if necessary for the computation to complete, and then
+ * retrieves its result.
+ *
+ * @return the computed result
+ * @throws CancellationException if the computation was cancelled
+ * @throws ExecutionException if the computation threw an
+ * exception
+ * @throws InterruptedException if the current thread was interrupted
+ * while waiting
+ */
+ V get() throws InterruptedException, ExecutionException;
+
+ /**
+ * Waits if necessary for at most the given time for the computation
+ * to complete, and then retrieves its result, if available.
+ *
+ * @param timeout the maximum time to wait
+ * @param unit the time unit of the timeout argument
+ * @return the computed result
+ * @throws CancellationException if the computation was cancelled
+ * @throws ExecutionException if the computation threw an
+ * exception
+ * @throws InterruptedException if the current thread was interrupted
+ * while waiting
+ * @throws TimeoutException if the wait timed out
+ */
+ V get(long timeout, TimeUnit unit)
+ throws InterruptedException, ExecutionException, TimeoutException;
+}
+
+
+
diff --git a/concurrent/src/main/java/java/util/concurrent/FutureTask.java b/concurrent/src/main/java/java/util/concurrent/FutureTask.java
new file mode 100644
index 0000000..87db1cd
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/FutureTask.java
@@ -0,0 +1,276 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+import java.util.concurrent.locks.*;
+
+/**
+ * A cancellable asynchronous computation. This class provides a base
+ * implementation of {@link Future}, with methods to start and cancel
+ * a computation, query to see if the computation is complete, and
+ * retrieve the result of the computation. The result can only be
+ * retrieved when the computation has completed; the <tt>get</tt>
+ * method will block if the computation has not yet completed. Once
+ * the computation has completed, the computation cannot be restarted
+ * or cancelled.
+ *
+ * <p>A <tt>FutureTask</tt> can be used to wrap a {@link Callable} or
+ * {@link java.lang.Runnable} object. Because <tt>FutureTask</tt>
+ * implements <tt>Runnable</tt>, a <tt>FutureTask</tt> can be
+ * submitted to an {@link Executor} for execution.
+ *
+ * <p>In addition to serving as a standalone class, this class provides
+ * <tt>protected</tt> functionality that may be useful when creating
+ * customized task classes.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ * @param <V> The result type returned by this FutureTask's <tt>get</tt> method
+ */
+public class FutureTask<V> implements Future<V>, Runnable {
+ /** Synchronization control for FutureTask */
+ private final Sync sync;
+
+ /**
+ * Creates a <tt>FutureTask</tt> that will upon running, execute the
+ * given <tt>Callable</tt>.
+ *
+ * @param callable the callable task
+ * @throws NullPointerException if callable is null
+ */
+ public FutureTask(Callable<V> callable) {
+ if (callable == null)
+ throw new NullPointerException();
+ sync = new Sync(callable);
+ }
+
+ /**
+ * Creates a <tt>FutureTask</tt> that will upon running, execute the
+ * given <tt>Runnable</tt>, and arrange that <tt>get</tt> will return the
+ * given result on successful completion.
+ *
+ * @param runnable the runnable task
+ * @param result the result to return on successful completion. If
+ * you don't need a particular result, consider using
+ * constructions of the form:
+ * <tt>Future&lt;?&gt; f = new FutureTask&lt;Object&gt;(runnable, null)</tt>
+ * @throws NullPointerException if runnable is null
+ */
+ public FutureTask(Runnable runnable, V result) {
+ sync = new Sync(Executors.callable(runnable, result));
+ }
+
+ public boolean isCancelled() {
+ return sync.innerIsCancelled();
+ }
+
+ public boolean isDone() {
+ return sync.innerIsDone();
+ }
+
+ public boolean cancel(boolean mayInterruptIfRunning) {
+ return sync.innerCancel(mayInterruptIfRunning);
+ }
+
+ public V get() throws InterruptedException, ExecutionException {
+ return sync.innerGet();
+ }
+
+ public V get(long timeout, TimeUnit unit)
+ throws InterruptedException, ExecutionException, TimeoutException {
+ return sync.innerGet(unit.toNanos(timeout));
+ }
+
+ /**
+ * Protected method invoked when this task transitions to state
+ * <tt>isDone</tt> (whether normally or via cancellation). The
+ * default implementation does nothing. Subclasses may override
+ * this method to invoke completion callbacks or perform
+ * bookkeeping. Note that you can query status inside the
+ * implementation of this method to determine whether this task
+ * has been cancelled.
+ */
+ protected void done() { }
+
+ /**
+ * Sets the result of this Future to the given value unless
+ * this future has already been set or has been cancelled.
+ * @param v the value
+ */
+ protected void set(V v) {
+ sync.innerSet(v);
+ }
+
+ /**
+ * Causes this future to report an <tt>ExecutionException</tt>
+ * with the given throwable as its cause, unless this Future has
+ * already been set or has been cancelled.
+ * @param t the cause of failure.
+ */
+ protected void setException(Throwable t) {
+ sync.innerSetException(t);
+ }
+
+ /**
+ * Sets this Future to the result of computation unless
+ * it has been cancelled.
+ */
+ public void run() {
+ sync.innerRun();
+ }
+
+ /**
+ * Executes the computation without setting its result, and then
+ * resets this Future to initial state, failing to do so if the
+ * computation encounters an exception or is cancelled. This is
+ * designed for use with tasks that intrinsically execute more
+ * than once.
+ * @return true if successfully run and reset
+ */
+ protected boolean runAndReset() {
+ return sync.innerRunAndReset();
+ }
+
+ /**
+ * Synchronization control for FutureTask. Note that this must be
+ * a non-static inner class in order to invoke the protected
+ * <tt>done</tt> method. For clarity, all inner class support
+ * methods are same as outer, prefixed with "inner".
+ *
+ * Uses AQS sync state to represent run status
+ */
+ private final class Sync extends AbstractQueuedSynchronizer {
+ /** State value representing that task is running */
+ private static final int RUNNING = 1;
+ /** State value representing that task ran */
+ private static final int RAN = 2;
+ /** State value representing that task was cancelled */
+ private static final int CANCELLED = 4;
+
+ /** The underlying callable */
+ private final Callable<V> callable;
+ /** The result to return from get() */
+ private V result;
+ /** The exception to throw from get() */
+ private Throwable exception;
+
+ /**
+ * The thread running task. When nulled after set/cancel, this
+ * indicates that the results are accessible. Must be
+ * volatile, to serve as write barrier on completion.
+ */
+ private volatile Thread runner;
+
+ Sync(Callable<V> callable) {
+ this.callable = callable;
+ }
+
+ private boolean ranOrCancelled(int state) {
+ return (state & (RAN | CANCELLED)) != 0;
+ }
+
+ /**
+ * Implements AQS base acquire to succeed if ran or cancelled
+ */
+ protected int tryAcquireShared(int ignore) {
+ return innerIsDone()? 1 : -1;
+ }
+
+ /**
+ * Implements AQS base release to always signal after setting
+ * final done status by nulling runner thread.
+ */
+ protected boolean tryReleaseShared(int ignore) {
+ runner = null;
+ return true;
+ }
+
+ boolean innerIsCancelled() {
+ return getState() == CANCELLED;
+ }
+
+ boolean innerIsDone() {
+ return ranOrCancelled(getState()) && runner == null;
+ }
+
+ V innerGet() throws InterruptedException, ExecutionException {
+ acquireSharedInterruptibly(0);
+ if (getState() == CANCELLED)
+ throw new CancellationException();
+ if (exception != null)
+ throw new ExecutionException(exception);
+ return result;
+ }
+
+ V innerGet(long nanosTimeout) throws InterruptedException, ExecutionException, TimeoutException {
+ if (!tryAcquireSharedNanos(0, nanosTimeout))
+ throw new TimeoutException();
+ if (getState() == CANCELLED)
+ throw new CancellationException();
+ if (exception != null)
+ throw new ExecutionException(exception);
+ return result;
+ }
+
+ void innerSet(V v) {
+ int s = getState();
+ if (ranOrCancelled(s) || !compareAndSetState(s, RAN))
+ return;
+ result = v;
+ releaseShared(0);
+ done();
+ }
+
+ void innerSetException(Throwable t) {
+ int s = getState();
+ if (ranOrCancelled(s) || !compareAndSetState(s, RAN))
+ return;
+ exception = t;
+ result = null;
+ releaseShared(0);
+ done();
+ }
+
+ boolean innerCancel(boolean mayInterruptIfRunning) {
+ int s = getState();
+ if (ranOrCancelled(s) || !compareAndSetState(s, CANCELLED))
+ return false;
+ if (mayInterruptIfRunning) {
+ Thread r = runner;
+ if (r != null)
+ r.interrupt();
+ }
+ releaseShared(0);
+ done();
+ return true;
+ }
+
+ void innerRun() {
+ if (!compareAndSetState(0, RUNNING))
+ return;
+ try {
+ runner = Thread.currentThread();
+ innerSet(callable.call());
+ } catch(Throwable ex) {
+ innerSetException(ex);
+ }
+ }
+
+ boolean innerRunAndReset() {
+ if (!compareAndSetState(0, RUNNING))
+ return false;
+ try {
+ runner = Thread.currentThread();
+ callable.call(); // don't set result
+ runner = null;
+ return compareAndSetState(RUNNING, 0);
+ } catch(Throwable ex) {
+ innerSetException(ex);
+ return false;
+ }
+ }
+ }
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/LinkedBlockingQueue.java b/concurrent/src/main/java/java/util/concurrent/LinkedBlockingQueue.java
new file mode 100644
index 0000000..f2ec05b
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/LinkedBlockingQueue.java
@@ -0,0 +1,720 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+import java.util.concurrent.atomic.*;
+import java.util.concurrent.locks.*;
+import java.util.*;
+
+// BEGIN android-note
+// removed link to collections framework docs
+// END android-note
+
+/**
+ * An optionally-bounded {@linkplain BlockingQueue blocking queue} based on
+ * linked nodes.
+ * This queue orders elements FIFO (first-in-first-out).
+ * The <em>head</em> of the queue is that element that has been on the
+ * queue the longest time.
+ * The <em>tail</em> of the queue is that element that has been on the
+ * queue the shortest time. New elements
+ * are inserted at the tail of the queue, and the queue retrieval
+ * operations obtain elements at the head of the queue.
+ * Linked queues typically have higher throughput than array-based queues but
+ * less predictable performance in most concurrent applications.
+ *
+ * <p> The optional capacity bound constructor argument serves as a
+ * way to prevent excessive queue expansion. The capacity, if unspecified,
+ * is equal to {@link Integer#MAX_VALUE}. Linked nodes are
+ * dynamically created upon each insertion unless this would bring the
+ * queue above capacity.
+ *
+ * <p>This class implements all of the <em>optional</em> methods
+ * of the {@link Collection} and {@link Iterator} interfaces.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ * @param <E> the type of elements held in this collection
+ *
+ **/
+public class LinkedBlockingQueue<E> extends AbstractQueue<E>
+ implements BlockingQueue<E>, java.io.Serializable {
+ private static final long serialVersionUID = -6903933977591709194L;
+
+ /*
+ * A variant of the "two lock queue" algorithm. The putLock gates
+ * entry to put (and offer), and has an associated condition for
+ * waiting puts. Similarly for the takeLock. The "count" field
+ * that they both rely on is maintained as an atomic to avoid
+ * needing to get both locks in most cases. Also, to minimize need
+ * for puts to get takeLock and vice-versa, cascading notifies are
+ * used. When a put notices that it has enabled at least one take,
+ * it signals taker. That taker in turn signals others if more
+ * items have been entered since the signal. And symmetrically for
+ * takes signalling puts. Operations such as remove(Object) and
+ * iterators acquire both locks.
+ */
+
+ /**
+ * Linked list node class
+ */
+ static class Node<E> {
+ /** The item, volatile to ensure barrier separating write and read */
+ volatile E item;
+ Node<E> next;
+ Node(E x) { item = x; }
+ }
+
+ /** The capacity bound, or Integer.MAX_VALUE if none */
+ private final int capacity;
+
+ /** Current number of elements */
+ private final AtomicInteger count = new AtomicInteger(0);
+
+ /** Head of linked list */
+ private transient Node<E> head;
+
+ /** Tail of linked list */
+ private transient Node<E> last;
+
+ /** Lock held by take, poll, etc */
+ private final ReentrantLock takeLock = new ReentrantLock();
+
+ /** Wait queue for waiting takes */
+ private final Condition notEmpty = takeLock.newCondition();
+
+ /** Lock held by put, offer, etc */
+ private final ReentrantLock putLock = new ReentrantLock();
+
+ /** Wait queue for waiting puts */
+ private final Condition notFull = putLock.newCondition();
+
+ /**
+ * Signal a waiting take. Called only from put/offer (which do not
+ * otherwise ordinarily lock takeLock.)
+ */
+ private void signalNotEmpty() {
+ final ReentrantLock takeLock = this.takeLock;
+ takeLock.lock();
+ try {
+ notEmpty.signal();
+ } finally {
+ takeLock.unlock();
+ }
+ }
+
+ /**
+ * Signal a waiting put. Called only from take/poll.
+ */
+ private void signalNotFull() {
+ final ReentrantLock putLock = this.putLock;
+ putLock.lock();
+ try {
+ notFull.signal();
+ } finally {
+ putLock.unlock();
+ }
+ }
+
+ /**
+ * Create a node and link it at end of queue
+ * @param x the item
+ */
+ private void insert(E x) {
+ last = last.next = new Node<E>(x);
+ }
+
+ /**
+ * Remove a node from head of queue,
+ * @return the node
+ */
+ private E extract() {
+ Node<E> first = head.next;
+ head = first;
+ E x = first.item;
+ first.item = null;
+ return x;
+ }
+
+ /**
+ * Lock to prevent both puts and takes.
+ */
+ private void fullyLock() {
+ putLock.lock();
+ takeLock.lock();
+ }
+
+ /**
+ * Unlock to allow both puts and takes.
+ */
+ private void fullyUnlock() {
+ takeLock.unlock();
+ putLock.unlock();
+ }
+
+
+ /**
+ * Creates a <tt>LinkedBlockingQueue</tt> with a capacity of
+ * {@link Integer#MAX_VALUE}.
+ */
+ public LinkedBlockingQueue() {
+ this(Integer.MAX_VALUE);
+ }
+
+ /**
+ * Creates a <tt>LinkedBlockingQueue</tt> with the given (fixed) capacity.
+ *
+ * @param capacity the capacity of this queue.
+ * @throws IllegalArgumentException if <tt>capacity</tt> is not greater
+ * than zero.
+ */
+ public LinkedBlockingQueue(int capacity) {
+ if (capacity <= 0) throw new IllegalArgumentException();
+ this.capacity = capacity;
+ last = head = new Node<E>(null);
+ }
+
+ /**
+ * Creates a <tt>LinkedBlockingQueue</tt> with a capacity of
+ * {@link Integer#MAX_VALUE}, initially containing the elements of the
+ * given collection,
+ * added in traversal order of the collection's iterator.
+ * @param c the collection of elements to initially contain
+ * @throws NullPointerException if <tt>c</tt> or any element within it
+ * is <tt>null</tt>
+ */
+ public LinkedBlockingQueue(Collection<? extends E> c) {
+ this(Integer.MAX_VALUE);
+ for (Iterator<? extends E> it = c.iterator(); it.hasNext();)
+ add(it.next());
+ }
+
+
+ // this doc comment is overridden to remove the reference to collections
+ // greater in size than Integer.MAX_VALUE
+ /**
+ * Returns the number of elements in this queue.
+ *
+ * @return the number of elements in this queue.
+ */
+ public int size() {
+ return count.get();
+ }
+
+ // this doc comment is a modified copy of the inherited doc comment,
+ // without the reference to unlimited queues.
+ /**
+ * Returns the number of elements that this queue can ideally (in
+ * the absence of memory or resource constraints) accept without
+ * blocking. This is always equal to the initial capacity of this queue
+ * less the current <tt>size</tt> of this queue.
+ * <p>Note that you <em>cannot</em> always tell if
+ * an attempt to <tt>add</tt> an element will succeed by
+ * inspecting <tt>remainingCapacity</tt> because it may be the
+ * case that a waiting consumer is ready to <tt>take</tt> an
+ * element out of an otherwise full queue.
+ *
+ * @return the remaining capacity
+ */
+ public int remainingCapacity() {
+ return capacity - count.get();
+ }
+
+ /**
+ * Adds the specified element to the tail of this queue, waiting if
+ * necessary for space to become available.
+ * @param o the element to add
+ * @throws InterruptedException if interrupted while waiting.
+ * @throws NullPointerException if the specified element is <tt>null</tt>.
+ */
+ public void put(E o) throws InterruptedException {
+ if (o == null) throw new NullPointerException();
+ // Note: convention in all put/take/etc is to preset
+ // local var holding count negative to indicate failure unless set.
+ int c = -1;
+ final ReentrantLock putLock = this.putLock;
+ final AtomicInteger count = this.count;
+ putLock.lockInterruptibly();
+ try {
+ /*
+ * Note that count is used in wait guard even though it is
+ * not protected by lock. This works because count can
+ * only decrease at this point (all other puts are shut
+ * out by lock), and we (or some other waiting put) are
+ * signalled if it ever changes from
+ * capacity. Similarly for all other uses of count in
+ * other wait guards.
+ */
+ try {
+ while (count.get() == capacity)
+ notFull.await();
+ } catch (InterruptedException ie) {
+ notFull.signal(); // propagate to a non-interrupted thread
+ throw ie;
+ }
+ insert(o);
+ c = count.getAndIncrement();
+ if (c + 1 < capacity)
+ notFull.signal();
+ } finally {
+ putLock.unlock();
+ }
+ if (c == 0)
+ signalNotEmpty();
+ }
+
+ /**
+ * Inserts the specified element at the tail of this queue, waiting if
+ * necessary up to the specified wait time for space to become available.
+ * @param o the element to add
+ * @param timeout how long to wait before giving up, in units of
+ * <tt>unit</tt>
+ * @param unit a <tt>TimeUnit</tt> determining how to interpret the
+ * <tt>timeout</tt> parameter
+ * @return <tt>true</tt> if successful, or <tt>false</tt> if
+ * the specified waiting time elapses before space is available.
+ * @throws InterruptedException if interrupted while waiting.
+ * @throws NullPointerException if the specified element is <tt>null</tt>.
+ */
+ public boolean offer(E o, long timeout, TimeUnit unit)
+ throws InterruptedException {
+
+ if (o == null) throw new NullPointerException();
+ long nanos = unit.toNanos(timeout);
+ int c = -1;
+ final ReentrantLock putLock = this.putLock;
+ final AtomicInteger count = this.count;
+ putLock.lockInterruptibly();
+ try {
+ for (;;) {
+ if (count.get() < capacity) {
+ insert(o);
+ c = count.getAndIncrement();
+ if (c + 1 < capacity)
+ notFull.signal();
+ break;
+ }
+ if (nanos <= 0)
+ return false;
+ try {
+ nanos = notFull.awaitNanos(nanos);
+ } catch (InterruptedException ie) {
+ notFull.signal(); // propagate to a non-interrupted thread
+ throw ie;
+ }
+ }
+ } finally {
+ putLock.unlock();
+ }
+ if (c == 0)
+ signalNotEmpty();
+ return true;
+ }
+
+ /**
+ * Inserts the specified element at the tail of this queue if possible,
+ * returning immediately if this queue is full.
+ *
+ * @param o the element to add.
+ * @return <tt>true</tt> if it was possible to add the element to
+ * this queue, else <tt>false</tt>
+ * @throws NullPointerException if the specified element is <tt>null</tt>
+ */
+ public boolean offer(E o) {
+ if (o == null) throw new NullPointerException();
+ final AtomicInteger count = this.count;
+ if (count.get() == capacity)
+ return false;
+ int c = -1;
+ final ReentrantLock putLock = this.putLock;
+ putLock.lock();
+ try {
+ if (count.get() < capacity) {
+ insert(o);
+ c = count.getAndIncrement();
+ if (c + 1 < capacity)
+ notFull.signal();
+ }
+ } finally {
+ putLock.unlock();
+ }
+ if (c == 0)
+ signalNotEmpty();
+ return c >= 0;
+ }
+
+ public E take() throws InterruptedException {
+ E x;
+ int c = -1;
+ final AtomicInteger count = this.count;
+ final ReentrantLock takeLock = this.takeLock;
+ takeLock.lockInterruptibly();
+ try {
+ try {
+ while (count.get() == 0)
+ notEmpty.await();
+ } catch (InterruptedException ie) {
+ notEmpty.signal(); // propagate to a non-interrupted thread
+ throw ie;
+ }
+
+ x = extract();
+ c = count.getAndDecrement();
+ if (c > 1)
+ notEmpty.signal();
+ } finally {
+ takeLock.unlock();
+ }
+ if (c == capacity)
+ signalNotFull();
+ return x;
+ }
+
+ public E poll(long timeout, TimeUnit unit) throws InterruptedException {
+ E x = null;
+ int c = -1;
+ long nanos = unit.toNanos(timeout);
+ final AtomicInteger count = this.count;
+ final ReentrantLock takeLock = this.takeLock;
+ takeLock.lockInterruptibly();
+ try {
+ for (;;) {
+ if (count.get() > 0) {
+ x = extract();
+ c = count.getAndDecrement();
+ if (c > 1)
+ notEmpty.signal();
+ break;
+ }
+ if (nanos <= 0)
+ return null;
+ try {
+ nanos = notEmpty.awaitNanos(nanos);
+ } catch (InterruptedException ie) {
+ notEmpty.signal(); // propagate to a non-interrupted thread
+ throw ie;
+ }
+ }
+ } finally {
+ takeLock.unlock();
+ }
+ if (c == capacity)
+ signalNotFull();
+ return x;
+ }
+
+ public E poll() {
+ final AtomicInteger count = this.count;
+ if (count.get() == 0)
+ return null;
+ E x = null;
+ int c = -1;
+ final ReentrantLock takeLock = this.takeLock;
+ takeLock.lock();
+ try {
+ if (count.get() > 0) {
+ x = extract();
+ c = count.getAndDecrement();
+ if (c > 1)
+ notEmpty.signal();
+ }
+ } finally {
+ takeLock.unlock();
+ }
+ if (c == capacity)
+ signalNotFull();
+ return x;
+ }
+
+ public E peek() {
+ if (count.get() == 0)
+ return null;
+ final ReentrantLock takeLock = this.takeLock;
+ takeLock.lock();
+ try {
+ Node<E> first = head.next;
+ if (first == null)
+ return null;
+ else
+ return first.item;
+ } finally {
+ takeLock.unlock();
+ }
+ }
+
+ public boolean remove(Object o) {
+ if (o == null) return false;
+ boolean removed = false;
+ fullyLock();
+ try {
+ Node<E> trail = head;
+ Node<E> p = head.next;
+ while (p != null) {
+ if (o.equals(p.item)) {
+ removed = true;
+ break;
+ }
+ trail = p;
+ p = p.next;
+ }
+ if (removed) {
+ p.item = null;
+ trail.next = p.next;
+ if (count.getAndDecrement() == capacity)
+ notFull.signalAll();
+ }
+ } finally {
+ fullyUnlock();
+ }
+ return removed;
+ }
+
+ public Object[] toArray() {
+ fullyLock();
+ try {
+ int size = count.get();
+ Object[] a = new Object[size];
+ int k = 0;
+ for (Node<E> p = head.next; p != null; p = p.next)
+ a[k++] = p.item;
+ return a;
+ } finally {
+ fullyUnlock();
+ }
+ }
+
+ public <T> T[] toArray(T[] a) {
+ fullyLock();
+ try {
+ int size = count.get();
+ if (a.length < size)
+ a = (T[])java.lang.reflect.Array.newInstance
+ (a.getClass().getComponentType(), size);
+
+ int k = 0;
+ for (Node p = head.next; p != null; p = p.next)
+ a[k++] = (T)p.item;
+ return a;
+ } finally {
+ fullyUnlock();
+ }
+ }
+
+ public String toString() {
+ fullyLock();
+ try {
+ return super.toString();
+ } finally {
+ fullyUnlock();
+ }
+ }
+
+ public void clear() {
+ fullyLock();
+ try {
+ head.next = null;
+ if (count.getAndSet(0) == capacity)
+ notFull.signalAll();
+ } finally {
+ fullyUnlock();
+ }
+ }
+
+ public int drainTo(Collection<? super E> c) {
+ if (c == null)
+ throw new NullPointerException();
+ if (c == this)
+ throw new IllegalArgumentException();
+ Node first;
+ fullyLock();
+ try {
+ first = head.next;
+ head.next = null;
+ if (count.getAndSet(0) == capacity)
+ notFull.signalAll();
+ } finally {
+ fullyUnlock();
+ }
+ // Transfer the elements outside of locks
+ int n = 0;
+ for (Node<E> p = first; p != null; p = p.next) {
+ c.add(p.item);
+ p.item = null;
+ ++n;
+ }
+ return n;
+ }
+
+ public int drainTo(Collection<? super E> c, int maxElements) {
+ if (c == null)
+ throw new NullPointerException();
+ if (c == this)
+ throw new IllegalArgumentException();
+ if (maxElements <= 0)
+ return 0;
+ fullyLock();
+ try {
+ int n = 0;
+ Node<E> p = head.next;
+ while (p != null && n < maxElements) {
+ c.add(p.item);
+ p.item = null;
+ p = p.next;
+ ++n;
+ }
+ if (n != 0) {
+ head.next = p;
+ if (count.getAndAdd(-n) == capacity)
+ notFull.signalAll();
+ }
+ return n;
+ } finally {
+ fullyUnlock();
+ }
+ }
+
+ /**
+ * Returns an iterator over the elements in this queue in proper sequence.
+ * The returned <tt>Iterator</tt> is a "weakly consistent" iterator that
+ * will never throw {@link java.util.ConcurrentModificationException},
+ * and guarantees to traverse elements as they existed upon
+ * construction of the iterator, and may (but is not guaranteed to)
+ * reflect any modifications subsequent to construction.
+ *
+ * @return an iterator over the elements in this queue in proper sequence.
+ */
+ public Iterator<E> iterator() {
+ return new Itr();
+ }
+
+ private class Itr implements Iterator<E> {
+ /*
+ * Basic weak-consistent iterator. At all times hold the next
+ * item to hand out so that if hasNext() reports true, we will
+ * still have it to return even if lost race with a take etc.
+ */
+ private Node<E> current;
+ private Node<E> lastRet;
+ private E currentElement;
+
+ Itr() {
+ final ReentrantLock putLock = LinkedBlockingQueue.this.putLock;
+ final ReentrantLock takeLock = LinkedBlockingQueue.this.takeLock;
+ putLock.lock();
+ takeLock.lock();
+ try {
+ current = head.next;
+ if (current != null)
+ currentElement = current.item;
+ } finally {
+ takeLock.unlock();
+ putLock.unlock();
+ }
+ }
+
+ public boolean hasNext() {
+ return current != null;
+ }
+
+ public E next() {
+ final ReentrantLock putLock = LinkedBlockingQueue.this.putLock;
+ final ReentrantLock takeLock = LinkedBlockingQueue.this.takeLock;
+ putLock.lock();
+ takeLock.lock();
+ try {
+ if (current == null)
+ throw new NoSuchElementException();
+ E x = currentElement;
+ lastRet = current;
+ current = current.next;
+ if (current != null)
+ currentElement = current.item;
+ return x;
+ } finally {
+ takeLock.unlock();
+ putLock.unlock();
+ }
+ }
+
+ public void remove() {
+ if (lastRet == null)
+ throw new IllegalStateException();
+ final ReentrantLock putLock = LinkedBlockingQueue.this.putLock;
+ final ReentrantLock takeLock = LinkedBlockingQueue.this.takeLock;
+ putLock.lock();
+ takeLock.lock();
+ try {
+ Node<E> node = lastRet;
+ lastRet = null;
+ Node<E> trail = head;
+ Node<E> p = head.next;
+ while (p != null && p != node) {
+ trail = p;
+ p = p.next;
+ }
+ if (p == node) {
+ p.item = null;
+ trail.next = p.next;
+ int c = count.getAndDecrement();
+ if (c == capacity)
+ notFull.signalAll();
+ }
+ } finally {
+ takeLock.unlock();
+ putLock.unlock();
+ }
+ }
+ }
+
+ /**
+ * Save the state to a stream (that is, serialize it).
+ *
+ * @serialData The capacity is emitted (int), followed by all of
+ * its elements (each an <tt>Object</tt>) in the proper order,
+ * followed by a null
+ * @param s the stream
+ */
+ private void writeObject(java.io.ObjectOutputStream s)
+ throws java.io.IOException {
+
+ fullyLock();
+ try {
+ // Write out any hidden stuff, plus capacity
+ s.defaultWriteObject();
+
+ // Write out all elements in the proper order.
+ for (Node<E> p = head.next; p != null; p = p.next)
+ s.writeObject(p.item);
+
+ // Use trailing null as sentinel
+ s.writeObject(null);
+ } finally {
+ fullyUnlock();
+ }
+ }
+
+ /**
+ * Reconstitute this queue instance from a stream (that is,
+ * deserialize it).
+ * @param s the stream
+ */
+ private void readObject(java.io.ObjectInputStream s)
+ throws java.io.IOException, ClassNotFoundException {
+ // Read in capacity, and any hidden stuff
+ s.defaultReadObject();
+
+ count.set(0);
+ last = head = new Node<E>(null);
+
+ // Read in all elements and place in queue
+ for (;;) {
+ E item = (E)s.readObject();
+ if (item == null)
+ break;
+ add(item);
+ }
+ }
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/PriorityBlockingQueue.java b/concurrent/src/main/java/java/util/concurrent/PriorityBlockingQueue.java
new file mode 100644
index 0000000..85c0165
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/PriorityBlockingQueue.java
@@ -0,0 +1,455 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+
+import java.util.concurrent.locks.*;
+import java.util.*;
+
+// BEGIN android-note
+// removed link to collections framework docs
+// END android-note
+
+/**
+ * An unbounded {@linkplain BlockingQueue blocking queue} that uses
+ * the same ordering rules as class {@link PriorityQueue} and supplies
+ * blocking retrieval operations. While this queue is logically
+ * unbounded, attempted additions may fail due to resource exhaustion
+ * (causing <tt>OutOfMemoryError</tt>). This class does not permit
+ * <tt>null</tt> elements. A priority queue relying on natural
+ * ordering also does not permit insertion of non-comparable objects
+ * (doing so results in <tt>ClassCastException</tt>).
+ *
+ * <p>This class implements all of the <em>optional</em> methods
+ * of the {@link Collection} and {@link Iterator} interfaces.
+ * <p>The Iterator provided in method {@link #iterator()} is
+ * <em>not</em> guaranteed to traverse the elements of the
+ * PriorityBlockingQueue in any particular order. If you need ordered
+ * traversal, consider using <tt>Arrays.sort(pq.toArray())</tt>.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ * @param <E> the type of elements held in this collection
+ */
+public class PriorityBlockingQueue<E> extends AbstractQueue<E>
+ implements BlockingQueue<E>, java.io.Serializable {
+ private static final long serialVersionUID = 5595510919245408276L;
+
+ private final PriorityQueue<E> q;
+ private final ReentrantLock lock = new ReentrantLock(true);
+ private final Condition notEmpty = lock.newCondition();
+
+ /**
+ * Creates a <tt>PriorityBlockingQueue</tt> with the default initial
+ * capacity
+ * (11) that orders its elements according to their natural
+ * ordering (using <tt>Comparable</tt>).
+ */
+ public PriorityBlockingQueue() {
+ q = new PriorityQueue<E>();
+ }
+
+ /**
+ * Creates a <tt>PriorityBlockingQueue</tt> with the specified initial
+ * capacity
+ * that orders its elements according to their natural ordering
+ * (using <tt>Comparable</tt>).
+ *
+ * @param initialCapacity the initial capacity for this priority queue.
+ * @throws IllegalArgumentException if <tt>initialCapacity</tt> is less
+ * than 1
+ */
+ public PriorityBlockingQueue(int initialCapacity) {
+ q = new PriorityQueue<E>(initialCapacity, null);
+ }
+
+ /**
+ * Creates a <tt>PriorityBlockingQueue</tt> with the specified initial
+ * capacity
+ * that orders its elements according to the specified comparator.
+ *
+ * @param initialCapacity the initial capacity for this priority queue.
+ * @param comparator the comparator used to order this priority queue.
+ * If <tt>null</tt> then the order depends on the elements' natural
+ * ordering.
+ * @throws IllegalArgumentException if <tt>initialCapacity</tt> is less
+ * than 1
+ */
+ public PriorityBlockingQueue(int initialCapacity,
+ Comparator<? super E> comparator) {
+ q = new PriorityQueue<E>(initialCapacity, comparator);
+ }
+
+ /**
+ * Creates a <tt>PriorityBlockingQueue</tt> containing the elements
+ * in the specified collection. The priority queue has an initial
+ * capacity of 110% of the size of the specified collection. If
+ * the specified collection is a {@link SortedSet} or a {@link
+ * PriorityQueue}, this priority queue will be sorted according to
+ * the same comparator, or according to its elements' natural
+ * order if the collection is sorted according to its elements'
+ * natural order. Otherwise, this priority queue is ordered
+ * according to its elements' natural order.
+ *
+ * @param c the collection whose elements are to be placed
+ * into this priority queue.
+ * @throws ClassCastException if elements of the specified collection
+ * cannot be compared to one another according to the priority
+ * queue's ordering.
+ * @throws NullPointerException if <tt>c</tt> or any element within it
+ * is <tt>null</tt>
+ */
+ public PriorityBlockingQueue(Collection<? extends E> c) {
+ q = new PriorityQueue<E>(c);
+ }
+
+
+ // these first few override just to update doc comments
+
+ /**
+ * Adds the specified element to this queue.
+ * @param o the element to add
+ * @return <tt>true</tt> (as per the general contract of
+ * <tt>Collection.add</tt>).
+ *
+ * @throws NullPointerException if the specified element is <tt>null</tt>.
+ * @throws ClassCastException if the specified element cannot be compared
+ * with elements currently in the priority queue according
+ * to the priority queue's ordering.
+ */
+ public boolean add(E o) {
+ return super.add(o);
+ }
+
+ // BEGIN android-changed
+ /**
+ * Returns the comparator used to order this collection, or <tt>null</tt>
+ * if this collection is sorted according to its elements natural ordering
+ * (using <tt>Comparable</tt>).
+ *
+ * @return the comparator used to order this collection, or <tt>null</tt>
+ * if this collection is sorted according to its elements natural ordering.
+ */
+ public Comparator<? super E> comparator() {
+ return q.comparator();
+ }
+ // END android-changed
+
+ /**
+ * Inserts the specified element into this priority queue.
+ *
+ * @param o the element to add
+ * @return <tt>true</tt>
+ * @throws ClassCastException if the specified element cannot be compared
+ * with elements currently in the priority queue according
+ * to the priority queue's ordering.
+ * @throws NullPointerException if the specified element is <tt>null</tt>.
+ */
+ public boolean offer(E o) {
+ if (o == null) throw new NullPointerException();
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ boolean ok = q.offer(o);
+ assert ok;
+ notEmpty.signal();
+ return true;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Adds the specified element to this priority queue. As the queue is
+ * unbounded this method will never block.
+ * @param o the element to add
+ * @throws ClassCastException if the element cannot be compared
+ * with elements currently in the priority queue according
+ * to the priority queue's ordering.
+ * @throws NullPointerException if the specified element is <tt>null</tt>.
+ */
+ public void put(E o) {
+ offer(o); // never need to block
+ }
+
+ /**
+ * Inserts the specified element into this priority queue. As the queue is
+ * unbounded this method will never block.
+ * @param o the element to add
+ * @param timeout This parameter is ignored as the method never blocks
+ * @param unit This parameter is ignored as the method never blocks
+ * @return <tt>true</tt>
+ * @throws ClassCastException if the element cannot be compared
+ * with elements currently in the priority queue according
+ * to the priority queue's ordering.
+ * @throws NullPointerException if the specified element is <tt>null</tt>.
+ */
+ public boolean offer(E o, long timeout, TimeUnit unit) {
+ return offer(o); // never need to block
+ }
+
+ public E take() throws InterruptedException {
+ final ReentrantLock lock = this.lock;
+ lock.lockInterruptibly();
+ try {
+ try {
+ while (q.size() == 0)
+ notEmpty.await();
+ } catch (InterruptedException ie) {
+ notEmpty.signal(); // propagate to non-interrupted thread
+ throw ie;
+ }
+ E x = q.poll();
+ assert x != null;
+ return x;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public E poll() {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ return q.poll();
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public E poll(long timeout, TimeUnit unit) throws InterruptedException {
+ long nanos = unit.toNanos(timeout);
+ final ReentrantLock lock = this.lock;
+ lock.lockInterruptibly();
+ try {
+ for (;;) {
+ E x = q.poll();
+ if (x != null)
+ return x;
+ if (nanos <= 0)
+ return null;
+ try {
+ nanos = notEmpty.awaitNanos(nanos);
+ } catch (InterruptedException ie) {
+ notEmpty.signal(); // propagate to non-interrupted thread
+ throw ie;
+ }
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public E peek() {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ return q.peek();
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public int size() {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ return q.size();
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Always returns <tt>Integer.MAX_VALUE</tt> because
+ * a <tt>PriorityBlockingQueue</tt> is not capacity constrained.
+ * @return <tt>Integer.MAX_VALUE</tt>
+ */
+ public int remainingCapacity() {
+ return Integer.MAX_VALUE;
+ }
+
+ public boolean remove(Object o) {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ return q.remove(o);
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public boolean contains(Object o) {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ return q.contains(o);
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public Object[] toArray() {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ return q.toArray();
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public String toString() {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ return q.toString();
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public int drainTo(Collection<? super E> c) {
+ if (c == null)
+ throw new NullPointerException();
+ if (c == this)
+ throw new IllegalArgumentException();
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ int n = 0;
+ E e;
+ while ( (e = q.poll()) != null) {
+ c.add(e);
+ ++n;
+ }
+ return n;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public int drainTo(Collection<? super E> c, int maxElements) {
+ if (c == null)
+ throw new NullPointerException();
+ if (c == this)
+ throw new IllegalArgumentException();
+ if (maxElements <= 0)
+ return 0;
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ int n = 0;
+ E e;
+ while (n < maxElements && (e = q.poll()) != null) {
+ c.add(e);
+ ++n;
+ }
+ return n;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Atomically removes all of the elements from this delay queue.
+ * The queue will be empty after this call returns.
+ */
+ public void clear() {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ q.clear();
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public <T> T[] toArray(T[] a) {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ return q.toArray(a);
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Returns an iterator over the elements in this queue. The
+ * iterator does not return the elements in any particular order.
+ * The returned iterator is a thread-safe "fast-fail" iterator
+ * that will throw {@link
+ * java.util.ConcurrentModificationException} upon detected
+ * interference.
+ *
+ * @return an iterator over the elements in this queue.
+ */
+ public Iterator<E> iterator() {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ return new Itr(q.iterator());
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ private class Itr<E> implements Iterator<E> {
+ private final Iterator<E> iter;
+ Itr(Iterator<E> i) {
+ iter = i;
+ }
+
+ public boolean hasNext() {
+ /*
+ * No sync -- we rely on underlying hasNext to be
+ * stateless, in which case we can return true by mistake
+ * only when next() will subsequently throw
+ * ConcurrentModificationException.
+ */
+ return iter.hasNext();
+ }
+
+ public E next() {
+ ReentrantLock lock = PriorityBlockingQueue.this.lock;
+ lock.lock();
+ try {
+ return iter.next();
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public void remove() {
+ ReentrantLock lock = PriorityBlockingQueue.this.lock;
+ lock.lock();
+ try {
+ iter.remove();
+ } finally {
+ lock.unlock();
+ }
+ }
+ }
+
+ /**
+ * Save the state to a stream (that is, serialize it). This
+ * merely wraps default serialization within lock. The
+ * serialization strategy for items is left to underlying
+ * Queue. Note that locking is not needed on deserialization, so
+ * readObject is not defined, just relying on default.
+ */
+ private void writeObject(java.io.ObjectOutputStream s)
+ throws java.io.IOException {
+ lock.lock();
+ try {
+ s.defaultWriteObject();
+ } finally {
+ lock.unlock();
+ }
+ }
+
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/RejectedExecutionException.java b/concurrent/src/main/java/java/util/concurrent/RejectedExecutionException.java
new file mode 100644
index 0000000..199b9de
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/RejectedExecutionException.java
@@ -0,0 +1,62 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+
+/**
+ * Exception thrown by an {@link Executor} when a task cannot be
+ * accepted for execution.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ */
+public class RejectedExecutionException extends RuntimeException {
+ private static final long serialVersionUID = -375805702767069545L;
+
+ /**
+ * Constructs a <tt>RejectedExecutionException</tt> with no detail message.
+ * The cause is not initialized, and may subsequently be
+ * initialized by a call to {@link #initCause(Throwable) initCause}.
+ */
+ public RejectedExecutionException() { }
+
+ /**
+ * Constructs a <tt>RejectedExecutionException</tt> with the
+ * specified detail message. The cause is not initialized, and may
+ * subsequently be initialized by a call to {@link
+ * #initCause(Throwable) initCause}.
+ *
+ * @param message the detail message
+ */
+ public RejectedExecutionException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs a <tt>RejectedExecutionException</tt> with the
+ * specified detail message and cause.
+ *
+ * @param message the detail message
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method)
+ */
+ public RejectedExecutionException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Constructs a <tt>RejectedExecutionException</tt> with the
+ * specified cause. The detail message is set to: <pre> (cause ==
+ * null ? null : cause.toString())</pre> (which typically contains
+ * the class and detail message of <tt>cause</tt>).
+ *
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method)
+ */
+ public RejectedExecutionException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/RejectedExecutionHandler.java b/concurrent/src/main/java/java/util/concurrent/RejectedExecutionHandler.java
new file mode 100644
index 0000000..4b4bbea
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/RejectedExecutionHandler.java
@@ -0,0 +1,33 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+
+/**
+ * A handler for tasks that cannot be executed by a {@link
+ * ThreadPoolExecutor}.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ */
+public interface RejectedExecutionHandler {
+
+ /**
+ * Method that may be invoked by a {@link ThreadPoolExecutor} when
+ * <tt>execute</tt> cannot accept a task. This may occur when no
+ * more threads or queue slots are available because their bounds
+ * would be exceeded, or upon shutdown of the Executor.
+ *
+ * In the absence other alternatives, the method may throw an
+ * unchecked {@link RejectedExecutionException}, which will be
+ * propagated to the caller of <tt>execute</tt>.
+ *
+ * @param r the runnable task requested to be executed
+ * @param executor the executor attempting to execute this task
+ * @throws RejectedExecutionException if there is no remedy
+ */
+ void rejectedExecution(Runnable r, ThreadPoolExecutor executor);
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/ScheduledExecutorService.java b/concurrent/src/main/java/java/util/concurrent/ScheduledExecutorService.java
new file mode 100644
index 0000000..9579fef
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/ScheduledExecutorService.java
@@ -0,0 +1,145 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+import java.util.concurrent.atomic.*;
+import java.util.*;
+
+/**
+ * An {@link ExecutorService} that can schedule commands to run after a given
+ * delay, or to execute periodically.
+ *
+ * <p> The <tt>schedule</tt> methods create tasks with various delays
+ * and return a task object that can be used to cancel or check
+ * execution. The <tt>scheduleAtFixedRate</tt> and
+ * <tt>scheduleWithFixedDelay</tt> methods create and execute tasks
+ * that run periodically until cancelled.
+ *
+ * <p> Commands submitted using the {@link Executor#execute} and
+ * {@link ExecutorService} <tt>submit</tt> methods are scheduled with
+ * a requested delay of zero. Zero and negative delays (but not
+ * periods) are also allowed in <tt>schedule</tt> methods, and are
+ * treated as requests for immediate execution.
+ *
+ * <p>All <tt>schedule</tt> methods accept <em>relative</em> delays and
+ * periods as arguments, not absolute times or dates. It is a simple
+ * matter to transform an absolute time represented as a {@link
+ * java.util.Date} to the required form. For example, to schedule at
+ * a certain future <tt>date</tt>, you can use: <tt>schedule(task,
+ * date.getTime() - System.currentTimeMillis(),
+ * TimeUnit.MILLISECONDS)</tt>. Beware however that expiration of a
+ * relative delay need not coincide with the current <tt>Date</tt> at
+ * which the task is enabled due to network time synchronization
+ * protocols, clock drift, or other factors.
+ *
+ * The {@link Executors} class provides convenient factory methods for
+ * the ScheduledExecutorService implementations provided in this package.
+ *
+ * <h3>Usage Example</h3>
+ *
+ * Here is a class with a method that sets up a ScheduledExecutorService
+ * to beep every ten seconds for an hour:
+ *
+ * <pre>
+ * import static java.util.concurrent.TimeUnit;
+ * class BeeperControl {
+ * private final ScheduledExecutorService scheduler =
+ * Executors.newScheduledThreadPool(1);
+ *
+ * public void beepForAnHour() {
+ * final Runnable beeper = new Runnable() {
+ * public void run() { System.out.println("beep"); }
+ * };
+ * final ScheduledFuture&lt;?&gt; beeperHandle =
+ * scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);
+ * scheduler.schedule(new Runnable() {
+ * public void run() { beeperHandle.cancel(true); }
+ * }, 60 * 60, SECONDS);
+ * }
+ * }
+ * </pre>
+ *
+ * @since 1.5
+ * @author Doug Lea
+ */
+public interface ScheduledExecutorService extends ExecutorService {
+
+ /**
+ * Creates and executes a one-shot action that becomes enabled
+ * after the given delay.
+ * @param command the task to execute.
+ * @param delay the time from now to delay execution.
+ * @param unit the time unit of the delay parameter.
+ * @return a Future representing pending completion of the task,
+ * and whose <tt>get()</tt> method will return <tt>null</tt>
+ * upon completion.
+ * @throws RejectedExecutionException if task cannot be scheduled
+ * for execution.
+ * @throws NullPointerException if command is null
+ */
+ public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit);
+
+ /**
+ * Creates and executes a ScheduledFuture that becomes enabled after the
+ * given delay.
+ * @param callable the function to execute.
+ * @param delay the time from now to delay execution.
+ * @param unit the time unit of the delay parameter.
+ * @return a ScheduledFuture that can be used to extract result or cancel.
+ * @throws RejectedExecutionException if task cannot be scheduled
+ * for execution.
+ * @throws NullPointerException if callable is null
+ */
+ public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit);
+
+ /**
+ * Creates and executes a periodic action that becomes enabled first
+ * after the given initial delay, and subsequently with the given
+ * period; that is executions will commence after
+ * <tt>initialDelay</tt> then <tt>initialDelay+period</tt>, then
+ * <tt>initialDelay + 2 * period</tt>, and so on.
+ * If any execution of the task
+ * encounters an exception, subsequent executions are suppressed.
+ * Otherwise, the task will only terminate via cancellation or
+ * termination of the executor.
+ * @param command the task to execute.
+ * @param initialDelay the time to delay first execution.
+ * @param period the period between successive executions.
+ * @param unit the time unit of the initialDelay and period parameters
+ * @return a Future representing pending completion of the task,
+ * and whose <tt>get()</tt> method will throw an exception upon
+ * cancellation.
+ * @throws RejectedExecutionException if task cannot be scheduled
+ * for execution.
+ * @throws NullPointerException if command is null
+ * @throws IllegalArgumentException if period less than or equal to zero.
+ */
+ public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit);
+
+ /**
+ * Creates and executes a periodic action that becomes enabled first
+ * after the given initial delay, and subsequently with the
+ * given delay between the termination of one execution and the
+ * commencement of the next. If any execution of the task
+ * encounters an exception, subsequent executions are suppressed.
+ * Otherwise, the task will only terminate via cancellation or
+ * termination of the executor.
+ * @param command the task to execute.
+ * @param initialDelay the time to delay first execution.
+ * @param delay the delay between the termination of one
+ * execution and the commencement of the next.
+ * @param unit the time unit of the initialDelay and delay parameters
+ * @return a Future representing pending completion of the task,
+ * and whose <tt>get()</tt> method will throw an exception upon
+ * cancellation.
+ * @throws RejectedExecutionException if task cannot be scheduled
+ * for execution.
+ * @throws NullPointerException if command is null
+ * @throws IllegalArgumentException if delay less than or equal to zero.
+ */
+ public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit);
+
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/ScheduledFuture.java b/concurrent/src/main/java/java/util/concurrent/ScheduledFuture.java
new file mode 100644
index 0000000..239d681
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/ScheduledFuture.java
@@ -0,0 +1,19 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+
+/**
+ * A delayed result-bearing action that can be cancelled.
+ * Usually a scheduled future is the result of scheduling
+ * a task with a {@link ScheduledExecutorService}.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ * @param <V> The result type returned by this Future
+ */
+public interface ScheduledFuture<V> extends Delayed, Future<V> {
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/ScheduledThreadPoolExecutor.java b/concurrent/src/main/java/java/util/concurrent/ScheduledThreadPoolExecutor.java
new file mode 100644
index 0000000..09ec681
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/ScheduledThreadPoolExecutor.java
@@ -0,0 +1,541 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+import java.util.concurrent.atomic.*;
+import java.util.*;
+
+/**
+ * A {@link ThreadPoolExecutor} that can additionally schedule
+ * commands to run after a given delay, or to execute
+ * periodically. This class is preferable to {@link java.util.Timer}
+ * when multiple worker threads are needed, or when the additional
+ * flexibility or capabilities of {@link ThreadPoolExecutor} (which
+ * this class extends) are required.
+ *
+ * <p> Delayed tasks execute no sooner than they are enabled, but
+ * without any real-time guarantees about when, after they are
+ * enabled, they will commence. Tasks scheduled for exactly the same
+ * execution time are enabled in first-in-first-out (FIFO) order of
+ * submission.
+ *
+ * <p>While this class inherits from {@link ThreadPoolExecutor}, a few
+ * of the inherited tuning methods are not useful for it. In
+ * particular, because it acts as a fixed-sized pool using
+ * <tt>corePoolSize</tt> threads and an unbounded queue, adjustments
+ * to <tt>maximumPoolSize</tt> have no useful effect.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ */
+public class ScheduledThreadPoolExecutor
+ extends ThreadPoolExecutor
+ implements ScheduledExecutorService {
+
+ /**
+ * False if should cancel/suppress periodic tasks on shutdown.
+ */
+ private volatile boolean continueExistingPeriodicTasksAfterShutdown;
+
+ /**
+ * False if should cancel non-periodic tasks on shutdown.
+ */
+ private volatile boolean executeExistingDelayedTasksAfterShutdown = true;
+
+ /**
+ * Sequence number to break scheduling ties, and in turn to
+ * guarantee FIFO order among tied entries.
+ */
+ private static final AtomicLong sequencer = new AtomicLong(0);
+
+ /** Base of nanosecond timings, to avoid wrapping */
+ private static final long NANO_ORIGIN = System.nanoTime();
+
+ /**
+ * Returns nanosecond time offset by origin
+ */
+ final long now() {
+ return System.nanoTime() - NANO_ORIGIN;
+ }
+
+ private class ScheduledFutureTask<V>
+ extends FutureTask<V> implements ScheduledFuture<V> {
+
+ /** Sequence number to break ties FIFO */
+ private final long sequenceNumber;
+ /** The time the task is enabled to execute in nanoTime units */
+ private long time;
+ /**
+ * Period in nanoseconds for repeating tasks. A positive
+ * value indicates fixed-rate execution. A negative value
+ * indicates fixed-delay execution. A value of 0 indicates a
+ * non-repeating task.
+ */
+ private final long period;
+
+ /**
+ * Creates a one-shot action with given nanoTime-based trigger time
+ */
+ ScheduledFutureTask(Runnable r, V result, long ns) {
+ super(r, result);
+ this.time = ns;
+ this.period = 0;
+ this.sequenceNumber = sequencer.getAndIncrement();
+ }
+
+ /**
+ * Creates a periodic action with given nano time and period
+ */
+ ScheduledFutureTask(Runnable r, V result, long ns, long period) {
+ super(r, result);
+ this.time = ns;
+ this.period = period;
+ this.sequenceNumber = sequencer.getAndIncrement();
+ }
+
+ /**
+ * Creates a one-shot action with given nanoTime-based trigger
+ */
+ ScheduledFutureTask(Callable<V> callable, long ns) {
+ super(callable);
+ this.time = ns;
+ this.period = 0;
+ this.sequenceNumber = sequencer.getAndIncrement();
+ }
+
+ public long getDelay(TimeUnit unit) {
+ long d = unit.convert(time - now(), TimeUnit.NANOSECONDS);
+ return d;
+ }
+
+ public int compareTo(Delayed other) {
+ if (other == this) // compare zero ONLY if same object
+ return 0;
+ ScheduledFutureTask<?> x = (ScheduledFutureTask<?>)other;
+ long diff = time - x.time;
+ if (diff < 0)
+ return -1;
+ else if (diff > 0)
+ return 1;
+ else if (sequenceNumber < x.sequenceNumber)
+ return -1;
+ else
+ return 1;
+ }
+
+ /**
+ * Returns true if this is a periodic (not a one-shot) action.
+ * @return true if periodic
+ */
+ boolean isPeriodic() {
+ return period != 0;
+ }
+
+ /**
+ * Run a periodic task
+ */
+ private void runPeriodic() {
+ boolean ok = ScheduledFutureTask.super.runAndReset();
+ boolean down = isShutdown();
+ // Reschedule if not cancelled and not shutdown or policy allows
+ if (ok && (!down ||
+ (getContinueExistingPeriodicTasksAfterShutdownPolicy() &&
+ !isTerminating()))) {
+ long p = period;
+ if (p > 0)
+ time += p;
+ else
+ time = now() - p;
+ ScheduledThreadPoolExecutor.super.getQueue().add(this);
+ }
+ // This might have been the final executed delayed
+ // task. Wake up threads to check.
+ else if (down)
+ interruptIdleWorkers();
+ }
+
+ /**
+ * Overrides FutureTask version so as to reset/requeue if periodic.
+ */
+ public void run() {
+ if (isPeriodic())
+ runPeriodic();
+ else
+ ScheduledFutureTask.super.run();
+ }
+ }
+
+ /**
+ * Specialized variant of ThreadPoolExecutor.execute for delayed tasks.
+ */
+ private void delayedExecute(Runnable command) {
+ if (isShutdown()) {
+ reject(command);
+ return;
+ }
+ // Prestart a thread if necessary. We cannot prestart it
+ // running the task because the task (probably) shouldn't be
+ // run yet, so thread will just idle until delay elapses.
+ if (getPoolSize() < getCorePoolSize())
+ prestartCoreThread();
+
+ super.getQueue().add(command);
+ }
+
+ /**
+ * Cancel and clear the queue of all tasks that should not be run
+ * due to shutdown policy.
+ */
+ private void cancelUnwantedTasks() {
+ boolean keepDelayed = getExecuteExistingDelayedTasksAfterShutdownPolicy();
+ boolean keepPeriodic = getContinueExistingPeriodicTasksAfterShutdownPolicy();
+ if (!keepDelayed && !keepPeriodic)
+ super.getQueue().clear();
+ else if (keepDelayed || keepPeriodic) {
+ Object[] entries = super.getQueue().toArray();
+ for (int i = 0; i < entries.length; ++i) {
+ Object e = entries[i];
+ if (e instanceof ScheduledFutureTask) {
+ ScheduledFutureTask<?> t = (ScheduledFutureTask<?>)e;
+ if (t.isPeriodic()? !keepPeriodic : !keepDelayed)
+ t.cancel(false);
+ }
+ }
+ entries = null;
+ purge();
+ }
+ }
+
+ public boolean remove(Runnable task) {
+ if (!(task instanceof ScheduledFutureTask))
+ return false;
+ return getQueue().remove(task);
+ }
+
+ /**
+ * Creates a new ScheduledThreadPoolExecutor with the given core
+ * pool size.
+ *
+ * @param corePoolSize the number of threads to keep in the pool,
+ * even if they are idle.
+ * @throws IllegalArgumentException if corePoolSize less than or
+ * equal to zero
+ */
+ public ScheduledThreadPoolExecutor(int corePoolSize) {
+ super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
+ new DelayedWorkQueue());
+ }
+
+ /**
+ * Creates a new ScheduledThreadPoolExecutor with the given
+ * initial parameters.
+ *
+ * @param corePoolSize the number of threads to keep in the pool,
+ * even if they are idle.
+ * @param threadFactory the factory to use when the executor
+ * creates a new thread.
+ * @throws NullPointerException if threadFactory is null
+ */
+ public ScheduledThreadPoolExecutor(int corePoolSize,
+ ThreadFactory threadFactory) {
+ super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
+ new DelayedWorkQueue(), threadFactory);
+ }
+
+ /**
+ * Creates a new ScheduledThreadPoolExecutor with the given
+ * initial parameters.
+ *
+ * @param corePoolSize the number of threads to keep in the pool,
+ * even if they are idle.
+ * @param handler the handler to use when execution is blocked
+ * because the thread bounds and queue capacities are reached.
+ * @throws NullPointerException if handler is null
+ */
+ public ScheduledThreadPoolExecutor(int corePoolSize,
+ RejectedExecutionHandler handler) {
+ super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
+ new DelayedWorkQueue(), handler);
+ }
+
+ /**
+ * Creates a new ScheduledThreadPoolExecutor with the given
+ * initial parameters.
+ *
+ * @param corePoolSize the number of threads to keep in the pool,
+ * even if they are idle.
+ * @param threadFactory the factory to use when the executor
+ * creates a new thread.
+ * @param handler the handler to use when execution is blocked
+ * because the thread bounds and queue capacities are reached.
+ * @throws NullPointerException if threadFactory or handler is null
+ */
+ public ScheduledThreadPoolExecutor(int corePoolSize,
+ ThreadFactory threadFactory,
+ RejectedExecutionHandler handler) {
+ super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
+ new DelayedWorkQueue(), threadFactory, handler);
+ }
+
+ public ScheduledFuture<?> schedule(Runnable command,
+ long delay,
+ TimeUnit unit) {
+ if (command == null || unit == null)
+ throw new NullPointerException();
+ long triggerTime = now() + unit.toNanos(delay);
+ ScheduledFutureTask<?> t =
+ new ScheduledFutureTask<Boolean>(command, null, triggerTime);
+ delayedExecute(t);
+ return t;
+ }
+
+ public <V> ScheduledFuture<V> schedule(Callable<V> callable,
+ long delay,
+ TimeUnit unit) {
+ if (callable == null || unit == null)
+ throw new NullPointerException();
+ if (delay < 0) delay = 0;
+ long triggerTime = now() + unit.toNanos(delay);
+ ScheduledFutureTask<V> t =
+ new ScheduledFutureTask<V>(callable, triggerTime);
+ delayedExecute(t);
+ return t;
+ }
+
+ public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
+ long initialDelay,
+ long period,
+ TimeUnit unit) {
+ if (command == null || unit == null)
+ throw new NullPointerException();
+ if (period <= 0)
+ throw new IllegalArgumentException();
+ if (initialDelay < 0) initialDelay = 0;
+ long triggerTime = now() + unit.toNanos(initialDelay);
+ ScheduledFutureTask<?> t =
+ new ScheduledFutureTask<Object>(command,
+ null,
+ triggerTime,
+ unit.toNanos(period));
+ delayedExecute(t);
+ return t;
+ }
+
+ public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
+ long initialDelay,
+ long delay,
+ TimeUnit unit) {
+ if (command == null || unit == null)
+ throw new NullPointerException();
+ if (delay <= 0)
+ throw new IllegalArgumentException();
+ if (initialDelay < 0) initialDelay = 0;
+ long triggerTime = now() + unit.toNanos(initialDelay);
+ ScheduledFutureTask<?> t =
+ new ScheduledFutureTask<Boolean>(command,
+ null,
+ triggerTime,
+ unit.toNanos(-delay));
+ delayedExecute(t);
+ return t;
+ }
+
+
+ /**
+ * Execute command with zero required delay. This has effect
+ * equivalent to <tt>schedule(command, 0, anyUnit)</tt>. Note
+ * that inspections of the queue and of the list returned by
+ * <tt>shutdownNow</tt> will access the zero-delayed
+ * {@link ScheduledFuture}, not the <tt>command</tt> itself.
+ *
+ * @param command the task to execute
+ * @throws RejectedExecutionException at discretion of
+ * <tt>RejectedExecutionHandler</tt>, if task cannot be accepted
+ * for execution because the executor has been shut down.
+ * @throws NullPointerException if command is null
+ */
+ public void execute(Runnable command) {
+ if (command == null)
+ throw new NullPointerException();
+ schedule(command, 0, TimeUnit.NANOSECONDS);
+ }
+
+ // Override AbstractExecutorService methods
+
+ public Future<?> submit(Runnable task) {
+ return schedule(task, 0, TimeUnit.NANOSECONDS);
+ }
+
+ public <T> Future<T> submit(Runnable task, T result) {
+ return schedule(Executors.callable(task, result),
+ 0, TimeUnit.NANOSECONDS);
+ }
+
+ public <T> Future<T> submit(Callable<T> task) {
+ return schedule(task, 0, TimeUnit.NANOSECONDS);
+ }
+
+ /**
+ * Set policy on whether to continue executing existing periodic
+ * tasks even when this executor has been <tt>shutdown</tt>. In
+ * this case, these tasks will only terminate upon
+ * <tt>shutdownNow</tt>, or after setting the policy to
+ * <tt>false</tt> when already shutdown. This value is by default
+ * false.
+ * @param value if true, continue after shutdown, else don't.
+ * @see #getExecuteExistingDelayedTasksAfterShutdownPolicy
+ */
+ public void setContinueExistingPeriodicTasksAfterShutdownPolicy(boolean value) {
+ continueExistingPeriodicTasksAfterShutdown = value;
+ if (!value && isShutdown())
+ cancelUnwantedTasks();
+ }
+
+ /**
+ * Get the policy on whether to continue executing existing
+ * periodic tasks even when this executor has been
+ * <tt>shutdown</tt>. In this case, these tasks will only
+ * terminate upon <tt>shutdownNow</tt> or after setting the policy
+ * to <tt>false</tt> when already shutdown. This value is by
+ * default false.
+ * @return true if will continue after shutdown.
+ * @see #setContinueExistingPeriodicTasksAfterShutdownPolicy
+ */
+ public boolean getContinueExistingPeriodicTasksAfterShutdownPolicy() {
+ return continueExistingPeriodicTasksAfterShutdown;
+ }
+
+ /**
+ * Set policy on whether to execute existing delayed
+ * tasks even when this executor has been <tt>shutdown</tt>. In
+ * this case, these tasks will only terminate upon
+ * <tt>shutdownNow</tt>, or after setting the policy to
+ * <tt>false</tt> when already shutdown. This value is by default
+ * true.
+ * @param value if true, execute after shutdown, else don't.
+ * @see #getExecuteExistingDelayedTasksAfterShutdownPolicy
+ */
+ public void setExecuteExistingDelayedTasksAfterShutdownPolicy(boolean value) {
+ executeExistingDelayedTasksAfterShutdown = value;
+ if (!value && isShutdown())
+ cancelUnwantedTasks();
+ }
+
+ /**
+ * Get policy on whether to execute existing delayed
+ * tasks even when this executor has been <tt>shutdown</tt>. In
+ * this case, these tasks will only terminate upon
+ * <tt>shutdownNow</tt>, or after setting the policy to
+ * <tt>false</tt> when already shutdown. This value is by default
+ * true.
+ * @return true if will execute after shutdown.
+ * @see #setExecuteExistingDelayedTasksAfterShutdownPolicy
+ */
+ public boolean getExecuteExistingDelayedTasksAfterShutdownPolicy() {
+ return executeExistingDelayedTasksAfterShutdown;
+ }
+
+
+ /**
+ * Initiates an orderly shutdown in which previously submitted
+ * tasks are executed, but no new tasks will be accepted. If the
+ * <tt>ExecuteExistingDelayedTasksAfterShutdownPolicy</tt> has
+ * been set <tt>false</tt>, existing delayed tasks whose delays
+ * have not yet elapsed are cancelled. And unless the
+ * <tt>ContinueExistingPeriodicTasksAfterShutdownPolicy</tt> has
+ * been set <tt>true</tt>, future executions of existing periodic
+ * tasks will be cancelled.
+ */
+ public void shutdown() {
+ cancelUnwantedTasks();
+ super.shutdown();
+ }
+
+ /**
+ * Attempts to stop all actively executing tasks, halts the
+ * processing of waiting tasks, and returns a list of the tasks that were
+ * awaiting execution.
+ *
+ * <p>There are no guarantees beyond best-effort attempts to stop
+ * processing actively executing tasks. This implementation
+ * cancels tasks via {@link Thread#interrupt}, so if any tasks mask or
+ * fail to respond to interrupts, they may never terminate.
+ *
+ * @return list of tasks that never commenced execution. Each
+ * element of this list is a {@link ScheduledFuture},
+ * including those tasks submitted using <tt>execute</tt>, which
+ * are for scheduling purposes used as the basis of a zero-delay
+ * <tt>ScheduledFuture</tt>.
+ */
+ public List<Runnable> shutdownNow() {
+ return super.shutdownNow();
+ }
+
+ /**
+ * Returns the task queue used by this executor. Each element of
+ * this queue is a {@link ScheduledFuture}, including those
+ * tasks submitted using <tt>execute</tt> which are for scheduling
+ * purposes used as the basis of a zero-delay
+ * <tt>ScheduledFuture</tt>. Iteration over this queue is
+ * <em>not</em> guaranteed to traverse tasks in the order in
+ * which they will execute.
+ *
+ * @return the task queue
+ */
+ public BlockingQueue<Runnable> getQueue() {
+ return super.getQueue();
+ }
+
+ /**
+ * An annoying wrapper class to convince generics compiler to
+ * use a DelayQueue<ScheduledFutureTask> as a BlockingQueue<Runnable>
+ */
+ private static class DelayedWorkQueue
+ extends AbstractCollection<Runnable>
+ implements BlockingQueue<Runnable> {
+
+ private final DelayQueue<ScheduledFutureTask> dq = new DelayQueue<ScheduledFutureTask>();
+ public Runnable poll() { return dq.poll(); }
+ public Runnable peek() { return dq.peek(); }
+ public Runnable take() throws InterruptedException { return dq.take(); }
+ public Runnable poll(long timeout, TimeUnit unit) throws InterruptedException {
+ return dq.poll(timeout, unit);
+ }
+
+ public boolean add(Runnable x) { return dq.add((ScheduledFutureTask)x); }
+ public boolean offer(Runnable x) { return dq.offer((ScheduledFutureTask)x); }
+ public void put(Runnable x) {
+ dq.put((ScheduledFutureTask)x);
+ }
+ public boolean offer(Runnable x, long timeout, TimeUnit unit) {
+ return dq.offer((ScheduledFutureTask)x, timeout, unit);
+ }
+
+ public Runnable remove() { return dq.remove(); }
+ public Runnable element() { return dq.element(); }
+ public void clear() { dq.clear(); }
+ public int drainTo(Collection<? super Runnable> c) { return dq.drainTo(c); }
+ public int drainTo(Collection<? super Runnable> c, int maxElements) {
+ return dq.drainTo(c, maxElements);
+ }
+
+ public int remainingCapacity() { return dq.remainingCapacity(); }
+ public boolean remove(Object x) { return dq.remove(x); }
+ public boolean contains(Object x) { return dq.contains(x); }
+ public int size() { return dq.size(); }
+ public boolean isEmpty() { return dq.isEmpty(); }
+ public Object[] toArray() { return dq.toArray(); }
+ public <T> T[] toArray(T[] array) { return dq.toArray(array); }
+ public Iterator<Runnable> iterator() {
+ return new Iterator<Runnable>() {
+ private Iterator<ScheduledFutureTask> it = dq.iterator();
+ public boolean hasNext() { return it.hasNext(); }
+ public Runnable next() { return it.next(); }
+ public void remove() { it.remove(); }
+ };
+ }
+ }
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/Semaphore.java b/concurrent/src/main/java/java/util/concurrent/Semaphore.java
new file mode 100644
index 0000000..6eb80bc
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/Semaphore.java
@@ -0,0 +1,665 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+import java.util.*;
+import java.util.concurrent.locks.*;
+import java.util.concurrent.atomic.*;
+
+/**
+ * A counting semaphore. Conceptually, a semaphore maintains a set of
+ * permits. Each {@link #acquire} blocks if necessary until a permit is
+ * available, and then takes it. Each {@link #release} adds a permit,
+ * potentially releasing a blocking acquirer.
+ * However, no actual permit objects are used; the <tt>Semaphore</tt> just
+ * keeps a count of the number available and acts accordingly.
+ *
+ * <p>Semaphores are often used to restrict the number of threads than can
+ * access some (physical or logical) resource. For example, here is
+ * a class that uses a semaphore to control access to a pool of items:
+ * <pre>
+ * class Pool {
+ * private static final MAX_AVAILABLE = 100;
+ * private final Semaphore available = new Semaphore(MAX_AVAILABLE, true);
+ *
+ * public Object getItem() throws InterruptedException {
+ * available.acquire();
+ * return getNextAvailableItem();
+ * }
+ *
+ * public void putItem(Object x) {
+ * if (markAsUnused(x))
+ * available.release();
+ * }
+ *
+ * // Not a particularly efficient data structure; just for demo
+ *
+ * protected Object[] items = ... whatever kinds of items being managed
+ * protected boolean[] used = new boolean[MAX_AVAILABLE];
+ *
+ * protected synchronized Object getNextAvailableItem() {
+ * for (int i = 0; i < MAX_AVAILABLE; ++i) {
+ * if (!used[i]) {
+ * used[i] = true;
+ * return items[i];
+ * }
+ * }
+ * return null; // not reached
+ * }
+ *
+ * protected synchronized boolean markAsUnused(Object item) {
+ * for (int i = 0; i < MAX_AVAILABLE; ++i) {
+ * if (item == items[i]) {
+ * if (used[i]) {
+ * used[i] = false;
+ * return true;
+ * } else
+ * return false;
+ * }
+ * }
+ * return false;
+ * }
+ *
+ * }
+ * </pre>
+ *
+ * <p>Before obtaining an item each thread must acquire a permit from
+ * the semaphore, guaranteeing that an item is available for use. When
+ * the thread has finished with the item it is returned back to the
+ * pool and a permit is returned to the semaphore, allowing another
+ * thread to acquire that item. Note that no synchronization lock is
+ * held when {@link #acquire} is called as that would prevent an item
+ * from being returned to the pool. The semaphore encapsulates the
+ * synchronization needed to restrict access to the pool, separately
+ * from any synchronization needed to maintain the consistency of the
+ * pool itself.
+ *
+ * <p>A semaphore initialized to one, and which is used such that it
+ * only has at most one permit available, can serve as a mutual
+ * exclusion lock. This is more commonly known as a <em>binary
+ * semaphore</em>, because it only has two states: one permit
+ * available, or zero permits available. When used in this way, the
+ * binary semaphore has the property (unlike many {@link Lock}
+ * implementations), that the &quot;lock&quot; can be released by a
+ * thread other than the owner (as semaphores have no notion of
+ * ownership). This can be useful in some specialized contexts, such
+ * as deadlock recovery.
+ *
+ * <p> The constructor for this class optionally accepts a
+ * <em>fairness</em> parameter. When set false, this class makes no
+ * guarantees about the order in which threads acquire permits. In
+ * particular, <em>barging</em> is permitted, that is, a thread
+ * invoking {@link #acquire} can be allocated a permit ahead of a
+ * thread that has been waiting. When fairness is set true, the
+ * semaphore guarantees that threads invoking any of the {@link
+ * #acquire() acquire} methods are allocated permits in the order in
+ * which their invocation of those methods was processed
+ * (first-in-first-out; FIFO). Note that FIFO ordering necessarily
+ * applies to specific internal points of execution within these
+ * methods. So, it is possible for one thread to invoke
+ * <tt>acquire</tt> before another, but reach the ordering point after
+ * the other, and similarly upon return from the method.
+ *
+ * <p>Generally, semaphores used to control resource access should be
+ * initialized as fair, to ensure that no thread is starved out from
+ * accessing a resource. When using semaphores for other kinds of
+ * synchronization control, the throughput advantages of non-fair
+ * ordering often outweigh fairness considerations.
+ *
+ * <p>This class also provides convenience methods to {@link
+ * #acquire(int) acquire} and {@link #release(int) release} multiple
+ * permits at a time. Beware of the increased risk of indefinite
+ * postponement when these methods are used without fairness set true.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ *
+ */
+
+public class Semaphore implements java.io.Serializable {
+ private static final long serialVersionUID = -3222578661600680210L;
+ /** All mechanics via AbstractQueuedSynchronizer subclass */
+ private final Sync sync;
+
+ /**
+ * Synchronization implementation for semaphore. Uses AQS state
+ * to represent permits. Subclassed into fair and nonfair
+ * versions.
+ */
+ abstract static class Sync extends AbstractQueuedSynchronizer {
+ Sync(int permits) {
+ setState(permits);
+ }
+
+ final int getPermits() {
+ return getState();
+ }
+
+ final int nonfairTryAcquireShared(int acquires) {
+ for (;;) {
+ int available = getState();
+ int remaining = available - acquires;
+ if (remaining < 0 ||
+ compareAndSetState(available, remaining))
+ return remaining;
+ }
+ }
+
+ protected final boolean tryReleaseShared(int releases) {
+ for (;;) {
+ int p = getState();
+ if (compareAndSetState(p, p + releases))
+ return true;
+ }
+ }
+
+ final void reducePermits(int reductions) {
+ for (;;) {
+ int current = getState();
+ int next = current - reductions;
+ if (compareAndSetState(current, next))
+ return;
+ }
+ }
+
+ final int drainPermits() {
+ for (;;) {
+ int current = getState();
+ if (current == 0 || compareAndSetState(current, 0))
+ return current;
+ }
+ }
+ }
+
+ /**
+ * NonFair version
+ */
+ final static class NonfairSync extends Sync {
+ NonfairSync(int permits) {
+ super(permits);
+ }
+
+ protected int tryAcquireShared(int acquires) {
+ return nonfairTryAcquireShared(acquires);
+ }
+ }
+
+ /**
+ * Fair version
+ */
+ final static class FairSync extends Sync {
+ FairSync(int permits) {
+ super(permits);
+ }
+
+ protected int tryAcquireShared(int acquires) {
+ Thread current = Thread.currentThread();
+ for (;;) {
+ Thread first = getFirstQueuedThread();
+ if (first != null && first != current)
+ return -1;
+ int available = getState();
+ int remaining = available - acquires;
+ if (remaining < 0 ||
+ compareAndSetState(available, remaining))
+ return remaining;
+ }
+ }
+ }
+
+ /**
+ * Creates a <tt>Semaphore</tt> with the given number of
+ * permits and nonfair fairness setting.
+ * @param permits the initial number of permits available. This
+ * value may be negative, in which case releases must
+ * occur before any acquires will be granted.
+ */
+ public Semaphore(int permits) {
+ sync = new NonfairSync(permits);
+ }
+
+ /**
+ * Creates a <tt>Semaphore</tt> with the given number of
+ * permits and the given fairness setting.
+ * @param permits the initial number of permits available. This
+ * value may be negative, in which case releases must
+ * occur before any acquires will be granted.
+ * @param fair true if this semaphore will guarantee first-in
+ * first-out granting of permits under contention, else false.
+ */
+ public Semaphore(int permits, boolean fair) {
+ sync = (fair)? new FairSync(permits) : new NonfairSync(permits);
+ }
+
+ /**
+ * Acquires a permit from this semaphore, blocking until one is
+ * available, or the thread is {@link Thread#interrupt interrupted}.
+ *
+ * <p>Acquires a permit, if one is available and returns immediately,
+ * reducing the number of available permits by one.
+ * <p>If no permit is available then the current thread becomes
+ * disabled for thread scheduling purposes and lies dormant until
+ * one of two things happens:
+ * <ul>
+ * <li>Some other thread invokes the {@link #release} method for this
+ * semaphore and the current thread is next to be assigned a permit; or
+ * <li>Some other thread {@link Thread#interrupt interrupts} the current
+ * thread.
+ * </ul>
+ *
+ * <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
+ * for a permit,
+ * </ul>
+ * then {@link InterruptedException} is thrown and the current thread's
+ * interrupted status is cleared.
+ *
+ * @throws InterruptedException if the current thread is interrupted
+ *
+ * @see Thread#interrupt
+ */
+ public void acquire() throws InterruptedException {
+ sync.acquireSharedInterruptibly(1);
+ }
+
+ /**
+ * Acquires a permit from this semaphore, blocking until one is
+ * available.
+ *
+ * <p>Acquires a permit, if one is available and returns immediately,
+ * reducing the number of available permits by one.
+ * <p>If no permit is available then the current thread becomes
+ * disabled for thread scheduling purposes and lies dormant until
+ * some other thread invokes the {@link #release} method for this
+ * semaphore and the current thread is next to be assigned a permit.
+ *
+ * <p>If the current thread
+ * is {@link Thread#interrupt interrupted} while waiting
+ * for a permit then it will continue to wait, but the time at which
+ * the thread is assigned a permit may change compared to the time it
+ * would have received the permit had no interruption occurred. When the
+ * thread does return from this method its interrupt status will be set.
+ *
+ */
+ public void acquireUninterruptibly() {
+ sync.acquireShared(1);
+ }
+
+ /**
+ * Acquires a permit from this semaphore, only if one is available at the
+ * time of invocation.
+ * <p>Acquires a permit, if one is available and returns immediately,
+ * with the value <tt>true</tt>,
+ * reducing the number of available permits by one.
+ *
+ * <p>If no permit is available then this method will return
+ * immediately with the value <tt>false</tt>.
+ *
+ * <p>Even when this semaphore has been set to use a
+ * fair ordering policy, a call to <tt>tryAcquire()</tt> <em>will</em>
+ * immediately acquire a permit if one is available, whether or not
+ * other threads are currently waiting.
+ * This &quot;barging&quot; behavior can be useful in certain
+ * circumstances, even though it breaks fairness. If you want to honor
+ * the fairness setting, then use
+ * {@link #tryAcquire(long, TimeUnit) tryAcquire(0, TimeUnit.SECONDS) }
+ * which is almost equivalent (it also detects interruption).
+ *
+ * @return <tt>true</tt> if a permit was acquired and <tt>false</tt>
+ * otherwise.
+ */
+ public boolean tryAcquire() {
+ return sync.nonfairTryAcquireShared(1) >= 0;
+ }
+
+ /**
+ * Acquires a permit from this semaphore, if one becomes available
+ * within the given waiting time and the
+ * current thread has not been {@link Thread#interrupt interrupted}.
+ * <p>Acquires a permit, if one is available and returns immediately,
+ * with the value <tt>true</tt>,
+ * reducing the number of available permits by one.
+ * <p>If no permit is available then
+ * the current thread becomes disabled for thread scheduling
+ * purposes and lies dormant until one of three things happens:
+ * <ul>
+ * <li>Some other thread invokes the {@link #release} method for this
+ * semaphore and the current thread is next to be assigned a permit; or
+ * <li>Some other thread {@link Thread#interrupt interrupts} the current
+ * thread; or
+ * <li>The specified waiting time elapses.
+ * </ul>
+ * <p>If a permit is acquired then the value <tt>true</tt> is returned.
+ * <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 to acquire
+ * a permit,
+ * </ul>
+ * then {@link InterruptedException} is thrown and the current thread's
+ * interrupted status is cleared.
+ * <p>If the specified waiting time elapses then the value <tt>false</tt>
+ * is returned.
+ * If the time is less than or equal to zero, the method will not wait
+ * at all.
+ *
+ * @param timeout the maximum time to wait for a permit
+ * @param unit the time unit of the <tt>timeout</tt> argument.
+ * @return <tt>true</tt> if a permit was acquired and <tt>false</tt>
+ * if the waiting time elapsed before a permit was acquired.
+ *
+ * @throws InterruptedException if the current thread is interrupted
+ *
+ * @see Thread#interrupt
+ *
+ */
+ public boolean tryAcquire(long timeout, TimeUnit unit)
+ throws InterruptedException {
+ return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
+ }
+
+ /**
+ * Releases a permit, returning it to the semaphore.
+ * <p>Releases a permit, increasing the number of available permits
+ * by one.
+ * If any threads are blocking trying to acquire a permit, then one
+ * is selected and given the permit that was just released.
+ * That thread is re-enabled for thread scheduling purposes.
+ * <p>There is no requirement that a thread that releases a permit must
+ * have acquired that permit by calling {@link #acquire}.
+ * Correct usage of a semaphore is established by programming convention
+ * in the application.
+ */
+ public void release() {
+ sync.releaseShared(1);
+ }
+
+ /**
+ * Acquires the given number of permits from this semaphore,
+ * blocking until all are available,
+ * or the thread is {@link Thread#interrupt interrupted}.
+ *
+ * <p>Acquires the given number of permits, if they are available,
+ * and returns immediately,
+ * reducing the number of available permits by the given amount.
+ *
+ * <p>If insufficient permits are available then the current thread becomes
+ * disabled for thread scheduling purposes and lies dormant until
+ * one of two things happens:
+ * <ul>
+ * <li>Some other thread invokes one of the {@link #release() release}
+ * methods for this semaphore, the current thread is next to be assigned
+ * permits and the number of available permits satisfies this request; or
+ * <li>Some other thread {@link Thread#interrupt interrupts} the current
+ * thread.
+ * </ul>
+ *
+ * <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
+ * for a permit,
+ * </ul>
+ * then {@link InterruptedException} is thrown and the current thread's
+ * interrupted status is cleared.
+ * Any permits that were to be assigned to this thread are instead
+ * assigned to the next waiting thread(s), as if
+ * they had been made available by a call to {@link #release()}.
+ *
+ * @param permits the number of permits to acquire
+ *
+ * @throws InterruptedException if the current thread is interrupted
+ * @throws IllegalArgumentException if permits less than zero.
+ *
+ * @see Thread#interrupt
+ */
+ public void acquire(int permits) throws InterruptedException {
+ if (permits < 0) throw new IllegalArgumentException();
+ sync.acquireSharedInterruptibly(permits);
+ }
+
+ /**
+ * Acquires the given number of permits from this semaphore,
+ * blocking until all are available.
+ *
+ * <p>Acquires the given number of permits, if they are available,
+ * and returns immediately,
+ * reducing the number of available permits by the given amount.
+ *
+ * <p>If insufficient permits are available then the current thread becomes
+ * disabled for thread scheduling purposes and lies dormant until
+ * some other thread invokes one of the {@link #release() release}
+ * methods for this semaphore, the current thread is next to be assigned
+ * permits and the number of available permits satisfies this request.
+ *
+ * <p>If the current thread
+ * is {@link Thread#interrupt interrupted} while waiting
+ * for permits then it will continue to wait and its position in the
+ * queue is not affected. When the
+ * thread does return from this method its interrupt status will be set.
+ *
+ * @param permits the number of permits to acquire
+ * @throws IllegalArgumentException if permits less than zero.
+ *
+ */
+ public void acquireUninterruptibly(int permits) {
+ if (permits < 0) throw new IllegalArgumentException();
+ sync.acquireShared(permits);
+ }
+
+ /**
+ * Acquires the given number of permits from this semaphore, only
+ * if all are available at the time of invocation.
+ *
+ * <p>Acquires the given number of permits, if they are available, and
+ * returns immediately, with the value <tt>true</tt>,
+ * reducing the number of available permits by the given amount.
+ *
+ * <p>If insufficient permits are available then this method will return
+ * immediately with the value <tt>false</tt> and the number of available
+ * permits is unchanged.
+ *
+ * <p>Even when this semaphore has been set to use a fair ordering
+ * policy, a call to <tt>tryAcquire</tt> <em>will</em>
+ * immediately acquire a permit if one is available, whether or
+ * not other threads are currently waiting. This
+ * &quot;barging&quot; behavior can be useful in certain
+ * circumstances, even though it breaks fairness. If you want to
+ * honor the fairness setting, then use {@link #tryAcquire(int,
+ * long, TimeUnit) tryAcquire(permits, 0, TimeUnit.SECONDS) }
+ * which is almost equivalent (it also detects interruption).
+ *
+ * @param permits the number of permits to acquire
+ *
+ * @return <tt>true</tt> if the permits were acquired and <tt>false</tt>
+ * otherwise.
+ * @throws IllegalArgumentException if permits less than zero.
+ */
+ public boolean tryAcquire(int permits) {
+ if (permits < 0) throw new IllegalArgumentException();
+ return sync.nonfairTryAcquireShared(permits) >= 0;
+ }
+
+ /**
+ * Acquires the given number of permits from this semaphore, if all
+ * become available within the given waiting time and the
+ * current thread has not been {@link Thread#interrupt interrupted}.
+ * <p>Acquires the given number of permits, if they are available and
+ * returns immediately, with the value <tt>true</tt>,
+ * reducing the number of available permits by the given amount.
+ * <p>If insufficient permits are available then
+ * the current thread becomes disabled for thread scheduling
+ * purposes and lies dormant until one of three things happens:
+ * <ul>
+ * <li>Some other thread invokes one of the {@link #release() release}
+ * methods for this semaphore, the current thread is next to be assigned
+ * permits and the number of available permits satisfies this request; or
+ * <li>Some other thread {@link Thread#interrupt interrupts} the current
+ * thread; or
+ * <li>The specified waiting time elapses.
+ * </ul>
+ * <p>If the permits are acquired then the value <tt>true</tt> is returned.
+ * <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 to acquire
+ * the permits,
+ * </ul>
+ * then {@link InterruptedException} is thrown and the current thread's
+ * interrupted status is cleared.
+ * Any permits that were to be assigned to this thread, are instead
+ * assigned to the next waiting thread(s), as if
+ * they had been made available by a call to {@link #release()}.
+ *
+ * <p>If the specified waiting time elapses then the value <tt>false</tt>
+ * is returned.
+ * If the time is
+ * less than or equal to zero, the method will not wait at all.
+ * Any permits that were to be assigned to this thread, are instead
+ * assigned to the next waiting thread(s), as if
+ * they had been made available by a call to {@link #release()}.
+ *
+ * @param permits the number of permits to acquire
+ * @param timeout the maximum time to wait for the permits
+ * @param unit the time unit of the <tt>timeout</tt> argument.
+ * @return <tt>true</tt> if all permits were acquired and <tt>false</tt>
+ * if the waiting time elapsed before all permits were acquired.
+ *
+ * @throws InterruptedException if the current thread is interrupted
+ * @throws IllegalArgumentException if permits less than zero.
+ *
+ * @see Thread#interrupt
+ *
+ */
+ public boolean tryAcquire(int permits, long timeout, TimeUnit unit)
+ throws InterruptedException {
+ if (permits < 0) throw new IllegalArgumentException();
+ return sync.tryAcquireSharedNanos(permits, unit.toNanos(timeout));
+ }
+
+ /**
+ * Releases the given number of permits, returning them to the semaphore.
+ * <p>Releases the given number of permits, increasing the number of
+ * available permits by that amount.
+ * If any threads are blocking trying to acquire permits, then the
+ * one that has been waiting the longest
+ * is selected and given the permits that were just released.
+ * If the number of available permits satisfies that thread's request
+ * then that thread is re-enabled for thread scheduling purposes; otherwise
+ * the thread continues to wait. If there are still permits available
+ * after the first thread's request has been satisfied, then those permits
+ * are assigned to the next waiting thread. If it is satisfied then it is
+ * re-enabled for thread scheduling purposes. This continues until there
+ * are insufficient permits to satisfy the next waiting thread, or there
+ * are no more waiting threads.
+ *
+ * <p>There is no requirement that a thread that releases a permit must
+ * have acquired that permit by calling {@link Semaphore#acquire acquire}.
+ * Correct usage of a semaphore is established by programming convention
+ * in the application.
+ *
+ * @param permits the number of permits to release
+ * @throws IllegalArgumentException if permits less than zero.
+ */
+ public void release(int permits) {
+ if (permits < 0) throw new IllegalArgumentException();
+ sync.releaseShared(permits);
+ }
+
+ /**
+ * Returns the current number of permits available in this semaphore.
+ * <p>This method is typically used for debugging and testing purposes.
+ * @return the number of permits available in this semaphore.
+ */
+ public int availablePermits() {
+ return sync.getPermits();
+ }
+
+ /**
+ * Acquire and return all permits that are immediately available.
+ * @return the number of permits
+ */
+ public int drainPermits() {
+ return sync.drainPermits();
+ }
+
+ /**
+ * Shrinks the number of available permits by the indicated
+ * reduction. This method can be useful in subclasses that use
+ * semaphores to track resources that become unavailable. This
+ * method differs from <tt>acquire</tt> in that it does not block
+ * waiting for permits to become available.
+ * @param reduction the number of permits to remove
+ * @throws IllegalArgumentException if reduction is negative
+ */
+ protected void reducePermits(int reduction) {
+ if (reduction < 0) throw new IllegalArgumentException();
+ sync.reducePermits(reduction);
+ }
+
+ /**
+ * Returns true if this semaphore has fairness set true.
+ * @return true if this semaphore has fairness set true.
+ */
+ public boolean isFair() {
+ return sync instanceof FairSync;
+ }
+
+ /**
+ * Queries whether any threads are waiting to acquire. Note that
+ * because cancellations may occur at any time, a <tt>true</tt>
+ * return does not guarantee that any other thread will ever
+ * acquire. This method is designed primarily for use in
+ * monitoring of the system state.
+ *
+ * @return true if there may be other threads waiting to acquire
+ * the lock.
+ */
+ public final boolean hasQueuedThreads() {
+ return sync.hasQueuedThreads();
+ }
+
+ /**
+ * Returns an estimate of the number of threads waiting to
+ * acquire. The value is only an estimate because the number of
+ * threads may change dynamically while this method traverses
+ * internal data structures. This method is designed for use in
+ * monitoring of the system state, not for synchronization
+ * control.
+ * @return the estimated number of threads waiting for this lock
+ */
+ public final int getQueueLength() {
+ return sync.getQueueLength();
+ }
+
+ /**
+ * Returns a collection containing threads that may be waiting to
+ * acquire. Because the actual set of threads may change
+ * dynamically while constructing this result, the returned
+ * collection is only a best-effort estimate. The elements of the
+ * returned collection are in no particular order. This method is
+ * designed to facilitate construction of subclasses that provide
+ * more extensive monitoring facilities.
+ * @return the collection of threads
+ */
+ protected Collection<Thread> getQueuedThreads() {
+ return sync.getQueuedThreads();
+ }
+
+ /**
+ * Returns a string identifying this semaphore, as well as its state.
+ * The state, in brackets, includes the String
+ * &quot;Permits =&quot; followed by the number of permits.
+ * @return a string identifying this semaphore, as well as its
+ * state
+ */
+ public String toString() {
+ return super.toString() + "[Permits = " + sync.getPermits() + "]";
+ }
+
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/SynchronousQueue.java b/concurrent/src/main/java/java/util/concurrent/SynchronousQueue.java
new file mode 100644
index 0000000..811dc38
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/SynchronousQueue.java
@@ -0,0 +1,684 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+import java.util.concurrent.locks.*;
+import java.util.*;
+
+// BEGIN android-note
+// removed link to collections framework docs
+// END android-note
+
+/**
+ * A {@linkplain BlockingQueue blocking queue} in which each
+ * <tt>put</tt> must wait for a <tt>take</tt>, and vice versa. A
+ * synchronous queue does not have any internal capacity, not even a
+ * capacity of one. You cannot <tt>peek</tt> at a synchronous queue
+ * because an element is only present when you try to take it; you
+ * cannot add an element (using any method) unless another thread is
+ * trying to remove it; you cannot iterate as there is nothing to
+ * iterate. The <em>head</em> of the queue is the element that the
+ * first queued thread is trying to add to the queue; if there are no
+ * queued threads then no element is being added and the head is
+ * <tt>null</tt>. For purposes of other <tt>Collection</tt> methods
+ * (for example <tt>contains</tt>), a <tt>SynchronousQueue</tt> acts
+ * as an empty collection. This queue does not permit <tt>null</tt>
+ * elements.
+ *
+ * <p>Synchronous queues are similar to rendezvous channels used in
+ * CSP and Ada. They are well suited for handoff designs, in which an
+ * object running in one thread must sync up with an object running
+ * in another thread in order to hand it some information, event, or
+ * task.
+ *
+ * <p> This class supports an optional fairness policy for ordering
+ * waiting producer and consumer threads. By default, this ordering
+ * is not guaranteed. However, a queue constructed with fairness set
+ * to <tt>true</tt> grants threads access in FIFO order. Fairness
+ * generally decreases throughput but reduces variability and avoids
+ * starvation.
+ *
+ * <p>This class implements all of the <em>optional</em> methods
+ * of the {@link Collection} and {@link Iterator} interfaces.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ * @param <E> the type of elements held in this collection
+ */
+public class SynchronousQueue<E> extends AbstractQueue<E>
+ implements BlockingQueue<E>, java.io.Serializable {
+ private static final long serialVersionUID = -3223113410248163686L;
+
+ /*
+ This implementation divides actions into two cases for puts:
+
+ * An arriving producer that does not already have a waiting consumer
+ creates a node holding item, and then waits for a consumer to take it.
+ * An arriving producer that does already have a waiting consumer fills
+ the slot node created by the consumer, and notifies it to continue.
+
+ And symmetrically, two for takes:
+
+ * An arriving consumer that does not already have a waiting producer
+ creates an empty slot node, and then waits for a producer to fill it.
+ * An arriving consumer that does already have a waiting producer takes
+ item from the node created by the producer, and notifies it to continue.
+
+ When a put or take waiting for the actions of its counterpart
+ aborts due to interruption or timeout, it marks the node
+ it created as "CANCELLED", which causes its counterpart to retry
+ the entire put or take sequence.
+
+ This requires keeping two simple queues, waitingProducers and
+ waitingConsumers. Each of these can be FIFO (preserves fairness)
+ or LIFO (improves throughput).
+ */
+
+ /** Lock protecting both wait queues */
+ private final ReentrantLock qlock;
+ /** Queue holding waiting puts */
+ private final WaitQueue waitingProducers;
+ /** Queue holding waiting takes */
+ private final WaitQueue waitingConsumers;
+
+ /**
+ * Creates a <tt>SynchronousQueue</tt> with nonfair access policy.
+ */
+ public SynchronousQueue() {
+ this(false);
+ }
+
+ /**
+ * Creates a <tt>SynchronousQueue</tt> with specified fairness policy.
+ * @param fair if true, threads contend in FIFO order for access;
+ * otherwise the order is unspecified.
+ */
+ public SynchronousQueue(boolean fair) {
+ if (fair) {
+ qlock = new ReentrantLock(true);
+ waitingProducers = new FifoWaitQueue();
+ waitingConsumers = new FifoWaitQueue();
+ }
+ else {
+ qlock = new ReentrantLock();
+ waitingProducers = new LifoWaitQueue();
+ waitingConsumers = new LifoWaitQueue();
+ }
+ }
+
+ /**
+ * Queue to hold waiting puts/takes; specialized to Fifo/Lifo below.
+ * These queues have all transient fields, but are serializable
+ * in order to recover fairness settings when deserialized.
+ */
+ static abstract class WaitQueue implements java.io.Serializable {
+ /** Create, add, and return node for x */
+ abstract Node enq(Object x);
+ /** Remove and return node, or null if empty */
+ abstract Node deq();
+ }
+
+ /**
+ * FIFO queue to hold waiting puts/takes.
+ */
+ static final class FifoWaitQueue extends WaitQueue implements java.io.Serializable {
+ private static final long serialVersionUID = -3623113410248163686L;
+ private transient Node head;
+ private transient Node last;
+
+ Node enq(Object x) {
+ Node p = new Node(x);
+ if (last == null)
+ last = head = p;
+ else
+ last = last.next = p;
+ return p;
+ }
+
+ Node deq() {
+ Node p = head;
+ if (p != null) {
+ if ((head = p.next) == null)
+ last = null;
+ p.next = null;
+ }
+ return p;
+ }
+ }
+
+ /**
+ * LIFO queue to hold waiting puts/takes.
+ */
+ static final class LifoWaitQueue extends WaitQueue implements java.io.Serializable {
+ private static final long serialVersionUID = -3633113410248163686L;
+ private transient Node head;
+
+ Node enq(Object x) {
+ return head = new Node(x, head);
+ }
+
+ Node deq() {
+ Node p = head;
+ if (p != null) {
+ head = p.next;
+ p.next = null;
+ }
+ return p;
+ }
+ }
+
+ /**
+ * Nodes each maintain an item and handle waits and signals for
+ * getting and setting it. The class extends
+ * AbstractQueuedSynchronizer to manage blocking, using AQS state
+ * 0 for waiting, 1 for ack, -1 for cancelled.
+ */
+ static final class Node extends AbstractQueuedSynchronizer {
+ /** Synchronization state value representing that node acked */
+ private static final int ACK = 1;
+ /** Synchronization state value representing that node cancelled */
+ private static final int CANCEL = -1;
+
+ /** The item being transferred */
+ Object item;
+ /** Next node in wait queue */
+ Node next;
+
+ /** Creates a node with initial item */
+ Node(Object x) { item = x; }
+
+ /** Creates a node with initial item and next */
+ Node(Object x, Node n) { item = x; next = n; }
+
+ /**
+ * Implements AQS base acquire to succeed if not in WAITING state
+ */
+ protected boolean tryAcquire(int ignore) {
+ return getState() != 0;
+ }
+
+ /**
+ * Implements AQS base release to signal if state changed
+ */
+ protected boolean tryRelease(int newState) {
+ return compareAndSetState(0, newState);
+ }
+
+ /**
+ * Takes item and nulls out field (for sake of GC)
+ */
+ private Object extract() {
+ Object x = item;
+ item = null;
+ return x;
+ }
+
+ /**
+ * Tries to cancel on interrupt; if so rethrowing,
+ * else setting interrupt state
+ */
+ private void checkCancellationOnInterrupt(InterruptedException ie)
+ throws InterruptedException {
+ if (release(CANCEL))
+ throw ie;
+ Thread.currentThread().interrupt();
+ }
+
+ /**
+ * Fills in the slot created by the consumer and signal consumer to
+ * continue.
+ */
+ boolean setItem(Object x) {
+ item = x; // can place in slot even if cancelled
+ return release(ACK);
+ }
+
+ /**
+ * Removes item from slot created by producer and signal producer
+ * to continue.
+ */
+ Object getItem() {
+ return (release(ACK))? extract() : null;
+ }
+
+ /**
+ * Waits for a consumer to take item placed by producer.
+ */
+ void waitForTake() throws InterruptedException {
+ try {
+ acquireInterruptibly(0);
+ } catch (InterruptedException ie) {
+ checkCancellationOnInterrupt(ie);
+ }
+ }
+
+ /**
+ * Waits for a producer to put item placed by consumer.
+ */
+ Object waitForPut() throws InterruptedException {
+ try {
+ acquireInterruptibly(0);
+ } catch (InterruptedException ie) {
+ checkCancellationOnInterrupt(ie);
+ }
+ return extract();
+ }
+
+ /**
+ * Waits for a consumer to take item placed by producer or time out.
+ */
+ boolean waitForTake(long nanos) throws InterruptedException {
+ try {
+ if (!tryAcquireNanos(0, nanos) &&
+ release(CANCEL))
+ return false;
+ } catch (InterruptedException ie) {
+ checkCancellationOnInterrupt(ie);
+ }
+ return true;
+ }
+
+ /**
+ * Waits for a producer to put item placed by consumer, or time out.
+ */
+ Object waitForPut(long nanos) throws InterruptedException {
+ try {
+ if (!tryAcquireNanos(0, nanos) &&
+ release(CANCEL))
+ return null;
+ } catch (InterruptedException ie) {
+ checkCancellationOnInterrupt(ie);
+ }
+ return extract();
+ }
+ }
+
+ /**
+ * Adds the specified element to this queue, waiting if necessary for
+ * another thread to receive it.
+ * @param o the element to add
+ * @throws InterruptedException if interrupted while waiting.
+ * @throws NullPointerException if the specified element is <tt>null</tt>.
+ */
+ public void put(E o) throws InterruptedException {
+ if (o == null) throw new NullPointerException();
+ final ReentrantLock qlock = this.qlock;
+
+ for (;;) {
+ Node node;
+ boolean mustWait;
+ if (Thread.interrupted()) throw new InterruptedException();
+ qlock.lock();
+ try {
+ node = waitingConsumers.deq();
+ if ( (mustWait = (node == null)) )
+ node = waitingProducers.enq(o);
+ } finally {
+ qlock.unlock();
+ }
+
+ if (mustWait) {
+ node.waitForTake();
+ return;
+ }
+
+ else if (node.setItem(o))
+ return;
+
+ // else consumer cancelled, so retry
+ }
+ }
+
+ /**
+ * Inserts the specified element into this queue, waiting if necessary
+ * up to the specified wait time for another thread to receive it.
+ * @param o the element to add
+ * @param timeout how long to wait before giving up, in units of
+ * <tt>unit</tt>
+ * @param unit a <tt>TimeUnit</tt> determining how to interpret the
+ * <tt>timeout</tt> parameter
+ * @return <tt>true</tt> if successful, or <tt>false</tt> if
+ * the specified waiting time elapses before a consumer appears.
+ * @throws InterruptedException if interrupted while waiting.
+ * @throws NullPointerException if the specified element is <tt>null</tt>.
+ */
+ public boolean offer(E o, long timeout, TimeUnit unit) throws InterruptedException {
+ if (o == null) throw new NullPointerException();
+ long nanos = unit.toNanos(timeout);
+ final ReentrantLock qlock = this.qlock;
+ for (;;) {
+ Node node;
+ boolean mustWait;
+ if (Thread.interrupted()) throw new InterruptedException();
+ qlock.lock();
+ try {
+ node = waitingConsumers.deq();
+ if ( (mustWait = (node == null)) )
+ node = waitingProducers.enq(o);
+ } finally {
+ qlock.unlock();
+ }
+
+ if (mustWait)
+ return node.waitForTake(nanos);
+
+ else if (node.setItem(o))
+ return true;
+
+ // else consumer cancelled, so retry
+ }
+ }
+
+ /**
+ * Retrieves and removes the head of this queue, waiting if necessary
+ * for another thread to insert it.
+ * @throws InterruptedException if interrupted while waiting.
+ * @return the head of this queue
+ */
+ public E take() throws InterruptedException {
+ final ReentrantLock qlock = this.qlock;
+ for (;;) {
+ Node node;
+ boolean mustWait;
+
+ if (Thread.interrupted()) throw new InterruptedException();
+ qlock.lock();
+ try {
+ node = waitingProducers.deq();
+ if ( (mustWait = (node == null)) )
+ node = waitingConsumers.enq(null);
+ } finally {
+ qlock.unlock();
+ }
+
+ if (mustWait) {
+ Object x = node.waitForPut();
+ return (E)x;
+ }
+ else {
+ Object x = node.getItem();
+ if (x != null)
+ return (E)x;
+ // else cancelled, so retry
+ }
+ }
+ }
+
+ /**
+ * Retrieves and removes the head of this queue, waiting
+ * if necessary up to the specified wait time, for another thread
+ * to insert it.
+ * @param timeout how long to wait before giving up, in units of
+ * <tt>unit</tt>
+ * @param unit a <tt>TimeUnit</tt> determining how to interpret the
+ * <tt>timeout</tt> parameter
+ * @return the head of this queue, or <tt>null</tt> if the
+ * specified waiting time elapses before an element is present.
+ * @throws InterruptedException if interrupted while waiting.
+ */
+ public E poll(long timeout, TimeUnit unit) throws InterruptedException {
+ long nanos = unit.toNanos(timeout);
+ final ReentrantLock qlock = this.qlock;
+
+ for (;;) {
+ Node node;
+ boolean mustWait;
+
+ if (Thread.interrupted()) throw new InterruptedException();
+ qlock.lock();
+ try {
+ node = waitingProducers.deq();
+ if ( (mustWait = (node == null)) )
+ node = waitingConsumers.enq(null);
+ } finally {
+ qlock.unlock();
+ }
+
+ if (mustWait) {
+ Object x = node.waitForPut(nanos);
+ return (E)x;
+ }
+ else {
+ Object x = node.getItem();
+ if (x != null)
+ return (E)x;
+ // else cancelled, so retry
+ }
+ }
+ }
+
+ // Untimed nonblocking versions
+
+ /**
+ * Inserts the specified element into this queue, if another thread is
+ * waiting to receive it.
+ *
+ * @param o the element to add.
+ * @return <tt>true</tt> if it was possible to add the element to
+ * this queue, else <tt>false</tt>
+ * @throws NullPointerException if the specified element is <tt>null</tt>
+ */
+ public boolean offer(E o) {
+ if (o == null) throw new NullPointerException();
+ final ReentrantLock qlock = this.qlock;
+
+ for (;;) {
+ Node node;
+ qlock.lock();
+ try {
+ node = waitingConsumers.deq();
+ } finally {
+ qlock.unlock();
+ }
+ if (node == null)
+ return false;
+
+ else if (node.setItem(o))
+ return true;
+ // else retry
+ }
+ }
+
+ /**
+ * Retrieves and removes the head of this queue, if another thread
+ * is currently making an element available.
+ *
+ * @return the head of this queue, or <tt>null</tt> if no
+ * element is available.
+ */
+ public E poll() {
+ final ReentrantLock qlock = this.qlock;
+ for (;;) {
+ Node node;
+ qlock.lock();
+ try {
+ node = waitingProducers.deq();
+ } finally {
+ qlock.unlock();
+ }
+ if (node == null)
+ return null;
+
+ else {
+ Object x = node.getItem();
+ if (x != null)
+ return (E)x;
+ // else retry
+ }
+ }
+ }
+
+ /**
+ * Always returns <tt>true</tt>.
+ * A <tt>SynchronousQueue</tt> has no internal capacity.
+ * @return <tt>true</tt>
+ */
+ public boolean isEmpty() {
+ return true;
+ }
+
+ /**
+ * Always returns zero.
+ * A <tt>SynchronousQueue</tt> has no internal capacity.
+ * @return zero.
+ */
+ public int size() {
+ return 0;
+ }
+
+ /**
+ * Always returns zero.
+ * A <tt>SynchronousQueue</tt> has no internal capacity.
+ * @return zero.
+ */
+ public int remainingCapacity() {
+ return 0;
+ }
+
+ /**
+ * Does nothing.
+ * A <tt>SynchronousQueue</tt> has no internal capacity.
+ */
+ public void clear() {}
+
+ /**
+ * Always returns <tt>false</tt>.
+ * A <tt>SynchronousQueue</tt> has no internal capacity.
+ * @param o the element
+ * @return <tt>false</tt>
+ */
+ public boolean contains(Object o) {
+ return false;
+ }
+
+ /**
+ * Always returns <tt>false</tt>.
+ * A <tt>SynchronousQueue</tt> has no internal capacity.
+ *
+ * @param o the element to remove
+ * @return <tt>false</tt>
+ */
+ public boolean remove(Object o) {
+ return false;
+ }
+
+ /**
+ * Returns <tt>false</tt> unless given collection is empty.
+ * A <tt>SynchronousQueue</tt> has no internal capacity.
+ * @param c the collection
+ * @return <tt>false</tt> unless given collection is empty
+ */
+ public boolean containsAll(Collection<?> c) {
+ return c.isEmpty();
+ }
+
+ /**
+ * Always returns <tt>false</tt>.
+ * A <tt>SynchronousQueue</tt> has no internal capacity.
+ * @param c the collection
+ * @return <tt>false</tt>
+ */
+ public boolean removeAll(Collection<?> c) {
+ return false;
+ }
+
+ /**
+ * Always returns <tt>false</tt>.
+ * A <tt>SynchronousQueue</tt> has no internal capacity.
+ * @param c the collection
+ * @return <tt>false</tt>
+ */
+ public boolean retainAll(Collection<?> c) {
+ return false;
+ }
+
+ /**
+ * Always returns <tt>null</tt>.
+ * A <tt>SynchronousQueue</tt> does not return elements
+ * unless actively waited on.
+ * @return <tt>null</tt>
+ */
+ public E peek() {
+ return null;
+ }
+
+
+ static class EmptyIterator<E> implements Iterator<E> {
+ public boolean hasNext() {
+ return false;
+ }
+ public E next() {
+ throw new NoSuchElementException();
+ }
+ public void remove() {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Returns an empty iterator in which <tt>hasNext</tt> always returns
+ * <tt>false</tt>.
+ *
+ * @return an empty iterator
+ */
+ public Iterator<E> iterator() {
+ return new EmptyIterator<E>();
+ }
+
+
+ /**
+ * Returns a zero-length array.
+ * @return a zero-length array
+ */
+ public Object[] toArray() {
+ return new Object[0];
+ }
+
+ /**
+ * Sets the zeroeth element of the specified array to <tt>null</tt>
+ * (if the array has non-zero length) and returns it.
+ * @param a the array
+ * @return the specified array
+ */
+ public <T> T[] toArray(T[] a) {
+ if (a.length > 0)
+ a[0] = null;
+ return a;
+ }
+
+ public int drainTo(Collection<? super E> c) {
+ if (c == null)
+ throw new NullPointerException();
+ if (c == this)
+ throw new IllegalArgumentException();
+ int n = 0;
+ E e;
+ while ( (e = poll()) != null) {
+ c.add(e);
+ ++n;
+ }
+ return n;
+ }
+
+ public int drainTo(Collection<? super E> c, int maxElements) {
+ if (c == null)
+ throw new NullPointerException();
+ if (c == this)
+ throw new IllegalArgumentException();
+ int n = 0;
+ E e;
+ while (n < maxElements && (e = poll()) != null) {
+ c.add(e);
+ ++n;
+ }
+ return n;
+ }
+}
+
+
+
+
+
diff --git a/concurrent/src/main/java/java/util/concurrent/ThreadFactory.java b/concurrent/src/main/java/java/util/concurrent/ThreadFactory.java
new file mode 100644
index 0000000..04c63e1
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/ThreadFactory.java
@@ -0,0 +1,40 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+
+/**
+ * An object that creates new threads on demand. Using thread factories
+ * removes hardwiring of calls to {@link Thread#Thread(Runnable) new Thread},
+ * enabling applications to use special thread subclasses, priorities, etc.
+ *
+ * <p>
+ * The simplest implementation of this interface is just:
+ * <pre>
+ * class SimpleThreadFactory implements ThreadFactory {
+ * public Thread newThread(Runnable r) {
+ * return new Thread(r);
+ * }
+ * }
+ * </pre>
+ *
+ * The {@link Executors#defaultThreadFactory} method provides a more
+ * useful simple implementation, that sets the created thread context
+ * to known values before returning it.
+ * @since 1.5
+ * @author Doug Lea
+ */
+public interface ThreadFactory {
+
+ /**
+ * Constructs a new <tt>Thread</tt>. Implementations may also initialize
+ * priority, name, daemon status, <tt>ThreadGroup</tt>, etc.
+ *
+ * @param r a runnable to be executed by new thread instance
+ * @return constructed thread
+ */
+ Thread newThread(Runnable r);
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/ThreadPoolExecutor.java b/concurrent/src/main/java/java/util/concurrent/ThreadPoolExecutor.java
new file mode 100644
index 0000000..1aa8e55
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/ThreadPoolExecutor.java
@@ -0,0 +1,1513 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+import java.util.concurrent.locks.*;
+import java.util.*;
+
+// BEGIN android-note
+// Altered {@link TimeUnit#NANOSECONDS} because our javadoc tool doesn't
+// like it.
+// END android-note
+
+/**
+ * An {@link ExecutorService} that executes each submitted task using
+ * one of possibly several pooled threads, normally configured
+ * using {@link Executors} factory methods.
+ *
+ * <p>Thread pools address two different problems: they usually
+ * provide improved performance when executing large numbers of
+ * asynchronous tasks, due to reduced per-task invocation overhead,
+ * and they provide a means of bounding and managing the resources,
+ * including threads, consumed when executing a collection of tasks.
+ * Each <tt>ThreadPoolExecutor</tt> also maintains some basic
+ * statistics, such as the number of completed tasks.
+ *
+ * <p>To be useful across a wide range of contexts, this class
+ * provides many adjustable parameters and extensibility
+ * hooks. However, programmers are urged to use the more convenient
+ * {@link Executors} factory methods {@link
+ * Executors#newCachedThreadPool} (unbounded thread pool, with
+ * automatic thread reclamation), {@link Executors#newFixedThreadPool}
+ * (fixed size thread pool) and {@link
+ * Executors#newSingleThreadExecutor} (single background thread), that
+ * preconfigure settings for the most common usage
+ * scenarios. Otherwise, use the following guide when manually
+ * configuring and tuning this class:
+ *
+ * <dl>
+ *
+ * <dt>Core and maximum pool sizes</dt>
+ *
+ * <dd>A <tt>ThreadPoolExecutor</tt> will automatically adjust the
+ * pool size
+ * (see {@link ThreadPoolExecutor#getPoolSize})
+ * according to the bounds set by corePoolSize
+ * (see {@link ThreadPoolExecutor#getCorePoolSize})
+ * and
+ * maximumPoolSize
+ * (see {@link ThreadPoolExecutor#getMaximumPoolSize}).
+ * When a new task is submitted in method {@link
+ * ThreadPoolExecutor#execute}, and fewer than corePoolSize threads
+ * are running, a new thread is created to handle the request, even if
+ * other worker threads are idle. If there are more than
+ * corePoolSize but less than maximumPoolSize threads running, a new
+ * thread will be created only if the queue is full. By setting
+ * corePoolSize and maximumPoolSize the same, you create a fixed-size
+ * thread pool. By setting maximumPoolSize to an essentially unbounded
+ * value such as <tt>Integer.MAX_VALUE</tt>, you allow the pool to
+ * accommodate an arbitrary number of concurrent tasks. Most typically,
+ * core and maximum pool sizes are set only upon construction, but they
+ * may also be changed dynamically using {@link
+ * ThreadPoolExecutor#setCorePoolSize} and {@link
+ * ThreadPoolExecutor#setMaximumPoolSize}. <dd>
+ *
+ * <dt> On-demand construction
+ *
+ * <dd> By default, even core threads are initially created and
+ * started only when needed by new tasks, but this can be overridden
+ * dynamically using method {@link
+ * ThreadPoolExecutor#prestartCoreThread} or
+ * {@link ThreadPoolExecutor#prestartAllCoreThreads}. </dd>
+ *
+ * <dt>Creating new threads</dt>
+ *
+ * <dd>New threads are created using a {@link
+ * java.util.concurrent.ThreadFactory}. If not otherwise specified, a
+ * {@link Executors#defaultThreadFactory} is used, that creates threads to all
+ * be in the same {@link ThreadGroup} and with the same
+ * <tt>NORM_PRIORITY</tt> priority and non-daemon status. By supplying
+ * a different ThreadFactory, you can alter the thread's name, thread
+ * group, priority, daemon status, etc. </dd>
+ *
+ * <dt>Keep-alive times</dt>
+ *
+ * <dd>If the pool currently has more than corePoolSize threads,
+ * excess threads will be terminated if they have been idle for more
+ * than the keepAliveTime (see {@link
+ * ThreadPoolExecutor#getKeepAliveTime}). This provides a means of
+ * reducing resource consumption when the pool is not being actively
+ * used. If the pool becomes more active later, new threads will be
+ * constructed. This parameter can also be changed dynamically
+ * using method {@link ThreadPoolExecutor#setKeepAliveTime}. Using
+ * a value of <tt>Long.MAX_VALUE</tt> <code>TimeUnit.NANOSECONDS</code>
+ * effectively disables idle threads from ever terminating prior
+ * to shut down.
+ * </dd>
+ *
+ * <dt>Queuing</dt>
+ *
+ * <dd>Any {@link BlockingQueue} may be used to transfer and hold
+ * submitted tasks. The use of this queue interacts with pool sizing:
+ *
+ * <ul>
+ *
+ * <li> If fewer than corePoolSize threads are running, the Executor
+ * always prefers adding a new thread
+ * rather than queuing.</li>
+ *
+ * <li> If corePoolSize or more threads are running, the Executor
+ * always prefers queuing a request rather than adding a new
+ * thread.</li>
+ *
+ * <li> If a request cannot be queued, a new thread is created unless
+ * this would exceed maximumPoolSize, in which case, the task will be
+ * rejected.</li>
+ *
+ * </ul>
+ *
+ * There are three general strategies for queuing:
+ * <ol>
+ *
+ * <li> <em> Direct handoffs.</em> A good default choice for a work
+ * queue is a {@link SynchronousQueue} that hands off tasks to threads
+ * without otherwise holding them. Here, an attempt to queue a task
+ * will fail if no threads are immediately available to run it, so a
+ * new thread will be constructed. This policy avoids lockups when
+ * handling sets of requests that might have internal dependencies.
+ * Direct handoffs generally require unbounded maximumPoolSizes to
+ * avoid rejection of new submitted tasks. This in turn admits the
+ * possibility of unbounded thread growth when commands continue to
+ * arrive on average faster than they can be processed. </li>
+ *
+ * <li><em> Unbounded queues.</em> Using an unbounded queue (for
+ * example a {@link LinkedBlockingQueue} without a predefined
+ * capacity) will cause new tasks to be queued in cases where all
+ * corePoolSize threads are busy. Thus, no more than corePoolSize
+ * threads will ever be created. (And the value of the maximumPoolSize
+ * therefore doesn't have any effect.) This may be appropriate when
+ * each task is completely independent of others, so tasks cannot
+ * affect each others execution; for example, in a web page server.
+ * While this style of queuing can be useful in smoothing out
+ * transient bursts of requests, it admits the possibility of
+ * unbounded work queue growth when commands continue to arrive on
+ * average faster than they can be processed. </li>
+ *
+ * <li><em>Bounded queues.</em> A bounded queue (for example, an
+ * {@link ArrayBlockingQueue}) helps prevent resource exhaustion when
+ * used with finite maximumPoolSizes, but can be more difficult to
+ * tune and control. Queue sizes and maximum pool sizes may be traded
+ * off for each other: Using large queues and small pools minimizes
+ * CPU usage, OS resources, and context-switching overhead, but can
+ * lead to artificially low throughput. If tasks frequently block (for
+ * example if they are I/O bound), a system may be able to schedule
+ * time for more threads than you otherwise allow. Use of small queues
+ * generally requires larger pool sizes, which keeps CPUs busier but
+ * may encounter unacceptable scheduling overhead, which also
+ * decreases throughput. </li>
+ *
+ * </ol>
+ *
+ * </dd>
+ *
+ * <dt>Rejected tasks</dt>
+ *
+ * <dd> New tasks submitted in method {@link
+ * ThreadPoolExecutor#execute} will be <em>rejected</em> when the
+ * Executor has been shut down, and also when the Executor uses finite
+ * bounds for both maximum threads and work queue capacity, and is
+ * saturated. In either case, the <tt>execute</tt> method invokes the
+ * {@link RejectedExecutionHandler#rejectedExecution} method of its
+ * {@link RejectedExecutionHandler}. Four predefined handler policies
+ * are provided:
+ *
+ * <ol>
+ *
+ * <li> In the
+ * default {@link ThreadPoolExecutor.AbortPolicy}, the handler throws a
+ * runtime {@link RejectedExecutionException} upon rejection. </li>
+ *
+ * <li> In {@link
+ * ThreadPoolExecutor.CallerRunsPolicy}, the thread that invokes
+ * <tt>execute</tt> itself runs the task. This provides a simple
+ * feedback control mechanism that will slow down the rate that new
+ * tasks are submitted. </li>
+ *
+ * <li> In {@link ThreadPoolExecutor.DiscardPolicy},
+ * a task that cannot be executed is simply dropped. </li>
+ *
+ * <li>In {@link
+ * ThreadPoolExecutor.DiscardOldestPolicy}, if the executor is not
+ * shut down, the task at the head of the work queue is dropped, and
+ * then execution is retried (which can fail again, causing this to be
+ * repeated.) </li>
+ *
+ * </ol>
+ *
+ * It is possible to define and use other kinds of {@link
+ * RejectedExecutionHandler} classes. Doing so requires some care
+ * especially when policies are designed to work only under particular
+ * capacity or queuing policies. </dd>
+ *
+ * <dt>Hook methods</dt>
+ *
+ * <dd>This class provides <tt>protected</tt> overridable {@link
+ * ThreadPoolExecutor#beforeExecute} and {@link
+ * ThreadPoolExecutor#afterExecute} methods that are called before and
+ * after execution of each task. These can be used to manipulate the
+ * execution environment, for example, reinitializing ThreadLocals,
+ * gathering statistics, or adding log entries. Additionally, method
+ * {@link ThreadPoolExecutor#terminated} can be overridden to perform
+ * any special processing that needs to be done once the Executor has
+ * fully terminated.</dd>
+ *
+ * <dt>Queue maintenance</dt>
+ *
+ * <dd> Method {@link ThreadPoolExecutor#getQueue} allows access to
+ * the work queue for purposes of monitoring and debugging. Use of
+ * this method for any other purpose is strongly discouraged. Two
+ * supplied methods, {@link ThreadPoolExecutor#remove} and {@link
+ * ThreadPoolExecutor#purge} are available to assist in storage
+ * reclamation when large numbers of queued tasks become
+ * cancelled.</dd> </dl>
+ *
+ * <p> <b>Extension example</b>. Most extensions of this class
+ * override one or more of the protected hook methods. For example,
+ * here is a subclass that adds a simple pause/resume feature:
+ *
+ * <pre>
+ * class PausableThreadPoolExecutor extends ThreadPoolExecutor {
+ * private boolean isPaused;
+ * private ReentrantLock pauseLock = new ReentrantLock();
+ * private Condition unpaused = pauseLock.newCondition();
+ *
+ * public PausableThreadPoolExecutor(...) { super(...); }
+ *
+ * protected void beforeExecute(Thread t, Runnable r) {
+ * super.beforeExecute(t, r);
+ * pauseLock.lock();
+ * try {
+ * while (isPaused) unpaused.await();
+ * } catch(InterruptedException ie) {
+ * t.interrupt();
+ * } finally {
+ * pauseLock.unlock();
+ * }
+ * }
+ *
+ * public void pause() {
+ * pauseLock.lock();
+ * try {
+ * isPaused = true;
+ * } finally {
+ * pauseLock.unlock();
+ * }
+ * }
+ *
+ * public void resume() {
+ * pauseLock.lock();
+ * try {
+ * isPaused = false;
+ * unpaused.signalAll();
+ * } finally {
+ * pauseLock.unlock();
+ * }
+ * }
+ * }
+ * </pre>
+ * @since 1.5
+ * @author Doug Lea
+ */
+public class ThreadPoolExecutor extends AbstractExecutorService {
+ /**
+ * Only used to force toArray() to produce a Runnable[].
+ */
+ private static final Runnable[] EMPTY_RUNNABLE_ARRAY = new Runnable[0];
+
+ /**
+ * Permission for checking shutdown
+ */
+ private static final RuntimePermission shutdownPerm =
+ new RuntimePermission("modifyThread");
+
+ /**
+ * Queue used for holding tasks and handing off to worker threads.
+ */
+ private final BlockingQueue<Runnable> workQueue;
+
+ /**
+ * Lock held on updates to poolSize, corePoolSize, maximumPoolSize, and
+ * workers set.
+ */
+ private final ReentrantLock mainLock = new ReentrantLock();
+
+ /**
+ * Wait condition to support awaitTermination
+ */
+ private final Condition termination = mainLock.newCondition();
+
+ /**
+ * Set containing all worker threads in pool.
+ */
+ private final HashSet<Worker> workers = new HashSet<Worker>();
+
+ /**
+ * Timeout in nanoseconds for idle threads waiting for work.
+ * Threads use this timeout only when there are more than
+ * corePoolSize present. Otherwise they wait forever for new work.
+ */
+ private volatile long keepAliveTime;
+
+ /**
+ * Core pool size, updated only while holding mainLock,
+ * but volatile to allow concurrent readability even
+ * during updates.
+ */
+ private volatile int corePoolSize;
+
+ /**
+ * Maximum pool size, updated only while holding mainLock
+ * but volatile to allow concurrent readability even
+ * during updates.
+ */
+ private volatile int maximumPoolSize;
+
+ /**
+ * Current pool size, updated only while holding mainLock
+ * but volatile to allow concurrent readability even
+ * during updates.
+ */
+ private volatile int poolSize;
+
+ /**
+ * Lifecycle state
+ */
+ volatile int runState;
+
+ // Special values for runState
+ /** Normal, not-shutdown mode */
+ static final int RUNNING = 0;
+ /** Controlled shutdown mode */
+ static final int SHUTDOWN = 1;
+ /** Immediate shutdown mode */
+ static final int STOP = 2;
+ /** Final state */
+ static final int TERMINATED = 3;
+
+ /**
+ * Handler called when saturated or shutdown in execute.
+ */
+ private volatile RejectedExecutionHandler handler;
+
+ /**
+ * Factory for new threads.
+ */
+ private volatile ThreadFactory threadFactory;
+
+ /**
+ * Tracks largest attained pool size.
+ */
+ private int largestPoolSize;
+
+ /**
+ * Counter for completed tasks. Updated only on termination of
+ * worker threads.
+ */
+ private long completedTaskCount;
+
+ /**
+ * The default rejected execution handler
+ */
+ private static final RejectedExecutionHandler defaultHandler =
+ new AbortPolicy();
+
+ /**
+ * Invoke the rejected execution handler for the given command.
+ */
+ void reject(Runnable command) {
+ handler.rejectedExecution(command, this);
+ }
+
+ /**
+ * Create and return a new thread running firstTask as its first
+ * task. Call only while holding mainLock
+ * @param firstTask the task the new thread should run first (or
+ * null if none)
+ * @return the new thread
+ */
+ private Thread addThread(Runnable firstTask) {
+ Worker w = new Worker(firstTask);
+ Thread t = threadFactory.newThread(w);
+ w.thread = t;
+ workers.add(w);
+ int nt = ++poolSize;
+ if (nt > largestPoolSize)
+ largestPoolSize = nt;
+ return t;
+ }
+
+ /**
+ * Create and start a new thread running firstTask as its first
+ * task, only if fewer than corePoolSize threads are running.
+ * @param firstTask the task the new thread should run first (or
+ * null if none)
+ * @return true if successful.
+ */
+ private boolean addIfUnderCorePoolSize(Runnable firstTask) {
+ Thread t = null;
+ final ReentrantLock mainLock = this.mainLock;
+ mainLock.lock();
+ try {
+ if (poolSize < corePoolSize)
+ t = addThread(firstTask);
+ } finally {
+ mainLock.unlock();
+ }
+ if (t == null)
+ return false;
+ t.start();
+ return true;
+ }
+
+ /**
+ * Create and start a new thread only if fewer than maximumPoolSize
+ * threads are running. The new thread runs as its first task the
+ * next task in queue, or if there is none, the given task.
+ * @param firstTask the task the new thread should run first (or
+ * null if none)
+ * @return null on failure, else the first task to be run by new thread.
+ */
+ private Runnable addIfUnderMaximumPoolSize(Runnable firstTask) {
+ Thread t = null;
+ Runnable next = null;
+ final ReentrantLock mainLock = this.mainLock;
+ mainLock.lock();
+ try {
+ if (poolSize < maximumPoolSize) {
+ next = workQueue.poll();
+ if (next == null)
+ next = firstTask;
+ t = addThread(next);
+ }
+ } finally {
+ mainLock.unlock();
+ }
+ if (t == null)
+ return null;
+ t.start();
+ return next;
+ }
+
+
+ /**
+ * Get the next task for a worker thread to run.
+ * @return the task
+ * @throws InterruptedException if interrupted while waiting for task
+ */
+ Runnable getTask() throws InterruptedException {
+ for (;;) {
+ switch(runState) {
+ case RUNNING: {
+ if (poolSize <= corePoolSize) // untimed wait if core
+ return workQueue.take();
+
+ long timeout = keepAliveTime;
+ if (timeout <= 0) // die immediately for 0 timeout
+ return null;
+ Runnable r = workQueue.poll(timeout, TimeUnit.NANOSECONDS);
+ if (r != null)
+ return r;
+ if (poolSize > corePoolSize) // timed out
+ return null;
+ // else, after timeout, pool shrank so shouldn't die, so retry
+ break;
+ }
+
+ case SHUTDOWN: {
+ // Help drain queue
+ Runnable r = workQueue.poll();
+ if (r != null)
+ return r;
+
+ // Check if can terminate
+ if (workQueue.isEmpty()) {
+ interruptIdleWorkers();
+ return null;
+ }
+
+ // There could still be delayed tasks in queue.
+ // Wait for one, re-checking state upon interruption
+ try {
+ return workQueue.take();
+ } catch(InterruptedException ignore) {}
+ break;
+ }
+
+ case STOP:
+ return null;
+ default:
+ assert false;
+ }
+ }
+ }
+
+ /**
+ * Wake up all threads that might be waiting for tasks.
+ */
+ void interruptIdleWorkers() {
+ final ReentrantLock mainLock = this.mainLock;
+ mainLock.lock();
+ try {
+ for (Worker w : workers)
+ w.interruptIfIdle();
+ } finally {
+ mainLock.unlock();
+ }
+ }
+
+ /**
+ * Perform bookkeeping for a terminated worker thread.
+ * @param w the worker
+ */
+ void workerDone(Worker w) {
+ final ReentrantLock mainLock = this.mainLock;
+ mainLock.lock();
+ try {
+ completedTaskCount += w.completedTasks;
+ workers.remove(w);
+ if (--poolSize > 0)
+ return;
+
+ // Else, this is the last thread. Deal with potential shutdown.
+
+ int state = runState;
+ assert state != TERMINATED;
+
+ if (state != STOP) {
+ // If there are queued tasks but no threads, create
+ // replacement.
+ Runnable r = workQueue.poll();
+ if (r != null) {
+ addThread(r).start();
+ return;
+ }
+
+ // If there are some (presumably delayed) tasks but
+ // none pollable, create an idle replacement to wait.
+ if (!workQueue.isEmpty()) {
+ addThread(null).start();
+ return;
+ }
+
+ // Otherwise, we can exit without replacement
+ if (state == RUNNING)
+ return;
+ }
+
+ // Either state is STOP, or state is SHUTDOWN and there is
+ // no work to do. So we can terminate.
+ termination.signalAll();
+ runState = TERMINATED;
+ // fall through to call terminate() outside of lock.
+ } finally {
+ mainLock.unlock();
+ }
+
+ assert runState == TERMINATED;
+ terminated();
+ }
+
+ /**
+ * Worker threads
+ */
+ private class Worker implements Runnable {
+
+ /**
+ * The runLock is acquired and released surrounding each task
+ * execution. It mainly protects against interrupts that are
+ * intended to cancel the worker thread from instead
+ * interrupting the task being run.
+ */
+ private final ReentrantLock runLock = new ReentrantLock();
+
+ /**
+ * Initial task to run before entering run loop
+ */
+ private Runnable firstTask;
+
+ /**
+ * Per thread completed task counter; accumulated
+ * into completedTaskCount upon termination.
+ */
+ volatile long completedTasks;
+
+ /**
+ * Thread this worker is running in. Acts as a final field,
+ * but cannot be set until thread is created.
+ */
+ Thread thread;
+
+ Worker(Runnable firstTask) {
+ this.firstTask = firstTask;
+ }
+
+ boolean isActive() {
+ return runLock.isLocked();
+ }
+
+ /**
+ * Interrupt thread if not running a task
+ */
+ void interruptIfIdle() {
+ final ReentrantLock runLock = this.runLock;
+ if (runLock.tryLock()) {
+ try {
+ thread.interrupt();
+ } finally {
+ runLock.unlock();
+ }
+ }
+ }
+
+ /**
+ * Cause thread to die even if running a task.
+ */
+ void interruptNow() {
+ thread.interrupt();
+ }
+
+ /**
+ * Run a single task between before/after methods.
+ */
+ private void runTask(Runnable task) {
+ final ReentrantLock runLock = this.runLock;
+ runLock.lock();
+ try {
+ // Abort now if immediate cancel. Otherwise, we have
+ // committed to run this task.
+ if (runState == STOP)
+ return;
+
+ Thread.interrupted(); // clear interrupt status on entry
+ boolean ran = false;
+ beforeExecute(thread, task);
+ try {
+ task.run();
+ ran = true;
+ afterExecute(task, null);
+ ++completedTasks;
+ } catch(RuntimeException ex) {
+ if (!ran)
+ afterExecute(task, ex);
+ // Else the exception occurred within
+ // afterExecute itself in which case we don't
+ // want to call it again.
+ throw ex;
+ }
+ } finally {
+ runLock.unlock();
+ }
+ }
+
+ /**
+ * Main run loop
+ */
+ public void run() {
+ try {
+ Runnable task = firstTask;
+ firstTask = null;
+ while (task != null || (task = getTask()) != null) {
+ runTask(task);
+ task = null; // unnecessary but can help GC
+ }
+ } catch(InterruptedException ie) {
+ // fall through
+ } finally {
+ workerDone(this);
+ }
+ }
+ }
+
+ // Public methods
+
+ /**
+ * Creates a new <tt>ThreadPoolExecutor</tt> with the given
+ * initial parameters and default thread factory and handler. It
+ * may be more convenient to use one of the {@link Executors}
+ * factory methods instead of this general purpose constructor.
+ *
+ * @param corePoolSize the number of threads to keep in the
+ * pool, even if they are idle.
+ * @param maximumPoolSize the maximum number of threads to allow in the
+ * pool.
+ * @param keepAliveTime when the number of threads is greater than
+ * the core, this is the maximum time that excess idle threads
+ * will wait for new tasks before terminating.
+ * @param unit the time unit for the keepAliveTime
+ * argument.
+ * @param workQueue the queue to use for holding tasks before they
+ * are executed. This queue will hold only the <tt>Runnable</tt>
+ * tasks submitted by the <tt>execute</tt> method.
+ * @throws IllegalArgumentException if corePoolSize, or
+ * keepAliveTime less than zero, or if maximumPoolSize less than or
+ * equal to zero, or if corePoolSize greater than maximumPoolSize.
+ * @throws NullPointerException if <tt>workQueue</tt> is null
+ */
+ public ThreadPoolExecutor(int corePoolSize,
+ int maximumPoolSize,
+ long keepAliveTime,
+ TimeUnit unit,
+ BlockingQueue<Runnable> workQueue) {
+ this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
+ Executors.defaultThreadFactory(), defaultHandler);
+ }
+
+ /**
+ * Creates a new <tt>ThreadPoolExecutor</tt> with the given initial
+ * parameters.
+ *
+ * @param corePoolSize the number of threads to keep in the
+ * pool, even if they are idle.
+ * @param maximumPoolSize the maximum number of threads to allow in the
+ * pool.
+ * @param keepAliveTime when the number of threads is greater than
+ * the core, this is the maximum time that excess idle threads
+ * will wait for new tasks before terminating.
+ * @param unit the time unit for the keepAliveTime
+ * argument.
+ * @param workQueue the queue to use for holding tasks before they
+ * are executed. This queue will hold only the <tt>Runnable</tt>
+ * tasks submitted by the <tt>execute</tt> method.
+ * @param threadFactory the factory to use when the executor
+ * creates a new thread.
+ * @throws IllegalArgumentException if corePoolSize, or
+ * keepAliveTime less than zero, or if maximumPoolSize less than or
+ * equal to zero, or if corePoolSize greater than maximumPoolSize.
+ * @throws NullPointerException if <tt>workQueue</tt>
+ * or <tt>threadFactory</tt> are null.
+ */
+ public ThreadPoolExecutor(int corePoolSize,
+ int maximumPoolSize,
+ long keepAliveTime,
+ TimeUnit unit,
+ BlockingQueue<Runnable> workQueue,
+ ThreadFactory threadFactory) {
+ this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
+ threadFactory, defaultHandler);
+ }
+
+ /**
+ * Creates a new <tt>ThreadPoolExecutor</tt> with the given initial
+ * parameters.
+ *
+ * @param corePoolSize the number of threads to keep in the
+ * pool, even if they are idle.
+ * @param maximumPoolSize the maximum number of threads to allow in the
+ * pool.
+ * @param keepAliveTime when the number of threads is greater than
+ * the core, this is the maximum time that excess idle threads
+ * will wait for new tasks before terminating.
+ * @param unit the time unit for the keepAliveTime
+ * argument.
+ * @param workQueue the queue to use for holding tasks before they
+ * are executed. This queue will hold only the <tt>Runnable</tt>
+ * tasks submitted by the <tt>execute</tt> method.
+ * @param handler the handler to use when execution is blocked
+ * because the thread bounds and queue capacities are reached.
+ * @throws IllegalArgumentException if corePoolSize, or
+ * keepAliveTime less than zero, or if maximumPoolSize less than or
+ * equal to zero, or if corePoolSize greater than maximumPoolSize.
+ * @throws NullPointerException if <tt>workQueue</tt>
+ * or <tt>handler</tt> are null.
+ */
+ public ThreadPoolExecutor(int corePoolSize,
+ int maximumPoolSize,
+ long keepAliveTime,
+ TimeUnit unit,
+ BlockingQueue<Runnable> workQueue,
+ RejectedExecutionHandler handler) {
+ this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
+ Executors.defaultThreadFactory(), handler);
+ }
+
+ /**
+ * Creates a new <tt>ThreadPoolExecutor</tt> with the given initial
+ * parameters.
+ *
+ * @param corePoolSize the number of threads to keep in the
+ * pool, even if they are idle.
+ * @param maximumPoolSize the maximum number of threads to allow in the
+ * pool.
+ * @param keepAliveTime when the number of threads is greater than
+ * the core, this is the maximum time that excess idle threads
+ * will wait for new tasks before terminating.
+ * @param unit the time unit for the keepAliveTime
+ * argument.
+ * @param workQueue the queue to use for holding tasks before they
+ * are executed. This queue will hold only the <tt>Runnable</tt>
+ * tasks submitted by the <tt>execute</tt> method.
+ * @param threadFactory the factory to use when the executor
+ * creates a new thread.
+ * @param handler the handler to use when execution is blocked
+ * because the thread bounds and queue capacities are reached.
+ * @throws IllegalArgumentException if corePoolSize, or
+ * keepAliveTime less than zero, or if maximumPoolSize less than or
+ * equal to zero, or if corePoolSize greater than maximumPoolSize.
+ * @throws NullPointerException if <tt>workQueue</tt>
+ * or <tt>threadFactory</tt> or <tt>handler</tt> are null.
+ */
+ public ThreadPoolExecutor(int corePoolSize,
+ int maximumPoolSize,
+ long keepAliveTime,
+ TimeUnit unit,
+ BlockingQueue<Runnable> workQueue,
+ ThreadFactory threadFactory,
+ RejectedExecutionHandler handler) {
+ if (corePoolSize < 0 ||
+ maximumPoolSize <= 0 ||
+ maximumPoolSize < corePoolSize ||
+ keepAliveTime < 0)
+ throw new IllegalArgumentException();
+ if (workQueue == null || threadFactory == null || handler == null)
+ throw new NullPointerException();
+ this.corePoolSize = corePoolSize;
+ this.maximumPoolSize = maximumPoolSize;
+ this.workQueue = workQueue;
+ this.keepAliveTime = unit.toNanos(keepAliveTime);
+ this.threadFactory = threadFactory;
+ this.handler = handler;
+ }
+
+
+ /**
+ * Executes the given task sometime in the future. The task
+ * may execute in a new thread or in an existing pooled thread.
+ *
+ * If the task cannot be submitted for execution, either because this
+ * executor has been shutdown or because its capacity has been reached,
+ * the task is handled by the current <tt>RejectedExecutionHandler</tt>.
+ *
+ * @param command the task to execute
+ * @throws RejectedExecutionException at discretion of
+ * <tt>RejectedExecutionHandler</tt>, if task cannot be accepted
+ * for execution
+ * @throws NullPointerException if command is null
+ */
+ public void execute(Runnable command) {
+ if (command == null)
+ throw new NullPointerException();
+ for (;;) {
+ if (runState != RUNNING) {
+ reject(command);
+ return;
+ }
+ if (poolSize < corePoolSize && addIfUnderCorePoolSize(command))
+ return;
+ if (workQueue.offer(command))
+ return;
+ Runnable r = addIfUnderMaximumPoolSize(command);
+ if (r == command)
+ return;
+ if (r == null) {
+ reject(command);
+ return;
+ }
+ // else retry
+ }
+ }
+
+ /**
+ * Initiates an orderly shutdown in which previously submitted
+ * tasks are executed, but no new tasks will be
+ * accepted. Invocation has no additional effect if already shut
+ * down.
+ * @throws SecurityException if a security manager exists and
+ * shutting down this ExecutorService may manipulate threads that
+ * the caller is not permitted to modify because it does not hold
+ * {@link java.lang.RuntimePermission}<tt>("modifyThread")</tt>,
+ * or the security manager's <tt>checkAccess</tt> method denies access.
+ */
+ public void shutdown() {
+ // Fail if caller doesn't have modifyThread permission
+ SecurityManager security = System.getSecurityManager();
+ if (security != null)
+ java.security.AccessController.checkPermission(shutdownPerm);
+
+ boolean fullyTerminated = false;
+ final ReentrantLock mainLock = this.mainLock;
+ mainLock.lock();
+ try {
+ if (workers.size() > 0) {
+ // Check if caller can modify worker threads. This
+ // might not be true even if passed above check, if
+ // the SecurityManager treats some threads specially.
+ if (security != null) {
+ for (Worker w: workers)
+ security.checkAccess(w.thread);
+ }
+
+ int state = runState;
+ if (state == RUNNING) // don't override shutdownNow
+ runState = SHUTDOWN;
+
+ try {
+ for (Worker w: workers)
+ w.interruptIfIdle();
+ } catch(SecurityException se) {
+ // If SecurityManager allows above checks, but
+ // then unexpectedly throws exception when
+ // interrupting threads (which it ought not do),
+ // back out as cleanly as we can. Some threads may
+ // have been killed but we remain in non-shutdown
+ // state.
+ runState = state;
+ throw se;
+ }
+ }
+ else { // If no workers, trigger full termination now
+ fullyTerminated = true;
+ runState = TERMINATED;
+ termination.signalAll();
+ }
+ } finally {
+ mainLock.unlock();
+ }
+ if (fullyTerminated)
+ terminated();
+ }
+
+
+ /**
+ * Attempts to stop all actively executing tasks, halts the
+ * processing of waiting tasks, and returns a list of the tasks that were
+ * awaiting execution.
+ *
+ * <p>This implementation cancels tasks via {@link
+ * Thread#interrupt}, so if any tasks mask or fail to respond to
+ * interrupts, they may never terminate.
+ *
+ * @return list of tasks that never commenced execution
+ * @throws SecurityException if a security manager exists and
+ * shutting down this ExecutorService may manipulate threads that
+ * the caller is not permitted to modify because it does not hold
+ * {@link java.lang.RuntimePermission}<tt>("modifyThread")</tt>,
+ * or the security manager's <tt>checkAccess</tt> method denies access.
+ */
+ public List<Runnable> shutdownNow() {
+ // Almost the same code as shutdown()
+ SecurityManager security = System.getSecurityManager();
+ if (security != null)
+ java.security.AccessController.checkPermission(shutdownPerm);
+
+ boolean fullyTerminated = false;
+ final ReentrantLock mainLock = this.mainLock;
+ mainLock.lock();
+ try {
+ if (workers.size() > 0) {
+ if (security != null) {
+ for (Worker w: workers)
+ security.checkAccess(w.thread);
+ }
+
+ int state = runState;
+ if (state != TERMINATED)
+ runState = STOP;
+ try {
+ for (Worker w : workers)
+ w.interruptNow();
+ } catch(SecurityException se) {
+ runState = state; // back out;
+ throw se;
+ }
+ }
+ else { // If no workers, trigger full termination now
+ fullyTerminated = true;
+ runState = TERMINATED;
+ termination.signalAll();
+ }
+ } finally {
+ mainLock.unlock();
+ }
+ if (fullyTerminated)
+ terminated();
+ return Arrays.asList(workQueue.toArray(EMPTY_RUNNABLE_ARRAY));
+ }
+
+ public boolean isShutdown() {
+ return runState != RUNNING;
+ }
+
+ /**
+ * Returns true if this executor is in the process of terminating
+ * after <tt>shutdown</tt> or <tt>shutdownNow</tt> but has not
+ * completely terminated. This method may be useful for
+ * debugging. A return of <tt>true</tt> reported a sufficient
+ * period after shutdown may indicate that submitted tasks have
+ * ignored or suppressed interruption, causing this executor not
+ * to properly terminate.
+ * @return true if terminating but not yet terminated.
+ */
+ public boolean isTerminating() {
+ return runState == STOP;
+ }
+
+ public boolean isTerminated() {
+ return runState == TERMINATED;
+ }
+
+ public boolean awaitTermination(long timeout, TimeUnit unit)
+ throws InterruptedException {
+ long nanos = unit.toNanos(timeout);
+ final ReentrantLock mainLock = this.mainLock;
+ mainLock.lock();
+ try {
+ for (;;) {
+ if (runState == TERMINATED)
+ return true;
+ if (nanos <= 0)
+ return false;
+ nanos = termination.awaitNanos(nanos);
+ }
+ } finally {
+ mainLock.unlock();
+ }
+ }
+
+ /**
+ * Invokes <tt>shutdown</tt> when this executor is no longer
+ * referenced.
+ */
+ protected void finalize() {
+ shutdown();
+ }
+
+ /**
+ * Sets the thread factory used to create new threads.
+ *
+ * @param threadFactory the new thread factory
+ * @throws NullPointerException if threadFactory is null
+ * @see #getThreadFactory
+ */
+ public void setThreadFactory(ThreadFactory threadFactory) {
+ if (threadFactory == null)
+ throw new NullPointerException();
+ this.threadFactory = threadFactory;
+ }
+
+ /**
+ * Returns the thread factory used to create new threads.
+ *
+ * @return the current thread factory
+ * @see #setThreadFactory
+ */
+ public ThreadFactory getThreadFactory() {
+ return threadFactory;
+ }
+
+ /**
+ * Sets a new handler for unexecutable tasks.
+ *
+ * @param handler the new handler
+ * @throws NullPointerException if handler is null
+ * @see #getRejectedExecutionHandler
+ */
+ public void setRejectedExecutionHandler(RejectedExecutionHandler handler) {
+ if (handler == null)
+ throw new NullPointerException();
+ this.handler = handler;
+ }
+
+ /**
+ * Returns the current handler for unexecutable tasks.
+ *
+ * @return the current handler
+ * @see #setRejectedExecutionHandler
+ */
+ public RejectedExecutionHandler getRejectedExecutionHandler() {
+ return handler;
+ }
+
+ /**
+ * Returns the task queue used by this executor. Access to the
+ * task queue is intended primarily for debugging and monitoring.
+ * This queue may be in active use. Retrieving the task queue
+ * does not prevent queued tasks from executing.
+ *
+ * @return the task queue
+ */
+ public BlockingQueue<Runnable> getQueue() {
+ return workQueue;
+ }
+
+ /**
+ * Removes this task from the executor's internal queue if it is
+ * present, thus causing it not to be run if it has not already
+ * started.
+ *
+ * <p> This method may be useful as one part of a cancellation
+ * scheme. It may fail to remove tasks that have been converted
+ * into other forms before being placed on the internal queue. For
+ * example, a task entered using <tt>submit</tt> might be
+ * converted into a form that maintains <tt>Future</tt> status.
+ * However, in such cases, method {@link ThreadPoolExecutor#purge}
+ * may be used to remove those Futures that have been cancelled.
+ *
+ *
+ * @param task the task to remove
+ * @return true if the task was removed
+ */
+ public boolean remove(Runnable task) {
+ return getQueue().remove(task);
+ }
+
+
+ /**
+ * Tries to remove from the work queue all {@link Future}
+ * tasks that have been cancelled. This method can be useful as a
+ * storage reclamation operation, that has no other impact on
+ * functionality. Cancelled tasks are never executed, but may
+ * accumulate in work queues until worker threads can actively
+ * remove them. Invoking this method instead tries to remove them now.
+ * However, this method may fail to remove tasks in
+ * the presence of interference by other threads.
+ */
+ public void purge() {
+ // Fail if we encounter interference during traversal
+ try {
+ Iterator<Runnable> it = getQueue().iterator();
+ while (it.hasNext()) {
+ Runnable r = it.next();
+ if (r instanceof Future<?>) {
+ Future<?> c = (Future<?>)r;
+ if (c.isCancelled())
+ it.remove();
+ }
+ }
+ }
+ catch(ConcurrentModificationException ex) {
+ return;
+ }
+ }
+
+ /**
+ * Sets the core number of threads. This overrides any value set
+ * in the constructor. If the new value is smaller than the
+ * current value, excess existing threads will be terminated when
+ * they next become idle. If larger, new threads will, if needed,
+ * be started to execute any queued tasks.
+ *
+ * @param corePoolSize the new core size
+ * @throws IllegalArgumentException if <tt>corePoolSize</tt>
+ * less than zero
+ * @see #getCorePoolSize
+ */
+ public void setCorePoolSize(int corePoolSize) {
+ if (corePoolSize < 0)
+ throw new IllegalArgumentException();
+ final ReentrantLock mainLock = this.mainLock;
+ mainLock.lock();
+ try {
+ int extra = this.corePoolSize - corePoolSize;
+ this.corePoolSize = corePoolSize;
+ if (extra < 0) {
+ Runnable r;
+ while (extra++ < 0 && poolSize < corePoolSize &&
+ (r = workQueue.poll()) != null)
+ addThread(r).start();
+ }
+ else if (extra > 0 && poolSize > corePoolSize) {
+ Iterator<Worker> it = workers.iterator();
+ while (it.hasNext() &&
+ extra-- > 0 &&
+ poolSize > corePoolSize &&
+ workQueue.remainingCapacity() == 0)
+ it.next().interruptIfIdle();
+ }
+ } finally {
+ mainLock.unlock();
+ }
+ }
+
+ /**
+ * Returns the core number of threads.
+ *
+ * @return the core number of threads
+ * @see #setCorePoolSize
+ */
+ public int getCorePoolSize() {
+ return corePoolSize;
+ }
+
+ /**
+ * Starts a core thread, causing it to idly wait for work. This
+ * overrides the default policy of starting core threads only when
+ * new tasks are executed. This method will return <tt>false</tt>
+ * if all core threads have already been started.
+ * @return true if a thread was started
+ */
+ public boolean prestartCoreThread() {
+ return addIfUnderCorePoolSize(null);
+ }
+
+ /**
+ * Starts all core threads, causing them to idly wait for work. This
+ * overrides the default policy of starting core threads only when
+ * new tasks are executed.
+ * @return the number of threads started.
+ */
+ public int prestartAllCoreThreads() {
+ int n = 0;
+ while (addIfUnderCorePoolSize(null))
+ ++n;
+ return n;
+ }
+
+ /**
+ * Sets the maximum allowed number of threads. This overrides any
+ * value set in the constructor. If the new value is smaller than
+ * the current value, excess existing threads will be
+ * terminated when they next become idle.
+ *
+ * @param maximumPoolSize the new maximum
+ * @throws IllegalArgumentException if maximumPoolSize less than zero or
+ * the {@link #getCorePoolSize core pool size}
+ * @see #getMaximumPoolSize
+ */
+ public void setMaximumPoolSize(int maximumPoolSize) {
+ if (maximumPoolSize <= 0 || maximumPoolSize < corePoolSize)
+ throw new IllegalArgumentException();
+ final ReentrantLock mainLock = this.mainLock;
+ mainLock.lock();
+ try {
+ int extra = this.maximumPoolSize - maximumPoolSize;
+ this.maximumPoolSize = maximumPoolSize;
+ if (extra > 0 && poolSize > maximumPoolSize) {
+ Iterator<Worker> it = workers.iterator();
+ while (it.hasNext() &&
+ extra > 0 &&
+ poolSize > maximumPoolSize) {
+ it.next().interruptIfIdle();
+ --extra;
+ }
+ }
+ } finally {
+ mainLock.unlock();
+ }
+ }
+
+ /**
+ * Returns the maximum allowed number of threads.
+ *
+ * @return the maximum allowed number of threads
+ * @see #setMaximumPoolSize
+ */
+ public int getMaximumPoolSize() {
+ return maximumPoolSize;
+ }
+
+ /**
+ * Sets the time limit for which threads may remain idle before
+ * being terminated. If there are more than the core number of
+ * threads currently in the pool, after waiting this amount of
+ * time without processing a task, excess threads will be
+ * terminated. This overrides any value set in the constructor.
+ * @param time the time to wait. A time value of zero will cause
+ * excess threads to terminate immediately after executing tasks.
+ * @param unit the time unit of the time argument
+ * @throws IllegalArgumentException if time less than zero
+ * @see #getKeepAliveTime
+ */
+ public void setKeepAliveTime(long time, TimeUnit unit) {
+ if (time < 0)
+ throw new IllegalArgumentException();
+ this.keepAliveTime = unit.toNanos(time);
+ }
+
+ /**
+ * Returns the thread keep-alive time, which is the amount of time
+ * which threads in excess of the core pool size may remain
+ * idle before being terminated.
+ *
+ * @param unit the desired time unit of the result
+ * @return the time limit
+ * @see #setKeepAliveTime
+ */
+ public long getKeepAliveTime(TimeUnit unit) {
+ return unit.convert(keepAliveTime, TimeUnit.NANOSECONDS);
+ }
+
+ /* Statistics */
+
+ /**
+ * Returns the current number of threads in the pool.
+ *
+ * @return the number of threads
+ */
+ public int getPoolSize() {
+ return poolSize;
+ }
+
+ /**
+ * Returns the approximate number of threads that are actively
+ * executing tasks.
+ *
+ * @return the number of threads
+ */
+ public int getActiveCount() {
+ final ReentrantLock mainLock = this.mainLock;
+ mainLock.lock();
+ try {
+ int n = 0;
+ for (Worker w : workers) {
+ if (w.isActive())
+ ++n;
+ }
+ return n;
+ } finally {
+ mainLock.unlock();
+ }
+ }
+
+ /**
+ * Returns the largest number of threads that have ever
+ * simultaneously been in the pool.
+ *
+ * @return the number of threads
+ */
+ public int getLargestPoolSize() {
+ final ReentrantLock mainLock = this.mainLock;
+ mainLock.lock();
+ try {
+ return largestPoolSize;
+ } finally {
+ mainLock.unlock();
+ }
+ }
+
+ /**
+ * Returns the approximate total number of tasks that have been
+ * scheduled for execution. Because the states of tasks and
+ * threads may change dynamically during computation, the returned
+ * value is only an approximation, but one that does not ever
+ * decrease across successive calls.
+ *
+ * @return the number of tasks
+ */
+ public long getTaskCount() {
+ final ReentrantLock mainLock = this.mainLock;
+ mainLock.lock();
+ try {
+ long n = completedTaskCount;
+ for (Worker w : workers) {
+ n += w.completedTasks;
+ if (w.isActive())
+ ++n;
+ }
+ return n + workQueue.size();
+ } finally {
+ mainLock.unlock();
+ }
+ }
+
+ /**
+ * Returns the approximate total number of tasks that have
+ * completed execution. Because the states of tasks and threads
+ * may change dynamically during computation, the returned value
+ * is only an approximation, but one that does not ever decrease
+ * across successive calls.
+ *
+ * @return the number of tasks
+ */
+ public long getCompletedTaskCount() {
+ final ReentrantLock mainLock = this.mainLock;
+ mainLock.lock();
+ try {
+ long n = completedTaskCount;
+ for (Worker w : workers)
+ n += w.completedTasks;
+ return n;
+ } finally {
+ mainLock.unlock();
+ }
+ }
+
+ /**
+ * Method invoked prior to executing the given Runnable in the
+ * given thread. This method is invoked by thread <tt>t</tt> that
+ * will execute task <tt>r</tt>, and may be used to re-initialize
+ * ThreadLocals, or to perform logging. Note: To properly nest
+ * multiple overridings, subclasses should generally invoke
+ * <tt>super.beforeExecute</tt> at the end of this method.
+ *
+ * @param t the thread that will run task r.
+ * @param r the task that will be executed.
+ */
+ protected void beforeExecute(Thread t, Runnable r) { }
+
+ /**
+ * Method invoked upon completion of execution of the given
+ * Runnable. This method is invoked by the thread that executed
+ * the task. If non-null, the Throwable is the uncaught exception
+ * that caused execution to terminate abruptly. Note: To properly
+ * nest multiple overridings, subclasses should generally invoke
+ * <tt>super.afterExecute</tt> at the beginning of this method.
+ *
+ * @param r the runnable that has completed.
+ * @param t the exception that caused termination, or null if
+ * execution completed normally.
+ */
+ protected void afterExecute(Runnable r, Throwable t) { }
+
+ /**
+ * Method invoked when the Executor has terminated. Default
+ * implementation does nothing. Note: To properly nest multiple
+ * overridings, subclasses should generally invoke
+ * <tt>super.terminated</tt> within this method.
+ */
+ protected void terminated() { }
+
+ /**
+ * A handler for rejected tasks that runs the rejected task
+ * directly in the calling thread of the <tt>execute</tt> method,
+ * unless the executor has been shut down, in which case the task
+ * is discarded.
+ */
+ public static class CallerRunsPolicy implements RejectedExecutionHandler {
+ /**
+ * Creates a <tt>CallerRunsPolicy</tt>.
+ */
+ public CallerRunsPolicy() { }
+
+ /**
+ * Executes task r in the caller's thread, unless the executor
+ * has been shut down, in which case the task is discarded.
+ * @param r the runnable task requested to be executed
+ * @param e the executor attempting to execute this task
+ */
+ public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
+ if (!e.isShutdown()) {
+ r.run();
+ }
+ }
+ }
+
+ /**
+ * A handler for rejected tasks that throws a
+ * <tt>RejectedExecutionException</tt>.
+ */
+ public static class AbortPolicy implements RejectedExecutionHandler {
+ /**
+ * Creates an <tt>AbortPolicy</tt>.
+ */
+ public AbortPolicy() { }
+
+ /**
+ * Always throws RejectedExecutionException.
+ * @param r the runnable task requested to be executed
+ * @param e the executor attempting to execute this task
+ * @throws RejectedExecutionException always.
+ */
+ public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
+ throw new RejectedExecutionException();
+ }
+ }
+
+ /**
+ * A handler for rejected tasks that silently discards the
+ * rejected task.
+ */
+ public static class DiscardPolicy implements RejectedExecutionHandler {
+ /**
+ * Creates a <tt>DiscardPolicy</tt>.
+ */
+ public DiscardPolicy() { }
+
+ /**
+ * Does nothing, which has the effect of discarding task r.
+ * @param r the runnable task requested to be executed
+ * @param e the executor attempting to execute this task
+ */
+ public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
+ }
+ }
+
+ /**
+ * A handler for rejected tasks that discards the oldest unhandled
+ * request and then retries <tt>execute</tt>, unless the executor
+ * is shut down, in which case the task is discarded.
+ */
+ public static class DiscardOldestPolicy implements RejectedExecutionHandler {
+ /**
+ * Creates a <tt>DiscardOldestPolicy</tt> for the given executor.
+ */
+ public DiscardOldestPolicy() { }
+
+ /**
+ * Obtains and ignores the next task that the executor
+ * would otherwise execute, if one is immediately available,
+ * and then retries execution of task r, unless the executor
+ * is shut down, in which case task r is instead discarded.
+ * @param r the runnable task requested to be executed
+ * @param e the executor attempting to execute this task
+ */
+ public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
+ if (!e.isShutdown()) {
+ e.getQueue().poll();
+ e.execute(r);
+ }
+ }
+ }
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/TimeUnit.java b/concurrent/src/main/java/java/util/concurrent/TimeUnit.java
new file mode 100644
index 0000000..b186aeb
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/TimeUnit.java
@@ -0,0 +1,238 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+
+/**
+ * A <tt>TimeUnit</tt> represents time durations at a given unit of
+ * granularity and provides utility methods to convert across units,
+ * and to perform timing and delay operations in these units. A
+ * <tt>TimeUnit</tt> does not maintain time information, but only
+ * helps organize and use time representations that may be maintained
+ * separately across various contexts.
+ *
+ * <p>A <tt>TimeUnit</tt> is mainly used to inform time-based methods
+ * how a given timing parameter should be interpreted. For example,
+ * the following code will timeout in 50 milliseconds if the {@link
+ * java.util.concurrent.locks.Lock lock} is not available:
+ *
+ * <pre> Lock lock = ...;
+ * if ( lock.tryLock(50L, TimeUnit.MILLISECONDS) ) ...
+ * </pre>
+ * while this code will timeout in 50 seconds:
+ * <pre>
+ * Lock lock = ...;
+ * if ( lock.tryLock(50L, TimeUnit.SECONDS) ) ...
+ * </pre>
+ *
+ * Note however, that there is no guarantee that a particular timeout
+ * implementation will be able to notice the passage of time at the
+ * same granularity as the given <tt>TimeUnit</tt>.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ */
+public enum TimeUnit {
+ /** TimeUnit which represents one nanosecond. */
+ NANOSECONDS(0),
+ /** TimeUnit which represents one microsecond. */
+ MICROSECONDS(1),
+ /** TimeUnit which represents one millisecond. */
+ MILLISECONDS(2),
+ /** TimeUnit which represents one second. */
+ SECONDS(3);
+
+ /** the index of this unit */
+ private final int index;
+
+ /** Internal constructor */
+ TimeUnit(int index) {
+ this.index = index;
+ }
+
+ /** Lookup table for conversion factors */
+ private static final int[] multipliers = {
+ 1,
+ 1000,
+ 1000 * 1000,
+ 1000 * 1000 * 1000
+ };
+
+ /**
+ * Lookup table to check saturation. Note that because we are
+ * dividing these down, we don't have to deal with asymmetry of
+ * MIN/MAX values.
+ */
+ private static final long[] overflows = {
+ 0, // unused
+ Long.MAX_VALUE / 1000,
+ Long.MAX_VALUE / (1000 * 1000),
+ Long.MAX_VALUE / (1000 * 1000 * 1000)
+ };
+
+ /**
+ * Perform conversion based on given delta representing the
+ * difference between units
+ * @param delta the difference in index values of source and target units
+ * @param duration the duration
+ * @return converted duration or saturated value
+ */
+ private static long doConvert(int delta, long duration) {
+ if (delta == 0)
+ return duration;
+ if (delta < 0)
+ return duration / multipliers[-delta];
+ if (duration > overflows[delta])
+ return Long.MAX_VALUE;
+ if (duration < -overflows[delta])
+ return Long.MIN_VALUE;
+ return duration * multipliers[delta];
+ }
+
+ /**
+ * Convert the given time duration in the given unit to this
+ * unit. Conversions from finer to coarser granularities
+ * truncate, so lose precision. For example converting
+ * <tt>999</tt> milliseconds to seconds results in
+ * <tt>0</tt>. Conversions from coarser to finer granularities
+ * with arguments that would numerically overflow saturate to
+ * <tt>Long.MIN_VALUE</tt> if negative or <tt>Long.MAX_VALUE</tt>
+ * if positive.
+ *
+ * @param duration the time duration in the given <tt>unit</tt>
+ * @param unit the unit of the <tt>duration</tt> argument
+ * @return the converted duration in this unit,
+ * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
+ * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
+ */
+ public long convert(long duration, TimeUnit unit) {
+ return doConvert(unit.index - index, duration);
+ }
+
+ /**
+ * Equivalent to <tt>NANOSECONDS.convert(duration, this)</tt>.
+ * @param duration the duration
+ * @return the converted duration,
+ * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
+ * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
+ * @see #convert
+ */
+ public long toNanos(long duration) {
+ return doConvert(index, duration);
+ }
+
+ /**
+ * Equivalent to <tt>MICROSECONDS.convert(duration, this)</tt>.
+ * @param duration the duration
+ * @return the converted duration,
+ * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
+ * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
+ * @see #convert
+ */
+ public long toMicros(long duration) {
+ return doConvert(index - MICROSECONDS.index, duration);
+ }
+
+ /**
+ * Equivalent to <tt>MILLISECONDS.convert(duration, this)</tt>.
+ * @param duration the duration
+ * @return the converted duration,
+ * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
+ * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
+ * @see #convert
+ */
+ public long toMillis(long duration) {
+ return doConvert(index - MILLISECONDS.index, duration);
+ }
+
+ /**
+ * Equivalent to <tt>SECONDS.convert(duration, this)</tt>.
+ * @param duration the duration
+ * @return the converted duration.
+ * @see #convert
+ */
+ public long toSeconds(long duration) {
+ return doConvert(index - SECONDS.index, duration);
+ }
+
+
+ /**
+ * Utility method to compute the excess-nanosecond argument to
+ * wait, sleep, join.
+ */
+ private int excessNanos(long time, long ms) {
+ if (this == NANOSECONDS)
+ return (int) (time - (ms * 1000 * 1000));
+ if (this == MICROSECONDS)
+ return (int) ((time * 1000) - (ms * 1000 * 1000));
+ return 0;
+ }
+
+ /**
+ * Perform a timed <tt>Object.wait</tt> using this time unit.
+ * This is a convenience method that converts timeout arguments
+ * into the form required by the <tt>Object.wait</tt> method.
+ *
+ * <p>For example, you could implement a blocking <tt>poll</tt>
+ * method (see {@link BlockingQueue#poll BlockingQueue.poll})
+ * using:
+ *
+ * <pre> public synchronized Object poll(long timeout, TimeUnit unit) throws InterruptedException {
+ * while (empty) {
+ * unit.timedWait(this, timeout);
+ * ...
+ * }
+ * }</pre>
+ *
+ * @param obj the object to wait on
+ * @param timeout the maximum time to wait.
+ * @throws InterruptedException if interrupted while waiting.
+ * @see Object#wait(long, int)
+ */
+ public void timedWait(Object obj, long timeout)
+ throws InterruptedException {
+ if (timeout > 0) {
+ long ms = toMillis(timeout);
+ int ns = excessNanos(timeout, ms);
+ obj.wait(ms, ns);
+ }
+ }
+
+ /**
+ * Perform a timed <tt>Thread.join</tt> using this time unit.
+ * This is a convenience method that converts time arguments into the
+ * form required by the <tt>Thread.join</tt> method.
+ * @param thread the thread to wait for
+ * @param timeout the maximum time to wait
+ * @throws InterruptedException if interrupted while waiting.
+ * @see Thread#join(long, int)
+ */
+ public void timedJoin(Thread thread, long timeout)
+ throws InterruptedException {
+ if (timeout > 0) {
+ long ms = toMillis(timeout);
+ int ns = excessNanos(timeout, ms);
+ thread.join(ms, ns);
+ }
+ }
+
+ /**
+ * Perform a <tt>Thread.sleep</tt> using this unit.
+ * This is a convenience method that converts time arguments into the
+ * form required by the <tt>Thread.sleep</tt> method.
+ * @param timeout the minimum time to sleep
+ * @throws InterruptedException if interrupted while sleeping.
+ * @see Thread#sleep
+ */
+ public void sleep(long timeout) throws InterruptedException {
+ if (timeout > 0) {
+ long ms = toMillis(timeout);
+ int ns = excessNanos(timeout, ms);
+ Thread.sleep(ms, ns);
+ }
+ }
+
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/TimeoutException.java b/concurrent/src/main/java/java/util/concurrent/TimeoutException.java
new file mode 100644
index 0000000..8b84f28
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/TimeoutException.java
@@ -0,0 +1,38 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+
+/**
+ * Exception thrown when a blocking operation times out. Blocking
+ * operations for which a timeout is specified need a means to
+ * indicate that the timeout has occurred. For many such operations it
+ * is possible to return a value that indicates timeout; when that is
+ * not possible or desirable then <tt>TimeoutException</tt> should be
+ * declared and thrown.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ */
+public class TimeoutException extends Exception {
+ private static final long serialVersionUID = 1900926677490660714L;
+
+ /**
+ * Constructs a <tt>TimeoutException</tt> with no specified detail
+ * message.
+ */
+ public TimeoutException() {}
+
+ /**
+ * Constructs a <tt>TimeoutException</tt> with the specified detail
+ * message.
+ *
+ * @param message the detail message
+ */
+ public TimeoutException(String message) {
+ super(message);
+ }
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicBoolean.java b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicBoolean.java
new file mode 100644
index 0000000..5b9b556
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicBoolean.java
@@ -0,0 +1,127 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.atomic;
+import sun.misc.Unsafe;
+
+/**
+ * A <tt>boolean</tt> value that may be updated atomically. See the
+ * {@link java.util.concurrent.atomic} package specification for
+ * description of the properties of atomic variables. An
+ * <tt>AtomicBoolean</tt> is used in applications such as atomically
+ * updated flags, and cannot be used as a replacement for a
+ * {@link java.lang.Boolean}.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ */
+public class AtomicBoolean implements java.io.Serializable {
+ private static final long serialVersionUID = 4654671469794556979L;
+
+ // setup to use Unsafe.compareAndSwapInt for updates
+ // BEGIN android-changed
+ private static final Unsafe unsafe = UnsafeAccess.THE_ONE;
+ // END android-changed
+
+ private static final long valueOffset;
+
+ static {
+ try {
+ valueOffset = unsafe.objectFieldOffset
+ (AtomicBoolean.class.getDeclaredField("value"));
+ } catch (Exception ex) { throw new Error(ex); }
+ }
+
+ private volatile int value;
+
+ /**
+ * Creates a new <tt>AtomicBoolean</tt> with the given initial value.
+ *
+ * @param initialValue the initial value
+ */
+ public AtomicBoolean(boolean initialValue) {
+ value = initialValue ? 1 : 0;
+ }
+
+ /**
+ * Creates a new <tt>AtomicBoolean</tt> with initial value <tt>false</tt>.
+ */
+ public AtomicBoolean() {
+ }
+
+ /**
+ * Returns the current value.
+ *
+ * @return the current value
+ */
+ public final boolean get() {
+ return value != 0;
+ }
+
+ /**
+ * Atomically sets the value to the given update value if the
+ * current value is equal to the expected value. Any given
+ * invocation of this operation may fail (return
+ * <tt>false</tt>) spuriously, but repeated invocation when
+ * the current value holds the expected value and no other thread
+ * is also attempting to set the value will eventually succeed.
+ *
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful
+ */
+ public final boolean compareAndSet(boolean expect, boolean update) {
+ int e = expect ? 1 : 0;
+ int u = update ? 1 : 0;
+ return unsafe.compareAndSwapInt(this, valueOffset, e, u);
+ }
+
+ /**
+ * Atomically set the value to the given updated value
+ * if the current value <tt>==</tt> the expected value.
+ * May fail spuriously.
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful.
+ */
+ public boolean weakCompareAndSet(boolean expect, boolean update) {
+ int e = expect ? 1 : 0;
+ int u = update ? 1 : 0;
+ return unsafe.compareAndSwapInt(this, valueOffset, e, u);
+ }
+
+ /**
+ * Unconditionally sets to the given value.
+ *
+ * @param newValue the new value
+ */
+ public final void set(boolean newValue) {
+ value = newValue ? 1 : 0;
+ }
+
+ /**
+ * Sets to the given value and returns the previous value.
+ *
+ * @param newValue the new value
+ * @return the previous value
+ */
+ public final boolean getAndSet(boolean newValue) {
+ for (;;) {
+ boolean current = get();
+ if (compareAndSet(current, newValue))
+ return current;
+ }
+ }
+
+ /**
+ * Returns the String representation of the current value.
+ * @return the String representation of the current value.
+ */
+ public String toString() {
+ return Boolean.toString(get());
+ }
+
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicInteger.java b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicInteger.java
new file mode 100644
index 0000000..2b9d15c
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicInteger.java
@@ -0,0 +1,223 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.atomic;
+import sun.misc.Unsafe;
+
+/**
+ * An <tt>int</tt> value that may be updated atomically. See the
+ * {@link java.util.concurrent.atomic} package specification for
+ * description of the properties of atomic variables. An
+ * <tt>AtomicInteger</tt> is used in applications such as atomically
+ * incremented counters, and cannot be used as a replacement for an
+ * {@link java.lang.Integer}. However, this class does extend
+ * <tt>Number</tt> to allow uniform access by tools and utilities that
+ * deal with numerically-based classes.
+ *
+ *
+ * @since 1.5
+ * @author Doug Lea
+*/
+public class AtomicInteger extends Number implements java.io.Serializable {
+ private static final long serialVersionUID = 6214790243416807050L;
+
+ // setup to use Unsafe.compareAndSwapInt for updates
+ // BEGIN android-changed
+ private static final Unsafe unsafe = UnsafeAccess.THE_ONE;
+ // END android-changed
+ private static final long valueOffset;
+
+ static {
+ try {
+ valueOffset = unsafe.objectFieldOffset
+ (AtomicInteger.class.getDeclaredField("value"));
+ } catch(Exception ex) { throw new Error(ex); }
+ }
+
+ private volatile int value;
+
+ /**
+ * Create a new AtomicInteger with the given initial value.
+ *
+ * @param initialValue the initial value
+ */
+ public AtomicInteger(int initialValue) {
+ value = initialValue;
+ }
+
+ /**
+ * Create a new AtomicInteger with initial value <tt>0</tt>.
+ */
+ public AtomicInteger() {
+ }
+
+ /**
+ * Get the current value.
+ *
+ * @return the current value
+ */
+ public final int get() {
+ return value;
+ }
+
+ /**
+ * Set to the given value.
+ *
+ * @param newValue the new value
+ */
+ public final void set(int newValue) {
+ value = newValue;
+ }
+
+ /**
+ * Set to the give value and return the old value.
+ *
+ * @param newValue the new value
+ * @return the previous value
+ */
+ public final int getAndSet(int newValue) {
+ for (;;) {
+ int current = get();
+ if (compareAndSet(current, newValue))
+ return current;
+ }
+ }
+
+
+ /**
+ * Atomically set the value to the given updated value
+ * if the current value <tt>==</tt> the expected value.
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful. False return indicates that
+ * the actual value was not equal to the expected value.
+ */
+ public final boolean compareAndSet(int expect, int update) {
+ return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
+ }
+
+ /**
+ * Atomically set the value to the given updated value
+ * if the current value <tt>==</tt> the expected value.
+ * May fail spuriously.
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful.
+ */
+ public final boolean weakCompareAndSet(int expect, int update) {
+ return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
+ }
+
+
+ /**
+ * Atomically increment by one the current value.
+ * @return the previous value
+ */
+ public final int getAndIncrement() {
+ for (;;) {
+ int current = get();
+ int next = current + 1;
+ if (compareAndSet(current, next))
+ return current;
+ }
+ }
+
+
+ /**
+ * Atomically decrement by one the current value.
+ * @return the previous value
+ */
+ public final int getAndDecrement() {
+ for (;;) {
+ int current = get();
+ int next = current - 1;
+ if (compareAndSet(current, next))
+ return current;
+ }
+ }
+
+
+ /**
+ * Atomically add the given value to current value.
+ * @param delta the value to add
+ * @return the previous value
+ */
+ public final int getAndAdd(int delta) {
+ for (;;) {
+ int current = get();
+ int next = current + delta;
+ if (compareAndSet(current, next))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically increment by one the current value.
+ * @return the updated value
+ */
+ public final int incrementAndGet() {
+ for (;;) {
+ int current = get();
+ int next = current + 1;
+ if (compareAndSet(current, next))
+ return next;
+ }
+ }
+
+ /**
+ * Atomically decrement by one the current value.
+ * @return the updated value
+ */
+ public final int decrementAndGet() {
+ for (;;) {
+ int current = get();
+ int next = current - 1;
+ if (compareAndSet(current, next))
+ return next;
+ }
+ }
+
+
+ /**
+ * Atomically add the given value to current value.
+ * @param delta the value to add
+ * @return the updated value
+ */
+ public final int addAndGet(int delta) {
+ for (;;) {
+ int current = get();
+ int next = current + delta;
+ if (compareAndSet(current, next))
+ return next;
+ }
+ }
+
+ /**
+ * Returns the String representation of the current value.
+ * @return the String representation of the current value.
+ */
+ public String toString() {
+ return Integer.toString(get());
+ }
+
+
+ public int intValue() {
+ return get();
+ }
+
+ public long longValue() {
+ return (long)get();
+ }
+
+ public float floatValue() {
+ return (float)get();
+ }
+
+ public double doubleValue() {
+ return (double)get();
+ }
+
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerArray.java b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerArray.java
new file mode 100644
index 0000000..5c49038
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerArray.java
@@ -0,0 +1,246 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.atomic;
+import sun.misc.Unsafe;
+import java.util.*;
+
+/**
+ * An <tt>int</tt> array in which elements may be updated atomically.
+ * See the {@link java.util.concurrent.atomic} package
+ * specification for description of the properties of atomic
+ * variables.
+ * @since 1.5
+ * @author Doug Lea
+ */
+public class AtomicIntegerArray implements java.io.Serializable {
+ private static final long serialVersionUID = 2862133569453604235L;
+
+ // setup to use Unsafe.compareAndSwapInt for updates
+ // BEGIN android-changed
+ private static final Unsafe unsafe = UnsafeAccess.THE_ONE;
+ // END android-changed
+
+ private static final int base = unsafe.arrayBaseOffset(int[].class);
+ private static final int scale = unsafe.arrayIndexScale(int[].class);
+ private final int[] array;
+
+ private long rawIndex(int i) {
+ if (i < 0 || i >= array.length)
+ throw new IndexOutOfBoundsException("index " + i);
+ return base + i * scale;
+ }
+
+ /**
+ * Create a new AtomicIntegerArray of given length.
+ *
+ * @param length the length of the array
+ */
+ public AtomicIntegerArray(int length) {
+ array = new int[length];
+ // must perform at least one volatile write to conform to JMM
+ if (length > 0)
+ unsafe.putIntVolatile(array, rawIndex(0), 0);
+ }
+
+ /**
+ * Create a new AtomicIntegerArray with the same length as, and
+ * all elements copied from, the given array.
+ *
+ * @param array the array to copy elements from
+ * @throws NullPointerException if array is null
+ */
+ public AtomicIntegerArray(int[] array) {
+ if (array == null)
+ throw new NullPointerException();
+ int length = array.length;
+ this.array = new int[length];
+ if (length > 0) {
+ int last = length-1;
+ for (int i = 0; i < last; ++i)
+ this.array[i] = array[i];
+ // Do the last write as volatile
+ unsafe.putIntVolatile(this.array, rawIndex(last), array[last]);
+ }
+ }
+
+ /**
+ * Returns the length of the array.
+ *
+ * @return the length of the array
+ */
+ public final int length() {
+ return array.length;
+ }
+
+ /**
+ * Get the current value at position <tt>i</tt>.
+ *
+ * @param i the index
+ * @return the current value
+ */
+ public final int get(int i) {
+ return unsafe.getIntVolatile(array, rawIndex(i));
+ }
+
+ /**
+ * Set the element at position <tt>i</tt> to the given value.
+ *
+ * @param i the index
+ * @param newValue the new value
+ */
+ public final void set(int i, int newValue) {
+ unsafe.putIntVolatile(array, rawIndex(i), newValue);
+ }
+
+ /**
+ * Set the element at position <tt>i</tt> to the given value and return the
+ * old value.
+ *
+ * @param i the index
+ * @param newValue the new value
+ * @return the previous value
+ */
+ public final int getAndSet(int i, int newValue) {
+ while (true) {
+ int current = get(i);
+ if (compareAndSet(i, current, newValue))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically set the value to the given updated value
+ * if the current value <tt>==</tt> the expected value.
+ *
+ * @param i the index
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful. False return indicates that
+ * the actual value was not equal to the expected value.
+ */
+ public final boolean compareAndSet(int i, int expect, int update) {
+ return unsafe.compareAndSwapInt(array, rawIndex(i),
+ expect, update);
+ }
+
+ /**
+ * Atomically set the value to the given updated value
+ * if the current value <tt>==</tt> the expected value.
+ * May fail spuriously.
+ *
+ * @param i the index
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful.
+ */
+ public final boolean weakCompareAndSet(int i, int expect, int update) {
+ return compareAndSet(i, expect, update);
+ }
+
+ /**
+ * Atomically increment by one the element at index <tt>i</tt>.
+ *
+ * @param i the index
+ * @return the previous value;
+ */
+ public final int getAndIncrement(int i) {
+ while (true) {
+ int current = get(i);
+ int next = current + 1;
+ if (compareAndSet(i, current, next))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically decrement by one the element at index <tt>i</tt>.
+ *
+ * @param i the index
+ * @return the previous value;
+ */
+ public final int getAndDecrement(int i) {
+ while (true) {
+ int current = get(i);
+ int next = current - 1;
+ if (compareAndSet(i, current, next))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically add the given value to element at index <tt>i</tt>.
+ *
+ * @param i the index
+ * @param delta the value to add
+ * @return the previous value;
+ */
+ public final int getAndAdd(int i, int delta) {
+ while (true) {
+ int current = get(i);
+ int next = current + delta;
+ if (compareAndSet(i, current, next))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically increment by one the element at index <tt>i</tt>.
+ *
+ * @param i the index
+ * @return the updated value;
+ */
+ public final int incrementAndGet(int i) {
+ while (true) {
+ int current = get(i);
+ int next = current + 1;
+ if (compareAndSet(i, current, next))
+ return next;
+ }
+ }
+
+ /**
+ * Atomically decrement by one the element at index <tt>i</tt>.
+ *
+ * @param i the index
+ * @return the updated value;
+ */
+ public final int decrementAndGet(int i) {
+ while (true) {
+ int current = get(i);
+ int next = current - 1;
+ if (compareAndSet(i, current, next))
+ return next;
+ }
+ }
+
+ /**
+ * Atomically add the given value to element at index <tt>i</tt>.
+ *
+ * @param i the index
+ * @param delta the value to add
+ * @return the updated value;
+ */
+ public final int addAndGet(int i, int delta) {
+ while (true) {
+ int current = get(i);
+ int next = current + delta;
+ if (compareAndSet(i, current, next))
+ return next;
+ }
+ }
+
+ /**
+ * Returns the String representation of the current values of array.
+ * @return the String representation of the current values of array.
+ */
+ public String toString() {
+ if (array.length > 0) // force volatile read
+ get(0);
+ return Arrays.toString(array);
+ }
+
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java
new file mode 100644
index 0000000..e3a0515
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java
@@ -0,0 +1,261 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.atomic;
+import sun.misc.Unsafe;
+import java.lang.reflect.*;
+
+/**
+ * A reflection-based utility that enables atomic updates to
+ * designated <tt>volatile int</tt> fields of designated classes.
+ * This class is designed for use in atomic data structures in which
+ * several fields of the same node are independently subject to atomic
+ * updates.
+ *
+ * <p> Note that the guarantees of the <tt>compareAndSet</tt> method
+ * in this class are weaker than in other atomic classes. Because this
+ * class cannot ensure that all uses of the field are appropriate for
+ * purposes of atomic access, it can guarantee atomicity and volatile
+ * semantics only with respect to other invocations of
+ * <tt>compareAndSet</tt> and <tt>set</tt>.
+ * @since 1.5
+ * @author Doug Lea
+ * @param <T> The type of the object holding the updatable field
+ */
+public abstract class AtomicIntegerFieldUpdater<T> {
+ /**
+ * Creates an updater for objects with the given field. The Class
+ * argument is needed to check that reflective types and generic
+ * types match.
+ * @param tclass the class of the objects holding the field
+ * @param fieldName the name of the field to be updated.
+ * @return the updater
+ * @throws IllegalArgumentException if the field is not a
+ * volatile integer type.
+ * @throws RuntimeException with a nested reflection-based
+ * exception if the class does not hold field or is the wrong type.
+ */
+ public static <U> AtomicIntegerFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) {
+ return new AtomicIntegerFieldUpdaterImpl<U>(tclass, fieldName);
+ }
+
+ /**
+ * Protected do-nothing constructor for use by subclasses.
+ */
+ protected AtomicIntegerFieldUpdater() {
+ }
+
+ /**
+ * Atomically set the value of the field of the given object managed
+ * by this Updater to the given updated value if the current value
+ * <tt>==</tt> the expected value. This method is guaranteed to be
+ * atomic with respect to other calls to <tt>compareAndSet</tt> and
+ * <tt>set</tt>, but not necessarily with respect to other
+ * changes in the field.
+ * @param obj An object whose field to conditionally set
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful.
+ * @throws ClassCastException if <tt>obj</tt> is not an instance
+ * of the class possessing the field established in the constructor.
+ */
+
+ public abstract boolean compareAndSet(T obj, int expect, int update);
+
+ /**
+ * Atomically set the value of the field of the given object managed
+ * by this Updater to the given updated value if the current value
+ * <tt>==</tt> the expected value. This method is guaranteed to be
+ * atomic with respect to other calls to <tt>compareAndSet</tt> and
+ * <tt>set</tt>, but not necessarily with respect to other
+ * changes in the field, and may fail spuriously.
+ * @param obj An object whose field to conditionally set
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful.
+ * @throws ClassCastException if <tt>obj</tt> is not an instance
+ * of the class possessing the field established in the constructor.
+ */
+
+ public abstract boolean weakCompareAndSet(T obj, int expect, int update);
+
+ /**
+ * Set the field of the given object managed by this updater. This
+ * operation is guaranteed to act as a volatile store with respect
+ * to subsequent invocations of <tt>compareAndSet</tt>.
+ * @param obj An object whose field to set
+ * @param newValue the new value
+ */
+ public abstract void set(T obj, int newValue);
+
+ /**
+ * Get the current value held in the field by the given object.
+ * @param obj An object whose field to get
+ * @return the current value
+ */
+ public abstract int get(T obj);
+
+ /**
+ * Set to the given value and return the old value.
+ *
+ * @param obj An object whose field to get and set
+ * @param newValue the new value
+ * @return the previous value
+ */
+ public int getAndSet(T obj, int newValue) {
+ for (;;) {
+ int current = get(obj);
+ if (compareAndSet(obj, current, newValue))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically increment by one the current value.
+ * @param obj An object whose field to get and set
+ * @return the previous value;
+ */
+ public int getAndIncrement(T obj) {
+ for (;;) {
+ int current = get(obj);
+ int next = current + 1;
+ if (compareAndSet(obj, current, next))
+ return current;
+ }
+ }
+
+
+ /**
+ * Atomically decrement by one the current value.
+ * @param obj An object whose field to get and set
+ * @return the previous value;
+ */
+ public int getAndDecrement(T obj) {
+ for (;;) {
+ int current = get(obj);
+ int next = current - 1;
+ if (compareAndSet(obj, current, next))
+ return current;
+ }
+ }
+
+
+ /**
+ * Atomically add the given value to current value.
+ * @param obj An object whose field to get and set
+ * @param delta the value to add
+ * @return the previous value;
+ */
+ public int getAndAdd(T obj, int delta) {
+ for (;;) {
+ int current = get(obj);
+ int next = current + delta;
+ if (compareAndSet(obj, current, next))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically increment by one the current value.
+ * @param obj An object whose field to get and set
+ * @return the updated value;
+ */
+ public int incrementAndGet(T obj) {
+ for (;;) {
+ int current = get(obj);
+ int next = current + 1;
+ if (compareAndSet(obj, current, next))
+ return next;
+ }
+ }
+
+
+ /**
+ * Atomically decrement by one the current value.
+ * @param obj An object whose field to get and set
+ * @return the updated value;
+ */
+ public int decrementAndGet(T obj) {
+ for (;;) {
+ int current = get(obj);
+ int next = current - 1;
+ if (compareAndSet(obj, current, next))
+ return next;
+ }
+ }
+
+
+ /**
+ * Atomically add the given value to current value.
+ * @param obj An object whose field to get and set
+ * @param delta the value to add
+ * @return the updated value;
+ */
+ public int addAndGet(T obj, int delta) {
+ for (;;) {
+ int current = get(obj);
+ int next = current + delta;
+ if (compareAndSet(obj, current, next))
+ return next;
+ }
+ }
+
+ /**
+ * Standard hotspot implementation using intrinsics
+ */
+ private static class AtomicIntegerFieldUpdaterImpl<T> extends AtomicIntegerFieldUpdater<T> {
+ // BEGIN android-changed
+ private static final Unsafe unsafe = UnsafeAccess.THE_ONE;
+ // END android-changed
+
+ private final long offset;
+ private final Class<T> tclass;
+
+ AtomicIntegerFieldUpdaterImpl(Class<T> tclass, String fieldName) {
+ Field field = null;
+ try {
+ field = tclass.getDeclaredField(fieldName);
+ } catch(Exception ex) {
+ throw new RuntimeException(ex);
+ }
+
+ Class fieldt = field.getType();
+ if (fieldt != int.class)
+ throw new IllegalArgumentException("Must be integer type");
+
+ if (!Modifier.isVolatile(field.getModifiers()))
+ throw new IllegalArgumentException("Must be volatile type");
+
+ this.tclass = tclass;
+ offset = unsafe.objectFieldOffset(field);
+ }
+
+ public boolean compareAndSet(T obj, int expect, int update) {
+ if (!tclass.isInstance(obj))
+ throw new ClassCastException();
+ return unsafe.compareAndSwapInt(obj, offset, expect, update);
+ }
+
+ public boolean weakCompareAndSet(T obj, int expect, int update) {
+ if (!tclass.isInstance(obj))
+ throw new ClassCastException();
+ return unsafe.compareAndSwapInt(obj, offset, expect, update);
+ }
+
+ public void set(T obj, int newValue) {
+ if (!tclass.isInstance(obj))
+ throw new ClassCastException();
+ unsafe.putIntVolatile(obj, offset, newValue);
+ }
+
+ public final int get(T obj) {
+ if (!tclass.isInstance(obj))
+ throw new ClassCastException();
+ return unsafe.getIntVolatile(obj, offset);
+ }
+ }
+}
+
diff --git a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLong.java b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLong.java
new file mode 100644
index 0000000..ca45984
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLong.java
@@ -0,0 +1,235 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.atomic;
+import sun.misc.Unsafe;
+
+/**
+ * A <tt>long</tt> value that may be updated atomically. See the
+ * {@link java.util.concurrent.atomic} package specification for
+ * description of the properties of atomic variables. An
+ * <tt>AtomicLong</tt> is used in applications such as atomically
+ * incremented sequence numbers, and cannot be used as a replacement
+ * for a {@link java.lang.Long}. However, this class does extend
+ * <tt>Number</tt> to allow uniform access by tools and utilities that
+ * deal with numerically-based classes.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ */
+public class AtomicLong extends Number implements java.io.Serializable {
+ private static final long serialVersionUID = 1927816293512124184L;
+
+ // setup to use Unsafe.compareAndSwapLong for updates
+ // BEGIN android-changed
+ private static final Unsafe unsafe = UnsafeAccess.THE_ONE;
+ // END android-changed
+
+ private static final long valueOffset;
+
+ /**
+ * Record whether the underlying JVM supports lockless
+ * CompareAndSet for longs. While the unsafe.CompareAndSetLong
+ * method works in either case, some constructions should be
+ * handled at Java level to avoid locking user-visible locks.
+ */
+ static final boolean VM_SUPPORTS_LONG_CAS = VMSupportsCS8();
+
+ /**
+ * Returns whether underlying JVM supports lockless CompareAndSet
+ * for longs. Called only once and cached in VM_SUPPORTS_LONG_CAS.
+ */
+ private static native boolean VMSupportsCS8();
+
+ static {
+ try {
+ valueOffset = unsafe.objectFieldOffset
+ (AtomicLong.class.getDeclaredField("value"));
+ } catch(Exception ex) { throw new Error(ex); }
+ }
+
+ private volatile long value;
+
+ /**
+ * Create a new AtomicLong with the given initial value.
+ *
+ * @param initialValue the initial value
+ */
+ public AtomicLong(long initialValue) {
+ value = initialValue;
+ }
+
+ /**
+ * Create a new AtomicLong with initial value <tt>0</tt>.
+ */
+ public AtomicLong() {
+ }
+
+ /**
+ * Get the current value.
+ *
+ * @return the current value
+ */
+ public final long get() {
+ return value;
+ }
+
+ /**
+ * Set to the given value.
+ *
+ * @param newValue the new value
+ */
+ public final void set(long newValue) {
+ value = newValue;
+ }
+
+ /**
+ * Set to the give value and return the old value.
+ *
+ * @param newValue the new value
+ * @return the previous value
+ */
+ public final long getAndSet(long newValue) {
+ while (true) {
+ long current = get();
+ if (compareAndSet(current, newValue))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically set the value to the given updated value
+ * if the current value <tt>==</tt> the expected value.
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful. False return indicates that
+ * the actual value was not equal to the expected value.
+ */
+ public final boolean compareAndSet(long expect, long update) {
+ return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
+ }
+
+ /**
+ * Atomically set the value to the given updated value
+ * if the current value <tt>==</tt> the expected value.
+ * May fail spuriously.
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful.
+ */
+ public final boolean weakCompareAndSet(long expect, long update) {
+ return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
+ }
+
+ /**
+ * Atomically increment by one the current value.
+ * @return the previous value
+ */
+ public final long getAndIncrement() {
+ while (true) {
+ long current = get();
+ long next = current + 1;
+ if (compareAndSet(current, next))
+ return current;
+ }
+ }
+
+
+ /**
+ * Atomically decrement by one the current value.
+ * @return the previous value
+ */
+ public final long getAndDecrement() {
+ while (true) {
+ long current = get();
+ long next = current - 1;
+ if (compareAndSet(current, next))
+ return current;
+ }
+ }
+
+
+ /**
+ * Atomically add the given value to current value.
+ * @param delta the value to add
+ * @return the previous value
+ */
+ public final long getAndAdd(long delta) {
+ while (true) {
+ long current = get();
+ long next = current + delta;
+ if (compareAndSet(current, next))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically increment by one the current value.
+ * @return the updated value
+ */
+ public final long incrementAndGet() {
+ for (;;) {
+ long current = get();
+ long next = current + 1;
+ if (compareAndSet(current, next))
+ return next;
+ }
+ }
+
+ /**
+ * Atomically decrement by one the current value.
+ * @return the updated value
+ */
+ public final long decrementAndGet() {
+ for (;;) {
+ long current = get();
+ long next = current - 1;
+ if (compareAndSet(current, next))
+ return next;
+ }
+ }
+
+
+ /**
+ * Atomically add the given value to current value.
+ * @param delta the value to add
+ * @return the updated value
+ */
+ public final long addAndGet(long delta) {
+ for (;;) {
+ long current = get();
+ long next = current + delta;
+ if (compareAndSet(current, next))
+ return next;
+ }
+ }
+
+ /**
+ * Returns the String representation of the current value.
+ * @return the String representation of the current value.
+ */
+ public String toString() {
+ return Long.toString(get());
+ }
+
+
+ public int intValue() {
+ return (int)get();
+ }
+
+ public long longValue() {
+ return (long)get();
+ }
+
+ public float floatValue() {
+ return (float)get();
+ }
+
+ public double doubleValue() {
+ return (double)get();
+ }
+
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java
new file mode 100644
index 0000000..b9201b2
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java
@@ -0,0 +1,243 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.atomic;
+import sun.misc.Unsafe;
+import java.util.*;
+
+/**
+ * A <tt>long</tt> array in which elements may be updated atomically.
+ * See the {@link java.util.concurrent.atomic} package specification
+ * for description of the properties of atomic variables.
+ * @since 1.5
+ * @author Doug Lea
+ */
+public class AtomicLongArray implements java.io.Serializable {
+ private static final long serialVersionUID = -2308431214976778248L;
+
+ // setup to use Unsafe.compareAndSwapInt for updates
+ // BEGIN android-changed
+ private static final Unsafe unsafe = UnsafeAccess.THE_ONE;
+ // END android-changed
+
+ private static final int base = unsafe.arrayBaseOffset(long[].class);
+ private static final int scale = unsafe.arrayIndexScale(long[].class);
+ private final long[] array;
+
+ private long rawIndex(int i) {
+ if (i < 0 || i >= array.length)
+ throw new IndexOutOfBoundsException("index " + i);
+ return base + i * scale;
+ }
+
+ /**
+ * Create a new AtomicLongArray of given length.
+ * @param length the length of the array
+ */
+ public AtomicLongArray(int length) {
+ array = new long[length];
+ // must perform at least one volatile write to conform to JMM
+ if (length > 0)
+ unsafe.putLongVolatile(array, rawIndex(0), 0);
+ }
+
+ /**
+ * Create a new AtomicLongArray with the same length as, and
+ * all elements copied from, the given array.
+ *
+ * @param array the array to copy elements from
+ * @throws NullPointerException if array is null
+ */
+ public AtomicLongArray(long[] array) {
+ if (array == null)
+ throw new NullPointerException();
+ int length = array.length;
+ this.array = new long[length];
+ if (length > 0) {
+ int last = length-1;
+ for (int i = 0; i < last; ++i)
+ this.array[i] = array[i];
+ // Do the last write as volatile
+ unsafe.putLongVolatile(this.array, rawIndex(last), array[last]);
+ }
+ }
+
+ /**
+ * Returns the length of the array.
+ *
+ * @return the length of the array
+ */
+ public final int length() {
+ return array.length;
+ }
+
+ /**
+ * Get the current value at position <tt>i</tt>.
+ *
+ * @param i the index
+ * @return the current value
+ */
+ public final long get(int i) {
+ return unsafe.getLongVolatile(array, rawIndex(i));
+ }
+
+ /**
+ * Set the element at position <tt>i</tt> to the given value.
+ *
+ * @param i the index
+ * @param newValue the new value
+ */
+ public final void set(int i, long newValue) {
+ unsafe.putLongVolatile(array, rawIndex(i), newValue);
+ }
+
+ /**
+ * Set the element at position <tt>i</tt> to the given value and return the
+ * old value.
+ *
+ * @param i the index
+ * @param newValue the new value
+ * @return the previous value
+ */
+ public final long getAndSet(int i, long newValue) {
+ while (true) {
+ long current = get(i);
+ if (compareAndSet(i, current, newValue))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically set the value to the given updated value
+ * if the current value <tt>==</tt> the expected value.
+ * @param i the index
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful. False return indicates that
+ * the actual value was not equal to the expected value.
+ */
+ public final boolean compareAndSet(int i, long expect, long update) {
+ return unsafe.compareAndSwapLong(array, rawIndex(i),
+ expect, update);
+ }
+
+ /**
+ * Atomically set the value to the given updated value
+ * if the current value <tt>==</tt> the expected value.
+ * May fail spuriously.
+ * @param i the index
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful.
+ */
+ public final boolean weakCompareAndSet(int i, long expect, long update) {
+ return compareAndSet(i, expect, update);
+ }
+
+ /**
+ * Atomically increment by one the element at index <tt>i</tt>.
+ *
+ * @param i the index
+ * @return the previous value;
+ */
+ public final long getAndIncrement(int i) {
+ while (true) {
+ long current = get(i);
+ long next = current + 1;
+ if (compareAndSet(i, current, next))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically decrement by one the element at index <tt>i</tt>.
+ *
+ * @param i the index
+ * @return the previous value;
+ */
+ public final long getAndDecrement(int i) {
+ while (true) {
+ long current = get(i);
+ long next = current - 1;
+ if (compareAndSet(i, current, next))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically add the given value to element at index <tt>i</tt>.
+ *
+ * @param i the index
+ * @param delta the value to add
+ * @return the previous value;
+ */
+ public final long getAndAdd(int i, long delta) {
+ while (true) {
+ long current = get(i);
+ long next = current + delta;
+ if (compareAndSet(i, current, next))
+ return current;
+ }
+ }
+
+
+ /**
+ * Atomically increment the element at index <tt>i</tt>.
+ *
+ * @param i the index
+ * @return the updated value;
+ */
+ public final long incrementAndGet(int i) {
+ while (true) {
+ long current = get(i);
+ long next = current + 1;
+ if (compareAndSet(i, current, next))
+ return next;
+ }
+ }
+
+ /**
+ * Atomically decrement the element at index <tt>i</tt>.
+ *
+ * @param i the index
+ * @return the updated value;
+ */
+ public final long decrementAndGet(int i) {
+ while (true) {
+ long current = get(i);
+ long next = current - 1;
+ if (compareAndSet(i, current, next))
+ return next;
+ }
+ }
+
+ /**
+ * Atomically add the given value to element at index <tt>i</tt>.
+ *
+ * @param i the index
+ * @param delta the value to add
+ * @return the updated value;
+ */
+ public long addAndGet(int i, long delta) {
+ while (true) {
+ long current = get(i);
+ long next = current + delta;
+ if (compareAndSet(i, current, next))
+ return next;
+ }
+ }
+
+ /**
+ * Returns the String representation of the current values of array.
+ * @return the String representation of the current values of array.
+ */
+ public String toString() {
+ if (array.length > 0) // force volatile read
+ get(0);
+ return Arrays.toString(array);
+ }
+
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java
new file mode 100644
index 0000000..ad5edd8
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java
@@ -0,0 +1,323 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.atomic;
+import sun.misc.Unsafe;
+import java.lang.reflect.*;
+
+/**
+ * A reflection-based utility that enables atomic updates to
+ * designated <tt>volatile long</tt> fields of designated classes.
+ * This class is designed for use in atomic data structures in which
+ * several fields of the same node are independently subject to atomic
+ * updates.
+ *
+ * <p> Note that the guarantees of the <tt>compareAndSet</tt> method
+ * in this class are weaker than in other atomic classes. Because this
+ * class cannot ensure that all uses of the field are appropriate for
+ * purposes of atomic access, it can guarantee atomicity and volatile
+ * semantics only with respect to other invocations of
+ * <tt>compareAndSet</tt> and <tt>set</tt>.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ * @param <T> The type of the object holding the updatable field
+ */
+public abstract class AtomicLongFieldUpdater<T> {
+ /**
+ * Creates an updater for objects with the given field. The Class
+ * argument is needed to check that reflective types and generic
+ * types match.
+ * @param tclass the class of the objects holding the field
+ * @param fieldName the name of the field to be updated.
+ * @return the updater
+ * @throws IllegalArgumentException if the field is not a
+ * volatile long type.
+ * @throws RuntimeException with a nested reflection-based
+ * exception if the class does not hold field or is the wrong type.
+ */
+ public static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) {
+ if (AtomicLong.VM_SUPPORTS_LONG_CAS)
+ return new CASUpdater<U>(tclass, fieldName);
+ else
+ return new LockedUpdater<U>(tclass, fieldName);
+ }
+
+ /**
+ * Protected do-nothing constructor for use by subclasses.
+ */
+ protected AtomicLongFieldUpdater() {
+ }
+
+ /**
+ * Atomically set the value of the field of the given object managed
+ * by this Updater to the given updated value if the current value
+ * <tt>==</tt> the expected value. This method is guaranteed to be
+ * atomic with respect to other calls to <tt>compareAndSet</tt> and
+ * <tt>set</tt>, but not necessarily with respect to other
+ * changes in the field.
+ * @param obj An object whose field to conditionally set
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful.
+ * @throws ClassCastException if <tt>obj</tt> is not an instance
+ * of the class possessing the field established in the constructor.
+ */
+
+ public abstract boolean compareAndSet(T obj, long expect, long update);
+
+ /**
+ * Atomically set the value of the field of the given object managed
+ * by this Updater to the given updated value if the current value
+ * <tt>==</tt> the expected value. This method is guaranteed to be
+ * atomic with respect to other calls to <tt>compareAndSet</tt> and
+ * <tt>set</tt>, but not necessarily with respect to other
+ * changes in the field, and may fail spuriously.
+ * @param obj An object whose field to conditionally set
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful.
+ * @throws ClassCastException if <tt>obj</tt> is not an instance
+ * of the class possessing the field established in the constructor.
+ */
+
+ public abstract boolean weakCompareAndSet(T obj, long expect, long update);
+
+ /**
+ * Set the field of the given object managed by this updater. This
+ * operation is guaranteed to act as a volatile store with respect
+ * to subsequent invocations of <tt>compareAndSet</tt>.
+ * @param obj An object whose field to set
+ * @param newValue the new value
+ */
+ public abstract void set(T obj, long newValue);
+
+ /**
+ * Get the current value held in the field by the given object.
+ * @param obj An object whose field to get
+ * @return the current value
+ */
+ public abstract long get(T obj);
+
+ /**
+ * Set to the given value and return the old value.
+ *
+ * @param obj An object whose field to get and set
+ * @param newValue the new value
+ * @return the previous value
+ */
+ public long getAndSet(T obj, long newValue) {
+ for (;;) {
+ long current = get(obj);
+ if (compareAndSet(obj, current, newValue))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically increment by one the current value.
+ * @param obj An object whose field to get and set
+ * @return the previous value;
+ */
+ public long getAndIncrement(T obj) {
+ for (;;) {
+ long current = get(obj);
+ long next = current + 1;
+ if (compareAndSet(obj, current, next))
+ return current;
+ }
+ }
+
+
+ /**
+ * Atomically decrement by one the current value.
+ * @param obj An object whose field to get and set
+ * @return the previous value;
+ */
+ public long getAndDecrement(T obj) {
+ for (;;) {
+ long current = get(obj);
+ long next = current - 1;
+ if (compareAndSet(obj, current, next))
+ return current;
+ }
+ }
+
+
+ /**
+ * Atomically add the given value to current value.
+ * @param obj An object whose field to get and set
+ * @param delta the value to add
+ * @return the previous value;
+ */
+ public long getAndAdd(T obj, long delta) {
+ for (;;) {
+ long current = get(obj);
+ long next = current + delta;
+ if (compareAndSet(obj, current, next))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically increment by one the current value.
+ * @param obj An object whose field to get and set
+ * @return the updated value;
+ */
+ public long incrementAndGet(T obj) {
+ for (;;) {
+ long current = get(obj);
+ long next = current + 1;
+ if (compareAndSet(obj, current, next))
+ return next;
+ }
+ }
+
+
+ /**
+ * Atomically decrement by one the current value.
+ * @param obj An object whose field to get and set
+ * @return the updated value;
+ */
+ public long decrementAndGet(T obj) {
+ for (;;) {
+ long current = get(obj);
+ long next = current - 1;
+ if (compareAndSet(obj, current, next))
+ return next;
+ }
+ }
+
+
+ /**
+ * Atomically add the given value to current value.
+ * @param obj An object whose field to get and set
+ * @param delta the value to add
+ * @return the updated value;
+ */
+ public long addAndGet(T obj, long delta) {
+ for (;;) {
+ long current = get(obj);
+ long next = current + delta;
+ if (compareAndSet(obj, current, next))
+ return next;
+ }
+ }
+
+ private static class CASUpdater<T> extends AtomicLongFieldUpdater<T> {
+ // BEGIN android-changed
+ private static final Unsafe unsafe = UnsafeAccess.THE_ONE;
+ // END android-changed
+
+ private final long offset;
+ private final Class<T> tclass;
+
+ CASUpdater(Class<T> tclass, String fieldName) {
+ Field field = null;
+ try {
+ field = tclass.getDeclaredField(fieldName);
+ } catch(Exception ex) {
+ throw new RuntimeException(ex);
+ }
+
+ Class fieldt = field.getType();
+ if (fieldt != long.class)
+ throw new IllegalArgumentException("Must be long type");
+
+ if (!Modifier.isVolatile(field.getModifiers()))
+ throw new IllegalArgumentException("Must be volatile type");
+
+ this.tclass = tclass;
+ offset = unsafe.objectFieldOffset(field);
+ }
+
+ public boolean compareAndSet(T obj, long expect, long update) {
+ if (!tclass.isInstance(obj))
+ throw new ClassCastException();
+ return unsafe.compareAndSwapLong(obj, offset, expect, update);
+ }
+
+ public boolean weakCompareAndSet(T obj, long expect, long update) {
+ if (!tclass.isInstance(obj))
+ throw new ClassCastException();
+ return unsafe.compareAndSwapLong(obj, offset, expect, update);
+ }
+
+ public void set(T obj, long newValue) {
+ if (!tclass.isInstance(obj))
+ throw new ClassCastException();
+ unsafe.putLongVolatile(obj, offset, newValue);
+ }
+
+ public long get(T obj) {
+ if (!tclass.isInstance(obj))
+ throw new ClassCastException();
+ return unsafe.getLongVolatile(obj, offset);
+ }
+ }
+
+
+ private static class LockedUpdater<T> extends AtomicLongFieldUpdater<T> {
+ // BEGIN android-changed
+ private static final Unsafe unsafe = UnsafeAccess.THE_ONE;
+ // END android-changed
+
+ private final long offset;
+ private final Class<T> tclass;
+
+ LockedUpdater(Class<T> tclass, String fieldName) {
+ Field field = null;
+ try {
+ field = tclass.getDeclaredField(fieldName);
+ } catch(Exception ex) {
+ throw new RuntimeException(ex);
+ }
+
+ Class fieldt = field.getType();
+ if (fieldt != long.class)
+ throw new IllegalArgumentException("Must be long type");
+
+ if (!Modifier.isVolatile(field.getModifiers()))
+ throw new IllegalArgumentException("Must be volatile type");
+
+ this.tclass = tclass;
+ offset = unsafe.objectFieldOffset(field);
+ }
+
+ public boolean compareAndSet(T obj, long expect, long update) {
+ if (!tclass.isInstance(obj))
+ throw new ClassCastException();
+ synchronized(this) {
+ long v = unsafe.getLong(obj, offset);
+ if (v != expect)
+ return false;
+ unsafe.putLong(obj, offset, update);
+ return true;
+ }
+ }
+
+ public boolean weakCompareAndSet(T obj, long expect, long update) {
+ return compareAndSet(obj, expect, update);
+ }
+
+ public void set(T obj, long newValue) {
+ if (!tclass.isInstance(obj))
+ throw new ClassCastException();
+ synchronized(this) {
+ unsafe.putLong(obj, offset, newValue);
+ }
+ }
+
+ public long get(T obj) {
+ if (!tclass.isInstance(obj))
+ throw new ClassCastException();
+ synchronized(this) {
+ return unsafe.getLong(obj, offset);
+ }
+ }
+ }
+}
+
diff --git a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicMarkableReference.java b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicMarkableReference.java
new file mode 100644
index 0000000..11c91ba
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicMarkableReference.java
@@ -0,0 +1,163 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.atomic;
+
+/**
+ * An <tt>AtomicMarkableReference</tt> maintains an object reference
+ * along with a mark bit, that can be updated atomically.
+ * <p>
+ * <p> Implementation note. This implementation maintains markable
+ * references by creating internal objects representing "boxed"
+ * [reference, boolean] pairs.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ * @param <V> The type of object referred to by this reference
+ */
+public class AtomicMarkableReference<V> {
+
+ private static class ReferenceBooleanPair<T> {
+ private final T reference;
+ private final boolean bit;
+ ReferenceBooleanPair(T r, boolean i) {
+ reference = r; bit = i;
+ }
+ }
+
+ private final AtomicReference<ReferenceBooleanPair<V>> atomicRef;
+
+ /**
+ * Creates a new <tt>AtomicMarkableReference</tt> with the given
+ * initial values.
+ *
+ * @param initialRef the initial reference
+ * @param initialMark the initial mark
+ */
+ public AtomicMarkableReference(V initialRef, boolean initialMark) {
+ atomicRef = new AtomicReference<ReferenceBooleanPair<V>> (new ReferenceBooleanPair<V>(initialRef, initialMark));
+ }
+
+ /**
+ * Returns the current value of the reference.
+ *
+ * @return the current value of the reference
+ */
+ public V getReference() {
+ return atomicRef.get().reference;
+ }
+
+ /**
+ * Returns the current value of the mark.
+ *
+ * @return the current value of the mark
+ */
+ public boolean isMarked() {
+ return atomicRef.get().bit;
+ }
+
+ /**
+ * Returns the current values of both the reference and the mark.
+ * Typical usage is <tt>boolean[1] holder; ref = v.get(holder); </tt>.
+ *
+ * @param markHolder an array of size of at least one. On return,
+ * <tt>markholder[0]</tt> will hold the value of the mark.
+ * @return the current value of the reference
+ */
+ public V get(boolean[] markHolder) {
+ ReferenceBooleanPair<V> p = atomicRef.get();
+ markHolder[0] = p.bit;
+ return p.reference;
+ }
+
+ /**
+ * Atomically sets the value of both the reference and mark
+ * to the given update values if the
+ * current reference is <tt>==</tt> to the expected reference
+ * and the current mark is equal to the expected mark. Any given
+ * invocation of this operation may fail (return
+ * <tt>false</tt>) spuriously, but repeated invocation when
+ * the current value holds the expected value and no other thread
+ * is also attempting to set the value will eventually succeed.
+ *
+ * @param expectedReference the expected value of the reference
+ * @param newReference the new value for the reference
+ * @param expectedMark the expected value of the mark
+ * @param newMark the new value for the mark
+ * @return true if successful
+ */
+ public boolean weakCompareAndSet(V expectedReference,
+ V newReference,
+ boolean expectedMark,
+ boolean newMark) {
+ ReferenceBooleanPair current = atomicRef.get();
+ return expectedReference == current.reference &&
+ expectedMark == current.bit &&
+ ((newReference == current.reference && newMark == current.bit) ||
+ atomicRef.weakCompareAndSet(current,
+ new ReferenceBooleanPair<V>(newReference,
+ newMark)));
+ }
+
+ /**
+ * Atomically sets the value of both the reference and mark
+ * to the given update values if the
+ * current reference is <tt>==</tt> to the expected reference
+ * and the current mark is equal to the expected mark.
+ *
+ * @param expectedReference the expected value of the reference
+ * @param newReference the new value for the reference
+ * @param expectedMark the expected value of the mark
+ * @param newMark the new value for the mark
+ * @return true if successful
+ */
+ public boolean compareAndSet(V expectedReference,
+ V newReference,
+ boolean expectedMark,
+ boolean newMark) {
+ ReferenceBooleanPair current = atomicRef.get();
+ return expectedReference == current.reference &&
+ expectedMark == current.bit &&
+ ((newReference == current.reference && newMark == current.bit) ||
+ atomicRef.compareAndSet(current,
+ new ReferenceBooleanPair<V>(newReference,
+ newMark)));
+ }
+
+ /**
+ * Unconditionally sets the value of both the reference and mark.
+ *
+ * @param newReference the new value for the reference
+ * @param newMark the new value for the mark
+ */
+ public void set(V newReference, boolean newMark) {
+ ReferenceBooleanPair current = atomicRef.get();
+ if (newReference != current.reference || newMark != current.bit)
+ atomicRef.set(new ReferenceBooleanPair<V>(newReference, newMark));
+ }
+
+ /**
+ * Atomically sets the value of the mark to the given update value
+ * if the current reference is <tt>==</tt> to the expected
+ * reference. Any given invocation of this operation may fail
+ * (return <tt>false</tt>) spuriously, but repeated invocation
+ * when the current value holds the expected value and no other
+ * thread is also attempting to set the value will eventually
+ * succeed.
+ *
+ * @param expectedReference the expected value of the reference
+ * @param newMark the new value for the mark
+ * @return true if successful
+ */
+ public boolean attemptMark(V expectedReference, boolean newMark) {
+ ReferenceBooleanPair current = atomicRef.get();
+ return expectedReference == current.reference &&
+ (newMark == current.bit ||
+ atomicRef.compareAndSet
+ (current, new ReferenceBooleanPair<V>(expectedReference,
+ newMark)));
+ }
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReference.java b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReference.java
new file mode 100644
index 0000000..d51d5ce
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReference.java
@@ -0,0 +1,115 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.atomic;
+import sun.misc.Unsafe;
+
+/**
+ * An object reference that may be updated atomically. See the {@link
+ * java.util.concurrent.atomic} package specification for description
+ * of the properties of atomic variables.
+ * @since 1.5
+ * @author Doug Lea
+ * @param <V> The type of object referred to by this reference
+ */
+public class AtomicReference<V> implements java.io.Serializable {
+ private static final long serialVersionUID = -1848883965231344442L;
+
+ // BEGIN android-changed
+ private static final Unsafe unsafe = UnsafeAccess.THE_ONE;
+ // END android-changed
+
+ private static final long valueOffset;
+
+ static {
+ try {
+ valueOffset = unsafe.objectFieldOffset
+ (AtomicReference.class.getDeclaredField("value"));
+ } catch(Exception ex) { throw new Error(ex); }
+ }
+
+ private volatile V value;
+
+ /**
+ * Create a new AtomicReference with the given initial value.
+ *
+ * @param initialValue the initial value
+ */
+ public AtomicReference(V initialValue) {
+ value = initialValue;
+ }
+
+ /**
+ * Create a new AtomicReference with null initial value.
+ */
+ public AtomicReference() {
+ }
+
+ /**
+ * Get the current value.
+ *
+ * @return the current value
+ */
+ public final V get() {
+ return value;
+ }
+
+ /**
+ * Set to the given value.
+ *
+ * @param newValue the new value
+ */
+ public final void set(V newValue) {
+ value = newValue;
+ }
+
+ /**
+ * Atomically set the value to the given updated value
+ * if the current value <tt>==</tt> the expected value.
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful. False return indicates that
+ * the actual value was not equal to the expected value.
+ */
+ public final boolean compareAndSet(V expect, V update) {
+ return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
+ }
+
+ /**
+ * Atomically set the value to the given updated value
+ * if the current value <tt>==</tt> the expected value.
+ * May fail spuriously.
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful.
+ */
+ public final boolean weakCompareAndSet(V expect, V update) {
+ return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
+ }
+
+ /**
+ * Set to the given value and return the old value.
+ *
+ * @param newValue the new value
+ * @return the previous value
+ */
+ public final V getAndSet(V newValue) {
+ while (true) {
+ V x = get();
+ if (compareAndSet(x, newValue))
+ return x;
+ }
+ }
+
+ /**
+ * Returns the String representation of the current value.
+ * @return the String representation of the current value.
+ */
+ public String toString() {
+ return String.valueOf(get());
+ }
+
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceArray.java b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceArray.java
new file mode 100644
index 0000000..98b83c4
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceArray.java
@@ -0,0 +1,152 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.atomic;
+import sun.misc.Unsafe;
+import java.util.*;
+
+/**
+ * An array of object references in which elements may be updated
+ * atomically. See the {@link java.util.concurrent.atomic} package
+ * specification for description of the properties of atomic
+ * variables.
+ * @since 1.5
+ * @author Doug Lea
+ * @param <E> The base class of elements held in this array
+ */
+public class AtomicReferenceArray<E> implements java.io.Serializable {
+ private static final long serialVersionUID = -6209656149925076980L;
+
+ // BEGIN android-changed
+ private static final Unsafe unsafe = UnsafeAccess.THE_ONE;
+ // END android-changed
+
+ private static final int base = unsafe.arrayBaseOffset(Object[].class);
+ private static final int scale = unsafe.arrayIndexScale(Object[].class);
+ private final Object[] array;
+
+ private long rawIndex(int i) {
+ if (i < 0 || i >= array.length)
+ throw new IndexOutOfBoundsException("index " + i);
+ return base + i * scale;
+ }
+
+ /**
+ * Create a new AtomicReferenceArray of given length.
+ * @param length the length of the array
+ */
+ public AtomicReferenceArray(int length) {
+ array = new Object[length];
+ // must perform at least one volatile write to conform to JMM
+ if (length > 0)
+ unsafe.putObjectVolatile(array, rawIndex(0), null);
+ }
+
+ /**
+ * Create a new AtomicReferenceArray with the same length as, and
+ * all elements copied from, the given array.
+ *
+ * @param array the array to copy elements from
+ * @throws NullPointerException if array is null
+ */
+ public AtomicReferenceArray(E[] array) {
+ if (array == null)
+ throw new NullPointerException();
+ int length = array.length;
+ this.array = new Object[length];
+ if (length > 0) {
+ int last = length-1;
+ for (int i = 0; i < last; ++i)
+ this.array[i] = array[i];
+ // Do the last write as volatile
+ E e = array[last];
+ unsafe.putObjectVolatile(this.array, rawIndex(last), e);
+ }
+ }
+
+ /**
+ * Returns the length of the array.
+ *
+ * @return the length of the array
+ */
+ public final int length() {
+ return array.length;
+ }
+
+ /**
+ * Get the current value at position <tt>i</tt>.
+ *
+ * @param i the index
+ * @return the current value
+ */
+ public final E get(int i) {
+ return (E) unsafe.getObjectVolatile(array, rawIndex(i));
+ }
+
+ /**
+ * Set the element at position <tt>i</tt> to the given value.
+ *
+ * @param i the index
+ * @param newValue the new value
+ */
+ public final void set(int i, E newValue) {
+ unsafe.putObjectVolatile(array, rawIndex(i), newValue);
+ }
+
+ /**
+ * Set the element at position <tt>i</tt> to the given value and return the
+ * old value.
+ *
+ * @param i the index
+ * @param newValue the new value
+ * @return the previous value
+ */
+ public final E getAndSet(int i, E newValue) {
+ while (true) {
+ E current = get(i);
+ if (compareAndSet(i, current, newValue))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically set the value to the given updated value
+ * if the current value <tt>==</tt> the expected value.
+ * @param i the index
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful. False return indicates that
+ * the actual value was not equal to the expected value.
+ */
+ public final boolean compareAndSet(int i, E expect, E update) {
+ return unsafe.compareAndSwapObject(array, rawIndex(i),
+ expect, update);
+ }
+
+ /**
+ * Atomically set the value to the given updated value
+ * if the current value <tt>==</tt> the expected value.
+ * May fail spuriously.
+ * @param i the index
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful.
+ */
+ public final boolean weakCompareAndSet(int i, E expect, E update) {
+ return compareAndSet(i, expect, update);
+ }
+
+ /**
+ * Returns the String representation of the current values of array.
+ * @return the String representation of the current values of array.
+ */
+ public String toString() {
+ if (array.length > 0) // force volatile read
+ get(0);
+ return Arrays.toString(array);
+ }
+
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java
new file mode 100644
index 0000000..044d6cd
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java
@@ -0,0 +1,198 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.atomic;
+import sun.misc.Unsafe;
+import java.lang.reflect.*;
+
+/**
+ * A reflection-based utility that enables atomic updates to
+ * designated <tt>volatile</tt> reference fields of designated
+ * classes. This class is designed for use in atomic data structures
+ * in which several reference fields of the same node are
+ * independently subject to atomic updates. For example, a tree node
+ * might be declared as
+ *
+ * <pre>
+ * class Node {
+ * private volatile Node left, right;
+ *
+ * private static final AtomicReferenceFieldUpdater&lt;Node, Node&gt; leftUpdater =
+ * AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "left");
+ * private static AtomicReferenceFieldUpdater&lt;Node, Node&gt; rightUpdater =
+ * AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "right");
+ *
+ * Node getLeft() { return left; }
+ * boolean compareAndSetLeft(Node expect, Node update) {
+ * return leftUpdater.compareAndSet(this, expect, update);
+ * }
+ * // ... and so on
+ * }
+ * </pre>
+ *
+ * <p> Note that the guarantees of the <tt>compareAndSet</tt>
+ * method in this class are weaker than in other atomic classes. Because this
+ * class cannot ensure that all uses of the field are appropriate for
+ * purposes of atomic access, it can guarantee atomicity and volatile
+ * semantics only with respect to other invocations of
+ * <tt>compareAndSet</tt> and <tt>set</tt>.
+ * @since 1.5
+ * @author Doug Lea
+ * @param <T> The type of the object holding the updatable field
+ * @param <V> The type of the field
+ */
+public abstract class AtomicReferenceFieldUpdater<T, V> {
+
+ /**
+ * Creates an updater for objects with the given field. The Class
+ * arguments are needed to check that reflective types and generic
+ * types match.
+ * @param tclass the class of the objects holding the field.
+ * @param vclass the class of the field
+ * @param fieldName the name of the field to be updated.
+ * @return the updater
+ * @throws IllegalArgumentException if the field is not a volatile reference type.
+ * @throws RuntimeException with a nested reflection-based
+ * exception if the class does not hold field or is the wrong type.
+ */
+ public static <U, W> AtomicReferenceFieldUpdater<U,W> newUpdater(Class<U> tclass, Class<W> vclass, String fieldName) {
+ // Currently rely on standard intrinsics implementation
+ return new AtomicReferenceFieldUpdaterImpl<U,W>(tclass,
+ vclass,
+ fieldName);
+ }
+
+ /**
+ * Protected do-nothing constructor for use by subclasses.
+ */
+ protected AtomicReferenceFieldUpdater() {
+ }
+
+ /**
+ * Atomically set the value of the field of the given object managed
+ * by this Updater to the given updated value if the current value
+ * <tt>==</tt> the expected value. This method is guaranteed to be
+ * atomic with respect to other calls to <tt>compareAndSet</tt> and
+ * <tt>set</tt>, but not necessarily with respect to other
+ * changes in the field.
+ * @param obj An object whose field to conditionally set
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful.
+ */
+
+ public abstract boolean compareAndSet(T obj, V expect, V update);
+
+ /**
+ * Atomically set the value of the field of the given object managed
+ * by this Updater to the given updated value if the current value
+ * <tt>==</tt> the expected value. This method is guaranteed to be
+ * atomic with respect to other calls to <tt>compareAndSet</tt> and
+ * <tt>set</tt>, but not necessarily with respect to other
+ * changes in the field, and may fail spuriously.
+ * @param obj An object whose field to conditionally set
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful.
+ */
+ public abstract boolean weakCompareAndSet(T obj, V expect, V update);
+
+ /**
+ * Set the field of the given object managed by this updater. This
+ * operation is guaranteed to act as a volatile store with respect
+ * to subsequent invocations of <tt>compareAndSet</tt>.
+ * @param obj An object whose field to set
+ * @param newValue the new value
+ */
+ public abstract void set(T obj, V newValue);
+
+ /**
+ * Get the current value held in the field by the given object.
+ * @param obj An object whose field to get
+ * @return the current value
+ */
+ public abstract V get(T obj);
+
+ /**
+ * Set to the given value and return the old value.
+ *
+ * @param obj An object whose field to get and set
+ * @param newValue the new value
+ * @return the previous value
+ */
+ public V getAndSet(T obj, V newValue) {
+ for (;;) {
+ V current = get(obj);
+ if (compareAndSet(obj, current, newValue))
+ return current;
+ }
+ }
+
+ /**
+ * Standard hotspot implementation using intrinsics
+ */
+ private static class AtomicReferenceFieldUpdaterImpl<T,V> extends AtomicReferenceFieldUpdater<T,V> {
+ // BEGIN android-changed
+ private static final Unsafe unsafe = UnsafeAccess.THE_ONE;
+ // END android-changed
+
+ private final long offset;
+ private final Class<T> tclass;
+ private final Class<V> vclass;
+
+ AtomicReferenceFieldUpdaterImpl(Class<T> tclass, Class<V> vclass, String fieldName) {
+ Field field = null;
+ Class fieldClass = null;
+ try {
+ field = tclass.getDeclaredField(fieldName);
+ fieldClass = field.getType();
+ } catch(Exception ex) {
+ throw new RuntimeException(ex);
+ }
+
+ if (vclass != fieldClass)
+ throw new ClassCastException();
+
+ if (!Modifier.isVolatile(field.getModifiers()))
+ throw new IllegalArgumentException("Must be volatile type");
+
+ this.tclass = tclass;
+ this.vclass = vclass;
+ offset = unsafe.objectFieldOffset(field);
+ }
+
+
+ public boolean compareAndSet(T obj, V expect, V update) {
+ if (!tclass.isInstance(obj) ||
+ (update != null && !vclass.isInstance(update)))
+ throw new ClassCastException();
+ return unsafe.compareAndSwapObject(obj, offset, expect, update);
+ }
+
+ public boolean weakCompareAndSet(T obj, V expect, V update) {
+ // same implementation as strong form for now
+ if (!tclass.isInstance(obj) ||
+ (update != null && !vclass.isInstance(update)))
+ throw new ClassCastException();
+ return unsafe.compareAndSwapObject(obj, offset, expect, update);
+ }
+
+
+ public void set(T obj, V newValue) {
+ if (!tclass.isInstance(obj) ||
+ (newValue != null && !vclass.isInstance(newValue)))
+ throw new ClassCastException();
+ unsafe.putObjectVolatile(obj, offset, newValue);
+ }
+
+ public V get(T obj) {
+ if (!tclass.isInstance(obj))
+ throw new ClassCastException();
+ return (V)unsafe.getObjectVolatile(obj, offset);
+ }
+ }
+}
+
diff --git a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicStampedReference.java b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicStampedReference.java
new file mode 100644
index 0000000..b0a02c2
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicStampedReference.java
@@ -0,0 +1,167 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.atomic;
+
+/**
+ * An <tt>AtomicStampedReference</tt> maintains an object reference
+ * along with an integer "stamp", that can be updated atomically.
+ *
+ * <p> Implementation note. This implementation maintains stamped
+ * references by creating internal objects representing "boxed"
+ * [reference, integer] pairs.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ * @param <V> The type of object referred to by this reference
+ */
+public class AtomicStampedReference<V> {
+
+ private static class ReferenceIntegerPair<T> {
+ private final T reference;
+ private final int integer;
+ ReferenceIntegerPair(T r, int i) {
+ reference = r; integer = i;
+ }
+ }
+
+ private final AtomicReference<ReferenceIntegerPair<V>> atomicRef;
+
+ /**
+ * Creates a new <tt>AtomicStampedReference</tt> with the given
+ * initial values.
+ *
+ * @param initialRef the initial reference
+ * @param initialStamp the initial stamp
+ */
+ public AtomicStampedReference(V initialRef, int initialStamp) {
+ atomicRef = new AtomicReference<ReferenceIntegerPair<V>>
+ (new ReferenceIntegerPair<V>(initialRef, initialStamp));
+ }
+
+ /**
+ * Returns the current value of the reference.
+ *
+ * @return the current value of the reference
+ */
+ public V getReference() {
+ return atomicRef.get().reference;
+ }
+
+ /**
+ * Returns the current value of the stamp.
+ *
+ * @return the current value of the stamp
+ */
+ public int getStamp() {
+ return atomicRef.get().integer;
+ }
+
+ /**
+ * Returns the current values of both the reference and the stamp.
+ * Typical usage is <tt>int[1] holder; ref = v.get(holder); </tt>.
+ *
+ * @param stampHolder an array of size of at least one. On return,
+ * <tt>stampholder[0]</tt> will hold the value of the stamp.
+ * @return the current value of the reference
+ */
+ public V get(int[] stampHolder) {
+ ReferenceIntegerPair<V> p = atomicRef.get();
+ stampHolder[0] = p.integer;
+ return p.reference;
+ }
+
+ /**
+ * Atomically sets the value of both the reference and stamp
+ * to the given update values if the
+ * current reference is <tt>==</tt> to the expected reference
+ * and the current stamp is equal to the expected stamp. Any given
+ * invocation of this operation may fail (return
+ * <tt>false</tt>) spuriously, but repeated invocation when
+ * the current value holds the expected value and no other thread
+ * is also attempting to set the value will eventually succeed.
+ *
+ * @param expectedReference the expected value of the reference
+ * @param newReference the new value for the reference
+ * @param expectedStamp the expected value of the stamp
+ * @param newStamp the new value for the stamp
+ * @return true if successful
+ */
+ public boolean weakCompareAndSet(V expectedReference,
+ V newReference,
+ int expectedStamp,
+ int newStamp) {
+ ReferenceIntegerPair current = atomicRef.get();
+ return expectedReference == current.reference &&
+ expectedStamp == current.integer &&
+ ((newReference == current.reference &&
+ newStamp == current.integer) ||
+ atomicRef.weakCompareAndSet(current,
+ new ReferenceIntegerPair<V>(newReference,
+ newStamp)));
+ }
+
+ /**
+ * Atomically sets the value of both the reference and stamp
+ * to the given update values if the
+ * current reference is <tt>==</tt> to the expected reference
+ * and the current stamp is equal to the expected stamp.
+ *
+ * @param expectedReference the expected value of the reference
+ * @param newReference the new value for the reference
+ * @param expectedStamp the expected value of the stamp
+ * @param newStamp the new value for the stamp
+ * @return true if successful
+ */
+ public boolean compareAndSet(V expectedReference,
+ V newReference,
+ int expectedStamp,
+ int newStamp) {
+ ReferenceIntegerPair current = atomicRef.get();
+ return expectedReference == current.reference &&
+ expectedStamp == current.integer &&
+ ((newReference == current.reference &&
+ newStamp == current.integer) ||
+ atomicRef.compareAndSet(current,
+ new ReferenceIntegerPair<V>(newReference,
+ newStamp)));
+ }
+
+
+ /**
+ * Unconditionally sets the value of both the reference and stamp.
+ *
+ * @param newReference the new value for the reference
+ * @param newStamp the new value for the stamp
+ */
+ public void set(V newReference, int newStamp) {
+ ReferenceIntegerPair current = atomicRef.get();
+ if (newReference != current.reference || newStamp != current.integer)
+ atomicRef.set(new ReferenceIntegerPair<V>(newReference, newStamp));
+ }
+
+ /**
+ * Atomically sets the value of the stamp to the given update value
+ * if the current reference is <tt>==</tt> to the expected
+ * reference. Any given invocation of this operation may fail
+ * (return <tt>false</tt>) spuriously, but repeated invocation
+ * when the current value holds the expected value and no other
+ * thread is also attempting to set the value will eventually
+ * succeed.
+ *
+ * @param expectedReference the expected value of the reference
+ * @param newStamp the new value for the stamp
+ * @return true if successful
+ */
+ public boolean attemptStamp(V expectedReference, int newStamp) {
+ ReferenceIntegerPair current = atomicRef.get();
+ return expectedReference == current.reference &&
+ (newStamp == current.integer ||
+ atomicRef.compareAndSet(current,
+ new ReferenceIntegerPair<V>(expectedReference,
+ newStamp)));
+ }
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/atomic/UnsafeAccess.java b/concurrent/src/main/java/java/util/concurrent/atomic/UnsafeAccess.java
new file mode 100644
index 0000000..96fff17
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/atomic/UnsafeAccess.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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
+ * 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.
+ */
+
+package java.util.concurrent.atomic;
+
+import sun.misc.Unsafe;
+
+/**
+ * Easy access to {@link Unsafe} for the rest of this package.
+ */
+/*package*/ final class UnsafeAccess {
+ /** non-null; unique instance of {@link Unsafe} */
+ /*package*/ static final Unsafe THE_ONE = Unsafe.getUnsafe();
+
+ /**
+ * This class is uninstantiable.
+ */
+ private UnsafeAccess() {
+ // This space intentionally left blank.
+ }
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/atomic/package.html b/concurrent/src/main/java/java/util/concurrent/atomic/package.html
new file mode 100644
index 0000000..5316e22
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/atomic/package.html
@@ -0,0 +1,133 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html> <head>
+<title>Atomics</title>
+</head>
+
+<body>
+
+A small toolkit of classes that support lock-free thread-safe
+programming on single variables. In essence, the classes in this
+package extend the notion of <tt>volatile</tt> values, fields, and
+array elements to those that also provide an atomic conditional update
+operation of the form:
+
+<pre>
+ boolean compareAndSet(expectedValue, updateValue);
+</pre>
+
+<p> This method (which varies in argument types across different
+classes) atomically sets a variable to the <tt>updateValue</tt> if it
+currently holds the <tt>expectedValue</tt>, reporting <tt>true</tt> on
+success. The classes in this package also contain methods to get and
+unconditionally set values, as well as a weaker conditional atomic
+update operation <tt> weakCompareAndSet</tt>. The weak version may be
+more efficient in the normal case, but differs in that any given
+invocation of <tt>weakCompareAndSet</tt> method may fail, even
+spuriously (that is, for no apparent reason). A <tt>false</tt> return
+means only that the operation may be retried if desired, relying on
+the guarantee that repeated invocation when the variable holds
+<tt>expectedValue</tt> and no other thread is also attempting to set
+the variable will eventually succeed.
+
+<p> The specifications of these methods enable implementations to
+employ efficient machine-level atomic instructions that are available
+on contemporary processors. However on some platforms, support may
+entail some form of internal locking. Thus the methods are not
+strictly guaranteed to be non-blocking --
+a thread may block transiently before performing the operation.
+
+<p> Instances of classes {@link
+java.util.concurrent.atomic.AtomicBoolean}, {@link
+java.util.concurrent.atomic.AtomicInteger}, {@link
+java.util.concurrent.atomic.AtomicLong}, and {@link
+java.util.concurrent.atomic.AtomicReference} each provide access and
+updates to a single variable of the corresponding type. Each class
+also provides appropriate utility methods for that type. For example,
+classes <tt>AtomicLong</tt> and <tt>AtomicInteger</tt> provide atomic
+increment methods. One application is to generate sequence numbers,
+as in:
+
+<pre>
+class Sequencer {
+ private AtomicLong sequenceNumber = new AtomicLong(0);
+ public long next() { return sequenceNumber.getAndIncrement(); }
+}
+</pre>
+
+<p>The memory effects for accesses and updates of atomics generally follow the
+rules for volatiles:
+
+<ul>
+
+ <li> <tt>get</tt> has the memory effects of reading a
+<tt>volatile</tt> variable.
+
+ <li> <tt>set</tt> has the memory effects of writing (assigning) a
+<tt>volatile</tt> variable.
+
+ <li><tt>weakCompareAndSet</tt> atomically reads and conditionally
+ writes a variable, is ordered with respect to other
+ memory operations on that variable, but otherwise acts as an
+ ordinary non-volatile memory operation.
+
+ <li> <tt>compareAndSet</tt>
+ and all other read-and-update operations such as <tt>getAndIncrement</tt>
+ have the memory effects of both reading and
+ writing <tt>volatile</tt> variables.
+</ul>
+
+<p>In addition to classes representing single values, this package
+contains <em>Updater</em> classes that can be used to obtain
+<tt>compareAndSet</tt> operations on any selected <tt>volatile</tt>
+field of any selected class. {@link
+java.util.concurrent.atomic.AtomicReferenceFieldUpdater}, {@link
+java.util.concurrent.atomic.AtomicIntegerFieldUpdater}, and {@link
+java.util.concurrent.atomic.AtomicLongFieldUpdater} are
+reflection-based utilities that provide access to the associated field
+types. These are mainly of use in atomic data structures in which
+several <tt>volatile</tt> fields of the same node (for example, the
+links of a tree node) are independently subject to atomic
+updates. These classes enable greater flexibility in how and when to
+use atomic updates, at the expense of more awkward reflection-based
+setup, less convenient usage, and weaker guarantees.
+
+<p>The {@link java.util.concurrent.atomic.AtomicIntegerArray}, {@link
+java.util.concurrent.atomic.AtomicLongArray}, and {@link
+java.util.concurrent.atomic.AtomicReferenceArray} classes further
+extend atomic operation support to arrays of these types. These
+classes are also notable in providing <tt>volatile</tt> access
+semantics for their array elements, which is not supported for
+ordinary arrays.
+
+<p> The {@link java.util.concurrent.atomic.AtomicMarkableReference}
+class associates a single boolean with a reference. For example, this
+bit might be used inside a data structure to mean that the object
+being referenced has logically been deleted. The {@link
+java.util.concurrent.atomic.AtomicStampedReference} class associates
+an integer value with a reference. This may be used for example, to
+represent version numbers corresponding to series of updates.
+
+<p> Atomic classes are designed primarily as building blocks for
+implementing non-blocking data structures and related infrastructure
+classes. The <tt>compareAndSet</tt> method is not a general
+replacement for locking. It applies only when critical updates for an
+object are confined to a <em>single</em> variable.
+
+<p> Atomic classes are not general purpose replacements for
+<tt>java.lang.Integer</tt> and related classes. They do <em>not</em>
+define methods such as <tt>hashCode</tt> and
+<tt>compareTo</tt>. (Because atomic variables are expected to be
+mutated, they are poor choices for hash table keys.) Additionally,
+classes are provided only for those types that are commonly useful in
+intended applications. For example, there is no atomic class for
+representing <tt>byte</tt>. In those infrequent cases where you would
+like to do so, you can use an <tt>AtomicInteger</tt> to hold
+<tt>byte</tt> values, and cast appropriately. You can also hold floats
+using <tt>Float.floatToIntBits</tt> and <tt>Float.intBitstoFloat</tt>
+conversions, and doubles using <tt>Double.doubleToLongBits</tt> and
+<tt>Double.longBitsToDouble</tt> conversions.
+
+@since 1.5
+@since Android 1.0
+
+</body> </html>
diff --git a/concurrent/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java b/concurrent/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java
new file mode 100644
index 0000000..da9d84d
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java
@@ -0,0 +1,2064 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.locks;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.*;
+import sun.misc.Unsafe;
+
+/**
+ * Provides a framework for implementing blocking locks and related
+ * synchronizers (semaphores, events, etc) that rely on
+ * first-in-first-out (FIFO) wait queues. This class is designed to
+ * be a useful basis for most kinds of synchronizers that rely on a
+ * single atomic <tt>int</tt> value to represent state. Subclasses
+ * must define the protected methods that change this state, and which
+ * define what that state means in terms of this object being acquired
+ * or released. Given these, the other methods in this class carry
+ * out all queuing and blocking mechanics. Subclasses can maintain
+ * other state fields, but only the atomically updated <tt>int</tt>
+ * value manipulated using methods {@link #getState}, {@link
+ * #setState} and {@link #compareAndSetState} is tracked with respect
+ * to synchronization.
+ *
+ * <p>Subclasses should be defined as non-public internal helper
+ * classes that are used to implement the synchronization properties
+ * of their enclosing class. Class
+ * <tt>AbstractQueuedSynchronizer</tt> does not implement any
+ * synchronization interface. Instead it defines methods such as
+ * {@link #acquireInterruptibly} that can be invoked as
+ * appropriate by concrete locks and related synchronizers to
+ * implement their public methods.
+ *
+ * <p>This class supports either or both a default <em>exclusive</em>
+ * mode and a <em>shared</em> mode. When acquired in exclusive mode,
+ * attempted acquires by other threads cannot succeed. Shared mode
+ * acquires by multiple threads may (but need not) succeed. This class
+ * does not &quot;understand&quot; these differences except in the
+ * mechanical sense that when a shared mode acquire succeeds, the next
+ * waiting thread (if one exists) must also determine whether it can
+ * acquire as well. Threads waiting in the different modes share the
+ * same FIFO queue. Usually, implementation subclasses support only
+ * one of these modes, but both can come into play for example in a
+ * {@link ReadWriteLock}. Subclasses that support only exclusive or
+ * only shared modes need not define the methods supporting the unused mode.
+ *
+ * <p>This class defines a nested {@link ConditionObject} class that
+ * can be used as a {@link Condition} implementation by subclasses
+ * supporting exclusive mode for which method {@link
+ * #isHeldExclusively} reports whether synchronization is exclusively
+ * held with respect to the current thread, method {@link #release}
+ * invoked with the current {@link #getState} value fully releases
+ * this object, and {@link #acquire}, given this saved state value,
+ * eventually restores this object to its previous acquired state. No
+ * <tt>AbstractQueuedSynchronizer</tt> method otherwise creates such a
+ * condition, so if this constraint cannot be met, do not use it. The
+ * behavior of {@link ConditionObject} depends of course on the
+ * semantics of its synchronizer implementation.
+ *
+ * <p> This class provides inspection, instrumentation, and monitoring
+ * methods for the internal queue, as well as similar methods for
+ * condition objects. These can be exported as desired into classes
+ * using an <tt>AbstractQueuedSynchronizer</tt> for their
+ * synchronization mechanics.
+ *
+ * <p> Serialization of this class stores only the underlying atomic
+ * integer maintaining state, so deserialized objects have empty
+ * thread queues. Typical subclasses requiring serializability will
+ * define a <tt>readObject</tt> method that restores this to a known
+ * initial state upon deserialization.
+ *
+ * <h3>Usage</h3>
+ *
+ * <p> To use this class as the basis of a synchronizer, redefine the
+ * following methods, as applicable, by inspecting and/or modifying
+ * the synchronization state using {@link #getState}, {@link
+ * #setState} and/or {@link #compareAndSetState}:
+ *
+ * <ul>
+ * <li> {@link #tryAcquire}
+ * <li> {@link #tryRelease}
+ * <li> {@link #tryAcquireShared}
+ * <li> {@link #tryReleaseShared}
+ * <li> {@link #isHeldExclusively}
+ *</ul>
+ *
+ * Each of these methods by default throws {@link
+ * UnsupportedOperationException}. Implementations of these methods
+ * must be internally thread-safe, and should in general be short and
+ * not block. Defining these methods is the <em>only</em> supported
+ * means of using this class. All other methods are declared
+ * <tt>final</tt> because they cannot be independently varied.
+ *
+ * <p> Even though this class is based on an internal FIFO queue, it
+ * does not automatically enforce FIFO acquisition policies. The core
+ * of exclusive synchronization takes the form:
+ *
+ * <pre>
+ * Acquire:
+ * while (!tryAcquire(arg)) {
+ * <em>enqueue thread if it is not already queued</em>;
+ * <em>possibly block current thread</em>;
+ * }
+ *
+ * Release:
+ * if (tryRelease(arg))
+ * <em>unblock the first queued thread</em>;
+ * </pre>
+ *
+ * (Shared mode is similar but may involve cascading signals.)
+ *
+ * <p> Because checks in acquire are invoked before enqueuing, a newly
+ * acquiring thread may <em>barge</em> ahead of others that are
+ * blocked and queued. However, you can, if desired, define
+ * <tt>tryAcquire</tt> and/or <tt>tryAcquireShared</tt> to disable
+ * barging by internally invoking one or more of the inspection
+ * methods. In particular, a strict FIFO lock can define
+ * <tt>tryAcquire</tt> to immediately return <tt>false</tt> if {@link
+ * #getFirstQueuedThread} does not return the current thread. A
+ * normally preferable non-strict fair version can immediately return
+ * <tt>false</tt> only if {@link #hasQueuedThreads} returns
+ * <tt>true</tt> and <tt>getFirstQueuedThread</tt> is not the current
+ * thread; or equivalently, that <tt>getFirstQueuedThread</tt> is both
+ * non-null and not the current thread. Further variations are
+ * possible.
+ *
+ * <p> Throughput and scalability are generally highest for the
+ * default barging (also known as <em>greedy</em>,
+ * <em>renouncement</em>, and <em>convoy-avoidance</em>) strategy.
+ * While this is not guaranteed to be fair or starvation-free, earlier
+ * queued threads are allowed to recontend before later queued
+ * threads, and each recontention has an unbiased chance to succeed
+ * against incoming threads. Also, while acquires do not
+ * &quot;spin&quot; in the usual sense, they may perform multiple
+ * invocations of <tt>tryAcquire</tt> interspersed with other
+ * computations before blocking. This gives most of the benefits of
+ * spins when exclusive synchronization is only briefly held, without
+ * most of the liabilities when it isn't. If so desired, you can
+ * augment this by preceding calls to acquire methods with
+ * "fast-path" checks, possibly prechecking {@link #hasContended}
+ * and/or {@link #hasQueuedThreads} to only do so if the synchronizer
+ * is likely not to be contended.
+ *
+ * <p> This class provides an efficient and scalable basis for
+ * synchronization in part by specializing its range of use to
+ * synchronizers that can rely on <tt>int</tt> state, acquire, and
+ * release parameters, and an internal FIFO wait queue. When this does
+ * not suffice, you can build synchronizers from a lower level using
+ * {@link java.util.concurrent.atomic atomic} classes, your own custom
+ * {@link java.util.Queue} classes, and {@link LockSupport} blocking
+ * support.
+ *
+ * <h3>Usage Examples</h3>
+ *
+ * <p>Here is a non-reentrant mutual exclusion lock class that uses
+ * the value zero to represent the unlocked state, and one to
+ * represent the locked state. It also supports conditions and exposes
+ * one of the instrumentation methods:
+ *
+ * <pre>
+ * class Mutex implements Lock, java.io.Serializable {
+ *
+ * // Our internal helper class
+ * private static class Sync extends AbstractQueuedSynchronizer {
+ * // Report whether in locked state
+ * protected boolean isHeldExclusively() {
+ * return getState() == 1;
+ * }
+ *
+ * // Acquire the lock if state is zero
+ * public boolean tryAcquire(int acquires) {
+ * assert acquires == 1; // Otherwise unused
+ * return compareAndSetState(0, 1);
+ * }
+ *
+ * // Release the lock by setting state to zero
+ * protected boolean tryRelease(int releases) {
+ * assert releases == 1; // Otherwise unused
+ * if (getState() == 0) throw new IllegalMonitorStateException();
+ * setState(0);
+ * return true;
+ * }
+ *
+ * // Provide a Condition
+ * Condition newCondition() { return new ConditionObject(); }
+ *
+ * // Deserialize properly
+ * private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
+ * s.defaultReadObject();
+ * setState(0); // reset to unlocked state
+ * }
+ * }
+ *
+ * // The sync object does all the hard work. We just forward to it.
+ * private final Sync sync = new Sync();
+ *
+ * public void lock() { sync.acquire(1); }
+ * public boolean tryLock() { return sync.tryAcquire(1); }
+ * public void unlock() { sync.release(1); }
+ * public Condition newCondition() { return sync.newCondition(); }
+ * public boolean isLocked() { return sync.isHeldExclusively(); }
+ * public boolean hasQueuedThreads() { return sync.hasQueuedThreads(); }
+ * public void lockInterruptibly() throws InterruptedException {
+ * sync.acquireInterruptibly(1);
+ * }
+ * public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
+ * return sync.tryAcquireNanos(1, unit.toNanos(timeout));
+ * }
+ * }
+ * </pre>
+ *
+ * <p> Here is a latch class that is like a {@link CountDownLatch}
+ * except that it only requires a single <tt>signal</tt> to
+ * fire. Because a latch is non-exclusive, it uses the <tt>shared</tt>
+ * acquire and release methods.
+ *
+ * <pre>
+ * class BooleanLatch {
+ *
+ * private static class Sync extends AbstractQueuedSynchronizer {
+ * boolean isSignalled() { return getState() != 0; }
+ *
+ * protected int tryAcquireShared(int ignore) {
+ * return isSignalled()? 1 : -1;
+ * }
+ *
+ * protected boolean tryReleaseShared(int ignore) {
+ * setState(1);
+ * return true;
+ * }
+ * }
+ *
+ * private final Sync sync = new Sync();
+ * public boolean isSignalled() { return sync.isSignalled(); }
+ * public void signal() { sync.releaseShared(1); }
+ * public void await() throws InterruptedException {
+ * sync.acquireSharedInterruptibly(1);
+ * }
+ * }
+ *
+ * </pre>
+ *
+ * @since 1.5
+ * @author Doug Lea
+ */
+public abstract class AbstractQueuedSynchronizer implements java.io.Serializable {
+ private static final long serialVersionUID = 7373984972572414691L;
+
+ /**
+ * Creates a new <tt>AbstractQueuedSynchronizer</tt> instance
+ * with initial synchronization state of zero.
+ */
+ protected AbstractQueuedSynchronizer() { }
+
+ /**
+ * Wait queue node class.
+ *
+ * <p> The wait queue is a variant of a "CLH" (Craig, Landin, and
+ * Hagersten) lock queue. CLH locks are normally used for
+ * spinlocks. We instead use them for blocking synchronizers, but
+ * use the same basic tactic of holding some of the control
+ * information about a thread in the predecessor of its node. A
+ * "status" field in each node keeps track of whether a thread
+ * should block. A node is signalled when its predecessor
+ * releases. Each node of the queue otherwise serves as a
+ * specific-notification-style monitor holding a single waiting
+ * thread. The status field does NOT control whether threads are
+ * granted locks etc though. A thread may try to acquire if it is
+ * first in the queue. But being first does not guarantee success;
+ * it only gives the right to contend. So the currently released
+ * contender thread may need to rewait.
+ *
+ * <p>To enqueue into a CLH lock, you atomically splice it in as new
+ * tail. To dequeue, you just set the head field.
+ * <pre>
+ * +------+ prev +-----+ +-----+
+ * head | | <---- | | <---- | | tail
+ * +------+ +-----+ +-----+
+ * </pre>
+ *
+ * <p>Insertion into a CLH queue requires only a single atomic
+ * operation on "tail", so there is a simple atomic point of
+ * demarcation from unqueued to queued. Similarly, dequeing
+ * involves only updating the "head". However, it takes a bit
+ * more work for nodes to determine who their successors are,
+ * in part to deal with possible cancellation due to timeouts
+ * and interrupts.
+ *
+ * <p>The "prev" links (not used in original CLH locks), are mainly
+ * needed to handle cancellation. If a node is cancelled, its
+ * successor is (normally) relinked to a non-cancelled
+ * predecessor. For explanation of similar mechanics in the case
+ * of spin locks, see the papers by Scott and Scherer at
+ * http://www.cs.rochester.edu/u/scott/synchronization/
+ *
+ * <p>We also use "next" links to implement blocking mechanics.
+ * The thread id for each node is kept in its own node, so a
+ * predecessor signals the next node to wake up by traversing
+ * next link to determine which thread it is. Determination of
+ * successor must avoid races with newly queued nodes to set
+ * the "next" fields of their predecessors. This is solved
+ * when necessary by checking backwards from the atomically
+ * updated "tail" when a node's successor appears to be null.
+ * (Or, said differently, the next-links are an optimization
+ * so that we don't usually need a backward scan.)
+ *
+ * <p>Cancellation introduces some conservatism to the basic
+ * algorithms. Since we must poll for cancellation of other
+ * nodes, we can miss noticing whether a cancelled node is
+ * ahead or behind us. This is dealt with by always unparking
+ * successors upon cancellation, allowing them to stabilize on
+ * a new predecessor.
+ *
+ * <p>CLH queues need a dummy header node to get started. But
+ * we don't create them on construction, because it would be wasted
+ * effort if there is never contention. Instead, the node
+ * is constructed and head and tail pointers are set upon first
+ * contention.
+ *
+ * <p>Threads waiting on Conditions use the same nodes, but
+ * use an additional link. Conditions only need to link nodes
+ * in simple (non-concurrent) linked queues because they are
+ * only accessed when exclusively held. Upon await, a node is
+ * inserted into a condition queue. Upon signal, the node is
+ * transferred to the main queue. A special value of status
+ * field is used to mark which queue a node is on.
+ *
+ * <p>Thanks go to Dave Dice, Mark Moir, Victor Luchangco, Bill
+ * Scherer and Michael Scott, along with members of JSR-166
+ * expert group, for helpful ideas, discussions, and critiques
+ * on the design of this class.
+ */
+ static final class Node {
+ /** waitStatus value to indicate thread has cancelled */
+ static final int CANCELLED = 1;
+ /** waitStatus value to indicate thread needs unparking */
+ static final int SIGNAL = -1;
+ /** waitStatus value to indicate thread is waiting on condition */
+ static final int CONDITION = -2;
+ /** Marker to indicate a node is waiting in shared mode */
+ static final Node SHARED = new Node();
+ /** Marker to indicate a node is waiting in exclusive mode */
+ static final Node EXCLUSIVE = null;
+
+ /**
+ * Status field, taking on only the values:
+ * SIGNAL: The successor of this node is (or will soon be)
+ * blocked (via park), so the current node must
+ * unpark its successor when it releases or
+ * cancels. To avoid races, acquire methods must
+ * first indicate they need a signal,
+ * then retry the atomic acquire, and then,
+ * on failure, block.
+ * CANCELLED: Node is cancelled due to timeout or interrupt
+ * Nodes never leave this state. In particular,
+ * a thread with cancelled node never again blocks.
+ * CONDITION: Node is currently on a condition queue
+ * It will not be used as a sync queue node until
+ * transferred. (Use of this value here
+ * has nothing to do with the other uses
+ * of the field, but simplifies mechanics.)
+ * 0: None of the above
+ *
+ * The values are arranged numerically to simplify use.
+ * Non-negative values mean that a node doesn't need to
+ * signal. So, most code doesn't need to check for particular
+ * values, just for sign.
+ *
+ * The field is initialized to 0 for normal sync nodes, and
+ * CONDITION for condition nodes. It is modified only using
+ * CAS.
+ */
+ volatile int waitStatus;
+
+ /**
+ * Link to predecessor node that current node/thread relies on
+ * for checking waitStatus. Assigned during enqueing, and nulled
+ * out (for sake of GC) only upon dequeuing. Also, upon
+ * cancellation of a predecessor, we short-circuit while
+ * finding a non-cancelled one, which will always exist
+ * because the head node is never cancelled: A node becomes
+ * head only as a result of successful acquire. A
+ * cancelled thread never succeeds in acquiring, and a thread only
+ * cancels itself, not any other node.
+ */
+ volatile Node prev;
+
+ /**
+ * Link to the successor node that the current node/thread
+ * unparks upon release. Assigned once during enqueuing, and
+ * nulled out (for sake of GC) when no longer needed. Upon
+ * cancellation, we cannot adjust this field, but can notice
+ * status and bypass the node if cancelled. The enq operation
+ * does not assign next field of a predecessor until after
+ * attachment, so seeing a null next field does not
+ * necessarily mean that node is at end of queue. However, if
+ * a next field appears to be null, we can scan prev's from
+ * the tail to double-check.
+ */
+ volatile Node next;
+
+ /**
+ * The thread that enqueued this node. Initialized on
+ * construction and nulled out after use.
+ */
+ volatile Thread thread;
+
+ /**
+ * Link to next node waiting on condition, or the special
+ * value SHARED. Because condition queues are accessed only
+ * when holding in exclusive mode, we just need a simple
+ * linked queue to hold nodes while they are waiting on
+ * conditions. They are then transferred to the queue to
+ * re-acquire. And because conditions can only be exclusive,
+ * we save a field by using special value to indicate shared
+ * mode.
+ */
+ Node nextWaiter;
+
+ /**
+ * Returns true if node is waiting in shared mode
+ */
+ final boolean isShared() {
+ return nextWaiter == SHARED;
+ }
+
+ /**
+ * Returns previous node, or throws NullPointerException if
+ * null. Use when predecessor cannot be null.
+ * @return the predecessor of this node
+ */
+ final Node predecessor() throws NullPointerException {
+ Node p = prev;
+ if (p == null)
+ throw new NullPointerException();
+ else
+ return p;
+ }
+
+ Node() { // Used to establish initial head or SHARED marker
+ }
+
+ Node(Thread thread, Node mode) { // Used by addWaiter
+ this.nextWaiter = mode;
+ this.thread = thread;
+ }
+
+ Node(Thread thread, int waitStatus) { // Used by Condition
+ this.waitStatus = waitStatus;
+ this.thread = thread;
+ }
+ }
+
+ /**
+ * Head of the wait queue, lazily initialized. Except for
+ * initialization, it is modified only via method setHead. Note:
+ * If head exists, its waitStatus is guaranteed not to be
+ * CANCELLED.
+ */
+ private transient volatile Node head;
+
+ /**
+ * Tail of the wait queue, lazily initialized. Modified only via
+ * method enq to add new wait node.
+ */
+ private transient volatile Node tail;
+
+ /**
+ * The synchronization state.
+ */
+ private volatile int state;
+
+ /**
+ * Returns the current value of synchronization state.
+ * This operation has memory semantics of a <tt>volatile</tt> read.
+ * @return current state value
+ */
+ protected final int getState() {
+ return state;
+ }
+
+ /**
+ * Sets the value of synchronization state.
+ * This operation has memory semantics of a <tt>volatile</tt> write.
+ * @param newState the new state value
+ */
+ protected final void setState(int newState) {
+ state = newState;
+ }
+
+ /**
+ * Atomically sets synchronization state to the given updated
+ * value if the current state value equals the expected value.
+ * This operation has memory semantics of a <tt>volatile</tt> read
+ * and write.
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful. False return indicates that
+ * the actual value was not equal to the expected value.
+ */
+ protected final boolean compareAndSetState(int expect, int update) {
+ // See below for intrinsics setup to support this
+ return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
+ }
+
+ // Queuing utilities
+
+ /**
+ * Insert node into queue, initializing if necessary. See picture above.
+ * @param node the node to insert
+ * @return node's predecessor
+ */
+ private Node enq(final Node node) {
+ for (;;) {
+ Node t = tail;
+ if (t == null) { // Must initialize
+ Node h = new Node(); // Dummy header
+ h.next = node;
+ node.prev = h;
+ if (compareAndSetHead(h)) {
+ tail = node;
+ return h;
+ }
+ }
+ else {
+ node.prev = t;
+ if (compareAndSetTail(t, node)) {
+ t.next = node;
+ return t;
+ }
+ }
+ }
+ }
+
+ /**
+ * Create and enq node for given thread and mode
+ * @param current the thread
+ * @param mode Node.EXCLUSIVE for exclusive, Node.SHARED for shared
+ * @return the new node
+ */
+ private Node addWaiter(Node mode) {
+ Node node = new Node(Thread.currentThread(), mode);
+ // Try the fast path of enq; backup to full enq on failure
+ Node pred = tail;
+ if (pred != null) {
+ node.prev = pred;
+ if (compareAndSetTail(pred, node)) {
+ pred.next = node;
+ return node;
+ }
+ }
+ enq(node);
+ return node;
+ }
+
+ /**
+ * Set head of queue to be node, thus dequeuing. Called only by
+ * acquire methods. Also nulls out unused fields for sake of GC
+ * and to suppress unnecessary signals and traversals.
+ * @param node the node
+ */
+ private void setHead(Node node) {
+ head = node;
+ node.thread = null;
+ node.prev = null;
+ }
+
+ /**
+ * Wake up node's successor, if one exists.
+ * @param node the node
+ */
+ private void unparkSuccessor(Node node) {
+ /*
+ * Try to clear status in anticipation of signalling. It is
+ * OK if this fails or if status is changed by waiting thread.
+ */
+ compareAndSetWaitStatus(node, Node.SIGNAL, 0);
+
+ /*
+ * Thread to unpark is held in successor, which is normally
+ * just the next node. But if cancelled or apparently null,
+ * traverse backwards from tail to find the actual
+ * non-cancelled successor.
+ */
+ Thread thread;
+ Node s = node.next;
+ if (s != null && s.waitStatus <= 0)
+ thread = s.thread;
+ else {
+ thread = null;
+ for (s = tail; s != null && s != node; s = s.prev)
+ if (s.waitStatus <= 0)
+ thread = s.thread;
+ }
+ LockSupport.unpark(thread);
+ }
+
+ /**
+ * Set head of queue, and check if successor may be waiting
+ * in shared mode, if so propagating if propagate > 0.
+ * @param pred the node holding waitStatus for node
+ * @param node the node
+ * @param propagate the return value from a tryAcquireShared
+ */
+ private void setHeadAndPropagate(Node node, int propagate) {
+ setHead(node);
+ if (propagate > 0 && node.waitStatus != 0) {
+ /*
+ * Don't bother fully figuring out successor. If it
+ * looks null, call unparkSuccessor anyway to be safe.
+ */
+ Node s = node.next;
+ if (s == null || s.isShared())
+ unparkSuccessor(node);
+ }
+ }
+
+ // Utilities for various versions of acquire
+
+ /**
+ * Cancel an ongoing attempt to acquire.
+ * @param node the node
+ */
+ private void cancelAcquire(Node node) {
+ if (node != null) { // Ignore if node doesn't exist
+ node.thread = null;
+ // Can use unconditional write instead of CAS here
+ node.waitStatus = Node.CANCELLED;
+ unparkSuccessor(node);
+ }
+ }
+
+ /**
+ * Checks and updates status for a node that failed to acquire.
+ * Returns true if thread should block. This is the main signal
+ * control in all acquire loops. Requires that pred == node.prev
+ * @param pred node's predecessor holding status
+ * @param node the node
+ * @return true if thread should block
+ */
+ private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
+ int s = pred.waitStatus;
+ if (s < 0)
+ /*
+ * This node has already set status asking a release
+ * to signal it, so it can safely park
+ */
+ return true;
+ if (s > 0)
+ /*
+ * Predecessor was cancelled. Move up to its predecessor
+ * and indicate retry.
+ */
+ node.prev = pred.prev;
+ else
+ /*
+ * Indicate that we need a signal, but don't park yet. Caller
+ * will need to retry to make sure it cannot acquire before
+ * parking.
+ */
+ compareAndSetWaitStatus(pred, 0, Node.SIGNAL);
+ return false;
+ }
+
+ /**
+ * Convenience method to interrupt current thread.
+ */
+ private static void selfInterrupt() {
+ Thread.currentThread().interrupt();
+ }
+
+ /**
+ * Convenience method to park and then check if interrupted
+ * @return true if interrupted
+ */
+ private static boolean parkAndCheckInterrupt() {
+ LockSupport.park();
+ return Thread.interrupted();
+ }
+
+ /*
+ * Various flavors of acquire, varying in exclusive/shared and
+ * control modes. Each is mostly the same, but annoyingly
+ * different. Only a little bit of factoring is possible due to
+ * interactions of exception mechanics (including ensuring that we
+ * cancel if tryAcquire throws exception) and other control, at
+ * least not without hurting performance too much.
+ */
+
+ /**
+ * Acquire in exclusive uninterruptible mode for thread already in
+ * queue. Used by condition wait methods as well as acquire.
+ * @param node the node
+ * @param arg the acquire argument
+ * @return true if interrupted while waiting
+ */
+ final boolean acquireQueued(final Node node, int arg) {
+ try {
+ boolean interrupted = false;
+ for (;;) {
+ final Node p = node.predecessor();
+ if (p == head && tryAcquire(arg)) {
+ setHead(node);
+ p.next = null; // help GC
+ return interrupted;
+ }
+ if (shouldParkAfterFailedAcquire(p, node) &&
+ parkAndCheckInterrupt())
+ interrupted = true;
+ }
+ } catch (RuntimeException ex) {
+ cancelAcquire(node);
+ throw ex;
+ }
+ }
+
+ /**
+ * Acquire in exclusive interruptible mode
+ * @param arg the acquire argument
+ */
+ private void doAcquireInterruptibly(int arg)
+ throws InterruptedException {
+ final Node node = addWaiter(Node.EXCLUSIVE);
+ try {
+ for (;;) {
+ final Node p = node.predecessor();
+ if (p == head && tryAcquire(arg)) {
+ setHead(node);
+ p.next = null; // help GC
+ return;
+ }
+ if (shouldParkAfterFailedAcquire(p, node) &&
+ parkAndCheckInterrupt())
+ break;
+ }
+ } catch (RuntimeException ex) {
+ cancelAcquire(node);
+ throw ex;
+ }
+ // Arrive here only if interrupted
+ cancelAcquire(node);
+ throw new InterruptedException();
+ }
+
+ /**
+ * Acquire in exclusive timed mode
+ * @param arg the acquire argument
+ * @param nanosTimeout max wait time
+ * @return true if acquired
+ */
+ private boolean doAcquireNanos(int arg, long nanosTimeout)
+ throws InterruptedException {
+ long lastTime = System.nanoTime();
+ final Node node = addWaiter(Node.EXCLUSIVE);
+ try {
+ for (;;) {
+ final Node p = node.predecessor();
+ if (p == head && tryAcquire(arg)) {
+ setHead(node);
+ p.next = null; // help GC
+ return true;
+ }
+ if (nanosTimeout <= 0) {
+ cancelAcquire(node);
+ return false;
+ }
+ if (shouldParkAfterFailedAcquire(p, node)) {
+ LockSupport.parkNanos(nanosTimeout);
+ if (Thread.interrupted())
+ break;
+ long now = System.nanoTime();
+ nanosTimeout -= now - lastTime;
+ lastTime = now;
+ }
+ }
+ } catch (RuntimeException ex) {
+ cancelAcquire(node);
+ throw ex;
+ }
+ // Arrive here only if interrupted
+ cancelAcquire(node);
+ throw new InterruptedException();
+ }
+
+ /**
+ * Acquire in shared uninterruptible mode
+ * @param arg the acquire argument
+ */
+ private void doAcquireShared(int arg) {
+ final Node node = addWaiter(Node.SHARED);
+ try {
+ boolean interrupted = false;
+ for (;;) {
+ final Node p = node.predecessor();
+ if (p == head) {
+ int r = tryAcquireShared(arg);
+ if (r >= 0) {
+ setHeadAndPropagate(node, r);
+ p.next = null; // help GC
+ if (interrupted)
+ selfInterrupt();
+ return;
+ }
+ }
+ if (shouldParkAfterFailedAcquire(p, node) &&
+ parkAndCheckInterrupt())
+ interrupted = true;
+ }
+ } catch (RuntimeException ex) {
+ cancelAcquire(node);
+ throw ex;
+ }
+ }
+
+ /**
+ * Acquire in shared interruptible mode
+ * @param arg the acquire argument
+ */
+ private void doAcquireSharedInterruptibly(int arg)
+ throws InterruptedException {
+ final Node node = addWaiter(Node.SHARED);
+ try {
+ for (;;) {
+ final Node p = node.predecessor();
+ if (p == head) {
+ int r = tryAcquireShared(arg);
+ if (r >= 0) {
+ setHeadAndPropagate(node, r);
+ p.next = null; // help GC
+ return;
+ }
+ }
+ if (shouldParkAfterFailedAcquire(p, node) &&
+ parkAndCheckInterrupt())
+ break;
+ }
+ } catch (RuntimeException ex) {
+ cancelAcquire(node);
+ throw ex;
+ }
+ // Arrive here only if interrupted
+ cancelAcquire(node);
+ throw new InterruptedException();
+ }
+
+ /**
+ * Acquire in shared timed mode
+ * @param arg the acquire argument
+ * @param nanosTimeout max wait time
+ * @return true if acquired
+ */
+ private boolean doAcquireSharedNanos(int arg, long nanosTimeout)
+ throws InterruptedException {
+
+ long lastTime = System.nanoTime();
+ final Node node = addWaiter(Node.SHARED);
+ try {
+ for (;;) {
+ final Node p = node.predecessor();
+ if (p == head) {
+ int r = tryAcquireShared(arg);
+ if (r >= 0) {
+ setHeadAndPropagate(node, r);
+ p.next = null; // help GC
+ return true;
+ }
+ }
+ if (nanosTimeout <= 0) {
+ cancelAcquire(node);
+ return false;
+ }
+ if (shouldParkAfterFailedAcquire(p, node)) {
+ LockSupport.parkNanos(nanosTimeout);
+ if (Thread.interrupted())
+ break;
+ long now = System.nanoTime();
+ nanosTimeout -= now - lastTime;
+ lastTime = now;
+ }
+ }
+ } catch (RuntimeException ex) {
+ cancelAcquire(node);
+ throw ex;
+ }
+ // Arrive here only if interrupted
+ cancelAcquire(node);
+ throw new InterruptedException();
+ }
+
+ // Main exported methods
+
+ /**
+ * Attempts to acquire in exclusive mode. This method should query
+ * if the state of the object permits it to be acquired in the
+ * exclusive mode, and if so to acquire it.
+ *
+ * <p>This method is always invoked by the thread performing
+ * acquire. If this method reports failure, the acquire method
+ * may queue the thread, if it is not already queued, until it is
+ * signalled by a release from some other thread. This can be used
+ * to implement method {@link Lock#tryLock()}.
+ *
+ * <p>The default
+ * implementation throws {@link UnsupportedOperationException}
+ *
+ * @param arg the acquire argument. This value
+ * is always the one passed to an acquire method,
+ * or is the value saved on entry to a condition wait.
+ * The value is otherwise uninterpreted and can represent anything
+ * you like.
+ * @return true if successful. Upon success, this object has been
+ * acquired.
+ * @throws IllegalMonitorStateException if acquiring would place
+ * this synchronizer in an illegal state. This exception must be
+ * thrown in a consistent fashion for synchronization to work
+ * correctly.
+ * @throws UnsupportedOperationException if exclusive mode is not supported
+ */
+ protected boolean tryAcquire(int arg) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Attempts to set the state to reflect a release in exclusive
+ * mode. <p>This method is always invoked by the thread
+ * performing release.
+ *
+ * <p>The default implementation throws
+ * {@link UnsupportedOperationException}
+ * @param arg the release argument. This value
+ * is always the one passed to a release method,
+ * or the current state value upon entry to a condition wait.
+ * The value is otherwise uninterpreted and can represent anything
+ * you like.
+ * @return <tt>true</tt> if this object is now in a fully released state,
+ * so that any waiting threads may attempt to acquire; and <tt>false</tt>
+ * otherwise.
+ * @throws IllegalMonitorStateException if releasing would place
+ * this synchronizer in an illegal state. This exception must be
+ * thrown in a consistent fashion for synchronization to work
+ * correctly.
+ * @throws UnsupportedOperationException if exclusive mode is not supported
+ */
+ protected boolean tryRelease(int arg) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Attempts to acquire in shared mode. This method should query if
+ * the state of the object permits it to be acquired in the shared
+ * mode, and if so to acquire it.
+ *
+ * <p>This method is always invoked by the thread performing
+ * acquire. If this method reports failure, the acquire method
+ * may queue the thread, if it is not already queued, until it is
+ * signalled by a release from some other thread.
+ *
+ * <p>The default implementation throws {@link
+ * UnsupportedOperationException}
+ *
+ * @param arg the acquire argument. This value
+ * is always the one passed to an acquire method,
+ * or is the value saved on entry to a condition wait.
+ * The value is otherwise uninterpreted and can represent anything
+ * you like.
+ * @return a negative value on failure, zero on exclusive success,
+ * and a positive value if non-exclusively successful, in which
+ * case a subsequent waiting thread must check
+ * availability. (Support for three different return values
+ * enables this method to be used in contexts where acquires only
+ * sometimes act exclusively.) Upon success, this object has been
+ * acquired.
+ * @throws IllegalMonitorStateException if acquiring would place
+ * this synchronizer in an illegal state. This exception must be
+ * thrown in a consistent fashion for synchronization to work
+ * correctly.
+ * @throws UnsupportedOperationException if shared mode is not supported
+ */
+ protected int tryAcquireShared(int arg) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Attempts to set the state to reflect a release in shared mode.
+ * <p>This method is always invoked by the thread performing release.
+ * <p> The default implementation throws
+ * {@link UnsupportedOperationException}
+ * @param arg the release argument. This value
+ * is always the one passed to a release method,
+ * or the current state value upon entry to a condition wait.
+ * The value is otherwise uninterpreted and can represent anything
+ * you like.
+ * @return <tt>true</tt> if this object is now in a fully released state,
+ * so that any waiting threads may attempt to acquire; and <tt>false</tt>
+ * otherwise.
+ * @throws IllegalMonitorStateException if releasing would place
+ * this synchronizer in an illegal state. This exception must be
+ * thrown in a consistent fashion for synchronization to work
+ * correctly.
+ * @throws UnsupportedOperationException if shared mode is not supported
+ */
+ protected boolean tryReleaseShared(int arg) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns true if synchronization is held exclusively with respect
+ * to the current (calling) thread. This method is invoked
+ * upon each call to a non-waiting {@link ConditionObject} method.
+ * (Waiting methods instead invoke {@link #release}.)
+ * <p>The default implementation throws {@link
+ * UnsupportedOperationException}. This method is invoked
+ * internally only within {@link ConditionObject} methods, so need
+ * not be defined if conditions are not used.
+ *
+ * @return true if synchronization is held exclusively;
+ * else false
+ * @throws UnsupportedOperationException if conditions are not supported
+ */
+ protected boolean isHeldExclusively() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Acquires in exclusive mode, ignoring interrupts. Implemented
+ * by invoking at least once {@link #tryAcquire},
+ * returning on success. Otherwise the thread is queued, possibly
+ * repeatedly blocking and unblocking, invoking {@link
+ * #tryAcquire} until success. This method can be used
+ * to implement method {@link Lock#lock}
+ * @param arg the acquire argument.
+ * This value is conveyed to {@link #tryAcquire} but is
+ * otherwise uninterpreted and can represent anything
+ * you like.
+ */
+ public final void acquire(int arg) {
+ if (!tryAcquire(arg) &&
+ acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
+ selfInterrupt();
+ }
+
+ /**
+ * Acquires in exclusive mode, aborting if interrupted.
+ * Implemented by first checking interrupt status, then invoking
+ * at least once {@link #tryAcquire}, returning on
+ * success. Otherwise the thread is queued, possibly repeatedly
+ * blocking and unblocking, invoking {@link #tryAcquire}
+ * until success or the thread is interrupted. This method can be
+ * used to implement method {@link Lock#lockInterruptibly}
+ * @param arg the acquire argument.
+ * This value is conveyed to {@link #tryAcquire} but is
+ * otherwise uninterpreted and can represent anything
+ * you like.
+ * @throws InterruptedException if the current thread is interrupted
+ */
+ public final void acquireInterruptibly(int arg) throws InterruptedException {
+ if (Thread.interrupted())
+ throw new InterruptedException();
+ if (!tryAcquire(arg))
+ doAcquireInterruptibly(arg);
+ }
+
+ /**
+ * Attempts to acquire in exclusive mode, aborting if interrupted,
+ * and failing if the given timeout elapses. Implemented by first
+ * checking interrupt status, then invoking at least once {@link
+ * #tryAcquire}, returning on success. Otherwise, the thread is
+ * queued, possibly repeatedly blocking and unblocking, invoking
+ * {@link #tryAcquire} until success or the thread is interrupted
+ * or the timeout elapses. This method can be used to implement
+ * method {@link Lock#tryLock(long, TimeUnit)}.
+ * @param arg the acquire argument.
+ * This value is conveyed to {@link #tryAcquire} but is
+ * otherwise uninterpreted and can represent anything
+ * you like.
+ * @param nanosTimeout the maximum number of nanoseconds to wait
+ * @return true if acquired; false if timed out
+ * @throws InterruptedException if the current thread is interrupted
+ */
+ public final boolean tryAcquireNanos(int arg, long nanosTimeout) throws InterruptedException {
+ if (Thread.interrupted())
+ throw new InterruptedException();
+ return tryAcquire(arg) ||
+ doAcquireNanos(arg, nanosTimeout);
+ }
+
+ /**
+ * Releases in exclusive mode. Implemented by unblocking one or
+ * more threads if {@link #tryRelease} returns true.
+ * This method can be used to implement method {@link Lock#unlock}
+ * @param arg the release argument.
+ * This value is conveyed to {@link #tryRelease} but is
+ * otherwise uninterpreted and can represent anything
+ * you like.
+ * @return the value returned from {@link #tryRelease}
+ */
+ public final boolean release(int arg) {
+ if (tryRelease(arg)) {
+ Node h = head;
+ if (h != null && h.waitStatus != 0)
+ unparkSuccessor(h);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Acquires in shared mode, ignoring interrupts. Implemented by
+ * first invoking at least once {@link #tryAcquireShared},
+ * returning on success. Otherwise the thread is queued, possibly
+ * repeatedly blocking and unblocking, invoking {@link
+ * #tryAcquireShared} until success.
+ * @param arg the acquire argument.
+ * This value is conveyed to {@link #tryAcquireShared} but is
+ * otherwise uninterpreted and can represent anything
+ * you like.
+ */
+ public final void acquireShared(int arg) {
+ if (tryAcquireShared(arg) < 0)
+ doAcquireShared(arg);
+ }
+
+ /**
+ * Acquires in shared mode, aborting if interrupted. Implemented
+ * by first checking interrupt status, then invoking at least once
+ * {@link #tryAcquireShared}, returning on success. Otherwise the
+ * thread is queued, possibly repeatedly blocking and unblocking,
+ * invoking {@link #tryAcquireShared} until success or the thread
+ * is interrupted.
+ * @param arg the acquire argument.
+ * This value is conveyed to {@link #tryAcquireShared} but is
+ * otherwise uninterpreted and can represent anything
+ * you like.
+ * @throws InterruptedException if the current thread is interrupted
+ */
+ public final void acquireSharedInterruptibly(int arg) throws InterruptedException {
+ if (Thread.interrupted())
+ throw new InterruptedException();
+ if (tryAcquireShared(arg) < 0)
+ doAcquireSharedInterruptibly(arg);
+ }
+
+ /**
+ * Attempts to acquire in shared mode, aborting if interrupted, and
+ * failing if the given timeout elapses. Implemented by first
+ * checking interrupt status, then invoking at least once {@link
+ * #tryAcquireShared}, returning on success. Otherwise, the
+ * thread is queued, possibly repeatedly blocking and unblocking,
+ * invoking {@link #tryAcquireShared} until success or the thread
+ * is interrupted or the timeout elapses.
+ * @param arg the acquire argument.
+ * This value is conveyed to {@link #tryAcquireShared} but is
+ * otherwise uninterpreted and can represent anything
+ * you like.
+ * @param nanosTimeout the maximum number of nanoseconds to wait
+ * @return true if acquired; false if timed out
+ * @throws InterruptedException if the current thread is interrupted
+ */
+ public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout) throws InterruptedException {
+ if (Thread.interrupted())
+ throw new InterruptedException();
+ return tryAcquireShared(arg) >= 0 ||
+ doAcquireSharedNanos(arg, nanosTimeout);
+ }
+
+ /**
+ * Releases in shared mode. Implemented by unblocking one or more
+ * threads if {@link #tryReleaseShared} returns true.
+ * @param arg the release argument.
+ * This value is conveyed to {@link #tryReleaseShared} but is
+ * otherwise uninterpreted and can represent anything
+ * you like.
+ * @return the value returned from {@link #tryReleaseShared}
+ */
+ public final boolean releaseShared(int arg) {
+ if (tryReleaseShared(arg)) {
+ Node h = head;
+ if (h != null && h.waitStatus != 0)
+ unparkSuccessor(h);
+ return true;
+ }
+ return false;
+ }
+
+ // Queue inspection methods
+
+ /**
+ * Queries whether any threads are waiting to acquire. Note that
+ * because cancellations due to interrupts and timeouts may occur
+ * at any time, a <tt>true</tt> return does not guarantee that any
+ * other thread will ever acquire.
+ *
+ * <p> In this implementation, this operation returns in
+ * constant time.
+ *
+ * @return true if there may be other threads waiting to acquire
+ * the lock.
+ */
+ public final boolean hasQueuedThreads() {
+ return head != tail;
+ }
+
+ /**
+ * Queries whether any threads have ever contended to acquire this
+ * synchronizer; that is if an acquire method has ever blocked.
+ *
+ * <p> In this implementation, this operation returns in
+ * constant time.
+ *
+ * @return true if there has ever been contention
+ */
+ public final boolean hasContended() {
+ return head != null;
+ }
+
+ /**
+ * Returns the first (longest-waiting) thread in the queue, or
+ * <tt>null</tt> if no threads are currently queued.
+ *
+ * <p> In this implementation, this operation normally returns in
+ * constant time, but may iterate upon contention if other threads are
+ * concurrently modifying the queue.
+ *
+ * @return the first (longest-waiting) thread in the queue, or
+ * <tt>null</tt> if no threads are currently queued.
+ */
+ public final Thread getFirstQueuedThread() {
+ // handle only fast path, else relay
+ return (head == tail)? null : fullGetFirstQueuedThread();
+ }
+
+ /**
+ * Version of getFirstQueuedThread called when fastpath fails
+ */
+ private Thread fullGetFirstQueuedThread() {
+ /*
+ * This loops only if the queue changes while we read sets of
+ * fields.
+ */
+ for (;;) {
+ Node h = head;
+ if (h == null) // No queue
+ return null;
+
+ /*
+ * The first node is normally h.next. Try to get its
+ * thread field, ensuring consistent reads: If thread
+ * field is nulled out or s.prev is no longer head, then
+ * some other thread(s) concurrently performed setHead in
+ * between some of our reads, so we must reread.
+ */
+ Node s = h.next;
+ if (s != null) {
+ Thread st = s.thread;
+ Node sp = s.prev;
+ if (st != null && sp == head)
+ return st;
+ }
+
+ /*
+ * Head's next field might not have been set yet, or may
+ * have been unset after setHead. So we must check to see
+ * if tail is actually first node, in almost the same way
+ * as above.
+ */
+ Node t = tail;
+ if (t == h) // Empty queue
+ return null;
+
+ if (t != null) {
+ Thread tt = t.thread;
+ Node tp = t.prev;
+ if (tt != null && tp == head)
+ return tt;
+ }
+ }
+ }
+
+ /**
+ * Returns true if the given thread is currently queued.
+ *
+ * <p> This implementation traverses the queue to determine
+ * presence of the given thread.
+ *
+ * @param thread the thread
+ * @return true if the given thread in on the queue
+ * @throws NullPointerException if thread null
+ */
+ public final boolean isQueued(Thread thread) {
+ if (thread == null)
+ throw new NullPointerException();
+ for (Node p = tail; p != null; p = p.prev)
+ if (p.thread == thread)
+ return true;
+ return false;
+ }
+
+ // Instrumentation and monitoring methods
+
+ /**
+ * Returns an estimate of the number of threads waiting to
+ * acquire. The value is only an estimate because the number of
+ * threads may change dynamically while this method traverses
+ * internal data structures. This method is designed for use in
+ * monitoring system state, not for synchronization
+ * control.
+ *
+ * @return the estimated number of threads waiting for this lock
+ */
+ public final int getQueueLength() {
+ int n = 0;
+ for (Node p = tail; p != null; p = p.prev) {
+ if (p.thread != null)
+ ++n;
+ }
+ return n;
+ }
+
+ /**
+ * Returns a collection containing threads that may be waiting to
+ * acquire. Because the actual set of threads may change
+ * dynamically while constructing this result, the returned
+ * collection is only a best-effort estimate. The elements of the
+ * returned collection are in no particular order. This method is
+ * designed to facilitate construction of subclasses that provide
+ * more extensive monitoring facilities.
+ * @return the collection of threads
+ */
+ public final Collection<Thread> getQueuedThreads() {
+ ArrayList<Thread> list = new ArrayList<Thread>();
+ for (Node p = tail; p != null; p = p.prev) {
+ Thread t = p.thread;
+ if (t != null)
+ list.add(t);
+ }
+ return list;
+ }
+
+ /**
+ * Returns a collection containing threads that may be waiting to
+ * acquire in exclusive mode. This has the same properties
+ * as {@link #getQueuedThreads} except that it only returns
+ * those threads waiting due to an exclusive acquire.
+ * @return the collection of threads
+ */
+ public final Collection<Thread> getExclusiveQueuedThreads() {
+ ArrayList<Thread> list = new ArrayList<Thread>();
+ for (Node p = tail; p != null; p = p.prev) {
+ if (!p.isShared()) {
+ Thread t = p.thread;
+ if (t != null)
+ list.add(t);
+ }
+ }
+ return list;
+ }
+
+ /**
+ * Returns a collection containing threads that may be waiting to
+ * acquire in shared mode. This has the same properties
+ * as {@link #getQueuedThreads} except that it only returns
+ * those threads waiting due to a shared acquire.
+ * @return the collection of threads
+ */
+ public final Collection<Thread> getSharedQueuedThreads() {
+ ArrayList<Thread> list = new ArrayList<Thread>();
+ for (Node p = tail; p != null; p = p.prev) {
+ if (p.isShared()) {
+ Thread t = p.thread;
+ if (t != null)
+ list.add(t);
+ }
+ }
+ return list;
+ }
+
+ /**
+ * Returns a string identifying this synchronizer, as well as its
+ * state. The state, in brackets, includes the String &quot;State
+ * =&quot; followed by the current value of {@link #getState}, and
+ * either &quot;nonempty&quot; or &quot;empty&quot; depending on
+ * whether the queue is empty.
+ *
+ * @return a string identifying this synchronizer, as well as its state.
+ */
+ public String toString() {
+ int s = getState();
+ String q = hasQueuedThreads()? "non" : "";
+ return super.toString() +
+ "[State = " + s + ", " + q + "empty queue]";
+ }
+
+
+ // Internal support methods for Conditions
+
+ /**
+ * Returns true if a node, always one that was initially placed on
+ * a condition queue, is now waiting to reacquire on sync queue.
+ * @param node the node
+ * @return true if is reacquiring
+ */
+ final boolean isOnSyncQueue(Node node) {
+ if (node.waitStatus == Node.CONDITION || node.prev == null)
+ return false;
+ if (node.next != null) // If has successor, it must be on queue
+ return true;
+ /*
+ * node.prev can be non-null, but not yet on queue because
+ * the CAS to place it on queue can fail. So we have to
+ * traverse from tail to make sure it actually made it. It
+ * will always be near the tail in calls to this method, and
+ * unless the CAS failed (which is unlikely), it will be
+ * there, so we hardly ever traverse much.
+ */
+ return findNodeFromTail(node);
+ }
+
+ /**
+ * Returns true if node is on sync queue by searching backwards from tail.
+ * Called only when needed by isOnSyncQueue.
+ * @return true if present
+ */
+ private boolean findNodeFromTail(Node node) {
+ Node t = tail;
+ for (;;) {
+ if (t == node)
+ return true;
+ if (t == null)
+ return false;
+ t = t.prev;
+ }
+ }
+
+ /**
+ * Transfers a node from a condition queue onto sync queue.
+ * Returns true if successful.
+ * @param node the node
+ * @return true if successfully transferred (else the node was
+ * cancelled before signal).
+ */
+ final boolean transferForSignal(Node node) {
+ /*
+ * If cannot change waitStatus, the node has been cancelled.
+ */
+ if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))
+ return false;
+
+ /*
+ * Splice onto queue and try to set waitStatus of predecessor to
+ * indicate that thread is (probably) waiting. If cancelled or
+ * attempt to set waitStatus fails, wake up to resync (in which
+ * case the waitStatus can be transiently and harmlessly wrong).
+ */
+ Node p = enq(node);
+ int c = p.waitStatus;
+ if (c > 0 || !compareAndSetWaitStatus(p, c, Node.SIGNAL))
+ LockSupport.unpark(node.thread);
+ return true;
+ }
+
+ /**
+ * Transfers node, if necessary, to sync queue after a cancelled
+ * wait. Returns true if thread was cancelled before being
+ * signalled.
+ * @param current the waiting thread
+ * @param node its node
+ * @return true if cancelled before the node was signalled.
+ */
+ final boolean transferAfterCancelledWait(Node node) {
+ if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) {
+ enq(node);
+ return true;
+ }
+ /*
+ * If we lost out to a signal(), then we can't proceed
+ * until it finishes its enq(). Cancelling during an
+ * incomplete transfer is both rare and transient, so just
+ * spin.
+ */
+ while (!isOnSyncQueue(node))
+ Thread.yield();
+ return false;
+ }
+
+ /**
+ * Invoke release with current state value; return saved state.
+ * Cancel node and throw exception on failure.
+ * @param node the condition node for this wait
+ * @return previous sync state
+ */
+ final int fullyRelease(Node node) {
+ try {
+ int savedState = getState();
+ if (release(savedState))
+ return savedState;
+ } catch(RuntimeException ex) {
+ node.waitStatus = Node.CANCELLED;
+ throw ex;
+ }
+ // reach here if release fails
+ node.waitStatus = Node.CANCELLED;
+ throw new IllegalMonitorStateException();
+ }
+
+ // Instrumentation methods for conditions
+
+ /**
+ * Queries whether the given ConditionObject
+ * uses this synchronizer as its lock.
+ * @param condition the condition
+ * @return <tt>true</tt> if owned
+ * @throws NullPointerException if condition null
+ */
+ public final boolean owns(ConditionObject condition) {
+ if (condition == null)
+ throw new NullPointerException();
+ return condition.isOwnedBy(this);
+ }
+
+ /**
+ * Queries whether any threads are waiting on the given condition
+ * associated with this synchronizer. Note that because timeouts
+ * and interrupts may occur at any time, a <tt>true</tt> return
+ * does not guarantee that a future <tt>signal</tt> will awaken
+ * any threads. This method is designed primarily for use in
+ * monitoring of the system state.
+ * @param condition the condition
+ * @return <tt>true</tt> if there are any waiting threads.
+ * @throws IllegalMonitorStateException if exclusive synchronization
+ * is not held
+ * @throws IllegalArgumentException if the given condition is
+ * not associated with this synchronizer
+ * @throws NullPointerException if condition null
+ */
+ public final boolean hasWaiters(ConditionObject condition) {
+ if (!owns(condition))
+ throw new IllegalArgumentException("Not owner");
+ return condition.hasWaiters();
+ }
+
+ /**
+ * Returns an estimate of the number of threads waiting on the
+ * given condition associated with this synchronizer. Note that
+ * because timeouts and interrupts may occur at any time, the
+ * estimate serves only as an upper bound on the actual number of
+ * waiters. This method is designed for use in monitoring of the
+ * system state, not for synchronization control.
+ * @param condition the condition
+ * @return the estimated number of waiting threads.
+ * @throws IllegalMonitorStateException if exclusive synchronization
+ * is not held
+ * @throws IllegalArgumentException if the given condition is
+ * not associated with this synchronizer
+ * @throws NullPointerException if condition null
+ */
+ public final int getWaitQueueLength(ConditionObject condition) {
+ if (!owns(condition))
+ throw new IllegalArgumentException("Not owner");
+ return condition.getWaitQueueLength();
+ }
+
+ /**
+ * Returns a collection containing those threads that may be
+ * waiting on the given condition associated with this
+ * synchronizer. Because the actual set of threads may change
+ * dynamically while constructing this result, the returned
+ * collection is only a best-effort estimate. The elements of the
+ * returned collection are in no particular order.
+ * @param condition the condition
+ * @return the collection of threads
+ * @throws IllegalMonitorStateException if exclusive synchronization
+ * is not held
+ * @throws IllegalArgumentException if the given condition is
+ * not associated with this synchronizer
+ * @throws NullPointerException if condition null
+ */
+ public final Collection<Thread> getWaitingThreads(ConditionObject condition) {
+ if (!owns(condition))
+ throw new IllegalArgumentException("Not owner");
+ return condition.getWaitingThreads();
+ }
+
+ /**
+ * Condition implementation for a {@link
+ * AbstractQueuedSynchronizer} serving as the basis of a {@link
+ * Lock} implementation.
+ *
+ * <p> Method documentation for this class describes mechanics,
+ * not behavioral specifications from the point of view of Lock
+ * and Condition users. Exported versions of this class will in
+ * general need to be accompanied by documentation describing
+ * condition semantics that rely on those of the associated
+ * <tt>AbstractQueuedSynchronizer</tt>.
+ *
+ * <p> This class is Serializable, but all fields are transient,
+ * so deserialized conditions have no waiters.
+ */
+ public class ConditionObject implements Condition, java.io.Serializable {
+ private static final long serialVersionUID = 1173984872572414699L;
+ /** First node of condition queue. */
+ private transient Node firstWaiter;
+ /** Last node of condition queue. */
+ private transient Node lastWaiter;
+
+ /**
+ * Creates a new <tt>ConditionObject</tt> instance.
+ */
+ public ConditionObject() { }
+
+ // Internal methods
+
+ /**
+ * Add a new waiter to wait queue
+ * @return its new wait node
+ */
+ private Node addConditionWaiter() {
+ Node node = new Node(Thread.currentThread(), Node.CONDITION);
+ Node t = lastWaiter;
+ if (t == null)
+ firstWaiter = node;
+ else
+ t.nextWaiter = node;
+ lastWaiter = node;
+ return node;
+ }
+
+ /**
+ * Remove and transfer nodes until hit non-cancelled one or
+ * null. Split out from signal in part to encourage compilers
+ * to inline the case of no waiters.
+ * @param first (non-null) the first node on condition queue
+ */
+ private void doSignal(Node first) {
+ do {
+ if ( (firstWaiter = first.nextWaiter) == null)
+ lastWaiter = null;
+ first.nextWaiter = null;
+ } while (!transferForSignal(first) &&
+ (first = firstWaiter) != null);
+ }
+
+ /**
+ * Remove and transfer all nodes.
+ * @param first (non-null) the first node on condition queue
+ */
+ private void doSignalAll(Node first) {
+ lastWaiter = firstWaiter = null;
+ do {
+ Node next = first.nextWaiter;
+ first.nextWaiter = null;
+ transferForSignal(first);
+ first = next;
+ } while (first != null);
+ }
+
+ // public methods
+
+ /**
+ * Moves the longest-waiting thread, if one exists, from the
+ * wait queue for this condition to the wait queue for the
+ * owning lock.
+ * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
+ * returns false
+ */
+ public final void signal() {
+ if (!isHeldExclusively())
+ throw new IllegalMonitorStateException();
+ Node first = firstWaiter;
+ if (first != null)
+ doSignal(first);
+ }
+
+ /**
+ * Moves all threads from the wait queue for this condition to
+ * the wait queue for the owning lock.
+ * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
+ * returns false
+ */
+ public final void signalAll() {
+ if (!isHeldExclusively())
+ throw new IllegalMonitorStateException();
+ Node first = firstWaiter;
+ if (first != null)
+ doSignalAll(first);
+ }
+
+ /**
+ * Implements uninterruptible condition wait.
+ * <ol>
+ * <li> Save lock state returned by {@link #getState}
+ * <li> Invoke {@link #release} with
+ * saved state as argument, throwing
+ * IllegalMonitorStateException if it fails.
+ * <li> Block until signalled
+ * <li> Reacquire by invoking specialized version of
+ * {@link #acquire} with saved state as argument.
+ * </ol>
+ */
+ public final void awaitUninterruptibly() {
+ Node node = addConditionWaiter();
+ int savedState = fullyRelease(node);
+ boolean interrupted = false;
+ while (!isOnSyncQueue(node)) {
+ LockSupport.park();
+ if (Thread.interrupted())
+ interrupted = true;
+ }
+ if (acquireQueued(node, savedState) || interrupted)
+ selfInterrupt();
+ }
+
+ /*
+ * For interruptible waits, we need to track whether to throw
+ * InterruptedException, if interrupted while blocked on
+ * condition, versus reinterrupt current thread, if
+ * interrupted while blocked waiting to re-acquire.
+ */
+
+ /** Mode meaning to reinterrupt on exit from wait */
+ private static final int REINTERRUPT = 1;
+ /** Mode meaning to throw InterruptedException on exit from wait */
+ private static final int THROW_IE = -1;
+
+ /**
+ * Check for interrupt, returning THROW_IE if interrupted
+ * before signalled, REINTERRUPT if after signalled, or
+ * 0 if not interrupted.
+ */
+ private int checkInterruptWhileWaiting(Node node) {
+ return (Thread.interrupted()) ?
+ ((transferAfterCancelledWait(node))? THROW_IE : REINTERRUPT) :
+ 0;
+ }
+
+ /**
+ * Throw InterruptedException, reinterrupt current thread, or
+ * do nothing, depending on mode.
+ */
+ private void reportInterruptAfterWait(int interruptMode)
+ throws InterruptedException {
+ if (interruptMode == THROW_IE)
+ throw new InterruptedException();
+ else if (interruptMode == REINTERRUPT)
+ Thread.currentThread().interrupt();
+ }
+
+ /**
+ * Implements interruptible condition wait.
+ * <ol>
+ * <li> If current thread is interrupted, throw InterruptedException
+ * <li> Save lock state returned by {@link #getState}
+ * <li> Invoke {@link #release} with
+ * saved state as argument, throwing
+ * IllegalMonitorStateException if it fails.
+ * <li> Block until signalled or interrupted
+ * <li> Reacquire by invoking specialized version of
+ * {@link #acquire} with saved state as argument.
+ * <li> If interrupted while blocked in step 4, throw exception
+ * </ol>
+ *
+ * @throws InterruptedException if the current thread is interrupted (and
+ * interruption of thread suspension is supported).
+ */
+ public final void await() throws InterruptedException {
+ if (Thread.interrupted())
+ throw new InterruptedException();
+ Node node = addConditionWaiter();
+ int savedState = fullyRelease(node);
+ int interruptMode = 0;
+ while (!isOnSyncQueue(node)) {
+ LockSupport.park();
+ if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
+ break;
+ }
+ if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
+ interruptMode = REINTERRUPT;
+ if (interruptMode != 0)
+ reportInterruptAfterWait(interruptMode);
+ }
+
+ /**
+ * Implements timed condition wait.
+ * <ol>
+ * <li> If current thread is interrupted, throw InterruptedException
+ * <li> Save lock state returned by {@link #getState}
+ * <li> Invoke {@link #release} with
+ * saved state as argument, throwing
+ * IllegalMonitorStateException if it fails.
+ * <li> Block until signalled, interrupted, or timed out
+ * <li> Reacquire by invoking specialized version of
+ * {@link #acquire} with saved state as argument.
+ * <li> If interrupted while blocked in step 4, throw InterruptedException
+ * </ol>
+ *
+ *
+ * @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).
+ */
+ public final long awaitNanos(long nanosTimeout) throws InterruptedException {
+ if (Thread.interrupted())
+ throw new InterruptedException();
+ Node node = addConditionWaiter();
+ int savedState = fullyRelease(node);
+ long lastTime = System.nanoTime();
+ int interruptMode = 0;
+ while (!isOnSyncQueue(node)) {
+ if (nanosTimeout <= 0L) {
+ transferAfterCancelledWait(node);
+ break;
+ }
+ LockSupport.parkNanos(nanosTimeout);
+ if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
+ break;
+ long now = System.nanoTime();
+ nanosTimeout -= now - lastTime;
+ lastTime = now;
+ }
+ if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
+ interruptMode = REINTERRUPT;
+ if (interruptMode != 0)
+ reportInterruptAfterWait(interruptMode);
+ return nanosTimeout - (System.nanoTime() - lastTime);
+ }
+
+ /**
+ * Implements absolute timed condition wait.
+ * <ol>
+ * <li> If current thread is interrupted, throw InterruptedException
+ * <li> Save lock state returned by {@link #getState}
+ * <li> Invoke {@link #release} with
+ * saved state as argument, throwing
+ * IllegalMonitorStateException if it fails.
+ * <li> Block until signalled, interrupted, or timed out
+ * <li> Reacquire by invoking specialized version of
+ * {@link #acquire} with saved state as argument.
+ * <li> If interrupted while blocked in step 4, throw InterruptedException
+ * <li> If timed out while blocked in step 4, return false, else true
+ * </ol>
+ *
+ *
+ * @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
+ * interruption of thread suspension is supported).
+ */
+ public final boolean awaitUntil(Date deadline) throws InterruptedException {
+ if (deadline == null)
+ throw new NullPointerException();
+ long abstime = deadline.getTime();
+ if (Thread.interrupted())
+ throw new InterruptedException();
+ Node node = addConditionWaiter();
+ int savedState = fullyRelease(node);
+ boolean timedout = false;
+ int interruptMode = 0;
+ while (!isOnSyncQueue(node)) {
+ if (System.currentTimeMillis() > abstime) {
+ timedout = transferAfterCancelledWait(node);
+ break;
+ }
+ LockSupport.parkUntil(abstime);
+ if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
+ break;
+ }
+ if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
+ interruptMode = REINTERRUPT;
+ if (interruptMode != 0)
+ reportInterruptAfterWait(interruptMode);
+ return !timedout;
+ }
+
+ /**
+ * Implements timed condition wait.
+ * <ol>
+ * <li> If current thread is interrupted, throw InterruptedException
+ * <li> Save lock state returned by {@link #getState}
+ * <li> Invoke {@link #release} with
+ * saved state as argument, throwing
+ * IllegalMonitorStateException if it fails.
+ * <li> Block until signalled, interrupted, or timed out
+ * <li> Reacquire by invoking specialized version of
+ * {@link #acquire} with saved state as argument.
+ * <li> If interrupted while blocked in step 4, throw InterruptedException
+ * <li> If timed out while blocked in step 4, return false, else true
+ * </ol>
+ *
+ *
+ *
+ * @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
+ * interruption of thread suspension is supported).
+ */
+ public final boolean await(long time, TimeUnit unit) throws InterruptedException {
+ if (unit == null)
+ throw new NullPointerException();
+ long nanosTimeout = unit.toNanos(time);
+ if (Thread.interrupted())
+ throw new InterruptedException();
+ Node node = addConditionWaiter();
+ int savedState = fullyRelease(node);
+ long lastTime = System.nanoTime();
+ boolean timedout = false;
+ int interruptMode = 0;
+ while (!isOnSyncQueue(node)) {
+ if (nanosTimeout <= 0L) {
+ timedout = transferAfterCancelledWait(node);
+ break;
+ }
+ LockSupport.parkNanos(nanosTimeout);
+ if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
+ break;
+ long now = System.nanoTime();
+ nanosTimeout -= now - lastTime;
+ lastTime = now;
+ }
+ if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
+ interruptMode = REINTERRUPT;
+ if (interruptMode != 0)
+ reportInterruptAfterWait(interruptMode);
+ return !timedout;
+ }
+
+ // support for instrumentation
+
+ /**
+ * Returns true if this condition was created by the given
+ * synchronization object
+ * @return true if owned
+ */
+ final boolean isOwnedBy(AbstractQueuedSynchronizer sync) {
+ return sync == AbstractQueuedSynchronizer.this;
+ }
+
+ /**
+ * Queries whether any threads are waiting on this condition.
+ * Implements {@link AbstractQueuedSynchronizer#hasWaiters}
+ * @return <tt>true</tt> if there are any waiting threads.
+ * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
+ * returns false
+ */
+ protected final boolean hasWaiters() {
+ if (!isHeldExclusively())
+ throw new IllegalMonitorStateException();
+ for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
+ if (w.waitStatus == Node.CONDITION)
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns an estimate of the number of threads waiting on
+ * this condition.
+ * Implements {@link AbstractQueuedSynchronizer#getWaitQueueLength}
+ * @return the estimated number of waiting threads.
+ * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
+ * returns false
+ */
+ protected final int getWaitQueueLength() {
+ if (!isHeldExclusively())
+ throw new IllegalMonitorStateException();
+ int n = 0;
+ for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
+ if (w.waitStatus == Node.CONDITION)
+ ++n;
+ }
+ return n;
+ }
+
+ /**
+ * Returns a collection containing those threads that may be
+ * waiting on this Condition.
+ * Implements {@link AbstractQueuedSynchronizer#getWaitingThreads}
+ * @return the collection of threads
+ * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
+ * returns false
+ */
+ protected final Collection<Thread> getWaitingThreads() {
+ if (!isHeldExclusively())
+ throw new IllegalMonitorStateException();
+ ArrayList<Thread> list = new ArrayList<Thread>();
+ for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
+ if (w.waitStatus == Node.CONDITION) {
+ Thread t = w.thread;
+ if (t != null)
+ list.add(t);
+ }
+ }
+ return list;
+ }
+ }
+
+ /**
+ * Setup to support compareAndSet. We need to natively implement
+ * this here: For the sake of permitting future enhancements, we
+ * cannot explicitly subclass AtomicInteger, which would be
+ * efficient and useful otherwise. So, as the lesser of evils, we
+ * natively implement using hotspot intrinsics API. And while we
+ * are at it, we do the same for other CASable fields (which could
+ * otherwise be done with atomic field updaters).
+ */
+
+ // BEGIN android-changed
+ private static final Unsafe unsafe = UnsafeAccess.THE_ONE;
+ // END android-changed
+
+ private static final long stateOffset;
+ private static final long headOffset;
+ private static final long tailOffset;
+ private static final long waitStatusOffset;
+
+ static {
+ try {
+ stateOffset = unsafe.objectFieldOffset
+ (AbstractQueuedSynchronizer.class.getDeclaredField("state"));
+ headOffset = unsafe.objectFieldOffset
+ (AbstractQueuedSynchronizer.class.getDeclaredField("head"));
+ tailOffset = unsafe.objectFieldOffset
+ (AbstractQueuedSynchronizer.class.getDeclaredField("tail"));
+ waitStatusOffset = unsafe.objectFieldOffset
+ (Node.class.getDeclaredField("waitStatus"));
+
+ } catch(Exception ex) { throw new Error(ex); }
+ }
+
+ /**
+ * CAS head field. Used only by enq
+ */
+ private final boolean compareAndSetHead(Node update) {
+ return unsafe.compareAndSwapObject(this, headOffset, null, update);
+ }
+
+ /**
+ * CAS tail field. Used only by enq
+ */
+ private final boolean compareAndSetTail(Node expect, Node update) {
+ return unsafe.compareAndSwapObject(this, tailOffset, expect, update);
+ }
+
+ /**
+ * CAS waitStatus field of a node.
+ */
+ private final static boolean compareAndSetWaitStatus(Node node,
+ int expect,
+ int update) {
+ return unsafe.compareAndSwapInt(node, waitStatusOffset,
+ expect, update);
+ }
+
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/locks/Condition.java b/concurrent/src/main/java/java/util/concurrent/locks/Condition.java
new file mode 100644
index 0000000..7a8ca5b
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/locks/Condition.java
@@ -0,0 +1,439 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.locks;
+import java.util.concurrent.*;
+import java.util.Date;
+
+/**
+ * <tt>Condition</tt> factors out the <tt>Object</tt> monitor
+ * 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
+ * <em>condition variables</em>) provide a means for one thread to
+ * suspend execution (to &quot;wait&quot;) 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.
+ * 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
+ * <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.
+ * We would like to keep waiting <tt>put</tt> threads and <tt>take</tt>
+ * threads in separate wait-sets so that we can use the optimization of
+ * 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>Lock lock = new ReentrantLock();</b>
+ * final Condition notFull = <b>lock.newCondition(); </b>
+ * final Condition notEmpty = <b>lock.newCondition(); </b>
+ *
+ * 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 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
+ * 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
+ * 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.
+ * Acquiring the monitor lock of a <tt>Condition</tt> instance, or using its
+ * monitor methods, has no specified relationship with acquiring the
+ * {@link Lock} associated with that <tt>Condition</tt> or the use of its
+ * {@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
+ * will result in a {@link NullPointerException} being thrown.
+ *
+ * <h3>Implementation Considerations</h3>
+ *
+ * <p>When waiting upon a <tt>Condition</tt>, a &quot;<em>spurious
+ * wakeup</em>&quot; 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
+ * 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
+ * (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
+ * 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
+ * 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
+ * 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
+ * released and the current thread becomes disabled for thread scheduling
+ * purposes and lies dormant until <em>one</em> of four 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>A &quot;<em>spurious wakeup</em>&quot; 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><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. 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
+ * 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
+ * released and the current thread becomes disabled for thread scheduling
+ * purposes and lies dormant until <em>one</em> of three 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>A &quot;<em>spurious wakeup</em>&quot; 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's interrupt 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 <em>interrupted status</em> will still
+ * be set.
+ *
+ * <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.
+ *
+ **/
+ 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 &quot;<em>spurious wakeup</em>&quot; 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 &gt; 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)) &gt; 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
+ * interruption of thread suspension is supported).
+ */
+ boolean await(long time, TimeUnit unit) throws InterruptedException;
+
+ /**
+ * 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
+ * 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 deadline elapses; or
+ * <li>A &quot;<em>spurious wakeup</em>&quot; 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 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>
+ *
+ * <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 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
+ * 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
+ * is selected for waking up. That thread must then re-acquire the
+ * lock before returning from <tt>await</tt>.
+ **/
+ void signal();
+
+ /**
+ * Wakes up all waiting threads.
+ *
+ * <p>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>.
+ **/
+ void signalAll();
+
+}
+
+
+
+
+
+
+
diff --git a/concurrent/src/main/java/java/util/concurrent/locks/Lock.java b/concurrent/src/main/java/java/util/concurrent/locks/Lock.java
new file mode 100644
index 0000000..f07b72e
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/locks/Lock.java
@@ -0,0 +1,329 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.locks;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * <tt>Lock</tt> implementations provide more extensive locking
+ * operations than can be obtained using <tt>synchronized</tt> methods
+ * and statements. They allow more flexible structuring, may have
+ * quite different properties, and may support multiple associated
+ * {@link Condition} objects.
+ *
+ * <p>A lock is a tool for controlling access to a shared resource by
+ * multiple threads. Commonly, a lock provides exclusive access to a
+ * shared resource: only one thread at a time can acquire the lock and
+ * all access to the shared resource requires that the lock be
+ * acquired first. However, some locks may allow concurrent access to
+ * a shared resource, such as the read lock of a {@link
+ * ReadWriteLock}.
+ *
+ * <p>The use of <tt>synchronized</tt> methods or statements provides
+ * access to the implicit monitor lock associated with every object, but
+ * forces all lock acquisition and release to occur in a block-structured way:
+ * when multiple locks are acquired they must be released in the opposite
+ * order, and all locks must be released in the same lexical scope in which
+ * they were acquired.
+ *
+ * <p>While the scoping mechanism for <tt>synchronized</tt> methods
+ * and statements makes it much easier to program with monitor locks,
+ * and helps avoid many common programming errors involving locks,
+ * there are occasions where you need to work with locks in a more
+ * flexible way. For example, some algorithms for traversing
+ * concurrently accessed data structures require the use of
+ * &quot;hand-over-hand&quot; or &quot;chain locking&quot;: you
+ * acquire the lock of node A, then node B, then release A and acquire
+ * C, then release B and acquire D and so on. Implementations of the
+ * <tt>Lock</tt> interface enable the use of such techniques by
+ * allowing a lock to be acquired and released in different scopes,
+ * and allowing multiple locks to be acquired and released in any
+ * order.
+ *
+ * <p>With this increased flexibility comes additional
+ * responsibility. The absence of block-structured locking removes the
+ * automatic release of locks that occurs with <tt>synchronized</tt>
+ * methods and statements. In most cases, the following idiom
+ * should be used:
+ *
+ * <pre><tt> Lock l = ...;
+ * l.lock();
+ * try {
+ * // access the resource protected by this lock
+ * } finally {
+ * l.unlock();
+ * }
+ * </tt></pre>
+ *
+ * When locking and unlocking occur in different scopes, care must be
+ * taken to ensure that all code that is executed while the lock is
+ * held is protected by try-finally or try-catch to ensure that the
+ * lock is released when necessary.
+ *
+ * <p><tt>Lock</tt> implementations provide additional functionality
+ * over the use of <tt>synchronized</tt> methods and statements by
+ * providing a non-blocking attempt to acquire a lock ({@link
+ * #tryLock()}), an attempt to acquire the lock that can be
+ * interrupted ({@link #lockInterruptibly}, and an attempt to acquire
+ * the lock that can timeout ({@link #tryLock(long, TimeUnit)}).
+ *
+ * <p>A <tt>Lock</tt> class can also provide behavior and semantics
+ * that is quite different from that of the implicit monitor lock,
+ * such as guaranteed ordering, non-reentrant usage, or deadlock
+ * detection. If an implementation provides such specialized semantics
+ * then the implementation must document those semantics.
+ *
+ * <p>Note that <tt>Lock</tt> instances are just normal objects and can
+ * themselves be used as the target in a <tt>synchronized</tt> statement.
+ * Acquiring the
+ * monitor lock of a <tt>Lock</tt> instance has no specified relationship
+ * with invoking any of the {@link #lock} methods of that instance.
+ * It is recommended that to avoid confusion you never use <tt>Lock</tt>
+ * instances in this way, except within their own implementation.
+ *
+ * <p>Except where noted, passing a <tt>null</tt> value for any
+ * parameter will result in a {@link NullPointerException} being
+ * thrown.
+ *
+ * <h3>Memory Synchronization</h3>
+ * <p>All <tt>Lock</tt> implementations <em>must</em> enforce the same
+ * memory synchronization semantics as provided by the built-in monitor lock:
+ * <ul>
+ * <li>A successful lock operation acts like a successful
+ * <tt>monitorEnter</tt> action
+ * <li>A successful <tt>unlock</tt> operation acts like a successful
+ * <tt>monitorExit</tt> action
+ * </ul>
+ *
+ * Unsuccessful locking and unlocking operations, and reentrant
+ * locking/unlocking operations, do not require any memory
+ * synchronization effects.
+ *
+ * <h3>Implementation Considerations</h3>
+ *
+ * <p> The three forms of lock acquisition (interruptible,
+ * non-interruptible, and timed) may differ in their performance
+ * characteristics, ordering guarantees, or other implementation
+ * qualities. Further, the ability to interrupt the <em>ongoing</em>
+ * acquisition of a lock may not be available in a given <tt>Lock</tt>
+ * class. Consequently, an implementation is not required to define
+ * exactly the same guarantees or semantics for all three forms of
+ * lock acquisition, nor is it required to support interruption of an
+ * ongoing lock acquisition. An implementation is required to clearly
+ * document the semantics and guarantees provided by each of the
+ * locking methods. It must also obey the interruption semantics as
+ * defined in this interface, to the extent that interruption of lock
+ * acquisition is supported: which is either totally, or only on
+ * method entry.
+ *
+ * <p>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.
+ *
+ *
+ * @see ReentrantLock
+ * @see Condition
+ * @see ReadWriteLock
+ *
+ * @since 1.5
+ * @author Doug Lea
+ *
+ **/
+public interface Lock {
+
+ /**
+ * Acquires the lock.
+ * <p>If the lock is not available then
+ * the current thread becomes disabled for thread scheduling
+ * purposes and lies dormant until the lock has been acquired.
+ * <p><b>Implementation Considerations</b>
+ * <p>A <tt>Lock</tt> implementation may be able to detect
+ * erroneous use of the lock, such as an invocation that would cause
+ * deadlock, and may throw an (unchecked) exception in such circumstances.
+ * The circumstances and the exception type must be documented by that
+ * <tt>Lock</tt> implementation.
+ *
+ **/
+ void lock();
+
+ /**
+ * Acquires the lock unless the current thread is
+ * {@link Thread#interrupt interrupted}.
+ * <p>Acquires the lock if it is available and returns immediately.
+ * <p>If the lock is not available then
+ * the current thread becomes disabled for thread scheduling
+ * purposes and lies dormant until one of two things happens:
+ * <ul>
+ * <li>The lock is acquired by the current thread; or
+ * <li>Some other thread {@link Thread#interrupt interrupts} the current
+ * thread, and interruption of lock acquisition is supported.
+ * </ul>
+ * <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 acquiring
+ * the lock, and interruption of lock acquisition is supported,
+ * </ul>
+ * then {@link InterruptedException} is thrown and the current thread's
+ * interrupted status is cleared.
+ *
+ * <p><b>Implementation Considerations</b>
+ *
+ * <p>The ability to interrupt a lock acquisition in some
+ * implementations may not be possible, and if possible may be an
+ * expensive operation. The programmer should be aware that this
+ * may be the case. An implementation should document when this is
+ * the case.
+ *
+ * <p>An implementation can favor responding to an interrupt over
+ * normal method return.
+ *
+ * <p>A <tt>Lock</tt> implementation may be able to detect
+ * erroneous use of the lock, such as an invocation that would
+ * cause deadlock, and may throw an (unchecked) exception in such
+ * circumstances. The circumstances and the exception type must
+ * be documented by that <tt>Lock</tt> implementation.
+ *
+ * @throws InterruptedException if the current thread is interrupted
+ * while acquiring the lock (and interruption of lock acquisition is
+ * supported).
+ *
+ * @see Thread#interrupt
+ *
+ **/
+ void lockInterruptibly() throws InterruptedException;
+
+
+ /**
+ * Acquires the lock only if it is free at the time of invocation.
+ * <p>Acquires the lock if it is available and returns immediately
+ * with the value <tt>true</tt>.
+ * If the lock is not available then this method will return
+ * immediately with the value <tt>false</tt>.
+ * <p>A typical usage idiom for this method would be:
+ * <pre>
+ * Lock lock = ...;
+ * if (lock.tryLock()) {
+ * try {
+ * // manipulate protected state
+ * } finally {
+ * lock.unlock();
+ * }
+ * } else {
+ * // perform alternative actions
+ * }
+ * </pre>
+ * This usage ensures that the lock is unlocked if it was acquired, and
+ * doesn't try to unlock if the lock was not acquired.
+ *
+ * @return <tt>true</tt> if the lock was acquired and <tt>false</tt>
+ * otherwise.
+ **/
+ boolean tryLock();
+
+ /**
+ * Acquires the lock if it is free within the given waiting time and the
+ * current thread has not been {@link Thread#interrupt interrupted}.
+ *
+ * <p>If the lock is available this method returns immediately
+ * with the value <tt>true</tt>.
+ * If the lock is not available then
+ * the current thread becomes disabled for thread scheduling
+ * purposes and lies dormant until one of three things happens:
+ * <ul>
+ * <li>The lock is acquired by the current thread; or
+ * <li>Some other thread {@link Thread#interrupt interrupts} the current
+ * thread, and interruption of lock acquisition is supported; or
+ * <li>The specified waiting time elapses
+ * </ul>
+ * <p>If the lock is acquired then the value <tt>true</tt> is returned.
+ * <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 acquiring
+ * the lock, and interruption of lock acquisition is supported,
+ * </ul>
+ * then {@link InterruptedException} is thrown and the current thread's
+ * interrupted status is cleared.
+ * <p>If the specified waiting time elapses then the value <tt>false</tt>
+ * is returned.
+ * If the time is
+ * less than or equal to zero, the method will not wait at all.
+ *
+ * <p><b>Implementation Considerations</b>
+ * <p>The ability to interrupt a lock acquisition in some implementations
+ * may not be possible, and if possible may
+ * be an expensive operation.
+ * The programmer should be aware that this may be the case. An
+ * implementation should document when this is the case.
+ * <p>An implementation can favor responding to an interrupt over normal
+ * method return, or reporting a timeout.
+ * <p>A <tt>Lock</tt> implementation may be able to detect
+ * erroneous use of the lock, such as an invocation that would cause
+ * deadlock, and may throw an (unchecked) exception in such circumstances.
+ * The circumstances and the exception type must be documented by that
+ * <tt>Lock</tt> implementation.
+ *
+ * @param time the maximum time to wait for the lock
+ * @param unit the time unit of the <tt>time</tt> argument.
+ * @return <tt>true</tt> if the lock was acquired and <tt>false</tt>
+ * if the waiting time elapsed before the lock was acquired.
+ *
+ * @throws InterruptedException if the current thread is interrupted
+ * while acquiring the lock (and interruption of lock acquisition is
+ * supported).
+ *
+ * @see Thread#interrupt
+ *
+ **/
+ boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
+
+ /**
+ * Releases the lock.
+ * <p><b>Implementation Considerations</b>
+ * <p>A <tt>Lock</tt> implementation will usually impose
+ * restrictions on which thread can release a lock (typically only the
+ * holder of the lock can release it) and may throw
+ * an (unchecked) exception if the restriction is violated.
+ * Any restrictions and the exception
+ * type must be documented by that <tt>Lock</tt> implementation.
+ **/
+ void unlock();
+
+ /**
+ * Returns a new {@link Condition} instance that is bound to this
+ * <tt>Lock</tt> instance.
+ * <p>Before waiting on the condition the lock must be held by the
+ * current thread.
+ * A call to {@link Condition#await()} will atomically release the lock
+ * before waiting and re-acquire the lock before the wait returns.
+ * <p><b>Implementation Considerations</b>
+ * <p>The exact operation of the {@link Condition} instance depends on the
+ * <tt>Lock</tt> implementation and must be documented by that
+ * implementation.
+ *
+ * @return A new {@link Condition} instance for this <tt>Lock</tt>
+ * instance.
+ * @throws UnsupportedOperationException if this <tt>Lock</tt>
+ * implementation does not support conditions.
+ **/
+ Condition newCondition();
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/concurrent/src/main/java/java/util/concurrent/locks/LockSupport.java b/concurrent/src/main/java/java/util/concurrent/locks/LockSupport.java
new file mode 100644
index 0000000..8603785
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/locks/LockSupport.java
@@ -0,0 +1,178 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.locks;
+import java.util.concurrent.*;
+import sun.misc.Unsafe;
+
+
+/**
+ * Basic thread blocking primitives for creating locks and other
+ * synchronization classes.
+ *
+ * <p>This class associates with each thread that uses it, a permit
+ * (in the sense of the {@link java.util.concurrent.Semaphore
+ * Semaphore} class). A call to <tt>park</tt> will return immediately
+ * if the permit is available, consuming it in the process; otherwise
+ * it <em>may</em> block. A call to <tt>unpark</tt> makes the permit
+ * available, if it was not already available. (Unlike with Semaphores
+ * though, permits do not accumulate. There is at most one.)
+ *
+ * <p>Methods <tt>park</tt> and <tt>unpark</tt> provide efficient
+ * means of blocking and unblocking threads that do not encounter the
+ * problems that cause the deprecated methods <tt>Thread.suspend</tt>
+ * and <tt>Thread.resume</tt> to be unusable for such purposes: Races
+ * between one thread invoking <tt>park</tt> and another thread trying
+ * to <tt>unpark</tt> it will preserve liveness, due to the
+ * permit. Additionally, <tt>park</tt> will return if the caller's
+ * thread was interrupted, and timeout versions are supported. The
+ * <tt>park</tt> method may also return at any other time, for "no
+ * reason", so in general must be invoked within a loop that rechecks
+ * conditions upon return. In this sense <tt>park</tt> serves as an
+ * optimization of a "busy wait" that does not waste as much time
+ * spinning, but must be paired with an <tt>unpark</tt> to be
+ * effective.
+ *
+ * <p>These methods are designed to be used as tools for creating
+ * higher-level synchronization utilities, and are not in themselves
+ * useful for most concurrency control applications.
+ *
+ * <p><b>Sample Usage.</b> Here is a sketch of a First-in-first-out
+ * non-reentrant lock class.
+ * <pre>
+ * private AtomicBoolean locked = new AtomicBoolean(false);
+ * private Queue&lt;Thread&gt; waiters = new ConcurrentLinkedQueue&lt;Thread&gt;();
+ *
+ * public void lock() {
+ * boolean wasInterrupted = false;
+ * Thread current = Thread.currentThread();
+ * waiters.add(current);
+ *
+ * // Block while not first in queue or cannot acquire lock
+ * while (waiters.peek() != current ||
+ * !locked.compareAndSet(false, true)) {
+ * LockSupport.park();
+ * if (Thread.interrupted()) // ignore interrupts while waiting
+ * wasInterrupted = true;
+ * }
+ *
+ * waiters.remove();
+ * if (wasInterrupted) // reassert interrupt status on exit
+ * current.interrupt();
+ * }
+ *
+ * public void unlock() {
+ * locked.set(false);
+ * LockSupport.unpark(waiters.peek());
+ * }
+ * }
+ * </pre>
+ */
+@SuppressWarnings("all")
+public class LockSupport {
+ private LockSupport() {} // Cannot be instantiated.
+
+ // BEGIN android-changed
+ private static final Unsafe unsafe = UnsafeAccess.THE_ONE;
+ // END android-changed
+
+ /**
+ * Make available the permit for the given thread, if it
+ * was not already available. If the thread was blocked on
+ * <tt>park</tt> then it will unblock. Otherwise, its next call
+ * to <tt>park</tt> is guaranteed not to block. This operation
+ * is not guaranteed to have any effect at all if the given
+ * thread has not been started.
+ * @param thread the thread to unpark, or <tt>null</tt>, in which case
+ * this operation has no effect.
+ */
+ public static void unpark(Thread thread) {
+ if (thread != null)
+ unsafe.unpark(thread);
+ }
+
+ /**
+ * Disables the current thread for thread scheduling purposes unless the
+ * permit is available.
+ * <p>If the permit is available then it is consumed and the call returns
+ * immediately; otherwise
+ * the current thread becomes disabled for thread scheduling
+ * purposes and lies dormant until one of three things happens:
+ * <ul>
+ * <li>Some other thread invokes <tt>unpark</tt> with the current thread
+ * as the target; or
+ * <li>Some other thread {@link Thread#interrupt interrupts} the current
+ * thread; or
+ * <li>The call spuriously (that is, for no reason) returns.
+ * </ul>
+ * <p>This method does <em>not</em> report which of these caused the
+ * method to return. Callers should re-check the conditions which caused
+ * the thread to park in the first place. Callers may also determine,
+ * for example, the interrupt status of the thread upon return.
+ */
+ public static void park() {
+ unsafe.park(false, 0L);
+ }
+
+ /**
+ * Disables the current thread for thread scheduling purposes, for up to
+ * the specified waiting time, unless the permit is available.
+ * <p>If the permit is available then it is consumed and the call returns
+ * immediately; otherwise
+ * the current thread becomes disabled for thread scheduling
+ * purposes and lies dormant until one of four things happens:
+ * <ul>
+ * <li>Some other thread invokes <tt>unpark</tt> with the current thread
+ * as the target; or
+ * <li>Some other thread {@link Thread#interrupt interrupts} the current
+ * thread; or
+ * <li>The specified waiting time elapses; or
+ * <li>The call spuriously (that is, for no reason) returns.
+ * </ul>
+ * <p>This method does <em>not</em> report which of these caused the
+ * method to return. Callers should re-check the conditions which caused
+ * the thread to park in the first place. Callers may also determine,
+ * for example, the interrupt status of the thread, or the elapsed time
+ * upon return.
+ *
+ * @param nanos the maximum number of nanoseconds to wait
+ */
+ public static void parkNanos(long nanos) {
+ if (nanos > 0)
+ unsafe.park(false, nanos);
+ }
+
+ /**
+ * Disables the current thread for thread scheduling purposes, until
+ * the specified deadline, unless the permit is available.
+ * <p>If the permit is available then it is consumed and the call returns
+ * immediately; otherwise
+ * the current thread becomes disabled for thread scheduling
+ * purposes and lies dormant until one of four things happens:
+ * <ul>
+ * <li>Some other thread invokes <tt>unpark</tt> with the current thread
+ * as the target; or
+ * <li>Some other thread {@link Thread#interrupt interrupts} the current
+ * thread; or
+ * <li>The specified deadline passes; or
+ * <li>The call spuriously (that is, for no reason) returns.
+ * </ul>
+ * <p>This method does <em>not</em> report which of these caused the
+ * method to return. Callers should re-check the conditions which caused
+ * the thread to park in the first place. Callers may also determine,
+ * for example, the interrupt status of the thread, or the current time
+ * upon return.
+ *
+ * @param deadline the absolute time, in milliseconds from the Epoch, to
+ * wait until
+ */
+ public static void parkUntil(long deadline) {
+ unsafe.park(true, deadline);
+ }
+
+}
+
+
diff --git a/concurrent/src/main/java/java/util/concurrent/locks/ReadWriteLock.java b/concurrent/src/main/java/java/util/concurrent/locks/ReadWriteLock.java
new file mode 100644
index 0000000..c7116d5
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/locks/ReadWriteLock.java
@@ -0,0 +1,97 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.locks;
+
+/**
+ * A <tt>ReadWriteLock</tt> maintains a pair of associated {@link
+ * Lock locks}, one for read-only operations and one for writing.
+ * The {@link #readLock read lock} may be held simultaneously by
+ * multiple reader threads, so long as there are no writers. The
+ * {@link #writeLock write lock} is exclusive.
+ *
+ * <p>A read-write lock allows for a greater level of concurrency in
+ * accessing shared data, than that permitted by a mutual exclusion lock.
+ * It exploits the fact that while only a single thread at a time (a
+ * <em>writer</em> thread) can modify the shared data, in many cases any
+ * number of threads can concurrently read the data (hence <em>reader</em>
+ * threads).
+ * In theory, the increase in concurrency permitted by the use of a read-write
+ * lock will lead to performance improvements over the use of a mutual
+ * exclusion lock. In practice this increase in concurrency will only be fully
+ * realized on a multi-processor, and then only if the access patterns for
+ * the shared data are suitable.
+ *
+ * <p>Whether or not a read-write lock will improve performance over the use
+ * of a mutual exclusion lock depends on the frequency that the data is
+ * read compared to being modified, the duration of the read and write
+ * operations, and the contention for the data - that is, the number of
+ * threads that will try to read or write the data at the same time.
+ * For example, a collection that is initially populated with data and
+ * thereafter infrequently modified, while being frequently searched
+ * (such as a directory of some kind) is an ideal candidate for the use of
+ * a read-write lock. However, if updates become frequent then the data
+ * spends most of its time being exclusively locked and there is little, if any
+ * increase in concurrency. Further, if the read operations are too short
+ * the overhead of the read-write lock implementation (which is inherently
+ * more complex than a mutual exclusion lock) can dominate the execution
+ * cost, particularly as many read-write lock implementations still serialize
+ * all threads through a small section of code. Ultimately, only profiling
+ * and measurement will establish whether the use of a read-write lock is
+ * suitable for your application.
+ *
+ *
+ * <p>Although the basic operation of a read-write lock is straight-forward,
+ * there are many policy decisions that an implementation must make, which
+ * may affect the effectiveness of the read-write lock in a given application.
+ * Examples of these policies include:
+ * <ul>
+ * <li>Determining whether to grant the read lock or the write lock, when
+ * both readers and writers are waiting, at the time that a writer releases
+ * the write lock. Writer preference is common, as writes are expected to be
+ * short and infrequent. Reader preference is less common as it can lead to
+ * lengthy delays for a write if the readers are frequent and long-lived as
+ * expected. Fair, or &quot;in-order&quot; implementations are also possible.
+ *
+ * <li>Determining whether readers that request the read lock while a
+ * reader is active and a writer is waiting, are granted the read lock.
+ * Preference to the reader can delay the writer indefinitely, while
+ * preference to the write can reduce the potential for concurrency.
+ *
+ * <li>Determining whether the locks are reentrant: can a thread with the
+ * write lock reacquire it? can it acquire a read lock while holding the
+ * write lock? is the read lock itself reentrant?
+ *
+ * <li>Can the write lock be downgraded to a read lock without allowing
+ * an intervening writer? Can a read lock be upgraded to a write lock,
+ * in preference to other waiting readers or writers?
+ *
+ * </ul>
+ * You should consider all of these things when evaluating the suitability
+ * of a given implementation for your application.
+ *
+ * @see ReentrantReadWriteLock
+ * @see Lock
+ * @see ReentrantLock
+ *
+ * @since 1.5
+ * @author Doug Lea
+ */
+public interface ReadWriteLock {
+ /**
+ * Returns the lock used for reading.
+ *
+ * @return the lock used for reading.
+ */
+ Lock readLock();
+
+ /**
+ * Returns the lock used for writing.
+ *
+ * @return the lock used for writing.
+ */
+ Lock writeLock();
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/locks/ReentrantLock.java b/concurrent/src/main/java/java/util/concurrent/locks/ReentrantLock.java
new file mode 100644
index 0000000..bf3d653
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/locks/ReentrantLock.java
@@ -0,0 +1,727 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.locks;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.*;
+
+/**
+ * A reentrant mutual exclusion {@link Lock} with the same basic
+ * behavior and semantics as the implicit monitor lock accessed using
+ * <tt>synchronized</tt> methods and statements, but with extended
+ * capabilities.
+ *
+ * <p> A <tt>ReentrantLock</tt> is <em>owned</em> by the thread last
+ * successfully locking, but not yet unlocking it. A thread invoking
+ * <tt>lock</tt> will return, successfully acquiring the lock, when
+ * the lock is not owned by another thread. The method will return
+ * immediately if the current thread already owns the lock. This can
+ * be checked using methods {@link #isHeldByCurrentThread}, and {@link
+ * #getHoldCount}.
+ *
+ * <p> The constructor for this class accepts an optional
+ * <em>fairness</em> parameter. When set <tt>true</tt>, under
+ * contention, locks favor granting access to the longest-waiting
+ * thread. Otherwise this lock does not guarantee any particular
+ * access order. Programs using fair locks accessed by many threads
+ * may display lower overall throughput (i.e., are slower; often much
+ * slower) than those using the default setting, but have smaller
+ * variances in times to obtain locks and guarantee lack of
+ * starvation. Note however, that fairness of locks does not guarantee
+ * fairness of thread scheduling. Thus, one of many threads using a
+ * fair lock may obtain it multiple times in succession while other
+ * active threads are not progressing and not currently holding the
+ * lock.
+ *
+ * <p> It is recommended practice to <em>always</em> immediately
+ * follow a call to <tt>lock</tt> with a <tt>try</tt> block, most
+ * typically in a before/after construction such as:
+ *
+ * <pre>
+ * class X {
+ * private final ReentrantLock lock = new ReentrantLock();
+ * // ...
+ *
+ * public void m() {
+ * lock.lock(); // block until condition holds
+ * try {
+ * // ... method body
+ * } finally {
+ * lock.unlock()
+ * }
+ * }
+ * }
+ * </pre>
+ *
+ * <p>In addition to implementing the {@link Lock} interface, this
+ * class defines methods <tt>isLocked</tt> and
+ * <tt>getLockQueueLength</tt>, as well as some associated
+ * <tt>protected</tt> access methods that may be useful for
+ * instrumentation and monitoring.
+ *
+ * <p> Serialization of this class behaves in the same way as built-in
+ * locks: a deserialized lock is in the unlocked state, regardless of
+ * its state when serialized.
+ *
+ * <p> This lock supports a maximum of 2147483648 recursive locks by
+ * the same thread.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ *
+ */
+public class ReentrantLock implements Lock, java.io.Serializable {
+ private static final long serialVersionUID = 7373984872572414699L;
+ /** Synchronizer providing all implementation mechanics */
+ private final Sync sync;
+
+ /**
+ * Base of synchronization control for this lock. Subclassed
+ * into fair and nonfair versions below. Uses AQS state to
+ * represent the number of holds on the lock.
+ */
+ static abstract class Sync extends AbstractQueuedSynchronizer {
+ /** Current owner thread */
+ transient Thread owner;
+
+ /**
+ * Perform {@link Lock#lock}. The main reason for subclassing
+ * is to allow fast path for nonfair version.
+ */
+ abstract void lock();
+
+ /**
+ * Perform non-fair tryLock. tryAcquire is
+ * implemented in subclasses, but both need nonfair
+ * try for trylock method
+ */
+ final boolean nonfairTryAcquire(int acquires) {
+ final Thread current = Thread.currentThread();
+ int c = getState();
+ if (c == 0) {
+ if (compareAndSetState(0, acquires)) {
+ owner = current;
+ return true;
+ }
+ }
+ else if (current == owner) {
+ setState(c+acquires);
+ return true;
+ }
+ return false;
+ }
+
+ protected final boolean tryRelease(int releases) {
+ int c = getState() - releases;
+ if (Thread.currentThread() != owner)
+ throw new IllegalMonitorStateException();
+ boolean free = false;
+ if (c == 0) {
+ free = true;
+ owner = null;
+ }
+ setState(c);
+ return free;
+ }
+
+ protected final boolean isHeldExclusively() {
+ return getState() != 0 && owner == Thread.currentThread();
+ }
+
+ final ConditionObject newCondition() {
+ return new ConditionObject();
+ }
+
+ // Methods relayed from outer class
+
+ final Thread getOwner() {
+ int c = getState();
+ Thread o = owner;
+ return (c == 0)? null : o;
+ }
+
+ final int getHoldCount() {
+ int c = getState();
+ Thread o = owner;
+ return (o == Thread.currentThread())? c : 0;
+ }
+
+ final boolean isLocked() {
+ return getState() != 0;
+ }
+
+ /**
+ * Reconstitute this lock instance from a stream
+ * @param s the stream
+ */
+ private void readObject(java.io.ObjectInputStream s)
+ throws java.io.IOException, ClassNotFoundException {
+ s.defaultReadObject();
+ setState(0); // reset to unlocked state
+ }
+ }
+
+ /**
+ * Sync object for non-fair locks
+ */
+ final static class NonfairSync extends Sync {
+ /**
+ * Perform lock. Try immediate barge, backing up to normal
+ * acquire on failure.
+ */
+ final void lock() {
+ if (compareAndSetState(0, 1))
+ owner = Thread.currentThread();
+ else
+ acquire(1);
+ }
+
+ protected final boolean tryAcquire(int acquires) {
+ return nonfairTryAcquire(acquires);
+ }
+ }
+
+ /**
+ * Sync object for fair locks
+ */
+ final static class FairSync extends Sync {
+ final void lock() {
+ acquire(1);
+ }
+
+ /**
+ * Fair version of tryAcquire. Don't grant access unless
+ * recursive call or no waiters or is first.
+ */
+ protected final boolean tryAcquire(int acquires) {
+ final Thread current = Thread.currentThread();
+ int c = getState();
+ if (c == 0) {
+ Thread first = getFirstQueuedThread();
+ if ((first == null || first == current) &&
+ compareAndSetState(0, acquires)) {
+ owner = current;
+ return true;
+ }
+ }
+ else if (current == owner) {
+ setState(c+acquires);
+ return true;
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Creates an instance of <tt>ReentrantLock</tt>.
+ * This is equivalent to using <tt>ReentrantLock(false)</tt>.
+ */
+ public ReentrantLock() {
+ sync = new NonfairSync();
+ }
+
+ /**
+ * Creates an instance of <tt>ReentrantLock</tt> with the
+ * given fairness policy.
+ * @param fair true if this lock will be fair; else false
+ */
+ public ReentrantLock(boolean fair) {
+ sync = (fair)? new FairSync() : new NonfairSync();
+ }
+
+ /**
+ * Acquires the lock.
+ *
+ * <p>Acquires the lock if it is not held by another thread and returns
+ * immediately, setting the lock hold count to one.
+ *
+ * <p>If the current thread
+ * already holds the lock then the hold count is incremented by one and
+ * the method returns immediately.
+ *
+ * <p>If the lock is held by another thread then the
+ * current thread becomes disabled for thread scheduling
+ * purposes and lies dormant until the lock has been acquired,
+ * at which time the lock hold count is set to one.
+ */
+ public void lock() {
+ sync.lock();
+ }
+
+ /**
+ * Acquires the lock unless the current thread is
+ * {@link Thread#interrupt interrupted}.
+ *
+ * <p>Acquires the lock if it is not held by another thread and returns
+ * immediately, setting the lock hold count to one.
+ *
+ * <p>If the current thread already holds this lock then the hold count
+ * is incremented by one and the method returns immediately.
+ *
+ * <p>If the lock is held by another thread then the
+ * current thread becomes disabled for thread scheduling
+ * purposes and lies dormant until one of two things happens:
+ *
+ * <ul>
+ *
+ * <li>The lock is acquired by the current thread; or
+ *
+ * <li>Some other thread {@link Thread#interrupt interrupts} the current
+ * thread.
+ *
+ * </ul>
+ *
+ * <p>If the lock is acquired by the current thread then the lock hold
+ * count is set to one.
+ *
+ * <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 acquiring
+ * the lock,
+ *
+ * </ul>
+ *
+ * then {@link InterruptedException} is thrown and the current thread's
+ * interrupted status is cleared.
+ *
+ * <p>In this implementation, as this method is an explicit interruption
+ * point, preference is
+ * given to responding to the interrupt over normal or reentrant
+ * acquisition of the lock.
+ *
+ * @throws InterruptedException if the current thread is interrupted
+ */
+ public void lockInterruptibly() throws InterruptedException {
+ sync.acquireInterruptibly(1);
+ }
+
+ /**
+ * Acquires the lock only if it is not held by another thread at the time
+ * of invocation.
+ *
+ * <p>Acquires the lock if it is not held by another thread and
+ * returns immediately with the value <tt>true</tt>, setting the
+ * lock hold count to one. Even when this lock has been set to use a
+ * fair ordering policy, a call to <tt>tryLock()</tt> <em>will</em>
+ * immediately acquire the lock if it is available, whether or not
+ * other threads are currently waiting for the lock.
+ * This &quot;barging&quot; behavior can be useful in certain
+ * circumstances, even though it breaks fairness. If you want to honor
+ * the fairness setting for this lock, then use
+ * {@link #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) }
+ * which is almost equivalent (it also detects interruption).
+ *
+ * <p> If the current thread
+ * already holds this lock then the hold count is incremented by one and
+ * the method returns <tt>true</tt>.
+ *
+ * <p>If the lock is held by another thread then this method will return
+ * immediately with the value <tt>false</tt>.
+ *
+ * @return <tt>true</tt> if the lock was free and was acquired by the
+ * current thread, or the lock was already held by the current thread; and
+ * <tt>false</tt> otherwise.
+ */
+ public boolean tryLock() {
+ return sync.nonfairTryAcquire(1);
+ }
+
+ /**
+ * Acquires the lock if it is not held by another thread within the given
+ * waiting time and the current thread has not been
+ * {@link Thread#interrupt interrupted}.
+ *
+ * <p>Acquires the lock if it is not held by another thread and returns
+ * immediately with the value <tt>true</tt>, setting the lock hold count
+ * to one. If this lock has been set to use a fair ordering policy then
+ * an available lock <em>will not</em> be acquired if any other threads
+ * are waiting for the lock. This is in contrast to the {@link #tryLock()}
+ * method. If you want a timed <tt>tryLock</tt> that does permit barging on
+ * a fair lock then combine the timed and un-timed forms together:
+ *
+ * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
+ * </pre>
+ *
+ * <p>If the current thread
+ * already holds this lock then the hold count is incremented by one and
+ * the method returns <tt>true</tt>.
+ *
+ * <p>If the lock is held by another thread then the
+ * current thread becomes disabled for thread scheduling
+ * purposes and lies dormant until one of three things happens:
+ *
+ * <ul>
+ *
+ * <li>The lock is acquired by the current thread; or
+ *
+ * <li>Some other thread {@link Thread#interrupt interrupts} the current
+ * thread; or
+ *
+ * <li>The specified waiting time elapses
+ *
+ * </ul>
+ *
+ * <p>If the lock is acquired then the value <tt>true</tt> is returned and
+ * the lock hold count is set to one.
+ *
+ * <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 acquiring
+ * the lock,
+ *
+ * </ul>
+ * then {@link InterruptedException} is thrown and the current thread's
+ * interrupted status is cleared.
+ *
+ * <p>If the specified waiting time elapses then the value <tt>false</tt>
+ * is returned.
+ * If the time is
+ * less than or equal to zero, the method will not wait at all.
+ *
+ * <p>In this implementation, as this method is an explicit interruption
+ * point, preference is
+ * given to responding to the interrupt over normal or reentrant
+ * acquisition of the lock, and over reporting the elapse of the waiting
+ * time.
+ *
+ * @param timeout the time to wait for the lock
+ * @param unit the time unit of the timeout argument
+ *
+ * @return <tt>true</tt> if the lock was free and was acquired by the
+ * current thread, or the lock was already held by the current thread; and
+ * <tt>false</tt> if the waiting time elapsed before the lock could be
+ * acquired.
+ *
+ * @throws InterruptedException if the current thread is interrupted
+ * @throws NullPointerException if unit is null
+ *
+ */
+ public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
+ return sync.tryAcquireNanos(1, unit.toNanos(timeout));
+ }
+
+ /**
+ * Attempts to release this lock.
+ *
+ * <p>If the current thread is the
+ * holder of this lock then the hold count is decremented. If the
+ * hold count is now zero then the lock is released. If the
+ * current thread is not the holder of this lock then {@link
+ * IllegalMonitorStateException} is thrown.
+ * @throws IllegalMonitorStateException if the current thread does not
+ * hold this lock.
+ */
+ public void unlock() {
+ sync.release(1);
+ }
+
+ /**
+ * Returns a {@link Condition} instance for use with this
+ * {@link Lock} instance.
+ *
+ * <p>The returned {@link Condition} instance supports the same
+ * usages as do the {@link Object} monitor methods ({@link
+ * Object#wait() wait}, {@link Object#notify notify}, and {@link
+ * Object#notifyAll notifyAll}) when used with the built-in
+ * monitor lock.
+ *
+ * <ul>
+ *
+ * <li>If this lock is not held when any of the {@link Condition}
+ * {@link Condition#await() waiting} or {@link Condition#signal
+ * signalling} methods are called, then an {@link
+ * IllegalMonitorStateException} is thrown.
+ *
+ * <li>When the condition {@link Condition#await() waiting}
+ * methods are called the lock is released and, before they
+ * return, the lock is reacquired and the lock hold count restored
+ * to what it was when the method was called.
+ *
+ * <li>If a thread is {@link Thread#interrupt interrupted} while
+ * waiting then the wait will terminate, an {@link
+ * InterruptedException} will be thrown, and the thread's
+ * interrupted status will be cleared.
+ *
+ * <li> Waiting threads are signalled in FIFO order
+ *
+ * <li>The ordering of lock reacquisition for threads returning
+ * from waiting methods is the same as for threads initially
+ * acquiring the lock, which is in the default case not specified,
+ * but for <em>fair</em> locks favors those threads that have been
+ * waiting the longest.
+ *
+ * </ul>
+ *
+ * @return the Condition object
+ */
+ public Condition newCondition() {
+ return sync.newCondition();
+ }
+
+ /**
+ * Queries the number of holds on this lock by the current thread.
+ *
+ * <p>A thread has a hold on a lock for each lock action that is not
+ * matched by an unlock action.
+ *
+ * <p>The hold count information is typically only used for testing and
+ * debugging purposes. For example, if a certain section of code should
+ * not be entered with the lock already held then we can assert that
+ * fact:
+ *
+ * <pre>
+ * class X {
+ * ReentrantLock lock = new ReentrantLock();
+ * // ...
+ * public void m() {
+ * assert lock.getHoldCount() == 0;
+ * lock.lock();
+ * try {
+ * // ... method body
+ * } finally {
+ * lock.unlock();
+ * }
+ * }
+ * }
+ * </pre>
+ *
+ * @return the number of holds on this lock by the current thread,
+ * or zero if this lock is not held by the current thread.
+ */
+ public int getHoldCount() {
+ return sync.getHoldCount();
+ }
+
+ /**
+ * Queries if this lock is held by the current thread.
+ *
+ * <p>Analogous to the {@link Thread#holdsLock} method for built-in
+ * monitor locks, this method is typically used for debugging and
+ * testing. For example, a method that should only be called while
+ * a lock is held can assert that this is the case:
+ *
+ * <pre>
+ * class X {
+ * ReentrantLock lock = new ReentrantLock();
+ * // ...
+ *
+ * public void m() {
+ * assert lock.isHeldByCurrentThread();
+ * // ... method body
+ * }
+ * }
+ * </pre>
+ *
+ * <p>It can also be used to ensure that a reentrant lock is used
+ * in a non-reentrant manner, for example:
+ *
+ * <pre>
+ * class X {
+ * ReentrantLock lock = new ReentrantLock();
+ * // ...
+ *
+ * public void m() {
+ * assert !lock.isHeldByCurrentThread();
+ * lock.lock();
+ * try {
+ * // ... method body
+ * } finally {
+ * lock.unlock();
+ * }
+ * }
+ * }
+ * </pre>
+ * @return <tt>true</tt> if current thread holds this lock and
+ * <tt>false</tt> otherwise.
+ */
+ public boolean isHeldByCurrentThread() {
+ return sync.isHeldExclusively();
+ }
+
+ /**
+ * Queries if this lock is held by any thread. This method is
+ * designed for use in monitoring of the system state,
+ * not for synchronization control.
+ * @return <tt>true</tt> if any thread holds this lock and
+ * <tt>false</tt> otherwise.
+ */
+ public boolean isLocked() {
+ return sync.isLocked();
+ }
+
+ /**
+ * Returns true if this lock has fairness set true.
+ * @return true if this lock has fairness set true.
+ */
+ public final boolean isFair() {
+ return sync instanceof FairSync;
+ }
+
+ /**
+ * Returns the thread that currently owns the exclusive lock, or
+ * <tt>null</tt> if not owned. Note that the owner may be
+ * momentarily <tt>null</tt> even if there are threads trying to
+ * acquire the lock but have not yet done so. This method is
+ * designed to facilitate construction of subclasses that provide
+ * more extensive lock monitoring facilities.
+ * @return the owner, or <tt>null</tt> if not owned.
+ */
+ protected Thread getOwner() {
+ return sync.getOwner();
+ }
+
+ /**
+ * Queries whether any threads are waiting to acquire. Note that
+ * because cancellations may occur at any time, a <tt>true</tt>
+ * return does not guarantee that any other thread will ever
+ * acquire. This method is designed primarily for use in
+ * monitoring of the system state.
+ *
+ * @return true if there may be other threads waiting to acquire
+ * the lock.
+ */
+ public final boolean hasQueuedThreads() {
+ return sync.hasQueuedThreads();
+ }
+
+
+ /**
+ * Queries whether the given thread is waiting to acquire this
+ * lock. Note that because cancellations may occur at any time, a
+ * <tt>true</tt> return does not guarantee that this thread
+ * will ever acquire. This method is designed primarily for use
+ * in monitoring of the system state.
+ *
+ * @param thread the thread
+ * @return true if the given thread is queued waiting for this lock.
+ * @throws NullPointerException if thread is null
+ */
+ public final boolean hasQueuedThread(Thread thread) {
+ return sync.isQueued(thread);
+ }
+
+
+ /**
+ * Returns an estimate of the number of threads waiting to
+ * acquire. The value is only an estimate because the number of
+ * threads may change dynamically while this method traverses
+ * internal data structures. This method is designed for use in
+ * monitoring of the system state, not for synchronization
+ * control.
+ * @return the estimated number of threads waiting for this lock
+ */
+ public final int getQueueLength() {
+ return sync.getQueueLength();
+ }
+
+ /**
+ * Returns a collection containing threads that may be waiting to
+ * acquire. Because the actual set of threads may change
+ * dynamically while constructing this result, the returned
+ * collection is only a best-effort estimate. The elements of the
+ * returned collection are in no particular order. This method is
+ * designed to facilitate construction of subclasses that provide
+ * more extensive monitoring facilities.
+ * @return the collection of threads
+ */
+ protected Collection<Thread> getQueuedThreads() {
+ return sync.getQueuedThreads();
+ }
+
+ /**
+ * Queries whether any threads are waiting on the given condition
+ * associated with this lock. Note that because timeouts and
+ * interrupts may occur at any time, a <tt>true</tt> return does
+ * not guarantee that a future <tt>signal</tt> will awaken any
+ * threads. This method is designed primarily for use in
+ * monitoring of the system state.
+ * @param condition the condition
+ * @return <tt>true</tt> if there are any waiting threads.
+ * @throws IllegalMonitorStateException if this lock
+ * is not held
+ * @throws IllegalArgumentException if the given condition is
+ * not associated with this lock
+ * @throws NullPointerException if condition null
+ */
+ public boolean hasWaiters(Condition condition) {
+ if (condition == null)
+ throw new NullPointerException();
+ if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
+ throw new IllegalArgumentException("not owner");
+ return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
+ }
+
+ /**
+ * Returns an estimate of the number of threads waiting on the
+ * given condition associated with this lock. Note that because
+ * timeouts and interrupts may occur at any time, the estimate
+ * serves only as an upper bound on the actual number of waiters.
+ * This method is designed for use in monitoring of the system
+ * state, not for synchronization control.
+ * @param condition the condition
+ * @return the estimated number of waiting threads.
+ * @throws IllegalMonitorStateException if this lock
+ * is not held
+ * @throws IllegalArgumentException if the given condition is
+ * not associated with this lock
+ * @throws NullPointerException if condition null
+ */
+ public int getWaitQueueLength(Condition condition) {
+ if (condition == null)
+ throw new NullPointerException();
+ if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
+ throw new IllegalArgumentException("not owner");
+ return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
+ }
+
+ /**
+ * Returns a collection containing those threads that may be
+ * waiting on the given condition associated with this lock.
+ * Because the actual set of threads may change dynamically while
+ * constructing this result, the returned collection is only a
+ * best-effort estimate. The elements of the returned collection
+ * are in no particular order. This method is designed to
+ * facilitate construction of subclasses that provide more
+ * extensive condition monitoring facilities.
+ * @param condition the condition
+ * @return the collection of threads
+ * @throws IllegalMonitorStateException if this lock
+ * is not held
+ * @throws IllegalArgumentException if the given condition is
+ * not associated with this lock
+ * @throws NullPointerException if condition null
+ */
+ protected Collection<Thread> getWaitingThreads(Condition condition) {
+ if (condition == null)
+ throw new NullPointerException();
+ if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
+ throw new IllegalArgumentException("not owner");
+ return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
+ }
+
+ /**
+ * Returns a string identifying this lock, as well as its lock
+ * state. The state, in brackets, includes either the String
+ * &quot;Unlocked&quot; or the String &quot;Locked by&quot;
+ * followed by the {@link Thread#getName} of the owning thread.
+ * @return a string identifying this lock, as well as its lock state.
+ */
+ public String toString() {
+ Thread owner = sync.getOwner();
+ return super.toString() + ((owner == null) ?
+ "[Unlocked]" :
+ "[Locked by thread " + owner.getName() + "]");
+ }
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java b/concurrent/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java
new file mode 100644
index 0000000..95fc7af
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java
@@ -0,0 +1,1119 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.locks;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.*;
+import java.util.*;
+
+/**
+ * An implementation of {@link ReadWriteLock} supporting similar
+ * semantics to {@link ReentrantLock}.
+ * <p>This class has the following properties:
+ *
+ * <ul>
+ * <li><b>Acquisition order</b>
+ *
+ * <p> This class does not impose a reader or writer preference
+ * ordering for lock access. However, it does support an optional
+ * <em>fairness</em> policy. When constructed as fair, threads
+ * contend for entry using an approximately arrival-order policy. When
+ * the write lock is released either the longest-waiting single writer
+ * will be assigned the write lock, or if there is a reader waiting
+ * longer than any writer, the set of readers will be assigned the
+ * read lock. When constructed as non-fair, the order of entry to the
+ * lock need not be in arrival order. In either case, if readers are
+ * active and a writer enters the lock then no subsequent readers will
+ * be granted the read lock until after that writer has acquired and
+ * released the write lock.
+ *
+ * <li><b>Reentrancy</b>
+ * <p>This lock allows both readers and writers to reacquire read or
+ * write locks in the style of a {@link ReentrantLock}. Readers are not
+ * allowed until all write locks held by the writing thread have been
+ * released.
+ * <p>Additionally, a writer can acquire the read lock - but not vice-versa.
+ * Among other applications, reentrancy can be useful when
+ * write locks are held during calls or callbacks to methods that
+ * perform reads under read locks.
+ * If a reader tries to acquire the write lock it will never succeed.
+ *
+ * <li><b>Lock downgrading</b>
+ * <p>Reentrancy also allows downgrading from the write lock to a read lock,
+ * by acquiring the write lock, then the read lock and then releasing the
+ * write lock. However, upgrading from a read lock to the write lock, is
+ * <b>not</b> possible.
+ *
+ * <li><b>Interruption of lock acquisition</b>
+ * <p>The read lock and write lock both support interruption during lock
+ * acquisition.
+ *
+ * <li><b>{@link Condition} support</b>
+ * <p>The write lock provides a {@link Condition} implementation that
+ * behaves in the same way, with respect to the write lock, as the
+ * {@link Condition} implementation provided by
+ * {@link ReentrantLock#newCondition} does for {@link ReentrantLock}.
+ * This {@link Condition} can, of course, only be used with the write lock.
+ * <p>The read lock does not support a {@link Condition} and
+ * <tt>readLock().newCondition()</tt> throws
+ * <tt>UnsupportedOperationException</tt>.
+ *
+ * <li><b>Instrumentation</b>
+ * <P> This class supports methods to determine whether locks
+ * are held or contended. These methods are designed for monitoring
+ * system state, not for synchronization control.
+ * </ul>
+ *
+ * <p> Serialization of this class behaves in the same way as built-in
+ * locks: a deserialized lock is in the unlocked state, regardless of
+ * its state when serialized.
+ *
+ * <p><b>Sample usages</b>. Here is a code sketch showing how to exploit
+ * reentrancy to perform lock downgrading after updating a cache (exception
+ * handling is elided for simplicity):
+ * <pre>
+ * class CachedData {
+ * Object data;
+ * volatile boolean cacheValid;
+ * ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
+ *
+ * void processCachedData() {
+ * rwl.readLock().lock();
+ * if (!cacheValid) {
+ * // upgrade lock manually
+ * rwl.readLock().unlock(); // must unlock first to obtain writelock
+ * rwl.writeLock().lock();
+ * if (!cacheValid) { // recheck
+ * data = ...
+ * cacheValid = true;
+ * }
+ * // downgrade lock
+ * rwl.readLock().lock(); // reacquire read without giving up write lock
+ * rwl.writeLock().unlock(); // unlock write, still hold read
+ * }
+ *
+ * use(data);
+ * rwl.readLock().unlock();
+ * }
+ * }
+ * </pre>
+ *
+ * ReentrantReadWriteLocks can be used to improve concurrency in some
+ * uses of some kinds of Collections. This is typically worthwhile
+ * only when the collections are expected to be large, accessed by
+ * more reader threads than writer threads, and entail operations with
+ * overhead that outweighs synchronization overhead. For example, here
+ * is a class using a TreeMap that is expected to be large and
+ * concurrently accessed.
+ *
+ * <pre>
+ * class RWDictionary {
+ * private final Map&lt;String, Data&gt; m = new TreeMap&lt;String, Data&gt;();
+ * private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
+ * private final Lock r = rwl.readLock();
+ * private final Lock w = rwl.writeLock();
+ *
+ * public Data get(String key) {
+ * r.lock(); try { return m.get(key); } finally { r.unlock(); }
+ * }
+ * public String[] allKeys() {
+ * r.lock(); try { return m.keySet().toArray(); } finally { r.unlock(); }
+ * }
+ * public Data put(String key, Data value) {
+ * w.lock(); try { return m.put(key, value); } finally { w.unlock(); }
+ * }
+ * public void clear() {
+ * w.lock(); try { m.clear(); } finally { w.unlock(); }
+ * }
+ * }
+ * </pre>
+ *
+ *
+ * <h3>Implementation Notes</h3>
+ *
+ * <p>A reentrant write lock intrinsically defines an owner and can
+ * only be released by the thread that acquired it. In contrast, in
+ * this implementation, the read lock has no concept of ownership, and
+ * there is no requirement that the thread releasing a read lock is
+ * the same as the one that acquired it. However, this property is
+ * not guaranteed to hold in future implementations of this class.
+ *
+ * <p> This lock supports a maximum of 65536 recursive write locks
+ * and 65536 read locks. Attempts to exceed these limits result in
+ * {@link Error} throws from locking methods.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ *
+ */
+public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializable {
+ private static final long serialVersionUID = -6992448646407690164L;
+ /** Inner class providing readlock */
+ private final ReentrantReadWriteLock.ReadLock readerLock;
+ /** Inner class providing writelock */
+ private final ReentrantReadWriteLock.WriteLock writerLock;
+ /** Performs all synchronization mechanics */
+ private final Sync sync;
+
+ /**
+ * Creates a new <tt>ReentrantReadWriteLock</tt> with
+ * default ordering properties.
+ */
+ public ReentrantReadWriteLock() {
+ sync = new NonfairSync();
+ readerLock = new ReadLock(this);
+ writerLock = new WriteLock(this);
+ }
+
+ /**
+ * Creates a new <tt>ReentrantReadWriteLock</tt> with
+ * the given fairness policy.
+ *
+ * @param fair true if this lock should use a fair ordering policy
+ */
+ public ReentrantReadWriteLock(boolean fair) {
+ sync = (fair)? new FairSync() : new NonfairSync();
+ readerLock = new ReadLock(this);
+ writerLock = new WriteLock(this);
+ }
+
+ public ReentrantReadWriteLock.WriteLock writeLock() { return writerLock; }
+ public ReentrantReadWriteLock.ReadLock readLock() { return readerLock; }
+
+ /*
+ * Read vs write count extraction constants and functions.
+ * Lock state is logically divided into two shorts: The lower
+ * one representing the exclusive (writer) lock hold count,
+ * and the upper the shared (reader) hold count.
+ */
+
+ static final int SHARED_SHIFT = 16;
+ static final int SHARED_UNIT = (1 << SHARED_SHIFT);
+ static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1;
+
+ /** Returns the number of shared holds represented in count */
+ static int sharedCount(int c) { return c >>> SHARED_SHIFT; }
+ /** Returns the number of exclusive holds represented in count */
+ static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; }
+
+ /**
+ * Synchronization implementation for ReentrantReadWriteLock.
+ * Subclassed into fair and nonfair versions.
+ */
+ abstract static class Sync extends AbstractQueuedSynchronizer {
+ /** Current (exclusive) owner thread */
+ transient Thread owner;
+
+ /**
+ * Perform write lock. Allows fast path in non-fair version.
+ */
+ abstract void wlock();
+
+ /**
+ * Perform non-fair tryLock for write. tryAcquire is
+ * implemented in subclasses, but both versions need nonfair
+ * try for trylock method
+ */
+ final boolean nonfairTryAcquire(int acquires) {
+ // mask out readlocks if called from condition methods
+ acquires = exclusiveCount(acquires);
+ Thread current = Thread.currentThread();
+ int c = getState();
+ int w = exclusiveCount(c);
+ if (w + acquires >= SHARED_UNIT)
+ throw new Error("Maximum lock count exceeded");
+ if (c != 0 && (w == 0 || current != owner))
+ return false;
+ if (!compareAndSetState(c, c + acquires))
+ return false;
+ owner = current;
+ return true;
+ }
+
+ /**
+ * Perform nonfair tryLock for read.
+ */
+ final int nonfairTryAcquireShared(int acquires) {
+ for (;;) {
+ int c = getState();
+ int nextc = c + (acquires << SHARED_SHIFT);
+ if (nextc < c)
+ throw new Error("Maximum lock count exceeded");
+ if (exclusiveCount(c) != 0 &&
+ owner != Thread.currentThread())
+ return -1;
+ if (compareAndSetState(c, nextc))
+ return 1;
+ // Recheck count if lost CAS
+ }
+ }
+
+ protected final boolean tryRelease(int releases) {
+ Thread current = Thread.currentThread();
+ int c = getState();
+ if (owner != current)
+ throw new IllegalMonitorStateException();
+ int nextc = c - releases;
+ boolean free = false;
+ if (exclusiveCount(c) == releases) {
+ free = true;
+ owner = null;
+ }
+ setState(nextc);
+ return free;
+ }
+
+ protected final boolean tryReleaseShared(int releases) {
+ for (;;) {
+ int c = getState();
+ int nextc = c - (releases << SHARED_SHIFT);
+ if (nextc < 0)
+ throw new IllegalMonitorStateException();
+ if (compareAndSetState(c, nextc))
+ return nextc == 0;
+ }
+ }
+
+ protected final boolean isHeldExclusively() {
+ return exclusiveCount(getState()) != 0 &&
+ owner == Thread.currentThread();
+ }
+
+ // Methods relayed to outer class
+
+ final ConditionObject newCondition() {
+ return new ConditionObject();
+ }
+
+ final Thread getOwner() {
+ int c = exclusiveCount(getState());
+ Thread o = owner;
+ return (c == 0)? null : o;
+ }
+
+ final int getReadLockCount() {
+ return sharedCount(getState());
+ }
+
+ final boolean isWriteLocked() {
+ return exclusiveCount(getState()) != 0;
+ }
+
+ final int getWriteHoldCount() {
+ int c = exclusiveCount(getState());
+ Thread o = owner;
+ return (o == Thread.currentThread())? c : 0;
+ }
+
+ /**
+ * Reconstitute this lock instance from a stream
+ * @param s the stream
+ */
+ private void readObject(java.io.ObjectInputStream s)
+ throws java.io.IOException, ClassNotFoundException {
+ s.defaultReadObject();
+ setState(0); // reset to unlocked state
+ }
+
+ final int getCount() { return getState(); }
+ }
+
+ /**
+ * Nonfair version of Sync
+ */
+ final static class NonfairSync extends Sync {
+ protected final boolean tryAcquire(int acquires) {
+ return nonfairTryAcquire(acquires);
+ }
+
+ protected final int tryAcquireShared(int acquires) {
+ return nonfairTryAcquireShared(acquires);
+ }
+
+ // Use fastpath for main write lock method
+ final void wlock() {
+ if (compareAndSetState(0, 1))
+ owner = Thread.currentThread();
+ else
+ acquire(1);
+ }
+ }
+
+ /**
+ * Fair version of Sync
+ */
+ final static class FairSync extends Sync {
+ protected final boolean tryAcquire(int acquires) {
+ // mask out readlocks if called from condition methods
+ acquires = exclusiveCount(acquires);
+ Thread current = Thread.currentThread();
+ Thread first;
+ int c = getState();
+ int w = exclusiveCount(c);
+ if (w + acquires >= SHARED_UNIT)
+ throw new Error("Maximum lock count exceeded");
+ if ((w == 0 || current != owner) &&
+ (c != 0 ||
+ ((first = getFirstQueuedThread()) != null &&
+ first != current)))
+ return false;
+ if (!compareAndSetState(c, c + acquires))
+ return false;
+ owner = current;
+ return true;
+ }
+
+ protected final int tryAcquireShared(int acquires) {
+ Thread current = Thread.currentThread();
+ for (;;) {
+ Thread first = getFirstQueuedThread();
+ if (first != null && first != current)
+ return -1;
+ int c = getState();
+ int nextc = c + (acquires << SHARED_SHIFT);
+ if (nextc < c)
+ throw new Error("Maximum lock count exceeded");
+ if (exclusiveCount(c) != 0 &&
+ owner != Thread.currentThread())
+ return -1;
+ if (compareAndSetState(c, nextc))
+ return 1;
+ // Recheck count if lost CAS
+ }
+ }
+
+ final void wlock() { // no fast path
+ acquire(1);
+ }
+ }
+
+ /**
+ * The lock returned by method {@link ReentrantReadWriteLock#readLock}.
+ */
+ public static class ReadLock implements Lock, java.io.Serializable {
+ private static final long serialVersionUID = -5992448646407690164L;
+ private final Sync sync;
+
+ /**
+ * Constructor for use by subclasses.
+ * @param lock the outer lock object
+ * @throws NullPointerException if lock null
+ */
+ protected ReadLock(ReentrantReadWriteLock lock) {
+ sync = lock.sync;
+ }
+
+ /**
+ * Acquires the shared lock.
+ *
+ * <p>Acquires the lock if it is not held exclusively by
+ * another thread and returns immediately.
+ *
+ * <p>If the lock is held exclusively by another thread then
+ * the current thread becomes disabled for thread scheduling
+ * purposes and lies dormant until the lock has been acquired.
+ */
+ public void lock() {
+ sync.acquireShared(1);
+ }
+
+ /**
+ * Acquires the shared lock unless the current thread is
+ * {@link Thread#interrupt interrupted}.
+ *
+ * <p>Acquires the shared lock if it is not held exclusively
+ * by another thread and returns immediately.
+ *
+ * <p>If the lock is held by another thread then the
+ * current thread becomes disabled for thread scheduling
+ * purposes and lies dormant until one of two things happens:
+ *
+ * <ul>
+ *
+ * <li>The lock is acquired by the current thread; or
+ *
+ * <li>Some other thread {@link Thread#interrupt interrupts}
+ * the current thread.
+ *
+ * </ul>
+ *
+ * <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 acquiring
+ * the lock,
+ *
+ * </ul>
+ *
+ * then {@link InterruptedException} is thrown and the current
+ * thread's interrupted status is cleared.
+ *
+ * <p>In this implementation, as this method is an explicit
+ * interruption point, preference is given to responding to
+ * the interrupt over normal or reentrant acquisition of the
+ * lock.
+ *
+ * @throws InterruptedException if the current thread is interrupted
+ */
+ public void lockInterruptibly() throws InterruptedException {
+ sync.acquireSharedInterruptibly(1);
+ }
+
+ /**
+ * Acquires the shared lock only if it is not held exclusively by
+ * another thread at the time of invocation.
+ *
+ * <p>Acquires the lock if it is not held exclusively by
+ * another thread and returns immediately with the value
+ * <tt>true</tt>. Even when this lock has been set to use a
+ * fair ordering policy, a call to <tt>tryLock()</tt>
+ * <em>will</em> immediately acquire the lock if it is
+ * available, whether or not other threads are currently
+ * waiting for the lock. This &quot;barging&quot; behavior
+ * can be useful in certain circumstances, even though it
+ * breaks fairness. If you want to honor the fairness setting
+ * for this lock, then use {@link #tryLock(long, TimeUnit)
+ * tryLock(0, TimeUnit.SECONDS) } which is almost equivalent
+ * (it also detects interruption).
+ *
+ * <p>If the lock is held exclusively by another thread then
+ * this method will return immediately with the value
+ * <tt>false</tt>.
+ *
+ * @return <tt>true</tt> if the lock was acquired.
+ */
+ public boolean tryLock() {
+ return sync.nonfairTryAcquireShared(1) >= 0;
+ }
+
+ /**
+ * Acquires the shared lock if it is not held exclusively by
+ * another thread within the given waiting time and the
+ * current thread has not been {@link Thread#interrupt
+ * interrupted}.
+ *
+ * <p>Acquires the lock if it is not held exclusively by
+ * another thread and returns immediately with the value
+ * <tt>true</tt>. If this lock has been set to use a fair
+ * ordering policy then an available lock <em>will not</em> be
+ * acquired if any other threads are waiting for the
+ * lock. This is in contrast to the {@link #tryLock()}
+ * method. If you want a timed <tt>tryLock</tt> that does
+ * permit barging on a fair lock then combine the timed and
+ * un-timed forms together:
+ *
+ * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
+ * </pre>
+ *
+ * <p>If the lock is held exclusively by another thread then the
+ * current thread becomes disabled for thread scheduling
+ * purposes and lies dormant until one of three things happens:
+ *
+ * <ul>
+ *
+ * <li>The lock is acquired by the current thread; or
+ *
+ * <li>Some other thread {@link Thread#interrupt interrupts} the current
+ * thread; or
+ *
+ * <li>The specified waiting time elapses
+ *
+ * </ul>
+ *
+ * <p>If the lock is acquired then the value <tt>true</tt> is
+ * returned.
+ *
+ * <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 acquiring
+ * the lock,
+ *
+ * </ul> then {@link InterruptedException} is thrown and the
+ * current thread's interrupted status is cleared.
+ *
+ * <p>If the specified waiting time elapses then the value
+ * <tt>false</tt> is returned. If the time is less than or
+ * equal to zero, the method will not wait at all.
+ *
+ * <p>In this implementation, as this method is an explicit
+ * interruption point, preference is given to responding to
+ * the interrupt over normal or reentrant acquisition of the
+ * lock, and over reporting the elapse of the waiting time.
+ *
+ * @param timeout the time to wait for the lock
+ * @param unit the time unit of the timeout argument
+ *
+ * @return <tt>true</tt> if the lock was acquired.
+ *
+ * @throws InterruptedException if the current thread is interrupted
+ * @throws NullPointerException if unit is null
+ *
+ */
+ public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
+ return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
+ }
+
+ /**
+ * Attempts to release this lock.
+ *
+ * <p> If the number of readers is now zero then the lock
+ * is made available for other lock attempts.
+ */
+ public void unlock() {
+ sync.releaseShared(1);
+ }
+
+ /**
+ * Throws UnsupportedOperationException because ReadLocks
+ * do not support conditions.
+ * @return A new {@link Condition} instance for this <tt>Lock</tt>
+ * instance.
+ * @throws UnsupportedOperationException always
+ */
+ public Condition newCondition() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns a string identifying this lock, as well as its lock state.
+ * The state, in brackets, includes the String
+ * &quot;Read locks =&quot; followed by the number of held
+ * read locks.
+ * @return a string identifying this lock, as well as its lock state.
+ */
+ public String toString() {
+ int r = sync.getReadLockCount();
+ return super.toString() +
+ "[Read locks = " + r + "]";
+ }
+
+ }
+
+ /**
+ * The lock returned by method {@link ReentrantReadWriteLock#writeLock}.
+ */
+ public static class WriteLock implements Lock, java.io.Serializable {
+ private static final long serialVersionUID = -4992448646407690164L;
+ private final Sync sync;
+
+ /**
+ * Constructor for use by subclasses.
+ * @param lock the outer lock object
+ * @throws NullPointerException if lock null
+ */
+ protected WriteLock(ReentrantReadWriteLock lock) {
+ sync = lock.sync;
+ }
+
+ /**
+ * Acquire the lock.
+ *
+ * <p>Acquires the lock if it is not held by another thread
+ * and returns immediately, setting the lock hold count to
+ * one.
+ *
+ * <p>If the current thread already holds the lock then the
+ * hold count is incremented by one and the method returns
+ * immediately.
+ *
+ * <p>If the lock is held by another thread then the current
+ * thread becomes disabled for thread scheduling purposes and
+ * lies dormant until the lock has been acquired, at which
+ * time the lock hold count is set to one.
+ */
+ public void lock() {
+ sync.wlock();
+ }
+
+ /**
+ * Acquires the lock unless the current thread is {@link
+ * Thread#interrupt interrupted}.
+ *
+ * <p>Acquires the lock if it is not held by another thread
+ * and returns immediately, setting the lock hold count to
+ * one.
+ *
+ * <p>If the current thread already holds this lock then the
+ * hold count is incremented by one and the method returns
+ * immediately.
+ *
+ * <p>If the lock is held by another thread then the current
+ * thread becomes disabled for thread scheduling purposes and
+ * lies dormant until one of two things happens:
+ *
+ * <ul>
+ *
+ * <li>The lock is acquired by the current thread; or
+ *
+ * <li>Some other thread {@link Thread#interrupt interrupts}
+ * the current thread.
+ *
+ * </ul>
+ *
+ * <p>If the lock is acquired by the current thread then the
+ * lock hold count is set to one.
+ *
+ * <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 acquiring
+ * the lock,
+ *
+ * </ul>
+ *
+ * then {@link InterruptedException} is thrown and the current
+ * thread's interrupted status is cleared.
+ *
+ * <p>In this implementation, as this method is an explicit
+ * interruption point, preference is given to responding to
+ * the interrupt over normal or reentrant acquisition of the
+ * lock.
+ *
+ * @throws InterruptedException if the current thread is interrupted
+ */
+ public void lockInterruptibly() throws InterruptedException {
+ sync.acquireInterruptibly(1);
+ }
+
+ /**
+ * Acquires the lock only if it is not held by another thread
+ * at the time of invocation.
+ *
+ * <p>Acquires the lock if it is not held by another thread
+ * and returns immediately with the value <tt>true</tt>,
+ * setting the lock hold count to one. Even when this lock has
+ * been set to use a fair ordering policy, a call to
+ * <tt>tryLock()</tt> <em>will</em> immediately acquire the
+ * lock if it is available, whether or not other threads are
+ * currently waiting for the lock. This &quot;barging&quot;
+ * behavior can be useful in certain circumstances, even
+ * though it breaks fairness. If you want to honor the
+ * fairness setting for this lock, then use {@link
+ * #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) }
+ * which is almost equivalent (it also detects interruption).
+ *
+ * <p> If the current thread already holds this lock then the
+ * hold count is incremented by one and the method returns
+ * <tt>true</tt>.
+ *
+ * <p>If the lock is held by another thread then this method
+ * will return immediately with the value <tt>false</tt>.
+ *
+ * @return <tt>true</tt> if the lock was free and was acquired by the
+ * current thread, or the lock was already held by the current thread; and
+ * <tt>false</tt> otherwise.
+ */
+ public boolean tryLock( ) {
+ return sync.nonfairTryAcquire(1);
+ }
+
+ /**
+ * Acquires the lock if it is not held by another thread
+ * within the given waiting time and the current thread has
+ * not been {@link Thread#interrupt interrupted}.
+ *
+ * <p>Acquires the lock if it is not held by another thread
+ * and returns immediately with the value <tt>true</tt>,
+ * setting the lock hold count to one. If this lock has been
+ * set to use a fair ordering policy then an available lock
+ * <em>will not</em> be acquired if any other threads are
+ * waiting for the lock. This is in contrast to the {@link
+ * #tryLock()} method. If you want a timed <tt>tryLock</tt>
+ * that does permit barging on a fair lock then combine the
+ * timed and un-timed forms together:
+ *
+ * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
+ * </pre>
+ *
+ * <p>If the current thread already holds this lock then the
+ * hold count is incremented by one and the method returns
+ * <tt>true</tt>.
+ *
+ * <p>If the lock is held by another thread then the current
+ * thread becomes disabled for thread scheduling purposes and
+ * lies dormant until one of three things happens:
+ *
+ * <ul>
+ *
+ * <li>The lock is acquired by the current thread; or
+ *
+ * <li>Some other thread {@link Thread#interrupt interrupts}
+ * the current thread; or
+ *
+ * <li>The specified waiting time elapses
+ *
+ * </ul>
+ *
+ * <p>If the lock is acquired then the value <tt>true</tt> is
+ * returned and the lock hold count is set to one.
+ *
+ * <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 acquiring
+ * the lock,
+ *
+ * </ul>
+ *
+ * then {@link InterruptedException} is thrown and the current
+ * thread's interrupted status is cleared.
+ *
+ * <p>If the specified waiting time elapses then the value
+ * <tt>false</tt> is returned. If the time is less than or
+ * equal to zero, the method will not wait at all.
+ *
+ * <p>In this implementation, as this method is an explicit
+ * interruption point, preference is given to responding to
+ * the interrupt over normal or reentrant acquisition of the
+ * lock, and over reporting the elapse of the waiting time.
+ *
+ * @param timeout the time to wait for the lock
+ * @param unit the time unit of the timeout argument
+ *
+ * @return <tt>true</tt> if the lock was free and was acquired
+ * by the current thread, or the lock was already held by the
+ * current thread; and <tt>false</tt> if the waiting time
+ * elapsed before the lock could be acquired.
+ *
+ * @throws InterruptedException if the current thread is interrupted
+ * @throws NullPointerException if unit is null
+ *
+ */
+ public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
+ return sync.tryAcquireNanos(1, unit.toNanos(timeout));
+ }
+
+ /**
+ * Attempts to release this lock.
+ *
+ * <p>If the current thread is the holder of this lock then
+ * the hold count is decremented. If the hold count is now
+ * zero then the lock is released. If the current thread is
+ * not the holder of this lock then {@link
+ * IllegalMonitorStateException} is thrown.
+ * @throws IllegalMonitorStateException if the current thread does not
+ * hold this lock.
+ */
+ public void unlock() {
+ sync.release(1);
+ }
+
+ /**
+ * Returns a {@link Condition} instance for use with this
+ * {@link Lock} instance.
+ * <p>The returned {@link Condition} instance supports the same
+ * usages as do the {@link Object} monitor methods ({@link
+ * Object#wait() wait}, {@link Object#notify notify}, and {@link
+ * Object#notifyAll notifyAll}) when used with the built-in
+ * monitor lock.
+ *
+ * <ul>
+ *
+ * <li>If this write lock is not held when any {@link
+ * Condition} method is called then an {@link
+ * IllegalMonitorStateException} is thrown. (Read locks are
+ * held independently of write locks, so are not checked or
+ * affected. However it is essentially always an error to
+ * invoke a condition waiting method when the current thread
+ * has also acquired read locks, since other threads that
+ * could unblock it will not be able to access the write
+ * lock.)
+ *
+ * <li>When the condition {@link Condition#await() waiting}
+ * methods are called the write lock is released and, before
+ * they return, the write lock is reacquired and the lock hold
+ * count restored to what it was when the method was called.
+ *
+ * <li>If a thread is {@link Thread#interrupt interrupted} while
+ * waiting then the wait will terminate, an {@link
+ * InterruptedException} will be thrown, and the thread's
+ * interrupted status will be cleared.
+ *
+ * <li> Waiting threads are signalled in FIFO order
+ *
+ * <li>The ordering of lock reacquisition for threads returning
+ * from waiting methods is the same as for threads initially
+ * acquiring the lock, which is in the default case not specified,
+ * but for <em>fair</em> locks favors those threads that have been
+ * waiting the longest.
+ *
+ * </ul>
+ * @return the Condition object
+ */
+ public Condition newCondition() {
+ return sync.newCondition();
+ }
+
+ /**
+ * Returns a string identifying this lock, as well as its lock
+ * state. The state, in brackets includes either the String
+ * &quot;Unlocked&quot; or the String &quot;Locked by&quot;
+ * followed by the {@link Thread#getName} of the owning thread.
+ * @return a string identifying this lock, as well as its lock state.
+ */
+ public String toString() {
+ Thread owner = sync.getOwner();
+ return super.toString() + ((owner == null) ?
+ "[Unlocked]" :
+ "[Locked by thread " + owner.getName() + "]");
+ }
+
+ }
+
+
+ // Instrumentation and status
+
+ /**
+ * Returns true if this lock has fairness set true.
+ * @return true if this lock has fairness set true.
+ */
+ public final boolean isFair() {
+ return sync instanceof FairSync;
+ }
+
+ /**
+ * Returns the thread that currently owns the exclusive lock, or
+ * <tt>null</tt> if not owned. Note that the owner may be
+ * momentarily <tt>null</tt> even if there are threads trying to
+ * acquire the lock but have not yet done so. This method is
+ * designed to facilitate construction of subclasses that provide
+ * more extensive lock monitoring facilities.
+ * @return the owner, or <tt>null</tt> if not owned.
+ */
+ protected Thread getOwner() {
+ return sync.getOwner();
+ }
+
+ /**
+ * Queries the number of read locks held for this lock. This
+ * method is designed for use in monitoring system state, not for
+ * synchronization control.
+ * @return the number of read locks held.
+ */
+ public int getReadLockCount() {
+ return sync.getReadLockCount();
+ }
+
+ /**
+ * Queries if the write lock is held by any thread. This method is
+ * designed for use in monitoring system state, not for
+ * synchronization control.
+ * @return <tt>true</tt> if any thread holds write lock and
+ * <tt>false</tt> otherwise.
+ */
+ public boolean isWriteLocked() {
+ return sync.isWriteLocked();
+ }
+
+ /**
+ * Queries if the write lock is held by the current thread.
+ * @return <tt>true</tt> if current thread holds this lock and
+ * <tt>false</tt> otherwise.
+ */
+ public boolean isWriteLockedByCurrentThread() {
+ return sync.isHeldExclusively();
+ }
+
+ /**
+ * Queries the number of reentrant write holds on this lock by the
+ * current thread. A writer thread has a hold on a lock for
+ * each lock action that is not matched by an unlock action.
+ *
+ * @return the number of holds on this lock by the current thread,
+ * or zero if this lock is not held by the current thread.
+ */
+ public int getWriteHoldCount() {
+ return sync.getWriteHoldCount();
+ }
+
+ /**
+ * Returns a collection containing threads that may be waiting to
+ * acquire the write lock. Because the actual set of threads may
+ * change dynamically while constructing this result, the returned
+ * collection is only a best-effort estimate. The elements of the
+ * returned collection are in no particular order. This method is
+ * designed to facilitate construction of subclasses that provide
+ * more extensive lock monitoring facilities.
+ * @return the collection of threads
+ */
+ protected Collection<Thread> getQueuedWriterThreads() {
+ return sync.getExclusiveQueuedThreads();
+ }
+
+ /**
+ * Returns a collection containing threads that may be waiting to
+ * acquire the read lock. Because the actual set of threads may
+ * change dynamically while constructing this result, the returned
+ * collection is only a best-effort estimate. The elements of the
+ * returned collection are in no particular order. This method is
+ * designed to facilitate construction of subclasses that provide
+ * more extensive lock monitoring facilities.
+ * @return the collection of threads
+ */
+ protected Collection<Thread> getQueuedReaderThreads() {
+ return sync.getSharedQueuedThreads();
+ }
+
+ /**
+ * Queries whether any threads are waiting to acquire. Note that
+ * because cancellations may occur at any time, a <tt>true</tt>
+ * return does not guarantee that any other thread will ever
+ * acquire. This method is designed primarily for use in
+ * monitoring of the system state.
+ *
+ * @return true if there may be other threads waiting to acquire
+ * the lock.
+ */
+ public final boolean hasQueuedThreads() {
+ return sync.hasQueuedThreads();
+ }
+
+ /**
+ * Queries whether the given thread is waiting to acquire this
+ * lock. Note that because cancellations may occur at any time, a
+ * <tt>true</tt> return does not guarantee that this thread
+ * will ever acquire. This method is designed primarily for use
+ * in monitoring of the system state.
+ *
+ * @param thread the thread
+ * @return true if the given thread is queued waiting for this lock.
+ * @throws NullPointerException if thread is null
+ */
+ public final boolean hasQueuedThread(Thread thread) {
+ return sync.isQueued(thread);
+ }
+
+ /**
+ * Returns an estimate of the number of threads waiting to
+ * acquire. The value is only an estimate because the number of
+ * threads may change dynamically while this method traverses
+ * internal data structures. This method is designed for use in
+ * monitoring of the system state, not for synchronization
+ * control.
+ * @return the estimated number of threads waiting for this lock
+ */
+ public final int getQueueLength() {
+ return sync.getQueueLength();
+ }
+
+ /**
+ * Returns a collection containing threads that may be waiting to
+ * acquire. Because the actual set of threads may change
+ * dynamically while constructing this result, the returned
+ * collection is only a best-effort estimate. The elements of the
+ * returned collection are in no particular order. This method is
+ * designed to facilitate construction of subclasses that provide
+ * more extensive monitoring facilities.
+ * @return the collection of threads
+ */
+ protected Collection<Thread> getQueuedThreads() {
+ return sync.getQueuedThreads();
+ }
+
+ /**
+ * Queries whether any threads are waiting on the given condition
+ * associated with the write lock. Note that because timeouts and
+ * interrupts may occur at any time, a <tt>true</tt> return does
+ * not guarantee that a future <tt>signal</tt> will awaken any
+ * threads. This method is designed primarily for use in
+ * monitoring of the system state.
+ * @param condition the condition
+ * @return <tt>true</tt> if there are any waiting threads.
+ * @throws IllegalMonitorStateException if this lock
+ * is not held
+ * @throws IllegalArgumentException if the given condition is
+ * not associated with this lock
+ * @throws NullPointerException if condition null
+ */
+ public boolean hasWaiters(Condition condition) {
+ if (condition == null)
+ throw new NullPointerException();
+ if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
+ throw new IllegalArgumentException("not owner");
+ return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
+ }
+
+ /**
+ * Returns an estimate of the number of threads waiting on the
+ * given condition associated with the write lock. Note that because
+ * timeouts and interrupts may occur at any time, the estimate
+ * serves only as an upper bound on the actual number of waiters.
+ * This method is designed for use in monitoring of the system
+ * state, not for synchronization control.
+ * @param condition the condition
+ * @return the estimated number of waiting threads.
+ * @throws IllegalMonitorStateException if this lock
+ * is not held
+ * @throws IllegalArgumentException if the given condition is
+ * not associated with this lock
+ * @throws NullPointerException if condition null
+ */
+ public int getWaitQueueLength(Condition condition) {
+ if (condition == null)
+ throw new NullPointerException();
+ if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
+ throw new IllegalArgumentException("not owner");
+ return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
+ }
+
+ /**
+ * Returns a collection containing those threads that may be
+ * waiting on the given condition associated with the write lock.
+ * Because the actual set of threads may change dynamically while
+ * constructing this result, the returned collection is only a
+ * best-effort estimate. The elements of the returned collection
+ * are in no particular order. This method is designed to
+ * facilitate construction of subclasses that provide more
+ * extensive condition monitoring facilities.
+ * @param condition the condition
+ * @return the collection of threads
+ * @throws IllegalMonitorStateException if this lock
+ * is not held
+ * @throws IllegalArgumentException if the given condition is
+ * not associated with this lock
+ * @throws NullPointerException if condition null
+ */
+ protected Collection<Thread> getWaitingThreads(Condition condition) {
+ if (condition == null)
+ throw new NullPointerException();
+ if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
+ throw new IllegalArgumentException("not owner");
+ return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
+ }
+
+ /**
+ * Returns a string identifying this lock, as well as its lock state.
+ * The state, in brackets, includes the String &quot;Write locks =&quot;
+ * follwed by the number of reentrantly held write locks, and the
+ * String &quot;Read locks =&quot; followed by the number of held
+ * read locks.
+ * @return a string identifying this lock, as well as its lock state.
+ */
+ public String toString() {
+ int c = sync.getCount();
+ int w = exclusiveCount(c);
+ int r = sharedCount(c);
+
+ return super.toString() +
+ "[Write locks = " + w + ", Read locks = " + r + "]";
+ }
+
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/locks/UnsafeAccess.java b/concurrent/src/main/java/java/util/concurrent/locks/UnsafeAccess.java
new file mode 100644
index 0000000..07f64e4
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/locks/UnsafeAccess.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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
+ * 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.
+ */
+
+package java.util.concurrent.locks;
+
+import sun.misc.Unsafe;
+
+/**
+ * Easy access to {@link Unsafe} for the rest of this package.
+ */
+/*package*/ final class UnsafeAccess {
+ /** non-null; unique instance of {@link Unsafe} */
+ /*package*/ static final Unsafe THE_ONE = Unsafe.getUnsafe();
+
+ /**
+ * This class is uninstantiable.
+ */
+ private UnsafeAccess() {
+ // This space intentionally left blank.
+ }
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/locks/package.html b/concurrent/src/main/java/java/util/concurrent/locks/package.html
new file mode 100644
index 0000000..5d3b3fc
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/locks/package.html
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html> <head>
+<title>Locks</title>
+</head>
+
+<body>
+
+Interfaces and classes providing a framework for locking and waiting
+for conditions that is distinct from built-in synchronization and
+monitors. The framework permits much greater flexibility in the use of
+locks and conditions, at the expense of more awkward syntax.
+
+<p> The {@link java.util.concurrent.locks.Lock} interface supports
+locking disciplines that differ in semantics (reentrant, fair, etc),
+and that can be used in non-block-structured contexts including
+hand-over-hand and lock reordering algorithms. The main implementation
+is {@link java.util.concurrent.locks.ReentrantLock}.
+
+<p> The {@link java.util.concurrent.locks.ReadWriteLock} interface
+similarly defines locks that may be shared among readers but are
+exclusive to writers. Only a single implementation, {@link
+java.util.concurrent.locks.ReentrantReadWriteLock}, is provided, since
+it covers most standard usage contexts. But programmers may create
+their own implementations to cover nonstandard requirements.
+
+<p> The {@link java.util.concurrent.locks.Condition} interface
+describes condition variables that may be associated with Locks.
+These are similar in usage to the implicit monitors accessed using
+<tt>Object.wait</tt>, but offer extended capabilities. In particular,
+multiple <tt>Condition</tt> objects may be associated with a single
+<tt>Lock</tt>. To avoid compatibility issues, the names of
+<tt>Condition</tt> methods are different than the corresponding
+<tt>Object</tt> versions.
+
+<p> The {@link java.util.concurrent.locks.AbstractQueuedSynchronizer}
+class serves as a useful superclass for defining locks and other
+synchronizers that rely on queuing blocked threads. The {@link
+java.util.concurrent.locks.LockSupport} class provides lower-level
+blocking and unblocking support that is useful for those developers
+implementing their own customized lock classes.
+
+@since 1.5
+@since Android 1.0
+
+</body> </html>
diff --git a/concurrent/src/main/java/java/util/concurrent/package.html b/concurrent/src/main/java/java/util/concurrent/package.html
new file mode 100644
index 0000000..f7a4ad3
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/package.html
@@ -0,0 +1,126 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html> <head>
+<title>Concurrency Utilities</title>
+</head>
+
+<body>
+
+<p> Utility classes commonly useful in concurrent programming. This
+package includes a few small standardized extensible frameworks, as
+well as some classes that provide useful functionality and are
+otherwise tedious or difficult to implement. Here are brief
+descriptions of the main components. See also the <tt>locks</tt> and
+<tt>atomic</tt> packages.
+
+<h2>Executors</h2>
+
+<b>Interfaces.</b> {@link java.util.concurrent.Executor} is a simple
+standardized interface for defining custom thread-like subsystems,
+including thread pools, asynchronous IO, and lightweight task
+frameworks. Depending on which concrete Executor class is being used,
+tasks may execute in a newly created thread, an existing
+task-execution thread, or the thread calling <tt>execute()</tt>, and
+may execute sequentially or concurrently. {@link
+java.util.concurrent.ExecutorService} provides a more complete
+asynchronous task execution framework. An ExecutorService manages
+queuing and scheduling of tasks, and allows controlled shutdown. The
+{@link java.util.concurrent.ScheduledExecutorService} subinterface
+adds support for delayed and periodic task execution.
+ExecutorServices provide methods arranging asynchronous execution of
+any function expressed as {@link java.util.concurrent.Callable}, the
+result-bearing analog of {@link java.lang.Runnable}. A {@link
+java.util.concurrent.Future} returns the results of a function, allows
+determination of whether execution has completed, and provides a means to
+cancel execution.
+
+<p>
+
+<b>Implementations.</b> Classes {@link
+java.util.concurrent.ThreadPoolExecutor} and {@link
+java.util.concurrent.ScheduledThreadPoolExecutor} provide tunable,
+flexible thread pools. The {@link java.util.concurrent.Executors}
+class provides factory methods for the most common kinds and
+configurations of Executors, as well as a few utility methods for
+using them. Other utilities based on Executors include the concrete
+class {@link java.util.concurrent.FutureTask} providing a common
+extensible implementation of Futures, and {@link
+java.util.concurrent.ExecutorCompletionService}, that assists in
+coordinating the processing of groups of asynchronous tasks.
+
+<h2>Queues</h2>
+
+The java.util.concurrent {@link
+java.util.concurrent.ConcurrentLinkedQueue} class supplies an
+efficient scalable thread-safe non-blocking FIFO queue. Five
+implementations in java.util.concurrent support the extended {@link
+java.util.concurrent.BlockingQueue} interface, that defines blocking
+versions of put and take: {@link
+java.util.concurrent.LinkedBlockingQueue}, {@link
+java.util.concurrent.ArrayBlockingQueue}, {@link
+java.util.concurrent.SynchronousQueue}, {@link
+java.util.concurrent.PriorityBlockingQueue}, and {@link
+java.util.concurrent.DelayQueue}. The different classes cover the most
+common usage contexts for producer-consumer, messaging, parallel
+tasking, and related concurrent designs.
+
+
+<h2>Timing</h2>
+
+The {@link java.util.concurrent.TimeUnit} class provides multiple
+granularities (including nanoseconds) for specifying and controlling
+time-out based operations. Most classes in the package contain
+operations based on time-outs in addition to indefinite waits. In all
+cases that time-outs are used, the time-out specifies the minimum time
+that the method should wait before indicating that it
+timed-out. Implementations make a &quot;best effort&quot; to detect
+time-outs as soon as possible after they occur. However, an indefinite
+amount of time may elapse between a time-out being detected and a
+thread actually executing again after that time-out.
+
+<h2>Synchronizers</h2>
+
+Four classes aid common special-purpose synchronization idioms.
+{@link java.util.concurrent.Semaphore} is a classic concurrency tool.
+{@link java.util.concurrent.CountDownLatch} is a very simple yet very
+common utility for blocking until a given number of signals, events,
+or conditions hold. A {@link java.util.concurrent.CyclicBarrier} is a
+resettable multiway synchronization point useful in some styles of
+parallel programming. An {@link java.util.concurrent.Exchanger} allows
+two threads to exchange objects at a rendezvous point, and is useful
+in several pipeline designs.
+
+<h2>Concurrent Collections</h2>
+
+Besides Queues, this package supplies a few Collection implementations
+designed for use in multithreaded contexts: {@link
+java.util.concurrent.ConcurrentHashMap}, {@link
+java.util.concurrent.CopyOnWriteArrayList}, and {@link
+java.util.concurrent.CopyOnWriteArraySet}.
+
+<p>The "Concurrent" prefix used with some classes in this package is a
+shorthand indicating several differences from similar "synchronized"
+classes. For example <tt>java.util.Hashtable</tt> and
+<tt>Collections.synchronizedMap(new HashMap())</tt> are
+synchronized. But {@link java.util.concurrent.ConcurrentHashMap} is
+"concurrent". A concurrent collection is thread-safe, but not
+governed by a single exclusion lock. In the particular case of
+ConcurrentHashMap, it safely permits any number of concurrent reads as
+well as a tunable number of concurrent writes. "Synchronized" classes
+can be useful when you need to prevent all access to a collection via
+a single lock, at the expense of poorer scalability. In other cases in
+which multiple threads are expected to access a common collection,
+"concurrent" versions are normally preferable. And unsynchronized
+collections are preferable when either collections are unshared, or
+are accessible only when holding other locks.
+
+<p> Most concurrent Collection implementations (including most Queues)
+also differ from the usual java.util conventions in that their Iterators
+provide <em>weakly consistent</em> rather than fast-fail traversal. A
+weakly consistent iterator is thread-safe, but does not necessarily
+freeze the collection while iterating, so it may (or may not) reflect
+any updates since the iterator was created.
+
+@since 1.5
+@since Android 1.0
+
+</body> </html>