diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:14 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:14 -0800 |
commit | 1c0fed63c71ddb230f3b304aac12caffbedf2f21 (patch) | |
tree | 4b825dc642cb6eb9a060e54bf8d69288fbee4904 /concurrent/src/main/java | |
parent | 2fb02ef3025449e24e756a7f645ea6eab7a1fd4f (diff) | |
download | libcore-1c0fed63c71ddb230f3b304aac12caffbedf2f21.zip libcore-1c0fed63c71ddb230f3b304aac12caffbedf2f21.tar.gz libcore-1c0fed63c71ddb230f3b304aac12caffbedf2f21.tar.bz2 |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'concurrent/src/main/java')
61 files changed, 0 insertions, 20531 deletions
diff --git a/concurrent/src/main/java/java/util/concurrent/AbstractExecutorService.java b/concurrent/src/main/java/java/util/concurrent/AbstractExecutorService.java deleted file mode 100644 index ed4ce4f..0000000 --- a/concurrent/src/main/java/java/util/concurrent/AbstractExecutorService.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * 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 deleted file mode 100644 index 43b9fd0..0000000 --- a/concurrent/src/main/java/java/util/concurrent/ArrayBlockingQueue.java +++ /dev/null @@ -1,687 +0,0 @@ -/* - * 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 "bounded buffer", 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 deleted file mode 100644 index ddb7d77..0000000 --- a/concurrent/src/main/java/java/util/concurrent/BlockingQueue.java +++ /dev/null @@ -1,227 +0,0 @@ -/* - * 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 "close" or "shutdown" 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 deleted file mode 100644 index 3f93fbb..0000000 --- a/concurrent/src/main/java/java/util/concurrent/BrokenBarrierException.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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 deleted file mode 100644 index abc4d04..0000000 --- a/concurrent/src/main/java/java/util/concurrent/Callable.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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 deleted file mode 100644 index 2c29544..0000000 --- a/concurrent/src/main/java/java/util/concurrent/CancellationException.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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 deleted file mode 100644 index e349e5f..0000000 --- a/concurrent/src/main/java/java/util/concurrent/CompletionService.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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 deleted file mode 100644 index f72c6fe..0000000 --- a/concurrent/src/main/java/java/util/concurrent/ConcurrentHashMap.java +++ /dev/null @@ -1,1353 +0,0 @@ -/* - * 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); - } - - // inherit Map javadoc - 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; - } - - // inherit Map javadoc - 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-removed - // /** - // * 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 deleted file mode 100644 index 794142d..0000000 --- a/concurrent/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java +++ /dev/null @@ -1,481 +0,0 @@ -/* - * 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 "wait-free" - * 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 deleted file mode 100644 index 32dc000..0000000 --- a/concurrent/src/main/java/java/util/concurrent/ConcurrentMap.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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 deleted file mode 100644 index 7274595..0000000 --- a/concurrent/src/main/java/java/util/concurrent/CopyOnWriteArrayList.java +++ /dev/null @@ -1,1190 +0,0 @@ -/* - * 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); - } - - @Override - 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 deleted file mode 100644 index 532952b..0000000 --- a/concurrent/src/main/java/java/util/concurrent/CopyOnWriteArraySet.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * 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<Handler> handlers = new CopyOnWriteArraySet<Handler>(); - * 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> - implements java.io.Serializable { - 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 deleted file mode 100644 index 721744c..0000000 --- a/concurrent/src/main/java/java/util/concurrent/CountDownLatch.java +++ /dev/null @@ -1,280 +0,0 @@ -/* - * 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 - * "Count =" 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 deleted file mode 100644 index d70c4c7..0000000 --- a/concurrent/src/main/java/java/util/concurrent/CyclicBarrier.java +++ /dev/null @@ -1,430 +0,0 @@ -/* - * 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 deleted file mode 100644 index 156dc7e..0000000 --- a/concurrent/src/main/java/java/util/concurrent/DelayQueue.java +++ /dev/null @@ -1,366 +0,0 @@ -/* - * 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 deleted file mode 100644 index bd48292..0000000 --- a/concurrent/src/main/java/java/util/concurrent/Delayed.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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.*; - -// BEGIN android-note -// Added generic type Delayed to Comparable to be closer to the RI. -// END android-note - -/** - * 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 deleted file mode 100644 index da8c815..0000000 --- a/concurrent/src/main/java/java/util/concurrent/Exchanger.java +++ /dev/null @@ -1,247 +0,0 @@ -/* - * 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<DataBuffer> 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 deleted file mode 100644 index 8f0e448..0000000 --- a/concurrent/src/main/java/java/util/concurrent/ExecutionException.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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 deleted file mode 100644 index 60fe193..0000000 --- a/concurrent/src/main/java/java/util/concurrent/Executor.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * 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<Runnable> tasks = new LinkedBlockingQueue<Runnable>(); - * 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 deleted file mode 100644 index 4f9c9d9..0000000 --- a/concurrent/src/main/java/java/util/concurrent/ExecutorCompletionService.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * 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<Callable<Result>> solvers) - * throws InterruptedException, ExecutionException { - * CompletionService<Result> ecs = new ExecutorCompletionService<Result>(e); - * for (Callable<Result> s : solvers) - * ecs.submit(s); - * int n = solvers.size(); - * for (int i = 0; i < 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<Callable<Result>> solvers) - * throws InterruptedException { - * CompletionService<Result> ecs = new ExecutorCompletionService<Result>(e); - * int n = solvers.size(); - * List<Future<Result>> futures = new ArrayList<Future<Result>>(n); - * Result result = null; - * try { - * for (Callable<Result> s : solvers) - * futures.add(ecs.submit(s)); - * for (int i = 0; i < n; ++i) { - * try { - * Result r = ecs.take().get(); - * if (r != null) { - * result = r; - * break; - * } - * } catch(ExecutionException ignore) {} - * } - * } - * finally { - * for (Future<Result> 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 deleted file mode 100644 index e178eb2..0000000 --- a/concurrent/src/main/java/java/util/concurrent/ExecutorService.java +++ /dev/null @@ -1,286 +0,0 @@ -/* - * 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 deleted file mode 100644 index 23f1b75..0000000 --- a/concurrent/src/main/java/java/util/concurrent/Executors.java +++ /dev/null @@ -1,659 +0,0 @@ -/* - * 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 deleted file mode 100644 index 38fa8c6..0000000 --- a/concurrent/src/main/java/java/util/concurrent/Future.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * 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<?></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<String> future = executor.submit(new Callable<String>() { - * 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<String> future = - * new FutureTask<String>(new Callable<String>() { - * 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 deleted file mode 100644 index 87db1cd..0000000 --- a/concurrent/src/main/java/java/util/concurrent/FutureTask.java +++ /dev/null @@ -1,276 +0,0 @@ -/* - * 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<?> f = new FutureTask<Object>(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 deleted file mode 100644 index 662f63e..0000000 --- a/concurrent/src/main/java/java/util/concurrent/LinkedBlockingQueue.java +++ /dev/null @@ -1,722 +0,0 @@ -/* - * 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 deleted file mode 100644 index 83f1040..0000000 --- a/concurrent/src/main/java/java/util/concurrent/PriorityBlockingQueue.java +++ /dev/null @@ -1,457 +0,0 @@ -/* - * 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 deleted file mode 100644 index 199b9de..0000000 --- a/concurrent/src/main/java/java/util/concurrent/RejectedExecutionException.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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 deleted file mode 100644 index 4b4bbea..0000000 --- a/concurrent/src/main/java/java/util/concurrent/RejectedExecutionHandler.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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 deleted file mode 100644 index 9579fef..0000000 --- a/concurrent/src/main/java/java/util/concurrent/ScheduledExecutorService.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * 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<?> 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 deleted file mode 100644 index 239d681..0000000 --- a/concurrent/src/main/java/java/util/concurrent/ScheduledFuture.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * 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 deleted file mode 100644 index 09ec681..0000000 --- a/concurrent/src/main/java/java/util/concurrent/ScheduledThreadPoolExecutor.java +++ /dev/null @@ -1,541 +0,0 @@ -/* - * 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 deleted file mode 100644 index 6eb80bc..0000000 --- a/concurrent/src/main/java/java/util/concurrent/Semaphore.java +++ /dev/null @@ -1,665 +0,0 @@ -/* - * 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 "lock" 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 "barging" 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 - * "barging" 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 - * "Permits =" 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 deleted file mode 100644 index b8d3536..0000000 --- a/concurrent/src/main/java/java/util/concurrent/SynchronousQueue.java +++ /dev/null @@ -1,685 +0,0 @@ -/* - * 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 deleted file mode 100644 index 04c63e1..0000000 --- a/concurrent/src/main/java/java/util/concurrent/ThreadFactory.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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 deleted file mode 100644 index 1aa8e55..0000000 --- a/concurrent/src/main/java/java/util/concurrent/ThreadPoolExecutor.java +++ /dev/null @@ -1,1513 +0,0 @@ -/* - * 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 deleted file mode 100644 index b186aeb..0000000 --- a/concurrent/src/main/java/java/util/concurrent/TimeUnit.java +++ /dev/null @@ -1,238 +0,0 @@ -/* - * 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 deleted file mode 100644 index 8b84f28..0000000 --- a/concurrent/src/main/java/java/util/concurrent/TimeoutException.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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 deleted file mode 100644 index fdd3d49..0000000 --- a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicBoolean.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * 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 deleted file mode 100644 index 2b9d15c..0000000 --- a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicInteger.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * 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 deleted file mode 100644 index 95807f3..0000000 --- a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerArray.java +++ /dev/null @@ -1,245 +0,0 @@ -/* - * 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 deleted file mode 100644 index 5f289c2..0000000 --- a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java +++ /dev/null @@ -1,260 +0,0 @@ -/* - * 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 deleted file mode 100644 index 7f41364..0000000 --- a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLong.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * 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 deleted file mode 100644 index a0e76b4..0000000 --- a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java +++ /dev/null @@ -1,242 +0,0 @@ -/* - * 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 deleted file mode 100644 index dcb8b2e..0000000 --- a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java +++ /dev/null @@ -1,321 +0,0 @@ -/* - * 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 deleted file mode 100644 index 11c91ba..0000000 --- a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicMarkableReference.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * 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 deleted file mode 100644 index 89c050c..0000000 --- a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReference.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * 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 deleted file mode 100644 index 9ad800c..0000000 --- a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceArray.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * 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 deleted file mode 100644 index f20661d..0000000 --- a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * 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<Node, Node> leftUpdater = - * AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "left"); - * private static AtomicReferenceFieldUpdater<Node, Node> 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 deleted file mode 100644 index b0a02c2..0000000 --- a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicStampedReference.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * 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 deleted file mode 100644 index 96fff17..0000000 --- a/concurrent/src/main/java/java/util/concurrent/atomic/UnsafeAccess.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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 deleted file mode 100644 index bdb15e8..0000000 --- a/concurrent/src/main/java/java/util/concurrent/atomic/package.html +++ /dev/null @@ -1,132 +0,0 @@ -<!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 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 deleted file mode 100644 index 29e72b5..0000000 --- a/concurrent/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java +++ /dev/null @@ -1,2058 +0,0 @@ -/* - * 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 "understand" 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 - * "spin" 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 "State - * =" followed by the current value of {@link #getState}, and - * either "nonempty" or "empty" 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 deleted file mode 100644 index 7a8ca5b..0000000 --- a/concurrent/src/main/java/java/util/concurrent/locks/Condition.java +++ /dev/null @@ -1,439 +0,0 @@ -/* - * 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 "wait") until notified by another - * thread that some state condition may now be true. Because access - * to this shared state information occurs in different threads, it - * must be protected, so a lock of some form is associated with the - * condition. The key property that waiting for a condition provides - * is that it <em>atomically</em> releases the associated lock and - * suspends the current thread, just like <tt>Object.wait</tt>. - * - * <p>A <tt>Condition</tt> instance is intrinsically bound to a lock. - * 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 "<em>spurious - * wakeup</em>" is permitted to occur, in - * general, as a concession to the underlying platform semantics. - * This has little practical impact on most application programs as a - * <tt>Condition</tt> should always be waited upon in a loop, testing - * the state predicate that is being waited for. An implementation is - * 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 "<em>spurious wakeup</em>" occurs - * </ul> - * - * <p>In all cases, before this method can return the current thread must - * re-acquire the lock associated with this condition. When the - * thread returns it is <em>guaranteed</em> to hold this lock. - * - * <p>If the current thread: - * <ul> - * <li>has its interrupted status set on entry to this method; or - * <li>is {@link Thread#interrupt interrupted} while waiting - * and interruption of thread suspension is supported, - * </ul> - * then {@link InterruptedException} is thrown and the current thread's - * interrupted status is cleared. It is not specified, in the first - * case, whether or not the test for interruption occurs before the lock - * is released. - * - * <p><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 "<em>spurious wakeup</em>" occurs - * </ul> - * - * <p>In all cases, before this method can return the current thread must - * re-acquire the lock associated with this condition. When the - * thread returns it is <em>guaranteed</em> to hold this lock. - * - * <p>If the current thread'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 "<em>spurious wakeup</em>" occurs. - * </ul> - * - * <p>In all cases, before this method can return the current thread must - * re-acquire the lock associated with this condition. When the - * thread returns it is <em>guaranteed</em> to hold this lock. - * - * <p>If the current thread: - * <ul> - * <li>has its interrupted status set on entry to this method; or - * <li>is {@link Thread#interrupt interrupted} while waiting - * and interruption of thread suspension is supported, - * </ul> - * then {@link InterruptedException} is thrown and the current thread's - * interrupted status is cleared. It is not specified, in the first - * case, whether or not the test for interruption occurs before the lock - * is released. - * - * <p>The method returns an estimate of the number of nanoseconds - * remaining to wait given the supplied <tt>nanosTimeout</tt> - * value upon return, or a value less than or equal to zero if it - * timed out. This value can be used to determine whether and how - * long to re-wait in cases where the wait returns but an awaited - * condition still does not hold. Typical uses of this method take - * the following form: - * - * <pre> - * synchronized boolean aMethod(long timeout, TimeUnit unit) { - * long nanosTimeout = unit.toNanos(timeout); - * while (!conditionBeingWaitedFor) { - * if (nanosTimeout > 0) - * nanosTimeout = theCondition.awaitNanos(nanosTimeout); - * else - * return false; - * } - * // ... - * } - * </pre> - * - * <p> Design note: This method requires a nanosecond argument so - * as to avoid truncation errors in reporting remaining times. - * Such precision loss would make it difficult for programmers to - * ensure that total waiting times are not systematically shorter - * than specified when re-waits occur. - * - * <p><b>Implementation Considerations</b> - * <p>The current thread is assumed to hold the lock associated with this - * <tt>Condition</tt> when this method is called. - * It is up to the implementation to determine if this is - * the case and if not, how to respond. Typically, an exception will be - * thrown (such as {@link IllegalMonitorStateException}) and the - * implementation must document that fact. - * - * <p>An implementation can favor responding to an interrupt over normal - * method return in response to a signal, or over indicating the elapse - * of the specified waiting time. In either case the implementation - * must ensure that the signal is redirected to another waiting thread, if - * there is one. - * - * @param nanosTimeout the maximum time to wait, in nanoseconds - * @return A value less than or equal to zero if the wait has - * timed out; otherwise an estimate, that - * is strictly less than the <tt>nanosTimeout</tt> argument, - * of the time still remaining when this method returned. - * - * @throws InterruptedException if the current thread is interrupted (and - * interruption of thread suspension is supported). - */ - long awaitNanos(long nanosTimeout) throws InterruptedException; - - /** - * Causes the current thread to wait until it is signalled or interrupted, - * or the specified waiting time elapses. This method is behaviorally - * equivalent to:<br> - * <pre> - * awaitNanos(unit.toNanos(time)) > 0 - * </pre> - * @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 "<em>spurious wakeup</em>" occurs. - * </ul> - * - * <p>In all cases, before this method can return the current thread must - * re-acquire the lock associated with this condition. When the - * thread returns it is <em>guaranteed</em> to hold this lock. - * - * - * <p>If the current thread: - * <ul> - * <li>has its interrupted status set on entry to this method; or - * <li>is {@link Thread#interrupt interrupted} while waiting - * and interruption of thread suspension is supported, - * </ul> - * then {@link InterruptedException} is thrown and the current thread's - * interrupted status is cleared. It is not specified, in the first - * case, whether or not the test for interruption occurs before the lock - * is released. - * - * - * <p>The 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 deleted file mode 100644 index f07b72e..0000000 --- a/concurrent/src/main/java/java/util/concurrent/locks/Lock.java +++ /dev/null @@ -1,329 +0,0 @@ -/* - * 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 - * "hand-over-hand" or "chain locking": 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 deleted file mode 100644 index 8603785..0000000 --- a/concurrent/src/main/java/java/util/concurrent/locks/LockSupport.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * 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<Thread> waiters = new ConcurrentLinkedQueue<Thread>(); - * - * 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 deleted file mode 100644 index c7116d5..0000000 --- a/concurrent/src/main/java/java/util/concurrent/locks/ReadWriteLock.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * 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 "in-order" 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 deleted file mode 100644 index bf3d653..0000000 --- a/concurrent/src/main/java/java/util/concurrent/locks/ReentrantLock.java +++ /dev/null @@ -1,727 +0,0 @@ -/* - * 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 "barging" 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 - * "Unlocked" or the String "Locked by" - * 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 deleted file mode 100644 index 95fc7af..0000000 --- a/concurrent/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java +++ /dev/null @@ -1,1119 +0,0 @@ -/* - * 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<String, Data> m = new TreeMap<String, Data>(); - * 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 "barging" 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 - * "Read locks =" 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 "barging" - * 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 - * "Unlocked" or the String "Locked by" - * 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 "Write locks =" - * follwed by the number of reentrantly held write locks, and the - * String "Read locks =" 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 deleted file mode 100644 index 07f64e4..0000000 --- a/concurrent/src/main/java/java/util/concurrent/locks/UnsafeAccess.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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 deleted file mode 100644 index 1cc156f..0000000 --- a/concurrent/src/main/java/java/util/concurrent/locks/package.html +++ /dev/null @@ -1,44 +0,0 @@ -<!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 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 deleted file mode 100644 index a5bb8d2..0000000 --- a/concurrent/src/main/java/java/util/concurrent/package.html +++ /dev/null @@ -1,125 +0,0 @@ -<!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 "best effort" 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 Android 1.0 - -</body> </html> |