1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/AbstractExecutorService.java Sat Mar 19 10:48:29 2016 +0100
1.3 @@ -0,0 +1,309 @@
1.4 +/*
1.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1.6 + *
1.7 + * This code is free software; you can redistribute it and/or modify it
1.8 + * under the terms of the GNU General Public License version 2 only, as
1.9 + * published by the Free Software Foundation. Oracle designates this
1.10 + * particular file as subject to the "Classpath" exception as provided
1.11 + * by Oracle in the LICENSE file that accompanied this code.
1.12 + *
1.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
1.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1.16 + * version 2 for more details (a copy is included in the LICENSE file that
1.17 + * accompanied this code).
1.18 + *
1.19 + * You should have received a copy of the GNU General Public License version
1.20 + * 2 along with this work; if not, write to the Free Software Foundation,
1.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1.22 + *
1.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1.24 + * or visit www.oracle.com if you need additional information or have any
1.25 + * questions.
1.26 + */
1.27 +
1.28 +/*
1.29 + * This file is available under and governed by the GNU General Public
1.30 + * License version 2 only, as published by the Free Software Foundation.
1.31 + * However, the following notice accompanied the original version of this
1.32 + * file:
1.33 + *
1.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
1.35 + * Expert Group and released to the public domain, as explained at
1.36 + * http://creativecommons.org/publicdomain/zero/1.0/
1.37 + */
1.38 +
1.39 +package java.util.concurrent;
1.40 +import java.util.*;
1.41 +
1.42 +/**
1.43 + * Provides default implementations of {@link ExecutorService}
1.44 + * execution methods. This class implements the <tt>submit</tt>,
1.45 + * <tt>invokeAny</tt> and <tt>invokeAll</tt> methods using a
1.46 + * {@link RunnableFuture} returned by <tt>newTaskFor</tt>, which defaults
1.47 + * to the {@link FutureTask} class provided in this package. For example,
1.48 + * the implementation of <tt>submit(Runnable)</tt> creates an
1.49 + * associated <tt>RunnableFuture</tt> that is executed and
1.50 + * returned. Subclasses may override the <tt>newTaskFor</tt> methods
1.51 + * to return <tt>RunnableFuture</tt> implementations other than
1.52 + * <tt>FutureTask</tt>.
1.53 + *
1.54 + * <p> <b>Extension example</b>. Here is a sketch of a class
1.55 + * that customizes {@link ThreadPoolExecutor} to use
1.56 + * a <tt>CustomTask</tt> class instead of the default <tt>FutureTask</tt>:
1.57 + * <pre> {@code
1.58 + * public class CustomThreadPoolExecutor extends ThreadPoolExecutor {
1.59 + *
1.60 + * static class CustomTask<V> implements RunnableFuture<V> {...}
1.61 + *
1.62 + * protected <V> RunnableFuture<V> newTaskFor(Callable<V> c) {
1.63 + * return new CustomTask<V>(c);
1.64 + * }
1.65 + * protected <V> RunnableFuture<V> newTaskFor(Runnable r, V v) {
1.66 + * return new CustomTask<V>(r, v);
1.67 + * }
1.68 + * // ... add constructors, etc.
1.69 + * }}</pre>
1.70 + *
1.71 + * @since 1.5
1.72 + * @author Doug Lea
1.73 + */
1.74 +public abstract class AbstractExecutorService implements ExecutorService {
1.75 +
1.76 + /**
1.77 + * Returns a <tt>RunnableFuture</tt> for the given runnable and default
1.78 + * value.
1.79 + *
1.80 + * @param runnable the runnable task being wrapped
1.81 + * @param value the default value for the returned future
1.82 + * @return a <tt>RunnableFuture</tt> which when run will run the
1.83 + * underlying runnable and which, as a <tt>Future</tt>, will yield
1.84 + * the given value as its result and provide for cancellation of
1.85 + * the underlying task.
1.86 + * @since 1.6
1.87 + */
1.88 + protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
1.89 + return new FutureTask<T>(runnable, value);
1.90 + }
1.91 +
1.92 + /**
1.93 + * Returns a <tt>RunnableFuture</tt> for the given callable task.
1.94 + *
1.95 + * @param callable the callable task being wrapped
1.96 + * @return a <tt>RunnableFuture</tt> which when run will call the
1.97 + * underlying callable and which, as a <tt>Future</tt>, will yield
1.98 + * the callable's result as its result and provide for
1.99 + * cancellation of the underlying task.
1.100 + * @since 1.6
1.101 + */
1.102 + protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
1.103 + return new FutureTask<T>(callable);
1.104 + }
1.105 +
1.106 + /**
1.107 + * @throws RejectedExecutionException {@inheritDoc}
1.108 + * @throws NullPointerException {@inheritDoc}
1.109 + */
1.110 + public Future<?> submit(Runnable task) {
1.111 + if (task == null) throw new NullPointerException();
1.112 + RunnableFuture<Void> ftask = newTaskFor(task, null);
1.113 + execute(ftask);
1.114 + return ftask;
1.115 + }
1.116 +
1.117 + /**
1.118 + * @throws RejectedExecutionException {@inheritDoc}
1.119 + * @throws NullPointerException {@inheritDoc}
1.120 + */
1.121 + public <T> Future<T> submit(Runnable task, T result) {
1.122 + if (task == null) throw new NullPointerException();
1.123 + RunnableFuture<T> ftask = newTaskFor(task, result);
1.124 + execute(ftask);
1.125 + return ftask;
1.126 + }
1.127 +
1.128 + /**
1.129 + * @throws RejectedExecutionException {@inheritDoc}
1.130 + * @throws NullPointerException {@inheritDoc}
1.131 + */
1.132 + public <T> Future<T> submit(Callable<T> task) {
1.133 + if (task == null) throw new NullPointerException();
1.134 + RunnableFuture<T> ftask = newTaskFor(task);
1.135 + execute(ftask);
1.136 + return ftask;
1.137 + }
1.138 +
1.139 + /**
1.140 + * the main mechanics of invokeAny.
1.141 + */
1.142 + private <T> T doInvokeAny(Collection<? extends Callable<T>> tasks,
1.143 + boolean timed, long nanos)
1.144 + throws InterruptedException, ExecutionException, TimeoutException {
1.145 + if (tasks == null)
1.146 + throw new NullPointerException();
1.147 + int ntasks = tasks.size();
1.148 + if (ntasks == 0)
1.149 + throw new IllegalArgumentException();
1.150 + List<Future<T>> futures= new ArrayList<Future<T>>(ntasks);
1.151 + ExecutorCompletionService<T> ecs =
1.152 + new ExecutorCompletionService<T>(this);
1.153 +
1.154 + // For efficiency, especially in executors with limited
1.155 + // parallelism, check to see if previously submitted tasks are
1.156 + // done before submitting more of them. This interleaving
1.157 + // plus the exception mechanics account for messiness of main
1.158 + // loop.
1.159 +
1.160 + try {
1.161 + // Record exceptions so that if we fail to obtain any
1.162 + // result, we can throw the last exception we got.
1.163 + ExecutionException ee = null;
1.164 + long lastTime = timed ? System.nanoTime() : 0;
1.165 + Iterator<? extends Callable<T>> it = tasks.iterator();
1.166 +
1.167 + // Start one task for sure; the rest incrementally
1.168 + futures.add(ecs.submit(it.next()));
1.169 + --ntasks;
1.170 + int active = 1;
1.171 +
1.172 + for (;;) {
1.173 + Future<T> f = ecs.poll();
1.174 + if (f == null) {
1.175 + if (ntasks > 0) {
1.176 + --ntasks;
1.177 + futures.add(ecs.submit(it.next()));
1.178 + ++active;
1.179 + }
1.180 + else if (active == 0)
1.181 + break;
1.182 + else if (timed) {
1.183 + f = ecs.poll(nanos, TimeUnit.NANOSECONDS);
1.184 + if (f == null)
1.185 + throw new TimeoutException();
1.186 + long now = System.nanoTime();
1.187 + nanos -= now - lastTime;
1.188 + lastTime = now;
1.189 + }
1.190 + else
1.191 + f = ecs.take();
1.192 + }
1.193 + if (f != null) {
1.194 + --active;
1.195 + try {
1.196 + return f.get();
1.197 + } catch (ExecutionException eex) {
1.198 + ee = eex;
1.199 + } catch (RuntimeException rex) {
1.200 + ee = new ExecutionException(rex);
1.201 + }
1.202 + }
1.203 + }
1.204 +
1.205 + if (ee == null)
1.206 + ee = new ExecutionException();
1.207 + throw ee;
1.208 +
1.209 + } finally {
1.210 + for (Future<T> f : futures)
1.211 + f.cancel(true);
1.212 + }
1.213 + }
1.214 +
1.215 + public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
1.216 + throws InterruptedException, ExecutionException {
1.217 + try {
1.218 + return doInvokeAny(tasks, false, 0);
1.219 + } catch (TimeoutException cannotHappen) {
1.220 + assert false;
1.221 + return null;
1.222 + }
1.223 + }
1.224 +
1.225 + public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
1.226 + long timeout, TimeUnit unit)
1.227 + throws InterruptedException, ExecutionException, TimeoutException {
1.228 + return doInvokeAny(tasks, true, unit.toNanos(timeout));
1.229 + }
1.230 +
1.231 + public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
1.232 + throws InterruptedException {
1.233 + if (tasks == null)
1.234 + throw new NullPointerException();
1.235 + List<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
1.236 + boolean done = false;
1.237 + try {
1.238 + for (Callable<T> t : tasks) {
1.239 + RunnableFuture<T> f = newTaskFor(t);
1.240 + futures.add(f);
1.241 + execute(f);
1.242 + }
1.243 + for (Future<T> f : futures) {
1.244 + if (!f.isDone()) {
1.245 + try {
1.246 + f.get();
1.247 + } catch (CancellationException ignore) {
1.248 + } catch (ExecutionException ignore) {
1.249 + }
1.250 + }
1.251 + }
1.252 + done = true;
1.253 + return futures;
1.254 + } finally {
1.255 + if (!done)
1.256 + for (Future<T> f : futures)
1.257 + f.cancel(true);
1.258 + }
1.259 + }
1.260 +
1.261 + public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
1.262 + long timeout, TimeUnit unit)
1.263 + throws InterruptedException {
1.264 + if (tasks == null || unit == null)
1.265 + throw new NullPointerException();
1.266 + long nanos = unit.toNanos(timeout);
1.267 + List<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
1.268 + boolean done = false;
1.269 + try {
1.270 + for (Callable<T> t : tasks)
1.271 + futures.add(newTaskFor(t));
1.272 +
1.273 + long lastTime = System.nanoTime();
1.274 +
1.275 + // Interleave time checks and calls to execute in case
1.276 + // executor doesn't have any/much parallelism.
1.277 + Iterator<Future<T>> it = futures.iterator();
1.278 + while (it.hasNext()) {
1.279 + execute((Runnable)(it.next()));
1.280 + long now = System.nanoTime();
1.281 + nanos -= now - lastTime;
1.282 + lastTime = now;
1.283 + if (nanos <= 0)
1.284 + return futures;
1.285 + }
1.286 +
1.287 + for (Future<T> f : futures) {
1.288 + if (!f.isDone()) {
1.289 + if (nanos <= 0)
1.290 + return futures;
1.291 + try {
1.292 + f.get(nanos, TimeUnit.NANOSECONDS);
1.293 + } catch (CancellationException ignore) {
1.294 + } catch (ExecutionException ignore) {
1.295 + } catch (TimeoutException toe) {
1.296 + return futures;
1.297 + }
1.298 + long now = System.nanoTime();
1.299 + nanos -= now - lastTime;
1.300 + lastTime = now;
1.301 + }
1.302 + }
1.303 + done = true;
1.304 + return futures;
1.305 + } finally {
1.306 + if (!done)
1.307 + for (Future<T> f : futures)
1.308 + f.cancel(true);
1.309 + }
1.310 + }
1.311 +
1.312 +}
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ArrayBlockingQueue.java Sat Mar 19 10:48:29 2016 +0100
2.3 @@ -0,0 +1,805 @@
2.4 +/*
2.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
2.6 + *
2.7 + * This code is free software; you can redistribute it and/or modify it
2.8 + * under the terms of the GNU General Public License version 2 only, as
2.9 + * published by the Free Software Foundation. Oracle designates this
2.10 + * particular file as subject to the "Classpath" exception as provided
2.11 + * by Oracle in the LICENSE file that accompanied this code.
2.12 + *
2.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
2.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
2.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2.16 + * version 2 for more details (a copy is included in the LICENSE file that
2.17 + * accompanied this code).
2.18 + *
2.19 + * You should have received a copy of the GNU General Public License version
2.20 + * 2 along with this work; if not, write to the Free Software Foundation,
2.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2.22 + *
2.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2.24 + * or visit www.oracle.com if you need additional information or have any
2.25 + * questions.
2.26 + */
2.27 +
2.28 +/*
2.29 + * This file is available under and governed by the GNU General Public
2.30 + * License version 2 only, as published by the Free Software Foundation.
2.31 + * However, the following notice accompanied the original version of this
2.32 + * file:
2.33 + *
2.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
2.35 + * Expert Group and released to the public domain, as explained at
2.36 + * http://creativecommons.org/publicdomain/zero/1.0/
2.37 + */
2.38 +
2.39 +package java.util.concurrent;
2.40 +import java.util.concurrent.locks.*;
2.41 +import java.util.*;
2.42 +
2.43 +/**
2.44 + * A bounded {@linkplain BlockingQueue blocking queue} backed by an
2.45 + * array. This queue orders elements FIFO (first-in-first-out). The
2.46 + * <em>head</em> of the queue is that element that has been on the
2.47 + * queue the longest time. The <em>tail</em> of the queue is that
2.48 + * element that has been on the queue the shortest time. New elements
2.49 + * are inserted at the tail of the queue, and the queue retrieval
2.50 + * operations obtain elements at the head of the queue.
2.51 + *
2.52 + * <p>This is a classic "bounded buffer", in which a
2.53 + * fixed-sized array holds elements inserted by producers and
2.54 + * extracted by consumers. Once created, the capacity cannot be
2.55 + * changed. Attempts to {@code put} an element into a full queue
2.56 + * will result in the operation blocking; attempts to {@code take} an
2.57 + * element from an empty queue will similarly block.
2.58 + *
2.59 + * <p>This class supports an optional fairness policy for ordering
2.60 + * waiting producer and consumer threads. By default, this ordering
2.61 + * is not guaranteed. However, a queue constructed with fairness set
2.62 + * to {@code true} grants threads access in FIFO order. Fairness
2.63 + * generally decreases throughput but reduces variability and avoids
2.64 + * starvation.
2.65 + *
2.66 + * <p>This class and its iterator implement all of the
2.67 + * <em>optional</em> methods of the {@link Collection} and {@link
2.68 + * Iterator} interfaces.
2.69 + *
2.70 + * <p>This class is a member of the
2.71 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
2.72 + * Java Collections Framework</a>.
2.73 + *
2.74 + * @since 1.5
2.75 + * @author Doug Lea
2.76 + * @param <E> the type of elements held in this collection
2.77 + */
2.78 +public class ArrayBlockingQueue<E> extends AbstractQueue<E>
2.79 + implements BlockingQueue<E>, java.io.Serializable {
2.80 +
2.81 + /**
2.82 + * Serialization ID. This class relies on default serialization
2.83 + * even for the items array, which is default-serialized, even if
2.84 + * it is empty. Otherwise it could not be declared final, which is
2.85 + * necessary here.
2.86 + */
2.87 + private static final long serialVersionUID = -817911632652898426L;
2.88 +
2.89 + /** The queued items */
2.90 + final Object[] items;
2.91 +
2.92 + /** items index for next take, poll, peek or remove */
2.93 + int takeIndex;
2.94 +
2.95 + /** items index for next put, offer, or add */
2.96 + int putIndex;
2.97 +
2.98 + /** Number of elements in the queue */
2.99 + int count;
2.100 +
2.101 + /*
2.102 + * Concurrency control uses the classic two-condition algorithm
2.103 + * found in any textbook.
2.104 + */
2.105 +
2.106 + /** Main lock guarding all access */
2.107 + final ReentrantLock lock;
2.108 + /** Condition for waiting takes */
2.109 + private final Condition notEmpty;
2.110 + /** Condition for waiting puts */
2.111 + private final Condition notFull;
2.112 +
2.113 + // Internal helper methods
2.114 +
2.115 + /**
2.116 + * Circularly increment i.
2.117 + */
2.118 + final int inc(int i) {
2.119 + return (++i == items.length) ? 0 : i;
2.120 + }
2.121 +
2.122 + /**
2.123 + * Circularly decrement i.
2.124 + */
2.125 + final int dec(int i) {
2.126 + return ((i == 0) ? items.length : i) - 1;
2.127 + }
2.128 +
2.129 + @SuppressWarnings("unchecked")
2.130 + static <E> E cast(Object item) {
2.131 + return (E) item;
2.132 + }
2.133 +
2.134 + /**
2.135 + * Returns item at index i.
2.136 + */
2.137 + final E itemAt(int i) {
2.138 + return this.<E>cast(items[i]);
2.139 + }
2.140 +
2.141 + /**
2.142 + * Throws NullPointerException if argument is null.
2.143 + *
2.144 + * @param v the element
2.145 + */
2.146 + private static void checkNotNull(Object v) {
2.147 + if (v == null)
2.148 + throw new NullPointerException();
2.149 + }
2.150 +
2.151 + /**
2.152 + * Inserts element at current put position, advances, and signals.
2.153 + * Call only when holding lock.
2.154 + */
2.155 + private void insert(E x) {
2.156 + items[putIndex] = x;
2.157 + putIndex = inc(putIndex);
2.158 + ++count;
2.159 + notEmpty.signal();
2.160 + }
2.161 +
2.162 + /**
2.163 + * Extracts element at current take position, advances, and signals.
2.164 + * Call only when holding lock.
2.165 + */
2.166 + private E extract() {
2.167 + final Object[] items = this.items;
2.168 + E x = this.<E>cast(items[takeIndex]);
2.169 + items[takeIndex] = null;
2.170 + takeIndex = inc(takeIndex);
2.171 + --count;
2.172 + notFull.signal();
2.173 + return x;
2.174 + }
2.175 +
2.176 + /**
2.177 + * Deletes item at position i.
2.178 + * Utility for remove and iterator.remove.
2.179 + * Call only when holding lock.
2.180 + */
2.181 + void removeAt(int i) {
2.182 + final Object[] items = this.items;
2.183 + // if removing front item, just advance
2.184 + if (i == takeIndex) {
2.185 + items[takeIndex] = null;
2.186 + takeIndex = inc(takeIndex);
2.187 + } else {
2.188 + // slide over all others up through putIndex.
2.189 + for (;;) {
2.190 + int nexti = inc(i);
2.191 + if (nexti != putIndex) {
2.192 + items[i] = items[nexti];
2.193 + i = nexti;
2.194 + } else {
2.195 + items[i] = null;
2.196 + putIndex = i;
2.197 + break;
2.198 + }
2.199 + }
2.200 + }
2.201 + --count;
2.202 + notFull.signal();
2.203 + }
2.204 +
2.205 + /**
2.206 + * Creates an {@code ArrayBlockingQueue} with the given (fixed)
2.207 + * capacity and default access policy.
2.208 + *
2.209 + * @param capacity the capacity of this queue
2.210 + * @throws IllegalArgumentException if {@code capacity < 1}
2.211 + */
2.212 + public ArrayBlockingQueue(int capacity) {
2.213 + this(capacity, false);
2.214 + }
2.215 +
2.216 + /**
2.217 + * Creates an {@code ArrayBlockingQueue} with the given (fixed)
2.218 + * capacity and the specified access policy.
2.219 + *
2.220 + * @param capacity the capacity of this queue
2.221 + * @param fair if {@code true} then queue accesses for threads blocked
2.222 + * on insertion or removal, are processed in FIFO order;
2.223 + * if {@code false} the access order is unspecified.
2.224 + * @throws IllegalArgumentException if {@code capacity < 1}
2.225 + */
2.226 + public ArrayBlockingQueue(int capacity, boolean fair) {
2.227 + if (capacity <= 0)
2.228 + throw new IllegalArgumentException();
2.229 + this.items = new Object[capacity];
2.230 + lock = new ReentrantLock(fair);
2.231 + notEmpty = lock.newCondition();
2.232 + notFull = lock.newCondition();
2.233 + }
2.234 +
2.235 + /**
2.236 + * Creates an {@code ArrayBlockingQueue} with the given (fixed)
2.237 + * capacity, the specified access policy and initially containing the
2.238 + * elements of the given collection,
2.239 + * added in traversal order of the collection's iterator.
2.240 + *
2.241 + * @param capacity the capacity of this queue
2.242 + * @param fair if {@code true} then queue accesses for threads blocked
2.243 + * on insertion or removal, are processed in FIFO order;
2.244 + * if {@code false} the access order is unspecified.
2.245 + * @param c the collection of elements to initially contain
2.246 + * @throws IllegalArgumentException if {@code capacity} is less than
2.247 + * {@code c.size()}, or less than 1.
2.248 + * @throws NullPointerException if the specified collection or any
2.249 + * of its elements are null
2.250 + */
2.251 + public ArrayBlockingQueue(int capacity, boolean fair,
2.252 + Collection<? extends E> c) {
2.253 + this(capacity, fair);
2.254 +
2.255 + final ReentrantLock lock = this.lock;
2.256 + lock.lock(); // Lock only for visibility, not mutual exclusion
2.257 + try {
2.258 + int i = 0;
2.259 + try {
2.260 + for (E e : c) {
2.261 + checkNotNull(e);
2.262 + items[i++] = e;
2.263 + }
2.264 + } catch (ArrayIndexOutOfBoundsException ex) {
2.265 + throw new IllegalArgumentException();
2.266 + }
2.267 + count = i;
2.268 + putIndex = (i == capacity) ? 0 : i;
2.269 + } finally {
2.270 + lock.unlock();
2.271 + }
2.272 + }
2.273 +
2.274 + /**
2.275 + * Inserts the specified element at the tail of this queue if it is
2.276 + * possible to do so immediately without exceeding the queue's capacity,
2.277 + * returning {@code true} upon success and throwing an
2.278 + * {@code IllegalStateException} if this queue is full.
2.279 + *
2.280 + * @param e the element to add
2.281 + * @return {@code true} (as specified by {@link Collection#add})
2.282 + * @throws IllegalStateException if this queue is full
2.283 + * @throws NullPointerException if the specified element is null
2.284 + */
2.285 + public boolean add(E e) {
2.286 + return super.add(e);
2.287 + }
2.288 +
2.289 + /**
2.290 + * Inserts the specified element at the tail of this queue if it is
2.291 + * possible to do so immediately without exceeding the queue's capacity,
2.292 + * returning {@code true} upon success and {@code false} if this queue
2.293 + * is full. This method is generally preferable to method {@link #add},
2.294 + * which can fail to insert an element only by throwing an exception.
2.295 + *
2.296 + * @throws NullPointerException if the specified element is null
2.297 + */
2.298 + public boolean offer(E e) {
2.299 + checkNotNull(e);
2.300 + final ReentrantLock lock = this.lock;
2.301 + lock.lock();
2.302 + try {
2.303 + if (count == items.length)
2.304 + return false;
2.305 + else {
2.306 + insert(e);
2.307 + return true;
2.308 + }
2.309 + } finally {
2.310 + lock.unlock();
2.311 + }
2.312 + }
2.313 +
2.314 + /**
2.315 + * Inserts the specified element at the tail of this queue, waiting
2.316 + * for space to become available if the queue is full.
2.317 + *
2.318 + * @throws InterruptedException {@inheritDoc}
2.319 + * @throws NullPointerException {@inheritDoc}
2.320 + */
2.321 + public void put(E e) throws InterruptedException {
2.322 + checkNotNull(e);
2.323 + final ReentrantLock lock = this.lock;
2.324 + lock.lockInterruptibly();
2.325 + try {
2.326 + while (count == items.length)
2.327 + notFull.await();
2.328 + insert(e);
2.329 + } finally {
2.330 + lock.unlock();
2.331 + }
2.332 + }
2.333 +
2.334 + /**
2.335 + * Inserts the specified element at the tail of this queue, waiting
2.336 + * up to the specified wait time for space to become available if
2.337 + * the queue is full.
2.338 + *
2.339 + * @throws InterruptedException {@inheritDoc}
2.340 + * @throws NullPointerException {@inheritDoc}
2.341 + */
2.342 + public boolean offer(E e, long timeout, TimeUnit unit)
2.343 + throws InterruptedException {
2.344 +
2.345 + checkNotNull(e);
2.346 + long nanos = unit.toNanos(timeout);
2.347 + final ReentrantLock lock = this.lock;
2.348 + lock.lockInterruptibly();
2.349 + try {
2.350 + while (count == items.length) {
2.351 + if (nanos <= 0)
2.352 + return false;
2.353 + nanos = notFull.awaitNanos(nanos);
2.354 + }
2.355 + insert(e);
2.356 + return true;
2.357 + } finally {
2.358 + lock.unlock();
2.359 + }
2.360 + }
2.361 +
2.362 + public E poll() {
2.363 + final ReentrantLock lock = this.lock;
2.364 + lock.lock();
2.365 + try {
2.366 + return (count == 0) ? null : extract();
2.367 + } finally {
2.368 + lock.unlock();
2.369 + }
2.370 + }
2.371 +
2.372 + public E take() throws InterruptedException {
2.373 + final ReentrantLock lock = this.lock;
2.374 + lock.lockInterruptibly();
2.375 + try {
2.376 + while (count == 0)
2.377 + notEmpty.await();
2.378 + return extract();
2.379 + } finally {
2.380 + lock.unlock();
2.381 + }
2.382 + }
2.383 +
2.384 + public E poll(long timeout, TimeUnit unit) throws InterruptedException {
2.385 + long nanos = unit.toNanos(timeout);
2.386 + final ReentrantLock lock = this.lock;
2.387 + lock.lockInterruptibly();
2.388 + try {
2.389 + while (count == 0) {
2.390 + if (nanos <= 0)
2.391 + return null;
2.392 + nanos = notEmpty.awaitNanos(nanos);
2.393 + }
2.394 + return extract();
2.395 + } finally {
2.396 + lock.unlock();
2.397 + }
2.398 + }
2.399 +
2.400 + public E peek() {
2.401 + final ReentrantLock lock = this.lock;
2.402 + lock.lock();
2.403 + try {
2.404 + return (count == 0) ? null : itemAt(takeIndex);
2.405 + } finally {
2.406 + lock.unlock();
2.407 + }
2.408 + }
2.409 +
2.410 + // this doc comment is overridden to remove the reference to collections
2.411 + // greater in size than Integer.MAX_VALUE
2.412 + /**
2.413 + * Returns the number of elements in this queue.
2.414 + *
2.415 + * @return the number of elements in this queue
2.416 + */
2.417 + public int size() {
2.418 + final ReentrantLock lock = this.lock;
2.419 + lock.lock();
2.420 + try {
2.421 + return count;
2.422 + } finally {
2.423 + lock.unlock();
2.424 + }
2.425 + }
2.426 +
2.427 + // this doc comment is a modified copy of the inherited doc comment,
2.428 + // without the reference to unlimited queues.
2.429 + /**
2.430 + * Returns the number of additional elements that this queue can ideally
2.431 + * (in the absence of memory or resource constraints) accept without
2.432 + * blocking. This is always equal to the initial capacity of this queue
2.433 + * less the current {@code size} of this queue.
2.434 + *
2.435 + * <p>Note that you <em>cannot</em> always tell if an attempt to insert
2.436 + * an element will succeed by inspecting {@code remainingCapacity}
2.437 + * because it may be the case that another thread is about to
2.438 + * insert or remove an element.
2.439 + */
2.440 + public int remainingCapacity() {
2.441 + final ReentrantLock lock = this.lock;
2.442 + lock.lock();
2.443 + try {
2.444 + return items.length - count;
2.445 + } finally {
2.446 + lock.unlock();
2.447 + }
2.448 + }
2.449 +
2.450 + /**
2.451 + * Removes a single instance of the specified element from this queue,
2.452 + * if it is present. More formally, removes an element {@code e} such
2.453 + * that {@code o.equals(e)}, if this queue contains one or more such
2.454 + * elements.
2.455 + * Returns {@code true} if this queue contained the specified element
2.456 + * (or equivalently, if this queue changed as a result of the call).
2.457 + *
2.458 + * <p>Removal of interior elements in circular array based queues
2.459 + * is an intrinsically slow and disruptive operation, so should
2.460 + * be undertaken only in exceptional circumstances, ideally
2.461 + * only when the queue is known not to be accessible by other
2.462 + * threads.
2.463 + *
2.464 + * @param o element to be removed from this queue, if present
2.465 + * @return {@code true} if this queue changed as a result of the call
2.466 + */
2.467 + public boolean remove(Object o) {
2.468 + if (o == null) return false;
2.469 + final Object[] items = this.items;
2.470 + final ReentrantLock lock = this.lock;
2.471 + lock.lock();
2.472 + try {
2.473 + for (int i = takeIndex, k = count; k > 0; i = inc(i), k--) {
2.474 + if (o.equals(items[i])) {
2.475 + removeAt(i);
2.476 + return true;
2.477 + }
2.478 + }
2.479 + return false;
2.480 + } finally {
2.481 + lock.unlock();
2.482 + }
2.483 + }
2.484 +
2.485 + /**
2.486 + * Returns {@code true} if this queue contains the specified element.
2.487 + * More formally, returns {@code true} if and only if this queue contains
2.488 + * at least one element {@code e} such that {@code o.equals(e)}.
2.489 + *
2.490 + * @param o object to be checked for containment in this queue
2.491 + * @return {@code true} if this queue contains the specified element
2.492 + */
2.493 + public boolean contains(Object o) {
2.494 + if (o == null) return false;
2.495 + final Object[] items = this.items;
2.496 + final ReentrantLock lock = this.lock;
2.497 + lock.lock();
2.498 + try {
2.499 + for (int i = takeIndex, k = count; k > 0; i = inc(i), k--)
2.500 + if (o.equals(items[i]))
2.501 + return true;
2.502 + return false;
2.503 + } finally {
2.504 + lock.unlock();
2.505 + }
2.506 + }
2.507 +
2.508 + /**
2.509 + * Returns an array containing all of the elements in this queue, in
2.510 + * proper sequence.
2.511 + *
2.512 + * <p>The returned array will be "safe" in that no references to it are
2.513 + * maintained by this queue. (In other words, this method must allocate
2.514 + * a new array). The caller is thus free to modify the returned array.
2.515 + *
2.516 + * <p>This method acts as bridge between array-based and collection-based
2.517 + * APIs.
2.518 + *
2.519 + * @return an array containing all of the elements in this queue
2.520 + */
2.521 + public Object[] toArray() {
2.522 + final Object[] items = this.items;
2.523 + final ReentrantLock lock = this.lock;
2.524 + lock.lock();
2.525 + try {
2.526 + final int count = this.count;
2.527 + Object[] a = new Object[count];
2.528 + for (int i = takeIndex, k = 0; k < count; i = inc(i), k++)
2.529 + a[k] = items[i];
2.530 + return a;
2.531 + } finally {
2.532 + lock.unlock();
2.533 + }
2.534 + }
2.535 +
2.536 + /**
2.537 + * Returns an array containing all of the elements in this queue, in
2.538 + * proper sequence; the runtime type of the returned array is that of
2.539 + * the specified array. If the queue fits in the specified array, it
2.540 + * is returned therein. Otherwise, a new array is allocated with the
2.541 + * runtime type of the specified array and the size of this queue.
2.542 + *
2.543 + * <p>If this queue fits in the specified array with room to spare
2.544 + * (i.e., the array has more elements than this queue), the element in
2.545 + * the array immediately following the end of the queue is set to
2.546 + * {@code null}.
2.547 + *
2.548 + * <p>Like the {@link #toArray()} method, this method acts as bridge between
2.549 + * array-based and collection-based APIs. Further, this method allows
2.550 + * precise control over the runtime type of the output array, and may,
2.551 + * under certain circumstances, be used to save allocation costs.
2.552 + *
2.553 + * <p>Suppose {@code x} is a queue known to contain only strings.
2.554 + * The following code can be used to dump the queue into a newly
2.555 + * allocated array of {@code String}:
2.556 + *
2.557 + * <pre>
2.558 + * String[] y = x.toArray(new String[0]);</pre>
2.559 + *
2.560 + * Note that {@code toArray(new Object[0])} is identical in function to
2.561 + * {@code toArray()}.
2.562 + *
2.563 + * @param a the array into which the elements of the queue are to
2.564 + * be stored, if it is big enough; otherwise, a new array of the
2.565 + * same runtime type is allocated for this purpose
2.566 + * @return an array containing all of the elements in this queue
2.567 + * @throws ArrayStoreException if the runtime type of the specified array
2.568 + * is not a supertype of the runtime type of every element in
2.569 + * this queue
2.570 + * @throws NullPointerException if the specified array is null
2.571 + */
2.572 + @SuppressWarnings("unchecked")
2.573 + public <T> T[] toArray(T[] a) {
2.574 + final Object[] items = this.items;
2.575 + final ReentrantLock lock = this.lock;
2.576 + lock.lock();
2.577 + try {
2.578 + final int count = this.count;
2.579 + final int len = a.length;
2.580 + if (len < count)
2.581 + a = (T[])java.lang.reflect.Array.newInstance(
2.582 + a.getClass().getComponentType(), count);
2.583 + for (int i = takeIndex, k = 0; k < count; i = inc(i), k++)
2.584 + a[k] = (T) items[i];
2.585 + if (len > count)
2.586 + a[count] = null;
2.587 + return a;
2.588 + } finally {
2.589 + lock.unlock();
2.590 + }
2.591 + }
2.592 +
2.593 + public String toString() {
2.594 + final ReentrantLock lock = this.lock;
2.595 + lock.lock();
2.596 + try {
2.597 + int k = count;
2.598 + if (k == 0)
2.599 + return "[]";
2.600 +
2.601 + StringBuilder sb = new StringBuilder();
2.602 + sb.append('[');
2.603 + for (int i = takeIndex; ; i = inc(i)) {
2.604 + Object e = items[i];
2.605 + sb.append(e == this ? "(this Collection)" : e);
2.606 + if (--k == 0)
2.607 + return sb.append(']').toString();
2.608 + sb.append(',').append(' ');
2.609 + }
2.610 + } finally {
2.611 + lock.unlock();
2.612 + }
2.613 + }
2.614 +
2.615 + /**
2.616 + * Atomically removes all of the elements from this queue.
2.617 + * The queue will be empty after this call returns.
2.618 + */
2.619 + public void clear() {
2.620 + final Object[] items = this.items;
2.621 + final ReentrantLock lock = this.lock;
2.622 + lock.lock();
2.623 + try {
2.624 + for (int i = takeIndex, k = count; k > 0; i = inc(i), k--)
2.625 + items[i] = null;
2.626 + count = 0;
2.627 + putIndex = 0;
2.628 + takeIndex = 0;
2.629 + notFull.signalAll();
2.630 + } finally {
2.631 + lock.unlock();
2.632 + }
2.633 + }
2.634 +
2.635 + /**
2.636 + * @throws UnsupportedOperationException {@inheritDoc}
2.637 + * @throws ClassCastException {@inheritDoc}
2.638 + * @throws NullPointerException {@inheritDoc}
2.639 + * @throws IllegalArgumentException {@inheritDoc}
2.640 + */
2.641 + public int drainTo(Collection<? super E> c) {
2.642 + checkNotNull(c);
2.643 + if (c == this)
2.644 + throw new IllegalArgumentException();
2.645 + final Object[] items = this.items;
2.646 + final ReentrantLock lock = this.lock;
2.647 + lock.lock();
2.648 + try {
2.649 + int i = takeIndex;
2.650 + int n = 0;
2.651 + int max = count;
2.652 + while (n < max) {
2.653 + c.add(this.<E>cast(items[i]));
2.654 + items[i] = null;
2.655 + i = inc(i);
2.656 + ++n;
2.657 + }
2.658 + if (n > 0) {
2.659 + count = 0;
2.660 + putIndex = 0;
2.661 + takeIndex = 0;
2.662 + notFull.signalAll();
2.663 + }
2.664 + return n;
2.665 + } finally {
2.666 + lock.unlock();
2.667 + }
2.668 + }
2.669 +
2.670 + /**
2.671 + * @throws UnsupportedOperationException {@inheritDoc}
2.672 + * @throws ClassCastException {@inheritDoc}
2.673 + * @throws NullPointerException {@inheritDoc}
2.674 + * @throws IllegalArgumentException {@inheritDoc}
2.675 + */
2.676 + public int drainTo(Collection<? super E> c, int maxElements) {
2.677 + checkNotNull(c);
2.678 + if (c == this)
2.679 + throw new IllegalArgumentException();
2.680 + if (maxElements <= 0)
2.681 + return 0;
2.682 + final Object[] items = this.items;
2.683 + final ReentrantLock lock = this.lock;
2.684 + lock.lock();
2.685 + try {
2.686 + int i = takeIndex;
2.687 + int n = 0;
2.688 + int max = (maxElements < count) ? maxElements : count;
2.689 + while (n < max) {
2.690 + c.add(this.<E>cast(items[i]));
2.691 + items[i] = null;
2.692 + i = inc(i);
2.693 + ++n;
2.694 + }
2.695 + if (n > 0) {
2.696 + count -= n;
2.697 + takeIndex = i;
2.698 + notFull.signalAll();
2.699 + }
2.700 + return n;
2.701 + } finally {
2.702 + lock.unlock();
2.703 + }
2.704 + }
2.705 +
2.706 + /**
2.707 + * Returns an iterator over the elements in this queue in proper sequence.
2.708 + * The elements will be returned in order from first (head) to last (tail).
2.709 + *
2.710 + * <p>The returned {@code Iterator} is a "weakly consistent" iterator that
2.711 + * will never throw {@link java.util.ConcurrentModificationException
2.712 + * ConcurrentModificationException},
2.713 + * and guarantees to traverse elements as they existed upon
2.714 + * construction of the iterator, and may (but is not guaranteed to)
2.715 + * reflect any modifications subsequent to construction.
2.716 + *
2.717 + * @return an iterator over the elements in this queue in proper sequence
2.718 + */
2.719 + public Iterator<E> iterator() {
2.720 + return new Itr();
2.721 + }
2.722 +
2.723 + /**
2.724 + * Iterator for ArrayBlockingQueue. To maintain weak consistency
2.725 + * with respect to puts and takes, we (1) read ahead one slot, so
2.726 + * as to not report hasNext true but then not have an element to
2.727 + * return -- however we later recheck this slot to use the most
2.728 + * current value; (2) ensure that each array slot is traversed at
2.729 + * most once (by tracking "remaining" elements); (3) skip over
2.730 + * null slots, which can occur if takes race ahead of iterators.
2.731 + * However, for circular array-based queues, we cannot rely on any
2.732 + * well established definition of what it means to be weakly
2.733 + * consistent with respect to interior removes since these may
2.734 + * require slot overwrites in the process of sliding elements to
2.735 + * cover gaps. So we settle for resiliency, operating on
2.736 + * established apparent nexts, which may miss some elements that
2.737 + * have moved between calls to next.
2.738 + */
2.739 + private class Itr implements Iterator<E> {
2.740 + private int remaining; // Number of elements yet to be returned
2.741 + private int nextIndex; // Index of element to be returned by next
2.742 + private E nextItem; // Element to be returned by next call to next
2.743 + private E lastItem; // Element returned by last call to next
2.744 + private int lastRet; // Index of last element returned, or -1 if none
2.745 +
2.746 + Itr() {
2.747 + final ReentrantLock lock = ArrayBlockingQueue.this.lock;
2.748 + lock.lock();
2.749 + try {
2.750 + lastRet = -1;
2.751 + if ((remaining = count) > 0)
2.752 + nextItem = itemAt(nextIndex = takeIndex);
2.753 + } finally {
2.754 + lock.unlock();
2.755 + }
2.756 + }
2.757 +
2.758 + public boolean hasNext() {
2.759 + return remaining > 0;
2.760 + }
2.761 +
2.762 + public E next() {
2.763 + final ReentrantLock lock = ArrayBlockingQueue.this.lock;
2.764 + lock.lock();
2.765 + try {
2.766 + if (remaining <= 0)
2.767 + throw new NoSuchElementException();
2.768 + lastRet = nextIndex;
2.769 + E x = itemAt(nextIndex); // check for fresher value
2.770 + if (x == null) {
2.771 + x = nextItem; // we are forced to report old value
2.772 + lastItem = null; // but ensure remove fails
2.773 + }
2.774 + else
2.775 + lastItem = x;
2.776 + while (--remaining > 0 && // skip over nulls
2.777 + (nextItem = itemAt(nextIndex = inc(nextIndex))) == null)
2.778 + ;
2.779 + return x;
2.780 + } finally {
2.781 + lock.unlock();
2.782 + }
2.783 + }
2.784 +
2.785 + public void remove() {
2.786 + final ReentrantLock lock = ArrayBlockingQueue.this.lock;
2.787 + lock.lock();
2.788 + try {
2.789 + int i = lastRet;
2.790 + if (i == -1)
2.791 + throw new IllegalStateException();
2.792 + lastRet = -1;
2.793 + E x = lastItem;
2.794 + lastItem = null;
2.795 + // only remove if item still at index
2.796 + if (x != null && x == items[i]) {
2.797 + boolean removingHead = (i == takeIndex);
2.798 + removeAt(i);
2.799 + if (!removingHead)
2.800 + nextIndex = dec(nextIndex);
2.801 + }
2.802 + } finally {
2.803 + lock.unlock();
2.804 + }
2.805 + }
2.806 + }
2.807 +
2.808 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/BlockingDeque.java Sat Mar 19 10:48:29 2016 +0100
3.3 @@ -0,0 +1,650 @@
3.4 +/*
3.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3.6 + *
3.7 + * This code is free software; you can redistribute it and/or modify it
3.8 + * under the terms of the GNU General Public License version 2 only, as
3.9 + * published by the Free Software Foundation. Oracle designates this
3.10 + * particular file as subject to the "Classpath" exception as provided
3.11 + * by Oracle in the LICENSE file that accompanied this code.
3.12 + *
3.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
3.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
3.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3.16 + * version 2 for more details (a copy is included in the LICENSE file that
3.17 + * accompanied this code).
3.18 + *
3.19 + * You should have received a copy of the GNU General Public License version
3.20 + * 2 along with this work; if not, write to the Free Software Foundation,
3.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
3.22 + *
3.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
3.24 + * or visit www.oracle.com if you need additional information or have any
3.25 + * questions.
3.26 + */
3.27 +
3.28 +/*
3.29 + * This file is available under and governed by the GNU General Public
3.30 + * License version 2 only, as published by the Free Software Foundation.
3.31 + * However, the following notice accompanied the original version of this
3.32 + * file:
3.33 + *
3.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
3.35 + * Expert Group and released to the public domain, as explained at
3.36 + * http://creativecommons.org/publicdomain/zero/1.0/
3.37 + */
3.38 +
3.39 +package java.util.concurrent;
3.40 +import java.util.*;
3.41 +
3.42 +/**
3.43 + * A {@link Deque} that additionally supports blocking operations that wait
3.44 + * for the deque to become non-empty when retrieving an element, and wait for
3.45 + * space to become available in the deque when storing an element.
3.46 + *
3.47 + * <p><tt>BlockingDeque</tt> methods come in four forms, with different ways
3.48 + * of handling operations that cannot be satisfied immediately, but may be
3.49 + * satisfied at some point in the future:
3.50 + * one throws an exception, the second returns a special value (either
3.51 + * <tt>null</tt> or <tt>false</tt>, depending on the operation), the third
3.52 + * blocks the current thread indefinitely until the operation can succeed,
3.53 + * and the fourth blocks for only a given maximum time limit before giving
3.54 + * up. These methods are summarized in the following table:
3.55 + *
3.56 + * <p>
3.57 + * <table BORDER CELLPADDING=3 CELLSPACING=1>
3.58 + * <tr>
3.59 + * <td ALIGN=CENTER COLSPAN = 5> <b>First Element (Head)</b></td>
3.60 + * </tr>
3.61 + * <tr>
3.62 + * <td></td>
3.63 + * <td ALIGN=CENTER><em>Throws exception</em></td>
3.64 + * <td ALIGN=CENTER><em>Special value</em></td>
3.65 + * <td ALIGN=CENTER><em>Blocks</em></td>
3.66 + * <td ALIGN=CENTER><em>Times out</em></td>
3.67 + * </tr>
3.68 + * <tr>
3.69 + * <td><b>Insert</b></td>
3.70 + * <td>{@link #addFirst addFirst(e)}</td>
3.71 + * <td>{@link #offerFirst(Object) offerFirst(e)}</td>
3.72 + * <td>{@link #putFirst putFirst(e)}</td>
3.73 + * <td>{@link #offerFirst(Object, long, TimeUnit) offerFirst(e, time, unit)}</td>
3.74 + * </tr>
3.75 + * <tr>
3.76 + * <td><b>Remove</b></td>
3.77 + * <td>{@link #removeFirst removeFirst()}</td>
3.78 + * <td>{@link #pollFirst pollFirst()}</td>
3.79 + * <td>{@link #takeFirst takeFirst()}</td>
3.80 + * <td>{@link #pollFirst(long, TimeUnit) pollFirst(time, unit)}</td>
3.81 + * </tr>
3.82 + * <tr>
3.83 + * <td><b>Examine</b></td>
3.84 + * <td>{@link #getFirst getFirst()}</td>
3.85 + * <td>{@link #peekFirst peekFirst()}</td>
3.86 + * <td><em>not applicable</em></td>
3.87 + * <td><em>not applicable</em></td>
3.88 + * </tr>
3.89 + * <tr>
3.90 + * <td ALIGN=CENTER COLSPAN = 5> <b>Last Element (Tail)</b></td>
3.91 + * </tr>
3.92 + * <tr>
3.93 + * <td></td>
3.94 + * <td ALIGN=CENTER><em>Throws exception</em></td>
3.95 + * <td ALIGN=CENTER><em>Special value</em></td>
3.96 + * <td ALIGN=CENTER><em>Blocks</em></td>
3.97 + * <td ALIGN=CENTER><em>Times out</em></td>
3.98 + * </tr>
3.99 + * <tr>
3.100 + * <td><b>Insert</b></td>
3.101 + * <td>{@link #addLast addLast(e)}</td>
3.102 + * <td>{@link #offerLast(Object) offerLast(e)}</td>
3.103 + * <td>{@link #putLast putLast(e)}</td>
3.104 + * <td>{@link #offerLast(Object, long, TimeUnit) offerLast(e, time, unit)}</td>
3.105 + * </tr>
3.106 + * <tr>
3.107 + * <td><b>Remove</b></td>
3.108 + * <td>{@link #removeLast() removeLast()}</td>
3.109 + * <td>{@link #pollLast() pollLast()}</td>
3.110 + * <td>{@link #takeLast takeLast()}</td>
3.111 + * <td>{@link #pollLast(long, TimeUnit) pollLast(time, unit)}</td>
3.112 + * </tr>
3.113 + * <tr>
3.114 + * <td><b>Examine</b></td>
3.115 + * <td>{@link #getLast getLast()}</td>
3.116 + * <td>{@link #peekLast peekLast()}</td>
3.117 + * <td><em>not applicable</em></td>
3.118 + * <td><em>not applicable</em></td>
3.119 + * </tr>
3.120 + * </table>
3.121 + *
3.122 + * <p>Like any {@link BlockingQueue}, a <tt>BlockingDeque</tt> is thread safe,
3.123 + * does not permit null elements, and may (or may not) be
3.124 + * capacity-constrained.
3.125 + *
3.126 + * <p>A <tt>BlockingDeque</tt> implementation may be used directly as a FIFO
3.127 + * <tt>BlockingQueue</tt>. The methods inherited from the
3.128 + * <tt>BlockingQueue</tt> interface are precisely equivalent to
3.129 + * <tt>BlockingDeque</tt> methods as indicated in the following table:
3.130 + *
3.131 + * <p>
3.132 + * <table BORDER CELLPADDING=3 CELLSPACING=1>
3.133 + * <tr>
3.134 + * <td ALIGN=CENTER> <b><tt>BlockingQueue</tt> Method</b></td>
3.135 + * <td ALIGN=CENTER> <b>Equivalent <tt>BlockingDeque</tt> Method</b></td>
3.136 + * </tr>
3.137 + * <tr>
3.138 + * <td ALIGN=CENTER COLSPAN = 2> <b>Insert</b></td>
3.139 + * </tr>
3.140 + * <tr>
3.141 + * <td>{@link #add(Object) add(e)}</td>
3.142 + * <td>{@link #addLast(Object) addLast(e)}</td>
3.143 + * </tr>
3.144 + * <tr>
3.145 + * <td>{@link #offer(Object) offer(e)}</td>
3.146 + * <td>{@link #offerLast(Object) offerLast(e)}</td>
3.147 + * </tr>
3.148 + * <tr>
3.149 + * <td>{@link #put(Object) put(e)}</td>
3.150 + * <td>{@link #putLast(Object) putLast(e)}</td>
3.151 + * </tr>
3.152 + * <tr>
3.153 + * <td>{@link #offer(Object, long, TimeUnit) offer(e, time, unit)}</td>
3.154 + * <td>{@link #offerLast(Object, long, TimeUnit) offerLast(e, time, unit)}</td>
3.155 + * </tr>
3.156 + * <tr>
3.157 + * <td ALIGN=CENTER COLSPAN = 2> <b>Remove</b></td>
3.158 + * </tr>
3.159 + * <tr>
3.160 + * <td>{@link #remove() remove()}</td>
3.161 + * <td>{@link #removeFirst() removeFirst()}</td>
3.162 + * </tr>
3.163 + * <tr>
3.164 + * <td>{@link #poll() poll()}</td>
3.165 + * <td>{@link #pollFirst() pollFirst()}</td>
3.166 + * </tr>
3.167 + * <tr>
3.168 + * <td>{@link #take() take()}</td>
3.169 + * <td>{@link #takeFirst() takeFirst()}</td>
3.170 + * </tr>
3.171 + * <tr>
3.172 + * <td>{@link #poll(long, TimeUnit) poll(time, unit)}</td>
3.173 + * <td>{@link #pollFirst(long, TimeUnit) pollFirst(time, unit)}</td>
3.174 + * </tr>
3.175 + * <tr>
3.176 + * <td ALIGN=CENTER COLSPAN = 2> <b>Examine</b></td>
3.177 + * </tr>
3.178 + * <tr>
3.179 + * <td>{@link #element() element()}</td>
3.180 + * <td>{@link #getFirst() getFirst()}</td>
3.181 + * </tr>
3.182 + * <tr>
3.183 + * <td>{@link #peek() peek()}</td>
3.184 + * <td>{@link #peekFirst() peekFirst()}</td>
3.185 + * </tr>
3.186 + * </table>
3.187 + *
3.188 + * <p>Memory consistency effects: As with other concurrent
3.189 + * collections, actions in a thread prior to placing an object into a
3.190 + * {@code BlockingDeque}
3.191 + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
3.192 + * actions subsequent to the access or removal of that element from
3.193 + * the {@code BlockingDeque} in another thread.
3.194 + *
3.195 + * <p>This interface is a member of the
3.196 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
3.197 + * Java Collections Framework</a>.
3.198 + *
3.199 + * @since 1.6
3.200 + * @author Doug Lea
3.201 + * @param <E> the type of elements held in this collection
3.202 + */
3.203 +public interface BlockingDeque<E> extends BlockingQueue<E>, Deque<E> {
3.204 + /*
3.205 + * We have "diamond" multiple interface inheritance here, and that
3.206 + * introduces ambiguities. Methods might end up with different
3.207 + * specs depending on the branch chosen by javadoc. Thus a lot of
3.208 + * methods specs here are copied from superinterfaces.
3.209 + */
3.210 +
3.211 + /**
3.212 + * Inserts the specified element at the front of this deque if it is
3.213 + * possible to do so immediately without violating capacity restrictions,
3.214 + * throwing an <tt>IllegalStateException</tt> if no space is currently
3.215 + * available. When using a capacity-restricted deque, it is generally
3.216 + * preferable to use {@link #offerFirst(Object) offerFirst}.
3.217 + *
3.218 + * @param e the element to add
3.219 + * @throws IllegalStateException {@inheritDoc}
3.220 + * @throws ClassCastException {@inheritDoc}
3.221 + * @throws NullPointerException if the specified element is null
3.222 + * @throws IllegalArgumentException {@inheritDoc}
3.223 + */
3.224 + void addFirst(E e);
3.225 +
3.226 + /**
3.227 + * Inserts the specified element at the end of this deque if it is
3.228 + * possible to do so immediately without violating capacity restrictions,
3.229 + * throwing an <tt>IllegalStateException</tt> if no space is currently
3.230 + * available. When using a capacity-restricted deque, it is generally
3.231 + * preferable to use {@link #offerLast(Object) offerLast}.
3.232 + *
3.233 + * @param e the element to add
3.234 + * @throws IllegalStateException {@inheritDoc}
3.235 + * @throws ClassCastException {@inheritDoc}
3.236 + * @throws NullPointerException if the specified element is null
3.237 + * @throws IllegalArgumentException {@inheritDoc}
3.238 + */
3.239 + void addLast(E e);
3.240 +
3.241 + /**
3.242 + * Inserts the specified element at the front of this deque if it is
3.243 + * possible to do so immediately without violating capacity restrictions,
3.244 + * returning <tt>true</tt> upon success and <tt>false</tt> if no space is
3.245 + * currently available.
3.246 + * When using a capacity-restricted deque, this method is generally
3.247 + * preferable to the {@link #addFirst(Object) addFirst} method, which can
3.248 + * fail to insert an element only by throwing an exception.
3.249 + *
3.250 + * @param e the element to add
3.251 + * @throws ClassCastException {@inheritDoc}
3.252 + * @throws NullPointerException if the specified element is null
3.253 + * @throws IllegalArgumentException {@inheritDoc}
3.254 + */
3.255 + boolean offerFirst(E e);
3.256 +
3.257 + /**
3.258 + * Inserts the specified element at the end of this deque if it is
3.259 + * possible to do so immediately without violating capacity restrictions,
3.260 + * returning <tt>true</tt> upon success and <tt>false</tt> if no space is
3.261 + * currently available.
3.262 + * When using a capacity-restricted deque, this method is generally
3.263 + * preferable to the {@link #addLast(Object) addLast} method, which can
3.264 + * fail to insert an element only by throwing an exception.
3.265 + *
3.266 + * @param e the element to add
3.267 + * @throws ClassCastException {@inheritDoc}
3.268 + * @throws NullPointerException if the specified element is null
3.269 + * @throws IllegalArgumentException {@inheritDoc}
3.270 + */
3.271 + boolean offerLast(E e);
3.272 +
3.273 + /**
3.274 + * Inserts the specified element at the front of this deque,
3.275 + * waiting if necessary for space to become available.
3.276 + *
3.277 + * @param e the element to add
3.278 + * @throws InterruptedException if interrupted while waiting
3.279 + * @throws ClassCastException if the class of the specified element
3.280 + * prevents it from being added to this deque
3.281 + * @throws NullPointerException if the specified element is null
3.282 + * @throws IllegalArgumentException if some property of the specified
3.283 + * element prevents it from being added to this deque
3.284 + */
3.285 + void putFirst(E e) throws InterruptedException;
3.286 +
3.287 + /**
3.288 + * Inserts the specified element at the end of this deque,
3.289 + * waiting if necessary for space to become available.
3.290 + *
3.291 + * @param e the element to add
3.292 + * @throws InterruptedException if interrupted while waiting
3.293 + * @throws ClassCastException if the class of the specified element
3.294 + * prevents it from being added to this deque
3.295 + * @throws NullPointerException if the specified element is null
3.296 + * @throws IllegalArgumentException if some property of the specified
3.297 + * element prevents it from being added to this deque
3.298 + */
3.299 + void putLast(E e) throws InterruptedException;
3.300 +
3.301 + /**
3.302 + * Inserts the specified element at the front of this deque,
3.303 + * waiting up to the specified wait time if necessary for space to
3.304 + * become available.
3.305 + *
3.306 + * @param e the element to add
3.307 + * @param timeout how long to wait before giving up, in units of
3.308 + * <tt>unit</tt>
3.309 + * @param unit a <tt>TimeUnit</tt> determining how to interpret the
3.310 + * <tt>timeout</tt> parameter
3.311 + * @return <tt>true</tt> if successful, or <tt>false</tt> if
3.312 + * the specified waiting time elapses before space is available
3.313 + * @throws InterruptedException if interrupted while waiting
3.314 + * @throws ClassCastException if the class of the specified element
3.315 + * prevents it from being added to this deque
3.316 + * @throws NullPointerException if the specified element is null
3.317 + * @throws IllegalArgumentException if some property of the specified
3.318 + * element prevents it from being added to this deque
3.319 + */
3.320 + boolean offerFirst(E e, long timeout, TimeUnit unit)
3.321 + throws InterruptedException;
3.322 +
3.323 + /**
3.324 + * Inserts the specified element at the end of this deque,
3.325 + * waiting up to the specified wait time if necessary for space to
3.326 + * become available.
3.327 + *
3.328 + * @param e the element to add
3.329 + * @param timeout how long to wait before giving up, in units of
3.330 + * <tt>unit</tt>
3.331 + * @param unit a <tt>TimeUnit</tt> determining how to interpret the
3.332 + * <tt>timeout</tt> parameter
3.333 + * @return <tt>true</tt> if successful, or <tt>false</tt> if
3.334 + * the specified waiting time elapses before space is available
3.335 + * @throws InterruptedException if interrupted while waiting
3.336 + * @throws ClassCastException if the class of the specified element
3.337 + * prevents it from being added to this deque
3.338 + * @throws NullPointerException if the specified element is null
3.339 + * @throws IllegalArgumentException if some property of the specified
3.340 + * element prevents it from being added to this deque
3.341 + */
3.342 + boolean offerLast(E e, long timeout, TimeUnit unit)
3.343 + throws InterruptedException;
3.344 +
3.345 + /**
3.346 + * Retrieves and removes the first element of this deque, waiting
3.347 + * if necessary until an element becomes available.
3.348 + *
3.349 + * @return the head of this deque
3.350 + * @throws InterruptedException if interrupted while waiting
3.351 + */
3.352 + E takeFirst() throws InterruptedException;
3.353 +
3.354 + /**
3.355 + * Retrieves and removes the last element of this deque, waiting
3.356 + * if necessary until an element becomes available.
3.357 + *
3.358 + * @return the tail of this deque
3.359 + * @throws InterruptedException if interrupted while waiting
3.360 + */
3.361 + E takeLast() throws InterruptedException;
3.362 +
3.363 + /**
3.364 + * Retrieves and removes the first element of this deque, waiting
3.365 + * up to the specified wait time if necessary for an element to
3.366 + * become available.
3.367 + *
3.368 + * @param timeout how long to wait before giving up, in units of
3.369 + * <tt>unit</tt>
3.370 + * @param unit a <tt>TimeUnit</tt> determining how to interpret the
3.371 + * <tt>timeout</tt> parameter
3.372 + * @return the head of this deque, or <tt>null</tt> if the specified
3.373 + * waiting time elapses before an element is available
3.374 + * @throws InterruptedException if interrupted while waiting
3.375 + */
3.376 + E pollFirst(long timeout, TimeUnit unit)
3.377 + throws InterruptedException;
3.378 +
3.379 + /**
3.380 + * Retrieves and removes the last element of this deque, waiting
3.381 + * up to the specified wait time if necessary for an element to
3.382 + * become available.
3.383 + *
3.384 + * @param timeout how long to wait before giving up, in units of
3.385 + * <tt>unit</tt>
3.386 + * @param unit a <tt>TimeUnit</tt> determining how to interpret the
3.387 + * <tt>timeout</tt> parameter
3.388 + * @return the tail of this deque, or <tt>null</tt> if the specified
3.389 + * waiting time elapses before an element is available
3.390 + * @throws InterruptedException if interrupted while waiting
3.391 + */
3.392 + E pollLast(long timeout, TimeUnit unit)
3.393 + throws InterruptedException;
3.394 +
3.395 + /**
3.396 + * Removes the first occurrence of the specified element from this deque.
3.397 + * If the deque does not contain the element, it is unchanged.
3.398 + * More formally, removes the first element <tt>e</tt> such that
3.399 + * <tt>o.equals(e)</tt> (if such an element exists).
3.400 + * Returns <tt>true</tt> if this deque contained the specified element
3.401 + * (or equivalently, if this deque changed as a result of the call).
3.402 + *
3.403 + * @param o element to be removed from this deque, if present
3.404 + * @return <tt>true</tt> if an element was removed as a result of this call
3.405 + * @throws ClassCastException if the class of the specified element
3.406 + * is incompatible with this deque
3.407 + * (<a href="../Collection.html#optional-restrictions">optional</a>)
3.408 + * @throws NullPointerException if the specified element is null
3.409 + * (<a href="../Collection.html#optional-restrictions">optional</a>)
3.410 + */
3.411 + boolean removeFirstOccurrence(Object o);
3.412 +
3.413 + /**
3.414 + * Removes the last occurrence of the specified element from this deque.
3.415 + * If the deque does not contain the element, it is unchanged.
3.416 + * More formally, removes the last element <tt>e</tt> such that
3.417 + * <tt>o.equals(e)</tt> (if such an element exists).
3.418 + * Returns <tt>true</tt> if this deque contained the specified element
3.419 + * (or equivalently, if this deque changed as a result of the call).
3.420 + *
3.421 + * @param o element to be removed from this deque, if present
3.422 + * @return <tt>true</tt> if an element was removed as a result of this call
3.423 + * @throws ClassCastException if the class of the specified element
3.424 + * is incompatible with this deque
3.425 + * (<a href="../Collection.html#optional-restrictions">optional</a>)
3.426 + * @throws NullPointerException if the specified element is null
3.427 + * (<a href="../Collection.html#optional-restrictions">optional</a>)
3.428 + */
3.429 + boolean removeLastOccurrence(Object o);
3.430 +
3.431 + // *** BlockingQueue methods ***
3.432 +
3.433 + /**
3.434 + * Inserts the specified element into the queue represented by this deque
3.435 + * (in other words, at the tail of this deque) if it is possible to do so
3.436 + * immediately without violating capacity restrictions, returning
3.437 + * <tt>true</tt> upon success and throwing an
3.438 + * <tt>IllegalStateException</tt> if no space is currently available.
3.439 + * When using a capacity-restricted deque, it is generally preferable to
3.440 + * use {@link #offer(Object) offer}.
3.441 + *
3.442 + * <p>This method is equivalent to {@link #addLast(Object) addLast}.
3.443 + *
3.444 + * @param e the element to add
3.445 + * @throws IllegalStateException {@inheritDoc}
3.446 + * @throws ClassCastException if the class of the specified element
3.447 + * prevents it from being added to this deque
3.448 + * @throws NullPointerException if the specified element is null
3.449 + * @throws IllegalArgumentException if some property of the specified
3.450 + * element prevents it from being added to this deque
3.451 + */
3.452 + boolean add(E e);
3.453 +
3.454 + /**
3.455 + * Inserts the specified element into the queue represented by this deque
3.456 + * (in other words, at the tail of this deque) if it is possible to do so
3.457 + * immediately without violating capacity restrictions, returning
3.458 + * <tt>true</tt> upon success and <tt>false</tt> if no space is currently
3.459 + * available. When using a capacity-restricted deque, this method is
3.460 + * generally preferable to the {@link #add} method, which can fail to
3.461 + * insert an element only by throwing an exception.
3.462 + *
3.463 + * <p>This method is equivalent to {@link #offerLast(Object) offerLast}.
3.464 + *
3.465 + * @param e the element to add
3.466 + * @throws ClassCastException if the class of the specified element
3.467 + * prevents it from being added to this deque
3.468 + * @throws NullPointerException if the specified element is null
3.469 + * @throws IllegalArgumentException if some property of the specified
3.470 + * element prevents it from being added to this deque
3.471 + */
3.472 + boolean offer(E e);
3.473 +
3.474 + /**
3.475 + * Inserts the specified element into the queue represented by this deque
3.476 + * (in other words, at the tail of this deque), waiting if necessary for
3.477 + * space to become available.
3.478 + *
3.479 + * <p>This method is equivalent to {@link #putLast(Object) putLast}.
3.480 + *
3.481 + * @param e the element to add
3.482 + * @throws InterruptedException {@inheritDoc}
3.483 + * @throws ClassCastException if the class of the specified element
3.484 + * prevents it from being added to this deque
3.485 + * @throws NullPointerException if the specified element is null
3.486 + * @throws IllegalArgumentException if some property of the specified
3.487 + * element prevents it from being added to this deque
3.488 + */
3.489 + void put(E e) throws InterruptedException;
3.490 +
3.491 + /**
3.492 + * Inserts the specified element into the queue represented by this deque
3.493 + * (in other words, at the tail of this deque), waiting up to the
3.494 + * specified wait time if necessary for space to become available.
3.495 + *
3.496 + * <p>This method is equivalent to
3.497 + * {@link #offerLast(Object,long,TimeUnit) offerLast}.
3.498 + *
3.499 + * @param e the element to add
3.500 + * @return <tt>true</tt> if the element was added to this deque, else
3.501 + * <tt>false</tt>
3.502 + * @throws InterruptedException {@inheritDoc}
3.503 + * @throws ClassCastException if the class of the specified element
3.504 + * prevents it from being added to this deque
3.505 + * @throws NullPointerException if the specified element is null
3.506 + * @throws IllegalArgumentException if some property of the specified
3.507 + * element prevents it from being added to this deque
3.508 + */
3.509 + boolean offer(E e, long timeout, TimeUnit unit)
3.510 + throws InterruptedException;
3.511 +
3.512 + /**
3.513 + * Retrieves and removes the head of the queue represented by this deque
3.514 + * (in other words, the first element of this deque).
3.515 + * This method differs from {@link #poll poll} only in that it
3.516 + * throws an exception if this deque is empty.
3.517 + *
3.518 + * <p>This method is equivalent to {@link #removeFirst() removeFirst}.
3.519 + *
3.520 + * @return the head of the queue represented by this deque
3.521 + * @throws NoSuchElementException if this deque is empty
3.522 + */
3.523 + E remove();
3.524 +
3.525 + /**
3.526 + * Retrieves and removes the head of the queue represented by this deque
3.527 + * (in other words, the first element of this deque), or returns
3.528 + * <tt>null</tt> if this deque is empty.
3.529 + *
3.530 + * <p>This method is equivalent to {@link #pollFirst()}.
3.531 + *
3.532 + * @return the head of this deque, or <tt>null</tt> if this deque is empty
3.533 + */
3.534 + E poll();
3.535 +
3.536 + /**
3.537 + * Retrieves and removes the head of the queue represented by this deque
3.538 + * (in other words, the first element of this deque), waiting if
3.539 + * necessary until an element becomes available.
3.540 + *
3.541 + * <p>This method is equivalent to {@link #takeFirst() takeFirst}.
3.542 + *
3.543 + * @return the head of this deque
3.544 + * @throws InterruptedException if interrupted while waiting
3.545 + */
3.546 + E take() throws InterruptedException;
3.547 +
3.548 + /**
3.549 + * Retrieves and removes the head of the queue represented by this deque
3.550 + * (in other words, the first element of this deque), waiting up to the
3.551 + * specified wait time if necessary for an element to become available.
3.552 + *
3.553 + * <p>This method is equivalent to
3.554 + * {@link #pollFirst(long,TimeUnit) pollFirst}.
3.555 + *
3.556 + * @return the head of this deque, or <tt>null</tt> if the
3.557 + * specified waiting time elapses before an element is available
3.558 + * @throws InterruptedException if interrupted while waiting
3.559 + */
3.560 + E poll(long timeout, TimeUnit unit)
3.561 + throws InterruptedException;
3.562 +
3.563 + /**
3.564 + * Retrieves, but does not remove, the head of the queue represented by
3.565 + * this deque (in other words, the first element of this deque).
3.566 + * This method differs from {@link #peek peek} only in that it throws an
3.567 + * exception if this deque is empty.
3.568 + *
3.569 + * <p>This method is equivalent to {@link #getFirst() getFirst}.
3.570 + *
3.571 + * @return the head of this deque
3.572 + * @throws NoSuchElementException if this deque is empty
3.573 + */
3.574 + E element();
3.575 +
3.576 + /**
3.577 + * Retrieves, but does not remove, the head of the queue represented by
3.578 + * this deque (in other words, the first element of this deque), or
3.579 + * returns <tt>null</tt> if this deque is empty.
3.580 + *
3.581 + * <p>This method is equivalent to {@link #peekFirst() peekFirst}.
3.582 + *
3.583 + * @return the head of this deque, or <tt>null</tt> if this deque is empty
3.584 + */
3.585 + E peek();
3.586 +
3.587 + /**
3.588 + * Removes the first occurrence of the specified element from this deque.
3.589 + * If the deque does not contain the element, it is unchanged.
3.590 + * More formally, removes the first element <tt>e</tt> such that
3.591 + * <tt>o.equals(e)</tt> (if such an element exists).
3.592 + * Returns <tt>true</tt> if this deque contained the specified element
3.593 + * (or equivalently, if this deque changed as a result of the call).
3.594 + *
3.595 + * <p>This method is equivalent to
3.596 + * {@link #removeFirstOccurrence(Object) removeFirstOccurrence}.
3.597 + *
3.598 + * @param o element to be removed from this deque, if present
3.599 + * @return <tt>true</tt> if this deque changed as a result of the call
3.600 + * @throws ClassCastException if the class of the specified element
3.601 + * is incompatible with this deque
3.602 + * (<a href="../Collection.html#optional-restrictions">optional</a>)
3.603 + * @throws NullPointerException if the specified element is null
3.604 + * (<a href="../Collection.html#optional-restrictions">optional</a>)
3.605 + */
3.606 + boolean remove(Object o);
3.607 +
3.608 + /**
3.609 + * Returns <tt>true</tt> if this deque contains the specified element.
3.610 + * More formally, returns <tt>true</tt> if and only if this deque contains
3.611 + * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>.
3.612 + *
3.613 + * @param o object to be checked for containment in this deque
3.614 + * @return <tt>true</tt> if this deque contains the specified element
3.615 + * @throws ClassCastException if the class of the specified element
3.616 + * is incompatible with this deque
3.617 + * (<a href="../Collection.html#optional-restrictions">optional</a>)
3.618 + * @throws NullPointerException if the specified element is null
3.619 + * (<a href="../Collection.html#optional-restrictions">optional</a>)
3.620 + */
3.621 + public boolean contains(Object o);
3.622 +
3.623 + /**
3.624 + * Returns the number of elements in this deque.
3.625 + *
3.626 + * @return the number of elements in this deque
3.627 + */
3.628 + public int size();
3.629 +
3.630 + /**
3.631 + * Returns an iterator over the elements in this deque in proper sequence.
3.632 + * The elements will be returned in order from first (head) to last (tail).
3.633 + *
3.634 + * @return an iterator over the elements in this deque in proper sequence
3.635 + */
3.636 + Iterator<E> iterator();
3.637 +
3.638 + // *** Stack methods ***
3.639 +
3.640 + /**
3.641 + * Pushes an element onto the stack represented by this deque. In other
3.642 + * words, inserts the element at the front of this deque unless it would
3.643 + * violate capacity restrictions.
3.644 + *
3.645 + * <p>This method is equivalent to {@link #addFirst(Object) addFirst}.
3.646 + *
3.647 + * @throws IllegalStateException {@inheritDoc}
3.648 + * @throws ClassCastException {@inheritDoc}
3.649 + * @throws NullPointerException if the specified element is null
3.650 + * @throws IllegalArgumentException {@inheritDoc}
3.651 + */
3.652 + void push(E e);
3.653 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/BlockingQueue.java Sat Mar 19 10:48:29 2016 +0100
4.3 @@ -0,0 +1,377 @@
4.4 +/*
4.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4.6 + *
4.7 + * This code is free software; you can redistribute it and/or modify it
4.8 + * under the terms of the GNU General Public License version 2 only, as
4.9 + * published by the Free Software Foundation. Oracle designates this
4.10 + * particular file as subject to the "Classpath" exception as provided
4.11 + * by Oracle in the LICENSE file that accompanied this code.
4.12 + *
4.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
4.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4.16 + * version 2 for more details (a copy is included in the LICENSE file that
4.17 + * accompanied this code).
4.18 + *
4.19 + * You should have received a copy of the GNU General Public License version
4.20 + * 2 along with this work; if not, write to the Free Software Foundation,
4.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
4.22 + *
4.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
4.24 + * or visit www.oracle.com if you need additional information or have any
4.25 + * questions.
4.26 + */
4.27 +
4.28 +/*
4.29 + * This file is available under and governed by the GNU General Public
4.30 + * License version 2 only, as published by the Free Software Foundation.
4.31 + * However, the following notice accompanied the original version of this
4.32 + * file:
4.33 + *
4.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
4.35 + * Expert Group and released to the public domain, as explained at
4.36 + * http://creativecommons.org/publicdomain/zero/1.0/
4.37 + */
4.38 +
4.39 +package java.util.concurrent;
4.40 +
4.41 +import java.util.Collection;
4.42 +import java.util.Queue;
4.43 +
4.44 +/**
4.45 + * A {@link java.util.Queue} that additionally supports operations
4.46 + * that wait for the queue to become non-empty when retrieving an
4.47 + * element, and wait for space to become available in the queue when
4.48 + * storing an element.
4.49 + *
4.50 + * <p><tt>BlockingQueue</tt> methods come in four forms, with different ways
4.51 + * of handling operations that cannot be satisfied immediately, but may be
4.52 + * satisfied at some point in the future:
4.53 + * one throws an exception, the second returns a special value (either
4.54 + * <tt>null</tt> or <tt>false</tt>, depending on the operation), the third
4.55 + * blocks the current thread indefinitely until the operation can succeed,
4.56 + * and the fourth blocks for only a given maximum time limit before giving
4.57 + * up. These methods are summarized in the following table:
4.58 + *
4.59 + * <p>
4.60 + * <table BORDER CELLPADDING=3 CELLSPACING=1>
4.61 + * <tr>
4.62 + * <td></td>
4.63 + * <td ALIGN=CENTER><em>Throws exception</em></td>
4.64 + * <td ALIGN=CENTER><em>Special value</em></td>
4.65 + * <td ALIGN=CENTER><em>Blocks</em></td>
4.66 + * <td ALIGN=CENTER><em>Times out</em></td>
4.67 + * </tr>
4.68 + * <tr>
4.69 + * <td><b>Insert</b></td>
4.70 + * <td>{@link #add add(e)}</td>
4.71 + * <td>{@link #offer offer(e)}</td>
4.72 + * <td>{@link #put put(e)}</td>
4.73 + * <td>{@link #offer(Object, long, TimeUnit) offer(e, time, unit)}</td>
4.74 + * </tr>
4.75 + * <tr>
4.76 + * <td><b>Remove</b></td>
4.77 + * <td>{@link #remove remove()}</td>
4.78 + * <td>{@link #poll poll()}</td>
4.79 + * <td>{@link #take take()}</td>
4.80 + * <td>{@link #poll(long, TimeUnit) poll(time, unit)}</td>
4.81 + * </tr>
4.82 + * <tr>
4.83 + * <td><b>Examine</b></td>
4.84 + * <td>{@link #element element()}</td>
4.85 + * <td>{@link #peek peek()}</td>
4.86 + * <td><em>not applicable</em></td>
4.87 + * <td><em>not applicable</em></td>
4.88 + * </tr>
4.89 + * </table>
4.90 + *
4.91 + * <p>A <tt>BlockingQueue</tt> does not accept <tt>null</tt> elements.
4.92 + * Implementations throw <tt>NullPointerException</tt> on attempts
4.93 + * to <tt>add</tt>, <tt>put</tt> or <tt>offer</tt> a <tt>null</tt>. A
4.94 + * <tt>null</tt> is used as a sentinel value to indicate failure of
4.95 + * <tt>poll</tt> operations.
4.96 + *
4.97 + * <p>A <tt>BlockingQueue</tt> may be capacity bounded. At any given
4.98 + * time it may have a <tt>remainingCapacity</tt> beyond which no
4.99 + * additional elements can be <tt>put</tt> without blocking.
4.100 + * A <tt>BlockingQueue</tt> without any intrinsic capacity constraints always
4.101 + * reports a remaining capacity of <tt>Integer.MAX_VALUE</tt>.
4.102 + *
4.103 + * <p> <tt>BlockingQueue</tt> implementations are designed to be used
4.104 + * primarily for producer-consumer queues, but additionally support
4.105 + * the {@link java.util.Collection} interface. So, for example, it is
4.106 + * possible to remove an arbitrary element from a queue using
4.107 + * <tt>remove(x)</tt>. However, such operations are in general
4.108 + * <em>not</em> performed very efficiently, and are intended for only
4.109 + * occasional use, such as when a queued message is cancelled.
4.110 + *
4.111 + * <p> <tt>BlockingQueue</tt> implementations are thread-safe. All
4.112 + * queuing methods achieve their effects atomically using internal
4.113 + * locks or other forms of concurrency control. However, the
4.114 + * <em>bulk</em> Collection operations <tt>addAll</tt>,
4.115 + * <tt>containsAll</tt>, <tt>retainAll</tt> and <tt>removeAll</tt> are
4.116 + * <em>not</em> necessarily performed atomically unless specified
4.117 + * otherwise in an implementation. So it is possible, for example, for
4.118 + * <tt>addAll(c)</tt> to fail (throwing an exception) after adding
4.119 + * only some of the elements in <tt>c</tt>.
4.120 + *
4.121 + * <p>A <tt>BlockingQueue</tt> does <em>not</em> intrinsically support
4.122 + * any kind of "close" or "shutdown" operation to
4.123 + * indicate that no more items will be added. The needs and usage of
4.124 + * such features tend to be implementation-dependent. For example, a
4.125 + * common tactic is for producers to insert special
4.126 + * <em>end-of-stream</em> or <em>poison</em> objects, that are
4.127 + * interpreted accordingly when taken by consumers.
4.128 + *
4.129 + * <p>
4.130 + * Usage example, based on a typical producer-consumer scenario.
4.131 + * Note that a <tt>BlockingQueue</tt> can safely be used with multiple
4.132 + * producers and multiple consumers.
4.133 + * <pre>
4.134 + * class Producer implements Runnable {
4.135 + * private final BlockingQueue queue;
4.136 + * Producer(BlockingQueue q) { queue = q; }
4.137 + * public void run() {
4.138 + * try {
4.139 + * while (true) { queue.put(produce()); }
4.140 + * } catch (InterruptedException ex) { ... handle ...}
4.141 + * }
4.142 + * Object produce() { ... }
4.143 + * }
4.144 + *
4.145 + * class Consumer implements Runnable {
4.146 + * private final BlockingQueue queue;
4.147 + * Consumer(BlockingQueue q) { queue = q; }
4.148 + * public void run() {
4.149 + * try {
4.150 + * while (true) { consume(queue.take()); }
4.151 + * } catch (InterruptedException ex) { ... handle ...}
4.152 + * }
4.153 + * void consume(Object x) { ... }
4.154 + * }
4.155 + *
4.156 + * class Setup {
4.157 + * void main() {
4.158 + * BlockingQueue q = new SomeQueueImplementation();
4.159 + * Producer p = new Producer(q);
4.160 + * Consumer c1 = new Consumer(q);
4.161 + * Consumer c2 = new Consumer(q);
4.162 + * new Thread(p).start();
4.163 + * new Thread(c1).start();
4.164 + * new Thread(c2).start();
4.165 + * }
4.166 + * }
4.167 + * </pre>
4.168 + *
4.169 + * <p>Memory consistency effects: As with other concurrent
4.170 + * collections, actions in a thread prior to placing an object into a
4.171 + * {@code BlockingQueue}
4.172 + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
4.173 + * actions subsequent to the access or removal of that element from
4.174 + * the {@code BlockingQueue} in another thread.
4.175 + *
4.176 + * <p>This interface is a member of the
4.177 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
4.178 + * Java Collections Framework</a>.
4.179 + *
4.180 + * @since 1.5
4.181 + * @author Doug Lea
4.182 + * @param <E> the type of elements held in this collection
4.183 + */
4.184 +public interface BlockingQueue<E> extends Queue<E> {
4.185 + /**
4.186 + * Inserts the specified element into this queue if it is possible to do
4.187 + * so immediately without violating capacity restrictions, returning
4.188 + * <tt>true</tt> upon success and throwing an
4.189 + * <tt>IllegalStateException</tt> if no space is currently available.
4.190 + * When using a capacity-restricted queue, it is generally preferable to
4.191 + * use {@link #offer(Object) offer}.
4.192 + *
4.193 + * @param e the element to add
4.194 + * @return <tt>true</tt> (as specified by {@link Collection#add})
4.195 + * @throws IllegalStateException if the element cannot be added at this
4.196 + * time due to capacity restrictions
4.197 + * @throws ClassCastException if the class of the specified element
4.198 + * prevents it from being added to this queue
4.199 + * @throws NullPointerException if the specified element is null
4.200 + * @throws IllegalArgumentException if some property of the specified
4.201 + * element prevents it from being added to this queue
4.202 + */
4.203 + boolean add(E e);
4.204 +
4.205 + /**
4.206 + * Inserts the specified element into this queue if it is possible to do
4.207 + * so immediately without violating capacity restrictions, returning
4.208 + * <tt>true</tt> upon success and <tt>false</tt> if no space is currently
4.209 + * available. When using a capacity-restricted queue, this method is
4.210 + * generally preferable to {@link #add}, which can fail to insert an
4.211 + * element only by throwing an exception.
4.212 + *
4.213 + * @param e the element to add
4.214 + * @return <tt>true</tt> if the element was added to this queue, else
4.215 + * <tt>false</tt>
4.216 + * @throws ClassCastException if the class of the specified element
4.217 + * prevents it from being added to this queue
4.218 + * @throws NullPointerException if the specified element is null
4.219 + * @throws IllegalArgumentException if some property of the specified
4.220 + * element prevents it from being added to this queue
4.221 + */
4.222 + boolean offer(E e);
4.223 +
4.224 + /**
4.225 + * Inserts the specified element into this queue, waiting if necessary
4.226 + * for space to become available.
4.227 + *
4.228 + * @param e the element to add
4.229 + * @throws InterruptedException if interrupted while waiting
4.230 + * @throws ClassCastException if the class of the specified element
4.231 + * prevents it from being added to this queue
4.232 + * @throws NullPointerException if the specified element is null
4.233 + * @throws IllegalArgumentException if some property of the specified
4.234 + * element prevents it from being added to this queue
4.235 + */
4.236 + void put(E e) throws InterruptedException;
4.237 +
4.238 + /**
4.239 + * Inserts the specified element into this queue, waiting up to the
4.240 + * specified wait time if necessary for space to become available.
4.241 + *
4.242 + * @param e the element to add
4.243 + * @param timeout how long to wait before giving up, in units of
4.244 + * <tt>unit</tt>
4.245 + * @param unit a <tt>TimeUnit</tt> determining how to interpret the
4.246 + * <tt>timeout</tt> parameter
4.247 + * @return <tt>true</tt> if successful, or <tt>false</tt> if
4.248 + * the specified waiting time elapses before space is available
4.249 + * @throws InterruptedException if interrupted while waiting
4.250 + * @throws ClassCastException if the class of the specified element
4.251 + * prevents it from being added to this queue
4.252 + * @throws NullPointerException if the specified element is null
4.253 + * @throws IllegalArgumentException if some property of the specified
4.254 + * element prevents it from being added to this queue
4.255 + */
4.256 + boolean offer(E e, long timeout, TimeUnit unit)
4.257 + throws InterruptedException;
4.258 +
4.259 + /**
4.260 + * Retrieves and removes the head of this queue, waiting if necessary
4.261 + * until an element becomes available.
4.262 + *
4.263 + * @return the head of this queue
4.264 + * @throws InterruptedException if interrupted while waiting
4.265 + */
4.266 + E take() throws InterruptedException;
4.267 +
4.268 + /**
4.269 + * Retrieves and removes the head of this queue, waiting up to the
4.270 + * specified wait time if necessary for an element to become available.
4.271 + *
4.272 + * @param timeout how long to wait before giving up, in units of
4.273 + * <tt>unit</tt>
4.274 + * @param unit a <tt>TimeUnit</tt> determining how to interpret the
4.275 + * <tt>timeout</tt> parameter
4.276 + * @return the head of this queue, or <tt>null</tt> if the
4.277 + * specified waiting time elapses before an element is available
4.278 + * @throws InterruptedException if interrupted while waiting
4.279 + */
4.280 + E poll(long timeout, TimeUnit unit)
4.281 + throws InterruptedException;
4.282 +
4.283 + /**
4.284 + * Returns the number of additional elements that this queue can ideally
4.285 + * (in the absence of memory or resource constraints) accept without
4.286 + * blocking, or <tt>Integer.MAX_VALUE</tt> if there is no intrinsic
4.287 + * limit.
4.288 + *
4.289 + * <p>Note that you <em>cannot</em> always tell if an attempt to insert
4.290 + * an element will succeed by inspecting <tt>remainingCapacity</tt>
4.291 + * because it may be the case that another thread is about to
4.292 + * insert or remove an element.
4.293 + *
4.294 + * @return the remaining capacity
4.295 + */
4.296 + int remainingCapacity();
4.297 +
4.298 + /**
4.299 + * Removes a single instance of the specified element from this queue,
4.300 + * if it is present. More formally, removes an element <tt>e</tt> such
4.301 + * that <tt>o.equals(e)</tt>, if this queue contains one or more such
4.302 + * elements.
4.303 + * Returns <tt>true</tt> if this queue contained the specified element
4.304 + * (or equivalently, if this queue changed as a result of the call).
4.305 + *
4.306 + * @param o element to be removed from this queue, if present
4.307 + * @return <tt>true</tt> if this queue changed as a result of the call
4.308 + * @throws ClassCastException if the class of the specified element
4.309 + * is incompatible with this queue
4.310 + * (<a href="../Collection.html#optional-restrictions">optional</a>)
4.311 + * @throws NullPointerException if the specified element is null
4.312 + * (<a href="../Collection.html#optional-restrictions">optional</a>)
4.313 + */
4.314 + boolean remove(Object o);
4.315 +
4.316 + /**
4.317 + * Returns <tt>true</tt> if this queue contains the specified element.
4.318 + * More formally, returns <tt>true</tt> if and only if this queue contains
4.319 + * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>.
4.320 + *
4.321 + * @param o object to be checked for containment in this queue
4.322 + * @return <tt>true</tt> if this queue contains the specified element
4.323 + * @throws ClassCastException if the class of the specified element
4.324 + * is incompatible with this queue
4.325 + * (<a href="../Collection.html#optional-restrictions">optional</a>)
4.326 + * @throws NullPointerException if the specified element is null
4.327 + * (<a href="../Collection.html#optional-restrictions">optional</a>)
4.328 + */
4.329 + public boolean contains(Object o);
4.330 +
4.331 + /**
4.332 + * Removes all available elements from this queue and adds them
4.333 + * to the given collection. This operation may be more
4.334 + * efficient than repeatedly polling this queue. A failure
4.335 + * encountered while attempting to add elements to
4.336 + * collection <tt>c</tt> may result in elements being in neither,
4.337 + * either or both collections when the associated exception is
4.338 + * thrown. Attempts to drain a queue to itself result in
4.339 + * <tt>IllegalArgumentException</tt>. Further, the behavior of
4.340 + * this operation is undefined if the specified collection is
4.341 + * modified while the operation is in progress.
4.342 + *
4.343 + * @param c the collection to transfer elements into
4.344 + * @return the number of elements transferred
4.345 + * @throws UnsupportedOperationException if addition of elements
4.346 + * is not supported by the specified collection
4.347 + * @throws ClassCastException if the class of an element of this queue
4.348 + * prevents it from being added to the specified collection
4.349 + * @throws NullPointerException if the specified collection is null
4.350 + * @throws IllegalArgumentException if the specified collection is this
4.351 + * queue, or some property of an element of this queue prevents
4.352 + * it from being added to the specified collection
4.353 + */
4.354 + int drainTo(Collection<? super E> c);
4.355 +
4.356 + /**
4.357 + * Removes at most the given number of available elements from
4.358 + * this queue and adds them to the given collection. A failure
4.359 + * encountered while attempting to add elements to
4.360 + * collection <tt>c</tt> may result in elements being in neither,
4.361 + * either or both collections when the associated exception is
4.362 + * thrown. Attempts to drain a queue to itself result in
4.363 + * <tt>IllegalArgumentException</tt>. Further, the behavior of
4.364 + * this operation is undefined if the specified collection is
4.365 + * modified while the operation is in progress.
4.366 + *
4.367 + * @param c the collection to transfer elements into
4.368 + * @param maxElements the maximum number of elements to transfer
4.369 + * @return the number of elements transferred
4.370 + * @throws UnsupportedOperationException if addition of elements
4.371 + * is not supported by the specified collection
4.372 + * @throws ClassCastException if the class of an element of this queue
4.373 + * prevents it from being added to the specified collection
4.374 + * @throws NullPointerException if the specified collection is null
4.375 + * @throws IllegalArgumentException if the specified collection is this
4.376 + * queue, or some property of an element of this queue prevents
4.377 + * it from being added to the specified collection
4.378 + */
4.379 + int drainTo(Collection<? super E> c, int maxElements);
4.380 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/BrokenBarrierException.java Sat Mar 19 10:48:29 2016 +0100
5.3 @@ -0,0 +1,67 @@
5.4 +/*
5.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5.6 + *
5.7 + * This code is free software; you can redistribute it and/or modify it
5.8 + * under the terms of the GNU General Public License version 2 only, as
5.9 + * published by the Free Software Foundation. Oracle designates this
5.10 + * particular file as subject to the "Classpath" exception as provided
5.11 + * by Oracle in the LICENSE file that accompanied this code.
5.12 + *
5.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
5.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
5.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5.16 + * version 2 for more details (a copy is included in the LICENSE file that
5.17 + * accompanied this code).
5.18 + *
5.19 + * You should have received a copy of the GNU General Public License version
5.20 + * 2 along with this work; if not, write to the Free Software Foundation,
5.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
5.22 + *
5.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
5.24 + * or visit www.oracle.com if you need additional information or have any
5.25 + * questions.
5.26 + */
5.27 +
5.28 +/*
5.29 + * This file is available under and governed by the GNU General Public
5.30 + * License version 2 only, as published by the Free Software Foundation.
5.31 + * However, the following notice accompanied the original version of this
5.32 + * file:
5.33 + *
5.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
5.35 + * Expert Group and released to the public domain, as explained at
5.36 + * http://creativecommons.org/publicdomain/zero/1.0/
5.37 + */
5.38 +
5.39 +package java.util.concurrent;
5.40 +
5.41 +/**
5.42 + * Exception thrown when a thread tries to wait upon a barrier that is
5.43 + * in a broken state, or which enters the broken state while the thread
5.44 + * is waiting.
5.45 + *
5.46 + * @see CyclicBarrier
5.47 + *
5.48 + * @since 1.5
5.49 + * @author Doug Lea
5.50 + *
5.51 + */
5.52 +public class BrokenBarrierException extends Exception {
5.53 + private static final long serialVersionUID = 7117394618823254244L;
5.54 +
5.55 + /**
5.56 + * Constructs a <tt>BrokenBarrierException</tt> with no specified detail
5.57 + * message.
5.58 + */
5.59 + public BrokenBarrierException() {}
5.60 +
5.61 + /**
5.62 + * Constructs a <tt>BrokenBarrierException</tt> with the specified
5.63 + * detail message.
5.64 + *
5.65 + * @param message the detail message
5.66 + */
5.67 + public BrokenBarrierException(String message) {
5.68 + super(message);
5.69 + }
5.70 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/CancellationException.java Sat Mar 19 10:48:29 2016 +0100
6.3 @@ -0,0 +1,63 @@
6.4 +/*
6.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6.6 + *
6.7 + * This code is free software; you can redistribute it and/or modify it
6.8 + * under the terms of the GNU General Public License version 2 only, as
6.9 + * published by the Free Software Foundation. Oracle designates this
6.10 + * particular file as subject to the "Classpath" exception as provided
6.11 + * by Oracle in the LICENSE file that accompanied this code.
6.12 + *
6.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
6.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6.16 + * version 2 for more details (a copy is included in the LICENSE file that
6.17 + * accompanied this code).
6.18 + *
6.19 + * You should have received a copy of the GNU General Public License version
6.20 + * 2 along with this work; if not, write to the Free Software Foundation,
6.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
6.22 + *
6.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
6.24 + * or visit www.oracle.com if you need additional information or have any
6.25 + * questions.
6.26 + */
6.27 +
6.28 +/*
6.29 + * This file is available under and governed by the GNU General Public
6.30 + * License version 2 only, as published by the Free Software Foundation.
6.31 + * However, the following notice accompanied the original version of this
6.32 + * file:
6.33 + *
6.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
6.35 + * Expert Group and released to the public domain, as explained at
6.36 + * http://creativecommons.org/publicdomain/zero/1.0/
6.37 + */
6.38 +
6.39 +package java.util.concurrent;
6.40 +
6.41 +/**
6.42 + * Exception indicating that the result of a value-producing task,
6.43 + * such as a {@link FutureTask}, cannot be retrieved because the task
6.44 + * was cancelled.
6.45 + *
6.46 + * @since 1.5
6.47 + * @author Doug Lea
6.48 + */
6.49 +public class CancellationException extends IllegalStateException {
6.50 + private static final long serialVersionUID = -9202173006928992231L;
6.51 +
6.52 + /**
6.53 + * Constructs a <tt>CancellationException</tt> with no detail message.
6.54 + */
6.55 + public CancellationException() {}
6.56 +
6.57 + /**
6.58 + * Constructs a <tt>CancellationException</tt> with the specified detail
6.59 + * message.
6.60 + *
6.61 + * @param message the detail message
6.62 + */
6.63 + public CancellationException(String message) {
6.64 + super(message);
6.65 + }
6.66 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/CompletionService.java Sat Mar 19 10:48:29 2016 +0100
7.3 @@ -0,0 +1,126 @@
7.4 +/*
7.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7.6 + *
7.7 + * This code is free software; you can redistribute it and/or modify it
7.8 + * under the terms of the GNU General Public License version 2 only, as
7.9 + * published by the Free Software Foundation. Oracle designates this
7.10 + * particular file as subject to the "Classpath" exception as provided
7.11 + * by Oracle in the LICENSE file that accompanied this code.
7.12 + *
7.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
7.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
7.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
7.16 + * version 2 for more details (a copy is included in the LICENSE file that
7.17 + * accompanied this code).
7.18 + *
7.19 + * You should have received a copy of the GNU General Public License version
7.20 + * 2 along with this work; if not, write to the Free Software Foundation,
7.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
7.22 + *
7.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
7.24 + * or visit www.oracle.com if you need additional information or have any
7.25 + * questions.
7.26 + */
7.27 +
7.28 +/*
7.29 + * This file is available under and governed by the GNU General Public
7.30 + * License version 2 only, as published by the Free Software Foundation.
7.31 + * However, the following notice accompanied the original version of this
7.32 + * file:
7.33 + *
7.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
7.35 + * Expert Group and released to the public domain, as explained at
7.36 + * http://creativecommons.org/publicdomain/zero/1.0/
7.37 + */
7.38 +
7.39 +package java.util.concurrent;
7.40 +
7.41 +/**
7.42 + * A service that decouples the production of new asynchronous tasks
7.43 + * from the consumption of the results of completed tasks. Producers
7.44 + * <tt>submit</tt> tasks for execution. Consumers <tt>take</tt>
7.45 + * completed tasks and process their results in the order they
7.46 + * complete. A <tt>CompletionService</tt> can for example be used to
7.47 + * manage asynchronous IO, in which tasks that perform reads are
7.48 + * submitted in one part of a program or system, and then acted upon
7.49 + * in a different part of the program when the reads complete,
7.50 + * possibly in a different order than they were requested.
7.51 + *
7.52 + * <p>Typically, a <tt>CompletionService</tt> relies on a separate
7.53 + * {@link Executor} to actually execute the tasks, in which case the
7.54 + * <tt>CompletionService</tt> only manages an internal completion
7.55 + * queue. The {@link ExecutorCompletionService} class provides an
7.56 + * implementation of this approach.
7.57 + *
7.58 + * <p>Memory consistency effects: Actions in a thread prior to
7.59 + * submitting a task to a {@code CompletionService}
7.60 + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
7.61 + * actions taken by that task, which in turn <i>happen-before</i>
7.62 + * actions following a successful return from the corresponding {@code take()}.
7.63 + *
7.64 + */
7.65 +public interface CompletionService<V> {
7.66 + /**
7.67 + * Submits a value-returning task for execution and returns a Future
7.68 + * representing the pending results of the task. Upon completion,
7.69 + * this task may be taken or polled.
7.70 + *
7.71 + * @param task the task to submit
7.72 + * @return a Future representing pending completion of the task
7.73 + * @throws RejectedExecutionException if the task cannot be
7.74 + * scheduled for execution
7.75 + * @throws NullPointerException if the task is null
7.76 + */
7.77 + Future<V> submit(Callable<V> task);
7.78 +
7.79 + /**
7.80 + * Submits a Runnable task for execution and returns a Future
7.81 + * representing that task. Upon completion, this task may be
7.82 + * taken or polled.
7.83 + *
7.84 + * @param task the task to submit
7.85 + * @param result the result to return upon successful completion
7.86 + * @return a Future representing pending completion of the task,
7.87 + * and whose <tt>get()</tt> method will return the given
7.88 + * result value upon completion
7.89 + * @throws RejectedExecutionException if the task cannot be
7.90 + * scheduled for execution
7.91 + * @throws NullPointerException if the task is null
7.92 + */
7.93 + Future<V> submit(Runnable task, V result);
7.94 +
7.95 + /**
7.96 + * Retrieves and removes the Future representing the next
7.97 + * completed task, waiting if none are yet present.
7.98 + *
7.99 + * @return the Future representing the next completed task
7.100 + * @throws InterruptedException if interrupted while waiting
7.101 + */
7.102 + Future<V> take() throws InterruptedException;
7.103 +
7.104 +
7.105 + /**
7.106 + * Retrieves and removes the Future representing the next
7.107 + * completed task or <tt>null</tt> if none are present.
7.108 + *
7.109 + * @return the Future representing the next completed task, or
7.110 + * <tt>null</tt> if none are present
7.111 + */
7.112 + Future<V> poll();
7.113 +
7.114 + /**
7.115 + * Retrieves and removes the Future representing the next
7.116 + * completed task, waiting if necessary up to the specified wait
7.117 + * time if none are yet present.
7.118 + *
7.119 + * @param timeout how long to wait before giving up, in units of
7.120 + * <tt>unit</tt>
7.121 + * @param unit a <tt>TimeUnit</tt> determining how to interpret the
7.122 + * <tt>timeout</tt> parameter
7.123 + * @return the Future representing the next completed task or
7.124 + * <tt>null</tt> if the specified waiting time elapses
7.125 + * before one is present
7.126 + * @throws InterruptedException if interrupted while waiting
7.127 + */
7.128 + Future<V> poll(long timeout, TimeUnit unit) throws InterruptedException;
7.129 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ConcurrentLinkedDeque.java Sat Mar 19 10:48:29 2016 +0100
8.3 @@ -0,0 +1,1469 @@
8.4 +/*
8.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8.6 + *
8.7 + * This code is free software; you can redistribute it and/or modify it
8.8 + * under the terms of the GNU General Public License version 2 only, as
8.9 + * published by the Free Software Foundation. Oracle designates this
8.10 + * particular file as subject to the "Classpath" exception as provided
8.11 + * by Oracle in the LICENSE file that accompanied this code.
8.12 + *
8.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
8.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
8.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
8.16 + * version 2 for more details (a copy is included in the LICENSE file that
8.17 + * accompanied this code).
8.18 + *
8.19 + * You should have received a copy of the GNU General Public License version
8.20 + * 2 along with this work; if not, write to the Free Software Foundation,
8.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
8.22 + *
8.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
8.24 + * or visit www.oracle.com if you need additional information or have any
8.25 + * questions.
8.26 + */
8.27 +
8.28 +/*
8.29 + * This file is available under and governed by the GNU General Public
8.30 + * License version 2 only, as published by the Free Software Foundation.
8.31 + * However, the following notice accompanied the original version of this
8.32 + * file:
8.33 + *
8.34 + * Written by Doug Lea and Martin Buchholz with assistance from members of
8.35 + * JCP JSR-166 Expert Group and released to the public domain, as explained
8.36 + * at http://creativecommons.org/publicdomain/zero/1.0/
8.37 + */
8.38 +
8.39 +package java.util.concurrent;
8.40 +
8.41 +import java.util.AbstractCollection;
8.42 +import java.util.ArrayList;
8.43 +import java.util.Collection;
8.44 +import java.util.Deque;
8.45 +import java.util.Iterator;
8.46 +import java.util.NoSuchElementException;
8.47 +import java.util.Queue;
8.48 +
8.49 +/**
8.50 + * An unbounded concurrent {@linkplain Deque deque} based on linked nodes.
8.51 + * Concurrent insertion, removal, and access operations execute safely
8.52 + * across multiple threads.
8.53 + * A {@code ConcurrentLinkedDeque} is an appropriate choice when
8.54 + * many threads will share access to a common collection.
8.55 + * Like most other concurrent collection implementations, this class
8.56 + * does not permit the use of {@code null} elements.
8.57 + *
8.58 + * <p>Iterators are <i>weakly consistent</i>, returning elements
8.59 + * reflecting the state of the deque at some point at or since the
8.60 + * creation of the iterator. They do <em>not</em> throw {@link
8.61 + * java.util.ConcurrentModificationException
8.62 + * ConcurrentModificationException}, and may proceed concurrently with
8.63 + * other operations.
8.64 + *
8.65 + * <p>Beware that, unlike in most collections, the {@code size} method
8.66 + * is <em>NOT</em> a constant-time operation. Because of the
8.67 + * asynchronous nature of these deques, determining the current number
8.68 + * of elements requires a traversal of the elements, and so may report
8.69 + * inaccurate results if this collection is modified during traversal.
8.70 + * Additionally, the bulk operations {@code addAll},
8.71 + * {@code removeAll}, {@code retainAll}, {@code containsAll},
8.72 + * {@code equals}, and {@code toArray} are <em>not</em> guaranteed
8.73 + * to be performed atomically. For example, an iterator operating
8.74 + * concurrently with an {@code addAll} operation might view only some
8.75 + * of the added elements.
8.76 + *
8.77 + * <p>This class and its iterator implement all of the <em>optional</em>
8.78 + * methods of the {@link Deque} and {@link Iterator} interfaces.
8.79 + *
8.80 + * <p>Memory consistency effects: As with other concurrent collections,
8.81 + * actions in a thread prior to placing an object into a
8.82 + * {@code ConcurrentLinkedDeque}
8.83 + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
8.84 + * actions subsequent to the access or removal of that element from
8.85 + * the {@code ConcurrentLinkedDeque} in another thread.
8.86 + *
8.87 + * <p>This class is a member of the
8.88 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
8.89 + * Java Collections Framework</a>.
8.90 + *
8.91 + * @since 1.7
8.92 + * @author Doug Lea
8.93 + * @author Martin Buchholz
8.94 + * @param <E> the type of elements held in this collection
8.95 + */
8.96 +
8.97 +public class ConcurrentLinkedDeque<E>
8.98 + extends AbstractCollection<E>
8.99 + implements Deque<E>, java.io.Serializable {
8.100 +
8.101 + /*
8.102 + * This is an implementation of a concurrent lock-free deque
8.103 + * supporting interior removes but not interior insertions, as
8.104 + * required to support the entire Deque interface.
8.105 + *
8.106 + * We extend the techniques developed for ConcurrentLinkedQueue and
8.107 + * LinkedTransferQueue (see the internal docs for those classes).
8.108 + * Understanding the ConcurrentLinkedQueue implementation is a
8.109 + * prerequisite for understanding the implementation of this class.
8.110 + *
8.111 + * The data structure is a symmetrical doubly-linked "GC-robust"
8.112 + * linked list of nodes. We minimize the number of volatile writes
8.113 + * using two techniques: advancing multiple hops with a single CAS
8.114 + * and mixing volatile and non-volatile writes of the same memory
8.115 + * locations.
8.116 + *
8.117 + * A node contains the expected E ("item") and links to predecessor
8.118 + * ("prev") and successor ("next") nodes:
8.119 + *
8.120 + * class Node<E> { volatile Node<E> prev, next; volatile E item; }
8.121 + *
8.122 + * A node p is considered "live" if it contains a non-null item
8.123 + * (p.item != null). When an item is CASed to null, the item is
8.124 + * atomically logically deleted from the collection.
8.125 + *
8.126 + * At any time, there is precisely one "first" node with a null
8.127 + * prev reference that terminates any chain of prev references
8.128 + * starting at a live node. Similarly there is precisely one
8.129 + * "last" node terminating any chain of next references starting at
8.130 + * a live node. The "first" and "last" nodes may or may not be live.
8.131 + * The "first" and "last" nodes are always mutually reachable.
8.132 + *
8.133 + * A new element is added atomically by CASing the null prev or
8.134 + * next reference in the first or last node to a fresh node
8.135 + * containing the element. The element's node atomically becomes
8.136 + * "live" at that point.
8.137 + *
8.138 + * A node is considered "active" if it is a live node, or the
8.139 + * first or last node. Active nodes cannot be unlinked.
8.140 + *
8.141 + * A "self-link" is a next or prev reference that is the same node:
8.142 + * p.prev == p or p.next == p
8.143 + * Self-links are used in the node unlinking process. Active nodes
8.144 + * never have self-links.
8.145 + *
8.146 + * A node p is active if and only if:
8.147 + *
8.148 + * p.item != null ||
8.149 + * (p.prev == null && p.next != p) ||
8.150 + * (p.next == null && p.prev != p)
8.151 + *
8.152 + * The deque object has two node references, "head" and "tail".
8.153 + * The head and tail are only approximations to the first and last
8.154 + * nodes of the deque. The first node can always be found by
8.155 + * following prev pointers from head; likewise for tail. However,
8.156 + * it is permissible for head and tail to be referring to deleted
8.157 + * nodes that have been unlinked and so may not be reachable from
8.158 + * any live node.
8.159 + *
8.160 + * There are 3 stages of node deletion;
8.161 + * "logical deletion", "unlinking", and "gc-unlinking".
8.162 + *
8.163 + * 1. "logical deletion" by CASing item to null atomically removes
8.164 + * the element from the collection, and makes the containing node
8.165 + * eligible for unlinking.
8.166 + *
8.167 + * 2. "unlinking" makes a deleted node unreachable from active
8.168 + * nodes, and thus eventually reclaimable by GC. Unlinked nodes
8.169 + * may remain reachable indefinitely from an iterator.
8.170 + *
8.171 + * Physical node unlinking is merely an optimization (albeit a
8.172 + * critical one), and so can be performed at our convenience. At
8.173 + * any time, the set of live nodes maintained by prev and next
8.174 + * links are identical, that is, the live nodes found via next
8.175 + * links from the first node is equal to the elements found via
8.176 + * prev links from the last node. However, this is not true for
8.177 + * nodes that have already been logically deleted - such nodes may
8.178 + * be reachable in one direction only.
8.179 + *
8.180 + * 3. "gc-unlinking" takes unlinking further by making active
8.181 + * nodes unreachable from deleted nodes, making it easier for the
8.182 + * GC to reclaim future deleted nodes. This step makes the data
8.183 + * structure "gc-robust", as first described in detail by Boehm
8.184 + * (http://portal.acm.org/citation.cfm?doid=503272.503282).
8.185 + *
8.186 + * GC-unlinked nodes may remain reachable indefinitely from an
8.187 + * iterator, but unlike unlinked nodes, are never reachable from
8.188 + * head or tail.
8.189 + *
8.190 + * Making the data structure GC-robust will eliminate the risk of
8.191 + * unbounded memory retention with conservative GCs and is likely
8.192 + * to improve performance with generational GCs.
8.193 + *
8.194 + * When a node is dequeued at either end, e.g. via poll(), we would
8.195 + * like to break any references from the node to active nodes. We
8.196 + * develop further the use of self-links that was very effective in
8.197 + * other concurrent collection classes. The idea is to replace
8.198 + * prev and next pointers with special values that are interpreted
8.199 + * to mean off-the-list-at-one-end. These are approximations, but
8.200 + * good enough to preserve the properties we want in our
8.201 + * traversals, e.g. we guarantee that a traversal will never visit
8.202 + * the same element twice, but we don't guarantee whether a
8.203 + * traversal that runs out of elements will be able to see more
8.204 + * elements later after enqueues at that end. Doing gc-unlinking
8.205 + * safely is particularly tricky, since any node can be in use
8.206 + * indefinitely (for example by an iterator). We must ensure that
8.207 + * the nodes pointed at by head/tail never get gc-unlinked, since
8.208 + * head/tail are needed to get "back on track" by other nodes that
8.209 + * are gc-unlinked. gc-unlinking accounts for much of the
8.210 + * implementation complexity.
8.211 + *
8.212 + * Since neither unlinking nor gc-unlinking are necessary for
8.213 + * correctness, there are many implementation choices regarding
8.214 + * frequency (eagerness) of these operations. Since volatile
8.215 + * reads are likely to be much cheaper than CASes, saving CASes by
8.216 + * unlinking multiple adjacent nodes at a time may be a win.
8.217 + * gc-unlinking can be performed rarely and still be effective,
8.218 + * since it is most important that long chains of deleted nodes
8.219 + * are occasionally broken.
8.220 + *
8.221 + * The actual representation we use is that p.next == p means to
8.222 + * goto the first node (which in turn is reached by following prev
8.223 + * pointers from head), and p.next == null && p.prev == p means
8.224 + * that the iteration is at an end and that p is a (static final)
8.225 + * dummy node, NEXT_TERMINATOR, and not the last active node.
8.226 + * Finishing the iteration when encountering such a TERMINATOR is
8.227 + * good enough for read-only traversals, so such traversals can use
8.228 + * p.next == null as the termination condition. When we need to
8.229 + * find the last (active) node, for enqueueing a new node, we need
8.230 + * to check whether we have reached a TERMINATOR node; if so,
8.231 + * restart traversal from tail.
8.232 + *
8.233 + * The implementation is completely directionally symmetrical,
8.234 + * except that most public methods that iterate through the list
8.235 + * follow next pointers ("forward" direction).
8.236 + *
8.237 + * We believe (without full proof) that all single-element deque
8.238 + * operations (e.g., addFirst, peekLast, pollLast) are linearizable
8.239 + * (see Herlihy and Shavit's book). However, some combinations of
8.240 + * operations are known not to be linearizable. In particular,
8.241 + * when an addFirst(A) is racing with pollFirst() removing B, it is
8.242 + * possible for an observer iterating over the elements to observe
8.243 + * A B C and subsequently observe A C, even though no interior
8.244 + * removes are ever performed. Nevertheless, iterators behave
8.245 + * reasonably, providing the "weakly consistent" guarantees.
8.246 + *
8.247 + * Empirically, microbenchmarks suggest that this class adds about
8.248 + * 40% overhead relative to ConcurrentLinkedQueue, which feels as
8.249 + * good as we can hope for.
8.250 + */
8.251 +
8.252 + private static final long serialVersionUID = 876323262645176354L;
8.253 +
8.254 + /**
8.255 + * A node from which the first node on list (that is, the unique node p
8.256 + * with p.prev == null && p.next != p) can be reached in O(1) time.
8.257 + * Invariants:
8.258 + * - the first node is always O(1) reachable from head via prev links
8.259 + * - all live nodes are reachable from the first node via succ()
8.260 + * - head != null
8.261 + * - (tmp = head).next != tmp || tmp != head
8.262 + * - head is never gc-unlinked (but may be unlinked)
8.263 + * Non-invariants:
8.264 + * - head.item may or may not be null
8.265 + * - head may not be reachable from the first or last node, or from tail
8.266 + */
8.267 + private transient volatile Node<E> head;
8.268 +
8.269 + /**
8.270 + * A node from which the last node on list (that is, the unique node p
8.271 + * with p.next == null && p.prev != p) can be reached in O(1) time.
8.272 + * Invariants:
8.273 + * - the last node is always O(1) reachable from tail via next links
8.274 + * - all live nodes are reachable from the last node via pred()
8.275 + * - tail != null
8.276 + * - tail is never gc-unlinked (but may be unlinked)
8.277 + * Non-invariants:
8.278 + * - tail.item may or may not be null
8.279 + * - tail may not be reachable from the first or last node, or from head
8.280 + */
8.281 + private transient volatile Node<E> tail;
8.282 +
8.283 + private static final Node<Object> PREV_TERMINATOR, NEXT_TERMINATOR;
8.284 +
8.285 + @SuppressWarnings("unchecked")
8.286 + Node<E> prevTerminator() {
8.287 + return (Node<E>) PREV_TERMINATOR;
8.288 + }
8.289 +
8.290 + @SuppressWarnings("unchecked")
8.291 + Node<E> nextTerminator() {
8.292 + return (Node<E>) NEXT_TERMINATOR;
8.293 + }
8.294 +
8.295 + static final class Node<E> {
8.296 + volatile Node<E> prev;
8.297 + volatile E item;
8.298 + volatile Node<E> next;
8.299 +
8.300 + Node() { // default constructor for NEXT_TERMINATOR, PREV_TERMINATOR
8.301 + }
8.302 +
8.303 + /**
8.304 + * Constructs a new node. Uses relaxed write because item can
8.305 + * only be seen after publication via casNext or casPrev.
8.306 + */
8.307 + Node(E item) {
8.308 + UNSAFE.putObject(this, itemOffset, item);
8.309 + }
8.310 +
8.311 + boolean casItem(E cmp, E val) {
8.312 + return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);
8.313 + }
8.314 +
8.315 + void lazySetNext(Node<E> val) {
8.316 + UNSAFE.putOrderedObject(this, nextOffset, val);
8.317 + }
8.318 +
8.319 + boolean casNext(Node<E> cmp, Node<E> val) {
8.320 + return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
8.321 + }
8.322 +
8.323 + void lazySetPrev(Node<E> val) {
8.324 + UNSAFE.putOrderedObject(this, prevOffset, val);
8.325 + }
8.326 +
8.327 + boolean casPrev(Node<E> cmp, Node<E> val) {
8.328 + return UNSAFE.compareAndSwapObject(this, prevOffset, cmp, val);
8.329 + }
8.330 +
8.331 + // Unsafe mechanics
8.332 +
8.333 + private static final sun.misc.Unsafe UNSAFE;
8.334 + private static final long prevOffset;
8.335 + private static final long itemOffset;
8.336 + private static final long nextOffset;
8.337 +
8.338 + static {
8.339 + try {
8.340 + UNSAFE = sun.misc.Unsafe.getUnsafe();
8.341 + Class k = Node.class;
8.342 + prevOffset = UNSAFE.objectFieldOffset
8.343 + (k.getDeclaredField("prev"));
8.344 + itemOffset = UNSAFE.objectFieldOffset
8.345 + (k.getDeclaredField("item"));
8.346 + nextOffset = UNSAFE.objectFieldOffset
8.347 + (k.getDeclaredField("next"));
8.348 + } catch (Exception e) {
8.349 + throw new Error(e);
8.350 + }
8.351 + }
8.352 + }
8.353 +
8.354 + /**
8.355 + * Links e as first element.
8.356 + */
8.357 + private void linkFirst(E e) {
8.358 + checkNotNull(e);
8.359 + final Node<E> newNode = new Node<E>(e);
8.360 +
8.361 + restartFromHead:
8.362 + for (;;)
8.363 + for (Node<E> h = head, p = h, q;;) {
8.364 + if ((q = p.prev) != null &&
8.365 + (q = (p = q).prev) != null)
8.366 + // Check for head updates every other hop.
8.367 + // If p == q, we are sure to follow head instead.
8.368 + p = (h != (h = head)) ? h : q;
8.369 + else if (p.next == p) // PREV_TERMINATOR
8.370 + continue restartFromHead;
8.371 + else {
8.372 + // p is first node
8.373 + newNode.lazySetNext(p); // CAS piggyback
8.374 + if (p.casPrev(null, newNode)) {
8.375 + // Successful CAS is the linearization point
8.376 + // for e to become an element of this deque,
8.377 + // and for newNode to become "live".
8.378 + if (p != h) // hop two nodes at a time
8.379 + casHead(h, newNode); // Failure is OK.
8.380 + return;
8.381 + }
8.382 + // Lost CAS race to another thread; re-read prev
8.383 + }
8.384 + }
8.385 + }
8.386 +
8.387 + /**
8.388 + * Links e as last element.
8.389 + */
8.390 + private void linkLast(E e) {
8.391 + checkNotNull(e);
8.392 + final Node<E> newNode = new Node<E>(e);
8.393 +
8.394 + restartFromTail:
8.395 + for (;;)
8.396 + for (Node<E> t = tail, p = t, q;;) {
8.397 + if ((q = p.next) != null &&
8.398 + (q = (p = q).next) != null)
8.399 + // Check for tail updates every other hop.
8.400 + // If p == q, we are sure to follow tail instead.
8.401 + p = (t != (t = tail)) ? t : q;
8.402 + else if (p.prev == p) // NEXT_TERMINATOR
8.403 + continue restartFromTail;
8.404 + else {
8.405 + // p is last node
8.406 + newNode.lazySetPrev(p); // CAS piggyback
8.407 + if (p.casNext(null, newNode)) {
8.408 + // Successful CAS is the linearization point
8.409 + // for e to become an element of this deque,
8.410 + // and for newNode to become "live".
8.411 + if (p != t) // hop two nodes at a time
8.412 + casTail(t, newNode); // Failure is OK.
8.413 + return;
8.414 + }
8.415 + // Lost CAS race to another thread; re-read next
8.416 + }
8.417 + }
8.418 + }
8.419 +
8.420 + private static final int HOPS = 2;
8.421 +
8.422 + /**
8.423 + * Unlinks non-null node x.
8.424 + */
8.425 + void unlink(Node<E> x) {
8.426 + // assert x != null;
8.427 + // assert x.item == null;
8.428 + // assert x != PREV_TERMINATOR;
8.429 + // assert x != NEXT_TERMINATOR;
8.430 +
8.431 + final Node<E> prev = x.prev;
8.432 + final Node<E> next = x.next;
8.433 + if (prev == null) {
8.434 + unlinkFirst(x, next);
8.435 + } else if (next == null) {
8.436 + unlinkLast(x, prev);
8.437 + } else {
8.438 + // Unlink interior node.
8.439 + //
8.440 + // This is the common case, since a series of polls at the
8.441 + // same end will be "interior" removes, except perhaps for
8.442 + // the first one, since end nodes cannot be unlinked.
8.443 + //
8.444 + // At any time, all active nodes are mutually reachable by
8.445 + // following a sequence of either next or prev pointers.
8.446 + //
8.447 + // Our strategy is to find the unique active predecessor
8.448 + // and successor of x. Try to fix up their links so that
8.449 + // they point to each other, leaving x unreachable from
8.450 + // active nodes. If successful, and if x has no live
8.451 + // predecessor/successor, we additionally try to gc-unlink,
8.452 + // leaving active nodes unreachable from x, by rechecking
8.453 + // that the status of predecessor and successor are
8.454 + // unchanged and ensuring that x is not reachable from
8.455 + // tail/head, before setting x's prev/next links to their
8.456 + // logical approximate replacements, self/TERMINATOR.
8.457 + Node<E> activePred, activeSucc;
8.458 + boolean isFirst, isLast;
8.459 + int hops = 1;
8.460 +
8.461 + // Find active predecessor
8.462 + for (Node<E> p = prev; ; ++hops) {
8.463 + if (p.item != null) {
8.464 + activePred = p;
8.465 + isFirst = false;
8.466 + break;
8.467 + }
8.468 + Node<E> q = p.prev;
8.469 + if (q == null) {
8.470 + if (p.next == p)
8.471 + return;
8.472 + activePred = p;
8.473 + isFirst = true;
8.474 + break;
8.475 + }
8.476 + else if (p == q)
8.477 + return;
8.478 + else
8.479 + p = q;
8.480 + }
8.481 +
8.482 + // Find active successor
8.483 + for (Node<E> p = next; ; ++hops) {
8.484 + if (p.item != null) {
8.485 + activeSucc = p;
8.486 + isLast = false;
8.487 + break;
8.488 + }
8.489 + Node<E> q = p.next;
8.490 + if (q == null) {
8.491 + if (p.prev == p)
8.492 + return;
8.493 + activeSucc = p;
8.494 + isLast = true;
8.495 + break;
8.496 + }
8.497 + else if (p == q)
8.498 + return;
8.499 + else
8.500 + p = q;
8.501 + }
8.502 +
8.503 + // TODO: better HOP heuristics
8.504 + if (hops < HOPS
8.505 + // always squeeze out interior deleted nodes
8.506 + && (isFirst | isLast))
8.507 + return;
8.508 +
8.509 + // Squeeze out deleted nodes between activePred and
8.510 + // activeSucc, including x.
8.511 + skipDeletedSuccessors(activePred);
8.512 + skipDeletedPredecessors(activeSucc);
8.513 +
8.514 + // Try to gc-unlink, if possible
8.515 + if ((isFirst | isLast) &&
8.516 +
8.517 + // Recheck expected state of predecessor and successor
8.518 + (activePred.next == activeSucc) &&
8.519 + (activeSucc.prev == activePred) &&
8.520 + (isFirst ? activePred.prev == null : activePred.item != null) &&
8.521 + (isLast ? activeSucc.next == null : activeSucc.item != null)) {
8.522 +
8.523 + updateHead(); // Ensure x is not reachable from head
8.524 + updateTail(); // Ensure x is not reachable from tail
8.525 +
8.526 + // Finally, actually gc-unlink
8.527 + x.lazySetPrev(isFirst ? prevTerminator() : x);
8.528 + x.lazySetNext(isLast ? nextTerminator() : x);
8.529 + }
8.530 + }
8.531 + }
8.532 +
8.533 + /**
8.534 + * Unlinks non-null first node.
8.535 + */
8.536 + private void unlinkFirst(Node<E> first, Node<E> next) {
8.537 + // assert first != null;
8.538 + // assert next != null;
8.539 + // assert first.item == null;
8.540 + for (Node<E> o = null, p = next, q;;) {
8.541 + if (p.item != null || (q = p.next) == null) {
8.542 + if (o != null && p.prev != p && first.casNext(next, p)) {
8.543 + skipDeletedPredecessors(p);
8.544 + if (first.prev == null &&
8.545 + (p.next == null || p.item != null) &&
8.546 + p.prev == first) {
8.547 +
8.548 + updateHead(); // Ensure o is not reachable from head
8.549 + updateTail(); // Ensure o is not reachable from tail
8.550 +
8.551 + // Finally, actually gc-unlink
8.552 + o.lazySetNext(o);
8.553 + o.lazySetPrev(prevTerminator());
8.554 + }
8.555 + }
8.556 + return;
8.557 + }
8.558 + else if (p == q)
8.559 + return;
8.560 + else {
8.561 + o = p;
8.562 + p = q;
8.563 + }
8.564 + }
8.565 + }
8.566 +
8.567 + /**
8.568 + * Unlinks non-null last node.
8.569 + */
8.570 + private void unlinkLast(Node<E> last, Node<E> prev) {
8.571 + // assert last != null;
8.572 + // assert prev != null;
8.573 + // assert last.item == null;
8.574 + for (Node<E> o = null, p = prev, q;;) {
8.575 + if (p.item != null || (q = p.prev) == null) {
8.576 + if (o != null && p.next != p && last.casPrev(prev, p)) {
8.577 + skipDeletedSuccessors(p);
8.578 + if (last.next == null &&
8.579 + (p.prev == null || p.item != null) &&
8.580 + p.next == last) {
8.581 +
8.582 + updateHead(); // Ensure o is not reachable from head
8.583 + updateTail(); // Ensure o is not reachable from tail
8.584 +
8.585 + // Finally, actually gc-unlink
8.586 + o.lazySetPrev(o);
8.587 + o.lazySetNext(nextTerminator());
8.588 + }
8.589 + }
8.590 + return;
8.591 + }
8.592 + else if (p == q)
8.593 + return;
8.594 + else {
8.595 + o = p;
8.596 + p = q;
8.597 + }
8.598 + }
8.599 + }
8.600 +
8.601 + /**
8.602 + * Guarantees that any node which was unlinked before a call to
8.603 + * this method will be unreachable from head after it returns.
8.604 + * Does not guarantee to eliminate slack, only that head will
8.605 + * point to a node that was active while this method was running.
8.606 + */
8.607 + private final void updateHead() {
8.608 + // Either head already points to an active node, or we keep
8.609 + // trying to cas it to the first node until it does.
8.610 + Node<E> h, p, q;
8.611 + restartFromHead:
8.612 + while ((h = head).item == null && (p = h.prev) != null) {
8.613 + for (;;) {
8.614 + if ((q = p.prev) == null ||
8.615 + (q = (p = q).prev) == null) {
8.616 + // It is possible that p is PREV_TERMINATOR,
8.617 + // but if so, the CAS is guaranteed to fail.
8.618 + if (casHead(h, p))
8.619 + return;
8.620 + else
8.621 + continue restartFromHead;
8.622 + }
8.623 + else if (h != head)
8.624 + continue restartFromHead;
8.625 + else
8.626 + p = q;
8.627 + }
8.628 + }
8.629 + }
8.630 +
8.631 + /**
8.632 + * Guarantees that any node which was unlinked before a call to
8.633 + * this method will be unreachable from tail after it returns.
8.634 + * Does not guarantee to eliminate slack, only that tail will
8.635 + * point to a node that was active while this method was running.
8.636 + */
8.637 + private final void updateTail() {
8.638 + // Either tail already points to an active node, or we keep
8.639 + // trying to cas it to the last node until it does.
8.640 + Node<E> t, p, q;
8.641 + restartFromTail:
8.642 + while ((t = tail).item == null && (p = t.next) != null) {
8.643 + for (;;) {
8.644 + if ((q = p.next) == null ||
8.645 + (q = (p = q).next) == null) {
8.646 + // It is possible that p is NEXT_TERMINATOR,
8.647 + // but if so, the CAS is guaranteed to fail.
8.648 + if (casTail(t, p))
8.649 + return;
8.650 + else
8.651 + continue restartFromTail;
8.652 + }
8.653 + else if (t != tail)
8.654 + continue restartFromTail;
8.655 + else
8.656 + p = q;
8.657 + }
8.658 + }
8.659 + }
8.660 +
8.661 + private void skipDeletedPredecessors(Node<E> x) {
8.662 + whileActive:
8.663 + do {
8.664 + Node<E> prev = x.prev;
8.665 + // assert prev != null;
8.666 + // assert x != NEXT_TERMINATOR;
8.667 + // assert x != PREV_TERMINATOR;
8.668 + Node<E> p = prev;
8.669 + findActive:
8.670 + for (;;) {
8.671 + if (p.item != null)
8.672 + break findActive;
8.673 + Node<E> q = p.prev;
8.674 + if (q == null) {
8.675 + if (p.next == p)
8.676 + continue whileActive;
8.677 + break findActive;
8.678 + }
8.679 + else if (p == q)
8.680 + continue whileActive;
8.681 + else
8.682 + p = q;
8.683 + }
8.684 +
8.685 + // found active CAS target
8.686 + if (prev == p || x.casPrev(prev, p))
8.687 + return;
8.688 +
8.689 + } while (x.item != null || x.next == null);
8.690 + }
8.691 +
8.692 + private void skipDeletedSuccessors(Node<E> x) {
8.693 + whileActive:
8.694 + do {
8.695 + Node<E> next = x.next;
8.696 + // assert next != null;
8.697 + // assert x != NEXT_TERMINATOR;
8.698 + // assert x != PREV_TERMINATOR;
8.699 + Node<E> p = next;
8.700 + findActive:
8.701 + for (;;) {
8.702 + if (p.item != null)
8.703 + break findActive;
8.704 + Node<E> q = p.next;
8.705 + if (q == null) {
8.706 + if (p.prev == p)
8.707 + continue whileActive;
8.708 + break findActive;
8.709 + }
8.710 + else if (p == q)
8.711 + continue whileActive;
8.712 + else
8.713 + p = q;
8.714 + }
8.715 +
8.716 + // found active CAS target
8.717 + if (next == p || x.casNext(next, p))
8.718 + return;
8.719 +
8.720 + } while (x.item != null || x.prev == null);
8.721 + }
8.722 +
8.723 + /**
8.724 + * Returns the successor of p, or the first node if p.next has been
8.725 + * linked to self, which will only be true if traversing with a
8.726 + * stale pointer that is now off the list.
8.727 + */
8.728 + final Node<E> succ(Node<E> p) {
8.729 + // TODO: should we skip deleted nodes here?
8.730 + Node<E> q = p.next;
8.731 + return (p == q) ? first() : q;
8.732 + }
8.733 +
8.734 + /**
8.735 + * Returns the predecessor of p, or the last node if p.prev has been
8.736 + * linked to self, which will only be true if traversing with a
8.737 + * stale pointer that is now off the list.
8.738 + */
8.739 + final Node<E> pred(Node<E> p) {
8.740 + Node<E> q = p.prev;
8.741 + return (p == q) ? last() : q;
8.742 + }
8.743 +
8.744 + /**
8.745 + * Returns the first node, the unique node p for which:
8.746 + * p.prev == null && p.next != p
8.747 + * The returned node may or may not be logically deleted.
8.748 + * Guarantees that head is set to the returned node.
8.749 + */
8.750 + Node<E> first() {
8.751 + restartFromHead:
8.752 + for (;;)
8.753 + for (Node<E> h = head, p = h, q;;) {
8.754 + if ((q = p.prev) != null &&
8.755 + (q = (p = q).prev) != null)
8.756 + // Check for head updates every other hop.
8.757 + // If p == q, we are sure to follow head instead.
8.758 + p = (h != (h = head)) ? h : q;
8.759 + else if (p == h
8.760 + // It is possible that p is PREV_TERMINATOR,
8.761 + // but if so, the CAS is guaranteed to fail.
8.762 + || casHead(h, p))
8.763 + return p;
8.764 + else
8.765 + continue restartFromHead;
8.766 + }
8.767 + }
8.768 +
8.769 + /**
8.770 + * Returns the last node, the unique node p for which:
8.771 + * p.next == null && p.prev != p
8.772 + * The returned node may or may not be logically deleted.
8.773 + * Guarantees that tail is set to the returned node.
8.774 + */
8.775 + Node<E> last() {
8.776 + restartFromTail:
8.777 + for (;;)
8.778 + for (Node<E> t = tail, p = t, q;;) {
8.779 + if ((q = p.next) != null &&
8.780 + (q = (p = q).next) != null)
8.781 + // Check for tail updates every other hop.
8.782 + // If p == q, we are sure to follow tail instead.
8.783 + p = (t != (t = tail)) ? t : q;
8.784 + else if (p == t
8.785 + // It is possible that p is NEXT_TERMINATOR,
8.786 + // but if so, the CAS is guaranteed to fail.
8.787 + || casTail(t, p))
8.788 + return p;
8.789 + else
8.790 + continue restartFromTail;
8.791 + }
8.792 + }
8.793 +
8.794 + // Minor convenience utilities
8.795 +
8.796 + /**
8.797 + * Throws NullPointerException if argument is null.
8.798 + *
8.799 + * @param v the element
8.800 + */
8.801 + private static void checkNotNull(Object v) {
8.802 + if (v == null)
8.803 + throw new NullPointerException();
8.804 + }
8.805 +
8.806 + /**
8.807 + * Returns element unless it is null, in which case throws
8.808 + * NoSuchElementException.
8.809 + *
8.810 + * @param v the element
8.811 + * @return the element
8.812 + */
8.813 + private E screenNullResult(E v) {
8.814 + if (v == null)
8.815 + throw new NoSuchElementException();
8.816 + return v;
8.817 + }
8.818 +
8.819 + /**
8.820 + * Creates an array list and fills it with elements of this list.
8.821 + * Used by toArray.
8.822 + *
8.823 + * @return the arrayList
8.824 + */
8.825 + private ArrayList<E> toArrayList() {
8.826 + ArrayList<E> list = new ArrayList<E>();
8.827 + for (Node<E> p = first(); p != null; p = succ(p)) {
8.828 + E item = p.item;
8.829 + if (item != null)
8.830 + list.add(item);
8.831 + }
8.832 + return list;
8.833 + }
8.834 +
8.835 + /**
8.836 + * Constructs an empty deque.
8.837 + */
8.838 + public ConcurrentLinkedDeque() {
8.839 + head = tail = new Node<E>(null);
8.840 + }
8.841 +
8.842 + /**
8.843 + * Constructs a deque initially containing the elements of
8.844 + * the given collection, added in traversal order of the
8.845 + * collection's iterator.
8.846 + *
8.847 + * @param c the collection of elements to initially contain
8.848 + * @throws NullPointerException if the specified collection or any
8.849 + * of its elements are null
8.850 + */
8.851 + public ConcurrentLinkedDeque(Collection<? extends E> c) {
8.852 + // Copy c into a private chain of Nodes
8.853 + Node<E> h = null, t = null;
8.854 + for (E e : c) {
8.855 + checkNotNull(e);
8.856 + Node<E> newNode = new Node<E>(e);
8.857 + if (h == null)
8.858 + h = t = newNode;
8.859 + else {
8.860 + t.lazySetNext(newNode);
8.861 + newNode.lazySetPrev(t);
8.862 + t = newNode;
8.863 + }
8.864 + }
8.865 + initHeadTail(h, t);
8.866 + }
8.867 +
8.868 + /**
8.869 + * Initializes head and tail, ensuring invariants hold.
8.870 + */
8.871 + private void initHeadTail(Node<E> h, Node<E> t) {
8.872 + if (h == t) {
8.873 + if (h == null)
8.874 + h = t = new Node<E>(null);
8.875 + else {
8.876 + // Avoid edge case of a single Node with non-null item.
8.877 + Node<E> newNode = new Node<E>(null);
8.878 + t.lazySetNext(newNode);
8.879 + newNode.lazySetPrev(t);
8.880 + t = newNode;
8.881 + }
8.882 + }
8.883 + head = h;
8.884 + tail = t;
8.885 + }
8.886 +
8.887 + /**
8.888 + * Inserts the specified element at the front of this deque.
8.889 + * As the deque is unbounded, this method will never throw
8.890 + * {@link IllegalStateException}.
8.891 + *
8.892 + * @throws NullPointerException if the specified element is null
8.893 + */
8.894 + public void addFirst(E e) {
8.895 + linkFirst(e);
8.896 + }
8.897 +
8.898 + /**
8.899 + * Inserts the specified element at the end of this deque.
8.900 + * As the deque is unbounded, this method will never throw
8.901 + * {@link IllegalStateException}.
8.902 + *
8.903 + * <p>This method is equivalent to {@link #add}.
8.904 + *
8.905 + * @throws NullPointerException if the specified element is null
8.906 + */
8.907 + public void addLast(E e) {
8.908 + linkLast(e);
8.909 + }
8.910 +
8.911 + /**
8.912 + * Inserts the specified element at the front of this deque.
8.913 + * As the deque is unbounded, this method will never return {@code false}.
8.914 + *
8.915 + * @return {@code true} (as specified by {@link Deque#offerFirst})
8.916 + * @throws NullPointerException if the specified element is null
8.917 + */
8.918 + public boolean offerFirst(E e) {
8.919 + linkFirst(e);
8.920 + return true;
8.921 + }
8.922 +
8.923 + /**
8.924 + * Inserts the specified element at the end of this deque.
8.925 + * As the deque is unbounded, this method will never return {@code false}.
8.926 + *
8.927 + * <p>This method is equivalent to {@link #add}.
8.928 + *
8.929 + * @return {@code true} (as specified by {@link Deque#offerLast})
8.930 + * @throws NullPointerException if the specified element is null
8.931 + */
8.932 + public boolean offerLast(E e) {
8.933 + linkLast(e);
8.934 + return true;
8.935 + }
8.936 +
8.937 + public E peekFirst() {
8.938 + for (Node<E> p = first(); p != null; p = succ(p)) {
8.939 + E item = p.item;
8.940 + if (item != null)
8.941 + return item;
8.942 + }
8.943 + return null;
8.944 + }
8.945 +
8.946 + public E peekLast() {
8.947 + for (Node<E> p = last(); p != null; p = pred(p)) {
8.948 + E item = p.item;
8.949 + if (item != null)
8.950 + return item;
8.951 + }
8.952 + return null;
8.953 + }
8.954 +
8.955 + /**
8.956 + * @throws NoSuchElementException {@inheritDoc}
8.957 + */
8.958 + public E getFirst() {
8.959 + return screenNullResult(peekFirst());
8.960 + }
8.961 +
8.962 + /**
8.963 + * @throws NoSuchElementException {@inheritDoc}
8.964 + */
8.965 + public E getLast() {
8.966 + return screenNullResult(peekLast());
8.967 + }
8.968 +
8.969 + public E pollFirst() {
8.970 + for (Node<E> p = first(); p != null; p = succ(p)) {
8.971 + E item = p.item;
8.972 + if (item != null && p.casItem(item, null)) {
8.973 + unlink(p);
8.974 + return item;
8.975 + }
8.976 + }
8.977 + return null;
8.978 + }
8.979 +
8.980 + public E pollLast() {
8.981 + for (Node<E> p = last(); p != null; p = pred(p)) {
8.982 + E item = p.item;
8.983 + if (item != null && p.casItem(item, null)) {
8.984 + unlink(p);
8.985 + return item;
8.986 + }
8.987 + }
8.988 + return null;
8.989 + }
8.990 +
8.991 + /**
8.992 + * @throws NoSuchElementException {@inheritDoc}
8.993 + */
8.994 + public E removeFirst() {
8.995 + return screenNullResult(pollFirst());
8.996 + }
8.997 +
8.998 + /**
8.999 + * @throws NoSuchElementException {@inheritDoc}
8.1000 + */
8.1001 + public E removeLast() {
8.1002 + return screenNullResult(pollLast());
8.1003 + }
8.1004 +
8.1005 + // *** Queue and stack methods ***
8.1006 +
8.1007 + /**
8.1008 + * Inserts the specified element at the tail of this deque.
8.1009 + * As the deque is unbounded, this method will never return {@code false}.
8.1010 + *
8.1011 + * @return {@code true} (as specified by {@link Queue#offer})
8.1012 + * @throws NullPointerException if the specified element is null
8.1013 + */
8.1014 + public boolean offer(E e) {
8.1015 + return offerLast(e);
8.1016 + }
8.1017 +
8.1018 + /**
8.1019 + * Inserts the specified element at the tail of this deque.
8.1020 + * As the deque is unbounded, this method will never throw
8.1021 + * {@link IllegalStateException} or return {@code false}.
8.1022 + *
8.1023 + * @return {@code true} (as specified by {@link Collection#add})
8.1024 + * @throws NullPointerException if the specified element is null
8.1025 + */
8.1026 + public boolean add(E e) {
8.1027 + return offerLast(e);
8.1028 + }
8.1029 +
8.1030 + public E poll() { return pollFirst(); }
8.1031 + public E remove() { return removeFirst(); }
8.1032 + public E peek() { return peekFirst(); }
8.1033 + public E element() { return getFirst(); }
8.1034 + public void push(E e) { addFirst(e); }
8.1035 + public E pop() { return removeFirst(); }
8.1036 +
8.1037 + /**
8.1038 + * Removes the first element {@code e} such that
8.1039 + * {@code o.equals(e)}, if such an element exists in this deque.
8.1040 + * If the deque does not contain the element, it is unchanged.
8.1041 + *
8.1042 + * @param o element to be removed from this deque, if present
8.1043 + * @return {@code true} if the deque contained the specified element
8.1044 + * @throws NullPointerException if the specified element is null
8.1045 + */
8.1046 + public boolean removeFirstOccurrence(Object o) {
8.1047 + checkNotNull(o);
8.1048 + for (Node<E> p = first(); p != null; p = succ(p)) {
8.1049 + E item = p.item;
8.1050 + if (item != null && o.equals(item) && p.casItem(item, null)) {
8.1051 + unlink(p);
8.1052 + return true;
8.1053 + }
8.1054 + }
8.1055 + return false;
8.1056 + }
8.1057 +
8.1058 + /**
8.1059 + * Removes the last element {@code e} such that
8.1060 + * {@code o.equals(e)}, if such an element exists in this deque.
8.1061 + * If the deque does not contain the element, it is unchanged.
8.1062 + *
8.1063 + * @param o element to be removed from this deque, if present
8.1064 + * @return {@code true} if the deque contained the specified element
8.1065 + * @throws NullPointerException if the specified element is null
8.1066 + */
8.1067 + public boolean removeLastOccurrence(Object o) {
8.1068 + checkNotNull(o);
8.1069 + for (Node<E> p = last(); p != null; p = pred(p)) {
8.1070 + E item = p.item;
8.1071 + if (item != null && o.equals(item) && p.casItem(item, null)) {
8.1072 + unlink(p);
8.1073 + return true;
8.1074 + }
8.1075 + }
8.1076 + return false;
8.1077 + }
8.1078 +
8.1079 + /**
8.1080 + * Returns {@code true} if this deque contains at least one
8.1081 + * element {@code e} such that {@code o.equals(e)}.
8.1082 + *
8.1083 + * @param o element whose presence in this deque is to be tested
8.1084 + * @return {@code true} if this deque contains the specified element
8.1085 + */
8.1086 + public boolean contains(Object o) {
8.1087 + if (o == null) return false;
8.1088 + for (Node<E> p = first(); p != null; p = succ(p)) {
8.1089 + E item = p.item;
8.1090 + if (item != null && o.equals(item))
8.1091 + return true;
8.1092 + }
8.1093 + return false;
8.1094 + }
8.1095 +
8.1096 + /**
8.1097 + * Returns {@code true} if this collection contains no elements.
8.1098 + *
8.1099 + * @return {@code true} if this collection contains no elements
8.1100 + */
8.1101 + public boolean isEmpty() {
8.1102 + return peekFirst() == null;
8.1103 + }
8.1104 +
8.1105 + /**
8.1106 + * Returns the number of elements in this deque. If this deque
8.1107 + * contains more than {@code Integer.MAX_VALUE} elements, it
8.1108 + * returns {@code Integer.MAX_VALUE}.
8.1109 + *
8.1110 + * <p>Beware that, unlike in most collections, this method is
8.1111 + * <em>NOT</em> a constant-time operation. Because of the
8.1112 + * asynchronous nature of these deques, determining the current
8.1113 + * number of elements requires traversing them all to count them.
8.1114 + * Additionally, it is possible for the size to change during
8.1115 + * execution of this method, in which case the returned result
8.1116 + * will be inaccurate. Thus, this method is typically not very
8.1117 + * useful in concurrent applications.
8.1118 + *
8.1119 + * @return the number of elements in this deque
8.1120 + */
8.1121 + public int size() {
8.1122 + int count = 0;
8.1123 + for (Node<E> p = first(); p != null; p = succ(p))
8.1124 + if (p.item != null)
8.1125 + // Collection.size() spec says to max out
8.1126 + if (++count == Integer.MAX_VALUE)
8.1127 + break;
8.1128 + return count;
8.1129 + }
8.1130 +
8.1131 + /**
8.1132 + * Removes the first element {@code e} such that
8.1133 + * {@code o.equals(e)}, if such an element exists in this deque.
8.1134 + * If the deque does not contain the element, it is unchanged.
8.1135 + *
8.1136 + * @param o element to be removed from this deque, if present
8.1137 + * @return {@code true} if the deque contained the specified element
8.1138 + * @throws NullPointerException if the specified element is null
8.1139 + */
8.1140 + public boolean remove(Object o) {
8.1141 + return removeFirstOccurrence(o);
8.1142 + }
8.1143 +
8.1144 + /**
8.1145 + * Appends all of the elements in the specified collection to the end of
8.1146 + * this deque, in the order that they are returned by the specified
8.1147 + * collection's iterator. Attempts to {@code addAll} of a deque to
8.1148 + * itself result in {@code IllegalArgumentException}.
8.1149 + *
8.1150 + * @param c the elements to be inserted into this deque
8.1151 + * @return {@code true} if this deque changed as a result of the call
8.1152 + * @throws NullPointerException if the specified collection or any
8.1153 + * of its elements are null
8.1154 + * @throws IllegalArgumentException if the collection is this deque
8.1155 + */
8.1156 + public boolean addAll(Collection<? extends E> c) {
8.1157 + if (c == this)
8.1158 + // As historically specified in AbstractQueue#addAll
8.1159 + throw new IllegalArgumentException();
8.1160 +
8.1161 + // Copy c into a private chain of Nodes
8.1162 + Node<E> beginningOfTheEnd = null, last = null;
8.1163 + for (E e : c) {
8.1164 + checkNotNull(e);
8.1165 + Node<E> newNode = new Node<E>(e);
8.1166 + if (beginningOfTheEnd == null)
8.1167 + beginningOfTheEnd = last = newNode;
8.1168 + else {
8.1169 + last.lazySetNext(newNode);
8.1170 + newNode.lazySetPrev(last);
8.1171 + last = newNode;
8.1172 + }
8.1173 + }
8.1174 + if (beginningOfTheEnd == null)
8.1175 + return false;
8.1176 +
8.1177 + // Atomically append the chain at the tail of this collection
8.1178 + restartFromTail:
8.1179 + for (;;)
8.1180 + for (Node<E> t = tail, p = t, q;;) {
8.1181 + if ((q = p.next) != null &&
8.1182 + (q = (p = q).next) != null)
8.1183 + // Check for tail updates every other hop.
8.1184 + // If p == q, we are sure to follow tail instead.
8.1185 + p = (t != (t = tail)) ? t : q;
8.1186 + else if (p.prev == p) // NEXT_TERMINATOR
8.1187 + continue restartFromTail;
8.1188 + else {
8.1189 + // p is last node
8.1190 + beginningOfTheEnd.lazySetPrev(p); // CAS piggyback
8.1191 + if (p.casNext(null, beginningOfTheEnd)) {
8.1192 + // Successful CAS is the linearization point
8.1193 + // for all elements to be added to this deque.
8.1194 + if (!casTail(t, last)) {
8.1195 + // Try a little harder to update tail,
8.1196 + // since we may be adding many elements.
8.1197 + t = tail;
8.1198 + if (last.next == null)
8.1199 + casTail(t, last);
8.1200 + }
8.1201 + return true;
8.1202 + }
8.1203 + // Lost CAS race to another thread; re-read next
8.1204 + }
8.1205 + }
8.1206 + }
8.1207 +
8.1208 + /**
8.1209 + * Removes all of the elements from this deque.
8.1210 + */
8.1211 + public void clear() {
8.1212 + while (pollFirst() != null)
8.1213 + ;
8.1214 + }
8.1215 +
8.1216 + /**
8.1217 + * Returns an array containing all of the elements in this deque, in
8.1218 + * proper sequence (from first to last element).
8.1219 + *
8.1220 + * <p>The returned array will be "safe" in that no references to it are
8.1221 + * maintained by this deque. (In other words, this method must allocate
8.1222 + * a new array). The caller is thus free to modify the returned array.
8.1223 + *
8.1224 + * <p>This method acts as bridge between array-based and collection-based
8.1225 + * APIs.
8.1226 + *
8.1227 + * @return an array containing all of the elements in this deque
8.1228 + */
8.1229 + public Object[] toArray() {
8.1230 + return toArrayList().toArray();
8.1231 + }
8.1232 +
8.1233 + /**
8.1234 + * Returns an array containing all of the elements in this deque,
8.1235 + * in proper sequence (from first to last element); the runtime
8.1236 + * type of the returned array is that of the specified array. If
8.1237 + * the deque fits in the specified array, it is returned therein.
8.1238 + * Otherwise, a new array is allocated with the runtime type of
8.1239 + * the specified array and the size of this deque.
8.1240 + *
8.1241 + * <p>If this deque fits in the specified array with room to spare
8.1242 + * (i.e., the array has more elements than this deque), the element in
8.1243 + * the array immediately following the end of the deque is set to
8.1244 + * {@code null}.
8.1245 + *
8.1246 + * <p>Like the {@link #toArray()} method, this method acts as
8.1247 + * bridge between array-based and collection-based APIs. Further,
8.1248 + * this method allows precise control over the runtime type of the
8.1249 + * output array, and may, under certain circumstances, be used to
8.1250 + * save allocation costs.
8.1251 + *
8.1252 + * <p>Suppose {@code x} is a deque known to contain only strings.
8.1253 + * The following code can be used to dump the deque into a newly
8.1254 + * allocated array of {@code String}:
8.1255 + *
8.1256 + * <pre>
8.1257 + * String[] y = x.toArray(new String[0]);</pre>
8.1258 + *
8.1259 + * Note that {@code toArray(new Object[0])} is identical in function to
8.1260 + * {@code toArray()}.
8.1261 + *
8.1262 + * @param a the array into which the elements of the deque are to
8.1263 + * be stored, if it is big enough; otherwise, a new array of the
8.1264 + * same runtime type is allocated for this purpose
8.1265 + * @return an array containing all of the elements in this deque
8.1266 + * @throws ArrayStoreException if the runtime type of the specified array
8.1267 + * is not a supertype of the runtime type of every element in
8.1268 + * this deque
8.1269 + * @throws NullPointerException if the specified array is null
8.1270 + */
8.1271 + public <T> T[] toArray(T[] a) {
8.1272 + return toArrayList().toArray(a);
8.1273 + }
8.1274 +
8.1275 + /**
8.1276 + * Returns an iterator over the elements in this deque in proper sequence.
8.1277 + * The elements will be returned in order from first (head) to last (tail).
8.1278 + *
8.1279 + * <p>The returned iterator is a "weakly consistent" iterator that
8.1280 + * will never throw {@link java.util.ConcurrentModificationException
8.1281 + * ConcurrentModificationException}, and guarantees to traverse
8.1282 + * elements as they existed upon construction of the iterator, and
8.1283 + * may (but is not guaranteed to) reflect any modifications
8.1284 + * subsequent to construction.
8.1285 + *
8.1286 + * @return an iterator over the elements in this deque in proper sequence
8.1287 + */
8.1288 + public Iterator<E> iterator() {
8.1289 + return new Itr();
8.1290 + }
8.1291 +
8.1292 + /**
8.1293 + * Returns an iterator over the elements in this deque in reverse
8.1294 + * sequential order. The elements will be returned in order from
8.1295 + * last (tail) to first (head).
8.1296 + *
8.1297 + * <p>The returned iterator is a "weakly consistent" iterator that
8.1298 + * will never throw {@link java.util.ConcurrentModificationException
8.1299 + * ConcurrentModificationException}, and guarantees to traverse
8.1300 + * elements as they existed upon construction of the iterator, and
8.1301 + * may (but is not guaranteed to) reflect any modifications
8.1302 + * subsequent to construction.
8.1303 + *
8.1304 + * @return an iterator over the elements in this deque in reverse order
8.1305 + */
8.1306 + public Iterator<E> descendingIterator() {
8.1307 + return new DescendingItr();
8.1308 + }
8.1309 +
8.1310 + private abstract class AbstractItr implements Iterator<E> {
8.1311 + /**
8.1312 + * Next node to return item for.
8.1313 + */
8.1314 + private Node<E> nextNode;
8.1315 +
8.1316 + /**
8.1317 + * nextItem holds on to item fields because once we claim
8.1318 + * that an element exists in hasNext(), we must return it in
8.1319 + * the following next() call even if it was in the process of
8.1320 + * being removed when hasNext() was called.
8.1321 + */
8.1322 + private E nextItem;
8.1323 +
8.1324 + /**
8.1325 + * Node returned by most recent call to next. Needed by remove.
8.1326 + * Reset to null if this element is deleted by a call to remove.
8.1327 + */
8.1328 + private Node<E> lastRet;
8.1329 +
8.1330 + abstract Node<E> startNode();
8.1331 + abstract Node<E> nextNode(Node<E> p);
8.1332 +
8.1333 + AbstractItr() {
8.1334 + advance();
8.1335 + }
8.1336 +
8.1337 + /**
8.1338 + * Sets nextNode and nextItem to next valid node, or to null
8.1339 + * if no such.
8.1340 + */
8.1341 + private void advance() {
8.1342 + lastRet = nextNode;
8.1343 +
8.1344 + Node<E> p = (nextNode == null) ? startNode() : nextNode(nextNode);
8.1345 + for (;; p = nextNode(p)) {
8.1346 + if (p == null) {
8.1347 + // p might be active end or TERMINATOR node; both are OK
8.1348 + nextNode = null;
8.1349 + nextItem = null;
8.1350 + break;
8.1351 + }
8.1352 + E item = p.item;
8.1353 + if (item != null) {
8.1354 + nextNode = p;
8.1355 + nextItem = item;
8.1356 + break;
8.1357 + }
8.1358 + }
8.1359 + }
8.1360 +
8.1361 + public boolean hasNext() {
8.1362 + return nextItem != null;
8.1363 + }
8.1364 +
8.1365 + public E next() {
8.1366 + E item = nextItem;
8.1367 + if (item == null) throw new NoSuchElementException();
8.1368 + advance();
8.1369 + return item;
8.1370 + }
8.1371 +
8.1372 + public void remove() {
8.1373 + Node<E> l = lastRet;
8.1374 + if (l == null) throw new IllegalStateException();
8.1375 + l.item = null;
8.1376 + unlink(l);
8.1377 + lastRet = null;
8.1378 + }
8.1379 + }
8.1380 +
8.1381 + /** Forward iterator */
8.1382 + private class Itr extends AbstractItr {
8.1383 + Node<E> startNode() { return first(); }
8.1384 + Node<E> nextNode(Node<E> p) { return succ(p); }
8.1385 + }
8.1386 +
8.1387 + /** Descending iterator */
8.1388 + private class DescendingItr extends AbstractItr {
8.1389 + Node<E> startNode() { return last(); }
8.1390 + Node<E> nextNode(Node<E> p) { return pred(p); }
8.1391 + }
8.1392 +
8.1393 + /**
8.1394 + * Saves the state to a stream (that is, serializes it).
8.1395 + *
8.1396 + * @serialData All of the elements (each an {@code E}) in
8.1397 + * the proper order, followed by a null
8.1398 + * @param s the stream
8.1399 + */
8.1400 + private void writeObject(java.io.ObjectOutputStream s)
8.1401 + throws java.io.IOException {
8.1402 +
8.1403 + // Write out any hidden stuff
8.1404 + s.defaultWriteObject();
8.1405 +
8.1406 + // Write out all elements in the proper order.
8.1407 + for (Node<E> p = first(); p != null; p = succ(p)) {
8.1408 + E item = p.item;
8.1409 + if (item != null)
8.1410 + s.writeObject(item);
8.1411 + }
8.1412 +
8.1413 + // Use trailing null as sentinel
8.1414 + s.writeObject(null);
8.1415 + }
8.1416 +
8.1417 + /**
8.1418 + * Reconstitutes the instance from a stream (that is, deserializes it).
8.1419 + * @param s the stream
8.1420 + */
8.1421 + private void readObject(java.io.ObjectInputStream s)
8.1422 + throws java.io.IOException, ClassNotFoundException {
8.1423 + s.defaultReadObject();
8.1424 +
8.1425 + // Read in elements until trailing null sentinel found
8.1426 + Node<E> h = null, t = null;
8.1427 + Object item;
8.1428 + while ((item = s.readObject()) != null) {
8.1429 + @SuppressWarnings("unchecked")
8.1430 + Node<E> newNode = new Node<E>((E) item);
8.1431 + if (h == null)
8.1432 + h = t = newNode;
8.1433 + else {
8.1434 + t.lazySetNext(newNode);
8.1435 + newNode.lazySetPrev(t);
8.1436 + t = newNode;
8.1437 + }
8.1438 + }
8.1439 + initHeadTail(h, t);
8.1440 + }
8.1441 +
8.1442 +
8.1443 + private boolean casHead(Node<E> cmp, Node<E> val) {
8.1444 + return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
8.1445 + }
8.1446 +
8.1447 + private boolean casTail(Node<E> cmp, Node<E> val) {
8.1448 + return UNSAFE.compareAndSwapObject(this, tailOffset, cmp, val);
8.1449 + }
8.1450 +
8.1451 + // Unsafe mechanics
8.1452 +
8.1453 + private static final sun.misc.Unsafe UNSAFE;
8.1454 + private static final long headOffset;
8.1455 + private static final long tailOffset;
8.1456 + static {
8.1457 + PREV_TERMINATOR = new Node<Object>();
8.1458 + PREV_TERMINATOR.next = PREV_TERMINATOR;
8.1459 + NEXT_TERMINATOR = new Node<Object>();
8.1460 + NEXT_TERMINATOR.prev = NEXT_TERMINATOR;
8.1461 + try {
8.1462 + UNSAFE = sun.misc.Unsafe.getUnsafe();
8.1463 + Class k = ConcurrentLinkedDeque.class;
8.1464 + headOffset = UNSAFE.objectFieldOffset
8.1465 + (k.getDeclaredField("head"));
8.1466 + tailOffset = UNSAFE.objectFieldOffset
8.1467 + (k.getDeclaredField("tail"));
8.1468 + } catch (Exception e) {
8.1469 + throw new Error(e);
8.1470 + }
8.1471 + }
8.1472 +}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java Sat Mar 19 10:48:29 2016 +0100
9.3 @@ -0,0 +1,835 @@
9.4 +/*
9.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
9.6 + *
9.7 + * This code is free software; you can redistribute it and/or modify it
9.8 + * under the terms of the GNU General Public License version 2 only, as
9.9 + * published by the Free Software Foundation. Oracle designates this
9.10 + * particular file as subject to the "Classpath" exception as provided
9.11 + * by Oracle in the LICENSE file that accompanied this code.
9.12 + *
9.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
9.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
9.16 + * version 2 for more details (a copy is included in the LICENSE file that
9.17 + * accompanied this code).
9.18 + *
9.19 + * You should have received a copy of the GNU General Public License version
9.20 + * 2 along with this work; if not, write to the Free Software Foundation,
9.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
9.22 + *
9.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
9.24 + * or visit www.oracle.com if you need additional information or have any
9.25 + * questions.
9.26 + */
9.27 +
9.28 +/*
9.29 + * This file is available under and governed by the GNU General Public
9.30 + * License version 2 only, as published by the Free Software Foundation.
9.31 + * However, the following notice accompanied the original version of this
9.32 + * file:
9.33 + *
9.34 + * Written by Doug Lea and Martin Buchholz with assistance from members of
9.35 + * JCP JSR-166 Expert Group and released to the public domain, as explained
9.36 + * at http://creativecommons.org/publicdomain/zero/1.0/
9.37 + */
9.38 +
9.39 +package java.util.concurrent;
9.40 +
9.41 +import java.util.AbstractQueue;
9.42 +import java.util.ArrayList;
9.43 +import java.util.Collection;
9.44 +import java.util.Iterator;
9.45 +import java.util.NoSuchElementException;
9.46 +import java.util.Queue;
9.47 +
9.48 +/**
9.49 + * An unbounded thread-safe {@linkplain Queue queue} based on linked nodes.
9.50 + * This queue orders elements FIFO (first-in-first-out).
9.51 + * The <em>head</em> of the queue is that element that has been on the
9.52 + * queue the longest time.
9.53 + * The <em>tail</em> of the queue is that element that has been on the
9.54 + * queue the shortest time. New elements
9.55 + * are inserted at the tail of the queue, and the queue retrieval
9.56 + * operations obtain elements at the head of the queue.
9.57 + * A {@code ConcurrentLinkedQueue} is an appropriate choice when
9.58 + * many threads will share access to a common collection.
9.59 + * Like most other concurrent collection implementations, this class
9.60 + * does not permit the use of {@code null} elements.
9.61 + *
9.62 + * <p>This implementation employs an efficient "wait-free"
9.63 + * algorithm based on one described in <a
9.64 + * href="http://www.cs.rochester.edu/u/michael/PODC96.html"> Simple,
9.65 + * Fast, and Practical Non-Blocking and Blocking Concurrent Queue
9.66 + * Algorithms</a> by Maged M. Michael and Michael L. Scott.
9.67 + *
9.68 + * <p>Iterators are <i>weakly consistent</i>, returning elements
9.69 + * reflecting the state of the queue at some point at or since the
9.70 + * creation of the iterator. They do <em>not</em> throw {@link
9.71 + * java.util.ConcurrentModificationException}, and may proceed concurrently
9.72 + * with other operations. Elements contained in the queue since the creation
9.73 + * of the iterator will be returned exactly once.
9.74 + *
9.75 + * <p>Beware that, unlike in most collections, the {@code size} method
9.76 + * is <em>NOT</em> a constant-time operation. Because of the
9.77 + * asynchronous nature of these queues, determining the current number
9.78 + * of elements requires a traversal of the elements, and so may report
9.79 + * inaccurate results if this collection is modified during traversal.
9.80 + * Additionally, the bulk operations {@code addAll},
9.81 + * {@code removeAll}, {@code retainAll}, {@code containsAll},
9.82 + * {@code equals}, and {@code toArray} are <em>not</em> guaranteed
9.83 + * to be performed atomically. For example, an iterator operating
9.84 + * concurrently with an {@code addAll} operation might view only some
9.85 + * of the added elements.
9.86 + *
9.87 + * <p>This class and its iterator implement all of the <em>optional</em>
9.88 + * methods of the {@link Queue} and {@link Iterator} interfaces.
9.89 + *
9.90 + * <p>Memory consistency effects: As with other concurrent
9.91 + * collections, actions in a thread prior to placing an object into a
9.92 + * {@code ConcurrentLinkedQueue}
9.93 + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
9.94 + * actions subsequent to the access or removal of that element from
9.95 + * the {@code ConcurrentLinkedQueue} in another thread.
9.96 + *
9.97 + * <p>This class is a member of the
9.98 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
9.99 + * Java Collections Framework</a>.
9.100 + *
9.101 + * @since 1.5
9.102 + * @author Doug Lea
9.103 + * @param <E> the type of elements held in this collection
9.104 + *
9.105 + */
9.106 +public class ConcurrentLinkedQueue<E> extends AbstractQueue<E>
9.107 + implements Queue<E>, java.io.Serializable {
9.108 + private static final long serialVersionUID = 196745693267521676L;
9.109 +
9.110 + /*
9.111 + * This is a modification of the Michael & Scott algorithm,
9.112 + * adapted for a garbage-collected environment, with support for
9.113 + * interior node deletion (to support remove(Object)). For
9.114 + * explanation, read the paper.
9.115 + *
9.116 + * Note that like most non-blocking algorithms in this package,
9.117 + * this implementation relies on the fact that in garbage
9.118 + * collected systems, there is no possibility of ABA problems due
9.119 + * to recycled nodes, so there is no need to use "counted
9.120 + * pointers" or related techniques seen in versions used in
9.121 + * non-GC'ed settings.
9.122 + *
9.123 + * The fundamental invariants are:
9.124 + * - There is exactly one (last) Node with a null next reference,
9.125 + * which is CASed when enqueueing. This last Node can be
9.126 + * reached in O(1) time from tail, but tail is merely an
9.127 + * optimization - it can always be reached in O(N) time from
9.128 + * head as well.
9.129 + * - The elements contained in the queue are the non-null items in
9.130 + * Nodes that are reachable from head. CASing the item
9.131 + * reference of a Node to null atomically removes it from the
9.132 + * queue. Reachability of all elements from head must remain
9.133 + * true even in the case of concurrent modifications that cause
9.134 + * head to advance. A dequeued Node may remain in use
9.135 + * indefinitely due to creation of an Iterator or simply a
9.136 + * poll() that has lost its time slice.
9.137 + *
9.138 + * The above might appear to imply that all Nodes are GC-reachable
9.139 + * from a predecessor dequeued Node. That would cause two problems:
9.140 + * - allow a rogue Iterator to cause unbounded memory retention
9.141 + * - cause cross-generational linking of old Nodes to new Nodes if
9.142 + * a Node was tenured while live, which generational GCs have a
9.143 + * hard time dealing with, causing repeated major collections.
9.144 + * However, only non-deleted Nodes need to be reachable from
9.145 + * dequeued Nodes, and reachability does not necessarily have to
9.146 + * be of the kind understood by the GC. We use the trick of
9.147 + * linking a Node that has just been dequeued to itself. Such a
9.148 + * self-link implicitly means to advance to head.
9.149 + *
9.150 + * Both head and tail are permitted to lag. In fact, failing to
9.151 + * update them every time one could is a significant optimization
9.152 + * (fewer CASes). As with LinkedTransferQueue (see the internal
9.153 + * documentation for that class), we use a slack threshold of two;
9.154 + * that is, we update head/tail when the current pointer appears
9.155 + * to be two or more steps away from the first/last node.
9.156 + *
9.157 + * Since head and tail are updated concurrently and independently,
9.158 + * it is possible for tail to lag behind head (why not)?
9.159 + *
9.160 + * CASing a Node's item reference to null atomically removes the
9.161 + * element from the queue. Iterators skip over Nodes with null
9.162 + * items. Prior implementations of this class had a race between
9.163 + * poll() and remove(Object) where the same element would appear
9.164 + * to be successfully removed by two concurrent operations. The
9.165 + * method remove(Object) also lazily unlinks deleted Nodes, but
9.166 + * this is merely an optimization.
9.167 + *
9.168 + * When constructing a Node (before enqueuing it) we avoid paying
9.169 + * for a volatile write to item by using Unsafe.putObject instead
9.170 + * of a normal write. This allows the cost of enqueue to be
9.171 + * "one-and-a-half" CASes.
9.172 + *
9.173 + * Both head and tail may or may not point to a Node with a
9.174 + * non-null item. If the queue is empty, all items must of course
9.175 + * be null. Upon creation, both head and tail refer to a dummy
9.176 + * Node with null item. Both head and tail are only updated using
9.177 + * CAS, so they never regress, although again this is merely an
9.178 + * optimization.
9.179 + */
9.180 +
9.181 + private static class Node<E> {
9.182 + volatile E item;
9.183 + volatile Node<E> next;
9.184 +
9.185 + /**
9.186 + * Constructs a new node. Uses relaxed write because item can
9.187 + * only be seen after publication via casNext.
9.188 + */
9.189 + Node(E item) {
9.190 + UNSAFE.putObject(this, itemOffset, item);
9.191 + }
9.192 +
9.193 + boolean casItem(E cmp, E val) {
9.194 + return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);
9.195 + }
9.196 +
9.197 + void lazySetNext(Node<E> val) {
9.198 + UNSAFE.putOrderedObject(this, nextOffset, val);
9.199 + }
9.200 +
9.201 + boolean casNext(Node<E> cmp, Node<E> val) {
9.202 + return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
9.203 + }
9.204 +
9.205 + // Unsafe mechanics
9.206 +
9.207 + private static final sun.misc.Unsafe UNSAFE;
9.208 + private static final long itemOffset;
9.209 + private static final long nextOffset;
9.210 +
9.211 + static {
9.212 + try {
9.213 + UNSAFE = sun.misc.Unsafe.getUnsafe();
9.214 + Class k = Node.class;
9.215 + itemOffset = UNSAFE.objectFieldOffset
9.216 + (k.getDeclaredField("item"));
9.217 + nextOffset = UNSAFE.objectFieldOffset
9.218 + (k.getDeclaredField("next"));
9.219 + } catch (Exception e) {
9.220 + throw new Error(e);
9.221 + }
9.222 + }
9.223 + }
9.224 +
9.225 + /**
9.226 + * A node from which the first live (non-deleted) node (if any)
9.227 + * can be reached in O(1) time.
9.228 + * Invariants:
9.229 + * - all live nodes are reachable from head via succ()
9.230 + * - head != null
9.231 + * - (tmp = head).next != tmp || tmp != head
9.232 + * Non-invariants:
9.233 + * - head.item may or may not be null.
9.234 + * - it is permitted for tail to lag behind head, that is, for tail
9.235 + * to not be reachable from head!
9.236 + */
9.237 + private transient volatile Node<E> head;
9.238 +
9.239 + /**
9.240 + * A node from which the last node on list (that is, the unique
9.241 + * node with node.next == null) can be reached in O(1) time.
9.242 + * Invariants:
9.243 + * - the last node is always reachable from tail via succ()
9.244 + * - tail != null
9.245 + * Non-invariants:
9.246 + * - tail.item may or may not be null.
9.247 + * - it is permitted for tail to lag behind head, that is, for tail
9.248 + * to not be reachable from head!
9.249 + * - tail.next may or may not be self-pointing to tail.
9.250 + */
9.251 + private transient volatile Node<E> tail;
9.252 +
9.253 +
9.254 + /**
9.255 + * Creates a {@code ConcurrentLinkedQueue} that is initially empty.
9.256 + */
9.257 + public ConcurrentLinkedQueue() {
9.258 + head = tail = new Node<E>(null);
9.259 + }
9.260 +
9.261 + /**
9.262 + * Creates a {@code ConcurrentLinkedQueue}
9.263 + * initially containing the elements of the given collection,
9.264 + * added in traversal order of the collection's iterator.
9.265 + *
9.266 + * @param c the collection of elements to initially contain
9.267 + * @throws NullPointerException if the specified collection or any
9.268 + * of its elements are null
9.269 + */
9.270 + public ConcurrentLinkedQueue(Collection<? extends E> c) {
9.271 + Node<E> h = null, t = null;
9.272 + for (E e : c) {
9.273 + checkNotNull(e);
9.274 + Node<E> newNode = new Node<E>(e);
9.275 + if (h == null)
9.276 + h = t = newNode;
9.277 + else {
9.278 + t.lazySetNext(newNode);
9.279 + t = newNode;
9.280 + }
9.281 + }
9.282 + if (h == null)
9.283 + h = t = new Node<E>(null);
9.284 + head = h;
9.285 + tail = t;
9.286 + }
9.287 +
9.288 + // Have to override just to update the javadoc
9.289 +
9.290 + /**
9.291 + * Inserts the specified element at the tail of this queue.
9.292 + * As the queue is unbounded, this method will never throw
9.293 + * {@link IllegalStateException} or return {@code false}.
9.294 + *
9.295 + * @return {@code true} (as specified by {@link Collection#add})
9.296 + * @throws NullPointerException if the specified element is null
9.297 + */
9.298 + public boolean add(E e) {
9.299 + return offer(e);
9.300 + }
9.301 +
9.302 + /**
9.303 + * Try to CAS head to p. If successful, repoint old head to itself
9.304 + * as sentinel for succ(), below.
9.305 + */
9.306 + final void updateHead(Node<E> h, Node<E> p) {
9.307 + if (h != p && casHead(h, p))
9.308 + h.lazySetNext(h);
9.309 + }
9.310 +
9.311 + /**
9.312 + * Returns the successor of p, or the head node if p.next has been
9.313 + * linked to self, which will only be true if traversing with a
9.314 + * stale pointer that is now off the list.
9.315 + */
9.316 + final Node<E> succ(Node<E> p) {
9.317 + Node<E> next = p.next;
9.318 + return (p == next) ? head : next;
9.319 + }
9.320 +
9.321 + /**
9.322 + * Inserts the specified element at the tail of this queue.
9.323 + * As the queue is unbounded, this method will never return {@code false}.
9.324 + *
9.325 + * @return {@code true} (as specified by {@link Queue#offer})
9.326 + * @throws NullPointerException if the specified element is null
9.327 + */
9.328 + public boolean offer(E e) {
9.329 + checkNotNull(e);
9.330 + final Node<E> newNode = new Node<E>(e);
9.331 +
9.332 + for (Node<E> t = tail, p = t;;) {
9.333 + Node<E> q = p.next;
9.334 + if (q == null) {
9.335 + // p is last node
9.336 + if (p.casNext(null, newNode)) {
9.337 + // Successful CAS is the linearization point
9.338 + // for e to become an element of this queue,
9.339 + // and for newNode to become "live".
9.340 + if (p != t) // hop two nodes at a time
9.341 + casTail(t, newNode); // Failure is OK.
9.342 + return true;
9.343 + }
9.344 + // Lost CAS race to another thread; re-read next
9.345 + }
9.346 + else if (p == q)
9.347 + // We have fallen off list. If tail is unchanged, it
9.348 + // will also be off-list, in which case we need to
9.349 + // jump to head, from which all live nodes are always
9.350 + // reachable. Else the new tail is a better bet.
9.351 + p = (t != (t = tail)) ? t : head;
9.352 + else
9.353 + // Check for tail updates after two hops.
9.354 + p = (p != t && t != (t = tail)) ? t : q;
9.355 + }
9.356 + }
9.357 +
9.358 + public E poll() {
9.359 + restartFromHead:
9.360 + for (;;) {
9.361 + for (Node<E> h = head, p = h, q;;) {
9.362 + E item = p.item;
9.363 +
9.364 + if (item != null && p.casItem(item, null)) {
9.365 + // Successful CAS is the linearization point
9.366 + // for item to be removed from this queue.
9.367 + if (p != h) // hop two nodes at a time
9.368 + updateHead(h, ((q = p.next) != null) ? q : p);
9.369 + return item;
9.370 + }
9.371 + else if ((q = p.next) == null) {
9.372 + updateHead(h, p);
9.373 + return null;
9.374 + }
9.375 + else if (p == q)
9.376 + continue restartFromHead;
9.377 + else
9.378 + p = q;
9.379 + }
9.380 + }
9.381 + }
9.382 +
9.383 + public E peek() {
9.384 + restartFromHead:
9.385 + for (;;) {
9.386 + for (Node<E> h = head, p = h, q;;) {
9.387 + E item = p.item;
9.388 + if (item != null || (q = p.next) == null) {
9.389 + updateHead(h, p);
9.390 + return item;
9.391 + }
9.392 + else if (p == q)
9.393 + continue restartFromHead;
9.394 + else
9.395 + p = q;
9.396 + }
9.397 + }
9.398 + }
9.399 +
9.400 + /**
9.401 + * Returns the first live (non-deleted) node on list, or null if none.
9.402 + * This is yet another variant of poll/peek; here returning the
9.403 + * first node, not element. We could make peek() a wrapper around
9.404 + * first(), but that would cost an extra volatile read of item,
9.405 + * and the need to add a retry loop to deal with the possibility
9.406 + * of losing a race to a concurrent poll().
9.407 + */
9.408 + Node<E> first() {
9.409 + restartFromHead:
9.410 + for (;;) {
9.411 + for (Node<E> h = head, p = h, q;;) {
9.412 + boolean hasItem = (p.item != null);
9.413 + if (hasItem || (q = p.next) == null) {
9.414 + updateHead(h, p);
9.415 + return hasItem ? p : null;
9.416 + }
9.417 + else if (p == q)
9.418 + continue restartFromHead;
9.419 + else
9.420 + p = q;
9.421 + }
9.422 + }
9.423 + }
9.424 +
9.425 + /**
9.426 + * Returns {@code true} if this queue contains no elements.
9.427 + *
9.428 + * @return {@code true} if this queue contains no elements
9.429 + */
9.430 + public boolean isEmpty() {
9.431 + return first() == null;
9.432 + }
9.433 +
9.434 + /**
9.435 + * Returns the number of elements in this queue. If this queue
9.436 + * contains more than {@code Integer.MAX_VALUE} elements, returns
9.437 + * {@code Integer.MAX_VALUE}.
9.438 + *
9.439 + * <p>Beware that, unlike in most collections, this method is
9.440 + * <em>NOT</em> a constant-time operation. Because of the
9.441 + * asynchronous nature of these queues, determining the current
9.442 + * number of elements requires an O(n) traversal.
9.443 + * Additionally, if elements are added or removed during execution
9.444 + * of this method, the returned result may be inaccurate. Thus,
9.445 + * this method is typically not very useful in concurrent
9.446 + * applications.
9.447 + *
9.448 + * @return the number of elements in this queue
9.449 + */
9.450 + public int size() {
9.451 + int count = 0;
9.452 + for (Node<E> p = first(); p != null; p = succ(p))
9.453 + if (p.item != null)
9.454 + // Collection.size() spec says to max out
9.455 + if (++count == Integer.MAX_VALUE)
9.456 + break;
9.457 + return count;
9.458 + }
9.459 +
9.460 + /**
9.461 + * Returns {@code true} if this queue contains the specified element.
9.462 + * More formally, returns {@code true} if and only if this queue contains
9.463 + * at least one element {@code e} such that {@code o.equals(e)}.
9.464 + *
9.465 + * @param o object to be checked for containment in this queue
9.466 + * @return {@code true} if this queue contains the specified element
9.467 + */
9.468 + public boolean contains(Object o) {
9.469 + if (o == null) return false;
9.470 + for (Node<E> p = first(); p != null; p = succ(p)) {
9.471 + E item = p.item;
9.472 + if (item != null && o.equals(item))
9.473 + return true;
9.474 + }
9.475 + return false;
9.476 + }
9.477 +
9.478 + /**
9.479 + * Removes a single instance of the specified element from this queue,
9.480 + * if it is present. More formally, removes an element {@code e} such
9.481 + * that {@code o.equals(e)}, if this queue contains one or more such
9.482 + * elements.
9.483 + * Returns {@code true} if this queue contained the specified element
9.484 + * (or equivalently, if this queue changed as a result of the call).
9.485 + *
9.486 + * @param o element to be removed from this queue, if present
9.487 + * @return {@code true} if this queue changed as a result of the call
9.488 + */
9.489 + public boolean remove(Object o) {
9.490 + if (o == null) return false;
9.491 + Node<E> pred = null;
9.492 + for (Node<E> p = first(); p != null; p = succ(p)) {
9.493 + E item = p.item;
9.494 + if (item != null &&
9.495 + o.equals(item) &&
9.496 + p.casItem(item, null)) {
9.497 + Node<E> next = succ(p);
9.498 + if (pred != null && next != null)
9.499 + pred.casNext(p, next);
9.500 + return true;
9.501 + }
9.502 + pred = p;
9.503 + }
9.504 + return false;
9.505 + }
9.506 +
9.507 + /**
9.508 + * Appends all of the elements in the specified collection to the end of
9.509 + * this queue, in the order that they are returned by the specified
9.510 + * collection's iterator. Attempts to {@code addAll} of a queue to
9.511 + * itself result in {@code IllegalArgumentException}.
9.512 + *
9.513 + * @param c the elements to be inserted into this queue
9.514 + * @return {@code true} if this queue changed as a result of the call
9.515 + * @throws NullPointerException if the specified collection or any
9.516 + * of its elements are null
9.517 + * @throws IllegalArgumentException if the collection is this queue
9.518 + */
9.519 + public boolean addAll(Collection<? extends E> c) {
9.520 + if (c == this)
9.521 + // As historically specified in AbstractQueue#addAll
9.522 + throw new IllegalArgumentException();
9.523 +
9.524 + // Copy c into a private chain of Nodes
9.525 + Node<E> beginningOfTheEnd = null, last = null;
9.526 + for (E e : c) {
9.527 + checkNotNull(e);
9.528 + Node<E> newNode = new Node<E>(e);
9.529 + if (beginningOfTheEnd == null)
9.530 + beginningOfTheEnd = last = newNode;
9.531 + else {
9.532 + last.lazySetNext(newNode);
9.533 + last = newNode;
9.534 + }
9.535 + }
9.536 + if (beginningOfTheEnd == null)
9.537 + return false;
9.538 +
9.539 + // Atomically append the chain at the tail of this collection
9.540 + for (Node<E> t = tail, p = t;;) {
9.541 + Node<E> q = p.next;
9.542 + if (q == null) {
9.543 + // p is last node
9.544 + if (p.casNext(null, beginningOfTheEnd)) {
9.545 + // Successful CAS is the linearization point
9.546 + // for all elements to be added to this queue.
9.547 + if (!casTail(t, last)) {
9.548 + // Try a little harder to update tail,
9.549 + // since we may be adding many elements.
9.550 + t = tail;
9.551 + if (last.next == null)
9.552 + casTail(t, last);
9.553 + }
9.554 + return true;
9.555 + }
9.556 + // Lost CAS race to another thread; re-read next
9.557 + }
9.558 + else if (p == q)
9.559 + // We have fallen off list. If tail is unchanged, it
9.560 + // will also be off-list, in which case we need to
9.561 + // jump to head, from which all live nodes are always
9.562 + // reachable. Else the new tail is a better bet.
9.563 + p = (t != (t = tail)) ? t : head;
9.564 + else
9.565 + // Check for tail updates after two hops.
9.566 + p = (p != t && t != (t = tail)) ? t : q;
9.567 + }
9.568 + }
9.569 +
9.570 + /**
9.571 + * Returns an array containing all of the elements in this queue, in
9.572 + * proper sequence.
9.573 + *
9.574 + * <p>The returned array will be "safe" in that no references to it are
9.575 + * maintained by this queue. (In other words, this method must allocate
9.576 + * a new array). The caller is thus free to modify the returned array.
9.577 + *
9.578 + * <p>This method acts as bridge between array-based and collection-based
9.579 + * APIs.
9.580 + *
9.581 + * @return an array containing all of the elements in this queue
9.582 + */
9.583 + public Object[] toArray() {
9.584 + // Use ArrayList to deal with resizing.
9.585 + ArrayList<E> al = new ArrayList<E>();
9.586 + for (Node<E> p = first(); p != null; p = succ(p)) {
9.587 + E item = p.item;
9.588 + if (item != null)
9.589 + al.add(item);
9.590 + }
9.591 + return al.toArray();
9.592 + }
9.593 +
9.594 + /**
9.595 + * Returns an array containing all of the elements in this queue, in
9.596 + * proper sequence; the runtime type of the returned array is that of
9.597 + * the specified array. If the queue fits in the specified array, it
9.598 + * is returned therein. Otherwise, a new array is allocated with the
9.599 + * runtime type of the specified array and the size of this queue.
9.600 + *
9.601 + * <p>If this queue fits in the specified array with room to spare
9.602 + * (i.e., the array has more elements than this queue), the element in
9.603 + * the array immediately following the end of the queue is set to
9.604 + * {@code null}.
9.605 + *
9.606 + * <p>Like the {@link #toArray()} method, this method acts as bridge between
9.607 + * array-based and collection-based APIs. Further, this method allows
9.608 + * precise control over the runtime type of the output array, and may,
9.609 + * under certain circumstances, be used to save allocation costs.
9.610 + *
9.611 + * <p>Suppose {@code x} is a queue known to contain only strings.
9.612 + * The following code can be used to dump the queue into a newly
9.613 + * allocated array of {@code String}:
9.614 + *
9.615 + * <pre>
9.616 + * String[] y = x.toArray(new String[0]);</pre>
9.617 + *
9.618 + * Note that {@code toArray(new Object[0])} is identical in function to
9.619 + * {@code toArray()}.
9.620 + *
9.621 + * @param a the array into which the elements of the queue are to
9.622 + * be stored, if it is big enough; otherwise, a new array of the
9.623 + * same runtime type is allocated for this purpose
9.624 + * @return an array containing all of the elements in this queue
9.625 + * @throws ArrayStoreException if the runtime type of the specified array
9.626 + * is not a supertype of the runtime type of every element in
9.627 + * this queue
9.628 + * @throws NullPointerException if the specified array is null
9.629 + */
9.630 + @SuppressWarnings("unchecked")
9.631 + public <T> T[] toArray(T[] a) {
9.632 + // try to use sent-in array
9.633 + int k = 0;
9.634 + Node<E> p;
9.635 + for (p = first(); p != null && k < a.length; p = succ(p)) {
9.636 + E item = p.item;
9.637 + if (item != null)
9.638 + a[k++] = (T)item;
9.639 + }
9.640 + if (p == null) {
9.641 + if (k < a.length)
9.642 + a[k] = null;
9.643 + return a;
9.644 + }
9.645 +
9.646 + // If won't fit, use ArrayList version
9.647 + ArrayList<E> al = new ArrayList<E>();
9.648 + for (Node<E> q = first(); q != null; q = succ(q)) {
9.649 + E item = q.item;
9.650 + if (item != null)
9.651 + al.add(item);
9.652 + }
9.653 + return al.toArray(a);
9.654 + }
9.655 +
9.656 + /**
9.657 + * Returns an iterator over the elements in this queue in proper sequence.
9.658 + * The elements will be returned in order from first (head) to last (tail).
9.659 + *
9.660 + * <p>The returned iterator is a "weakly consistent" iterator that
9.661 + * will never throw {@link java.util.ConcurrentModificationException
9.662 + * ConcurrentModificationException}, and guarantees to traverse
9.663 + * elements as they existed upon construction of the iterator, and
9.664 + * may (but is not guaranteed to) reflect any modifications
9.665 + * subsequent to construction.
9.666 + *
9.667 + * @return an iterator over the elements in this queue in proper sequence
9.668 + */
9.669 + public Iterator<E> iterator() {
9.670 + return new Itr();
9.671 + }
9.672 +
9.673 + private class Itr implements Iterator<E> {
9.674 + /**
9.675 + * Next node to return item for.
9.676 + */
9.677 + private Node<E> nextNode;
9.678 +
9.679 + /**
9.680 + * nextItem holds on to item fields because once we claim
9.681 + * that an element exists in hasNext(), we must return it in
9.682 + * the following next() call even if it was in the process of
9.683 + * being removed when hasNext() was called.
9.684 + */
9.685 + private E nextItem;
9.686 +
9.687 + /**
9.688 + * Node of the last returned item, to support remove.
9.689 + */
9.690 + private Node<E> lastRet;
9.691 +
9.692 + Itr() {
9.693 + advance();
9.694 + }
9.695 +
9.696 + /**
9.697 + * Moves to next valid node and returns item to return for
9.698 + * next(), or null if no such.
9.699 + */
9.700 + private E advance() {
9.701 + lastRet = nextNode;
9.702 + E x = nextItem;
9.703 +
9.704 + Node<E> pred, p;
9.705 + if (nextNode == null) {
9.706 + p = first();
9.707 + pred = null;
9.708 + } else {
9.709 + pred = nextNode;
9.710 + p = succ(nextNode);
9.711 + }
9.712 +
9.713 + for (;;) {
9.714 + if (p == null) {
9.715 + nextNode = null;
9.716 + nextItem = null;
9.717 + return x;
9.718 + }
9.719 + E item = p.item;
9.720 + if (item != null) {
9.721 + nextNode = p;
9.722 + nextItem = item;
9.723 + return x;
9.724 + } else {
9.725 + // skip over nulls
9.726 + Node<E> next = succ(p);
9.727 + if (pred != null && next != null)
9.728 + pred.casNext(p, next);
9.729 + p = next;
9.730 + }
9.731 + }
9.732 + }
9.733 +
9.734 + public boolean hasNext() {
9.735 + return nextNode != null;
9.736 + }
9.737 +
9.738 + public E next() {
9.739 + if (nextNode == null) throw new NoSuchElementException();
9.740 + return advance();
9.741 + }
9.742 +
9.743 + public void remove() {
9.744 + Node<E> l = lastRet;
9.745 + if (l == null) throw new IllegalStateException();
9.746 + // rely on a future traversal to relink.
9.747 + l.item = null;
9.748 + lastRet = null;
9.749 + }
9.750 + }
9.751 +
9.752 + /**
9.753 + * Saves the state to a stream (that is, serializes it).
9.754 + *
9.755 + * @serialData All of the elements (each an {@code E}) in
9.756 + * the proper order, followed by a null
9.757 + * @param s the stream
9.758 + */
9.759 + private void writeObject(java.io.ObjectOutputStream s)
9.760 + throws java.io.IOException {
9.761 +
9.762 + // Write out any hidden stuff
9.763 + s.defaultWriteObject();
9.764 +
9.765 + // Write out all elements in the proper order.
9.766 + for (Node<E> p = first(); p != null; p = succ(p)) {
9.767 + Object item = p.item;
9.768 + if (item != null)
9.769 + s.writeObject(item);
9.770 + }
9.771 +
9.772 + // Use trailing null as sentinel
9.773 + s.writeObject(null);
9.774 + }
9.775 +
9.776 + /**
9.777 + * Reconstitutes the instance from a stream (that is, deserializes it).
9.778 + * @param s the stream
9.779 + */
9.780 + private void readObject(java.io.ObjectInputStream s)
9.781 + throws java.io.IOException, ClassNotFoundException {
9.782 + s.defaultReadObject();
9.783 +
9.784 + // Read in elements until trailing null sentinel found
9.785 + Node<E> h = null, t = null;
9.786 + Object item;
9.787 + while ((item = s.readObject()) != null) {
9.788 + @SuppressWarnings("unchecked")
9.789 + Node<E> newNode = new Node<E>((E) item);
9.790 + if (h == null)
9.791 + h = t = newNode;
9.792 + else {
9.793 + t.lazySetNext(newNode);
9.794 + t = newNode;
9.795 + }
9.796 + }
9.797 + if (h == null)
9.798 + h = t = new Node<E>(null);
9.799 + head = h;
9.800 + tail = t;
9.801 + }
9.802 +
9.803 + /**
9.804 + * Throws NullPointerException if argument is null.
9.805 + *
9.806 + * @param v the element
9.807 + */
9.808 + private static void checkNotNull(Object v) {
9.809 + if (v == null)
9.810 + throw new NullPointerException();
9.811 + }
9.812 +
9.813 + private boolean casTail(Node<E> cmp, Node<E> val) {
9.814 + return UNSAFE.compareAndSwapObject(this, tailOffset, cmp, val);
9.815 + }
9.816 +
9.817 + private boolean casHead(Node<E> cmp, Node<E> val) {
9.818 + return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
9.819 + }
9.820 +
9.821 + // Unsafe mechanics
9.822 +
9.823 + private static final sun.misc.Unsafe UNSAFE;
9.824 + private static final long headOffset;
9.825 + private static final long tailOffset;
9.826 + static {
9.827 + try {
9.828 + UNSAFE = sun.misc.Unsafe.getUnsafe();
9.829 + Class k = ConcurrentLinkedQueue.class;
9.830 + headOffset = UNSAFE.objectFieldOffset
9.831 + (k.getDeclaredField("head"));
9.832 + tailOffset = UNSAFE.objectFieldOffset
9.833 + (k.getDeclaredField("tail"));
9.834 + } catch (Exception e) {
9.835 + throw new Error(e);
9.836 + }
9.837 + }
9.838 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ConcurrentNavigableMap.java Sat Mar 19 10:48:29 2016 +0100
10.3 @@ -0,0 +1,177 @@
10.4 +/*
10.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
10.6 + *
10.7 + * This code is free software; you can redistribute it and/or modify it
10.8 + * under the terms of the GNU General Public License version 2 only, as
10.9 + * published by the Free Software Foundation. Oracle designates this
10.10 + * particular file as subject to the "Classpath" exception as provided
10.11 + * by Oracle in the LICENSE file that accompanied this code.
10.12 + *
10.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
10.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
10.16 + * version 2 for more details (a copy is included in the LICENSE file that
10.17 + * accompanied this code).
10.18 + *
10.19 + * You should have received a copy of the GNU General Public License version
10.20 + * 2 along with this work; if not, write to the Free Software Foundation,
10.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
10.22 + *
10.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
10.24 + * or visit www.oracle.com if you need additional information or have any
10.25 + * questions.
10.26 + */
10.27 +
10.28 +/*
10.29 + * This file is available under and governed by the GNU General Public
10.30 + * License version 2 only, as published by the Free Software Foundation.
10.31 + * However, the following notice accompanied the original version of this
10.32 + * file:
10.33 + *
10.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
10.35 + * Expert Group and released to the public domain, as explained at
10.36 + * http://creativecommons.org/publicdomain/zero/1.0/
10.37 + */
10.38 +
10.39 +package java.util.concurrent;
10.40 +import java.util.*;
10.41 +
10.42 +/**
10.43 + * A {@link ConcurrentMap} supporting {@link NavigableMap} operations,
10.44 + * and recursively so for its navigable sub-maps.
10.45 + *
10.46 + * <p>This interface is a member of the
10.47 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
10.48 + * Java Collections Framework</a>.
10.49 + *
10.50 + * @author Doug Lea
10.51 + * @param <K> the type of keys maintained by this map
10.52 + * @param <V> the type of mapped values
10.53 + * @since 1.6
10.54 + */
10.55 +public interface ConcurrentNavigableMap<K,V>
10.56 + extends ConcurrentMap<K,V>, NavigableMap<K,V>
10.57 +{
10.58 + /**
10.59 + * @throws ClassCastException {@inheritDoc}
10.60 + * @throws NullPointerException {@inheritDoc}
10.61 + * @throws IllegalArgumentException {@inheritDoc}
10.62 + */
10.63 + ConcurrentNavigableMap<K,V> subMap(K fromKey, boolean fromInclusive,
10.64 + K toKey, boolean toInclusive);
10.65 +
10.66 + /**
10.67 + * @throws ClassCastException {@inheritDoc}
10.68 + * @throws NullPointerException {@inheritDoc}
10.69 + * @throws IllegalArgumentException {@inheritDoc}
10.70 + */
10.71 + ConcurrentNavigableMap<K,V> headMap(K toKey, boolean inclusive);
10.72 +
10.73 +
10.74 + /**
10.75 + * @throws ClassCastException {@inheritDoc}
10.76 + * @throws NullPointerException {@inheritDoc}
10.77 + * @throws IllegalArgumentException {@inheritDoc}
10.78 + */
10.79 + ConcurrentNavigableMap<K,V> tailMap(K fromKey, boolean inclusive);
10.80 +
10.81 + /**
10.82 + * @throws ClassCastException {@inheritDoc}
10.83 + * @throws NullPointerException {@inheritDoc}
10.84 + * @throws IllegalArgumentException {@inheritDoc}
10.85 + */
10.86 + ConcurrentNavigableMap<K,V> subMap(K fromKey, K toKey);
10.87 +
10.88 + /**
10.89 + * @throws ClassCastException {@inheritDoc}
10.90 + * @throws NullPointerException {@inheritDoc}
10.91 + * @throws IllegalArgumentException {@inheritDoc}
10.92 + */
10.93 + ConcurrentNavigableMap<K,V> headMap(K toKey);
10.94 +
10.95 + /**
10.96 + * @throws ClassCastException {@inheritDoc}
10.97 + * @throws NullPointerException {@inheritDoc}
10.98 + * @throws IllegalArgumentException {@inheritDoc}
10.99 + */
10.100 + ConcurrentNavigableMap<K,V> tailMap(K fromKey);
10.101 +
10.102 + /**
10.103 + * Returns a reverse order view of the mappings contained in this map.
10.104 + * The descending map is backed by this map, so changes to the map are
10.105 + * reflected in the descending map, and vice-versa.
10.106 + *
10.107 + * <p>The returned map has an ordering equivalent to
10.108 + * <tt>{@link Collections#reverseOrder(Comparator) Collections.reverseOrder}(comparator())</tt>.
10.109 + * The expression {@code m.descendingMap().descendingMap()} returns a
10.110 + * view of {@code m} essentially equivalent to {@code m}.
10.111 + *
10.112 + * @return a reverse order view of this map
10.113 + */
10.114 + ConcurrentNavigableMap<K,V> descendingMap();
10.115 +
10.116 + /**
10.117 + * Returns a {@link NavigableSet} view of the keys contained in this map.
10.118 + * The set's iterator returns the keys in ascending order.
10.119 + * The set is backed by the map, so changes to the map are
10.120 + * reflected in the set, and vice-versa. The set supports element
10.121 + * removal, which removes the corresponding mapping from the map,
10.122 + * via the {@code Iterator.remove}, {@code Set.remove},
10.123 + * {@code removeAll}, {@code retainAll}, and {@code clear}
10.124 + * operations. It does not support the {@code add} or {@code addAll}
10.125 + * operations.
10.126 + *
10.127 + * <p>The view's {@code iterator} is a "weakly consistent" iterator
10.128 + * that will never throw {@link ConcurrentModificationException},
10.129 + * and guarantees to traverse elements as they existed upon
10.130 + * construction of the iterator, and may (but is not guaranteed to)
10.131 + * reflect any modifications subsequent to construction.
10.132 + *
10.133 + * @return a navigable set view of the keys in this map
10.134 + */
10.135 + public NavigableSet<K> navigableKeySet();
10.136 +
10.137 + /**
10.138 + * Returns a {@link NavigableSet} view of the keys contained in this map.
10.139 + * The set's iterator returns the keys in ascending order.
10.140 + * The set is backed by the map, so changes to the map are
10.141 + * reflected in the set, and vice-versa. The set supports element
10.142 + * removal, which removes the corresponding mapping from the map,
10.143 + * via the {@code Iterator.remove}, {@code Set.remove},
10.144 + * {@code removeAll}, {@code retainAll}, and {@code clear}
10.145 + * operations. It does not support the {@code add} or {@code addAll}
10.146 + * operations.
10.147 + *
10.148 + * <p>The view's {@code iterator} is a "weakly consistent" iterator
10.149 + * that will never throw {@link ConcurrentModificationException},
10.150 + * and guarantees to traverse elements as they existed upon
10.151 + * construction of the iterator, and may (but is not guaranteed to)
10.152 + * reflect any modifications subsequent to construction.
10.153 + *
10.154 + * <p>This method is equivalent to method {@code navigableKeySet}.
10.155 + *
10.156 + * @return a navigable set view of the keys in this map
10.157 + */
10.158 + NavigableSet<K> keySet();
10.159 +
10.160 + /**
10.161 + * Returns a reverse order {@link NavigableSet} view of the keys contained in this map.
10.162 + * The set's iterator returns the keys in descending order.
10.163 + * The set is backed by the map, so changes to the map are
10.164 + * reflected in the set, and vice-versa. The set supports element
10.165 + * removal, which removes the corresponding mapping from the map,
10.166 + * via the {@code Iterator.remove}, {@code Set.remove},
10.167 + * {@code removeAll}, {@code retainAll}, and {@code clear}
10.168 + * operations. It does not support the {@code add} or {@code addAll}
10.169 + * operations.
10.170 + *
10.171 + * <p>The view's {@code iterator} is a "weakly consistent" iterator
10.172 + * that will never throw {@link ConcurrentModificationException},
10.173 + * and guarantees to traverse elements as they existed upon
10.174 + * construction of the iterator, and may (but is not guaranteed to)
10.175 + * reflect any modifications subsequent to construction.
10.176 + *
10.177 + * @return a reverse order navigable set view of the keys in this map
10.178 + */
10.179 + public NavigableSet<K> descendingKeySet();
10.180 +}
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ConcurrentSkipListMap.java Sat Mar 19 10:48:29 2016 +0100
11.3 @@ -0,0 +1,3119 @@
11.4 +/*
11.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
11.6 + *
11.7 + * This code is free software; you can redistribute it and/or modify it
11.8 + * under the terms of the GNU General Public License version 2 only, as
11.9 + * published by the Free Software Foundation. Oracle designates this
11.10 + * particular file as subject to the "Classpath" exception as provided
11.11 + * by Oracle in the LICENSE file that accompanied this code.
11.12 + *
11.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
11.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11.16 + * version 2 for more details (a copy is included in the LICENSE file that
11.17 + * accompanied this code).
11.18 + *
11.19 + * You should have received a copy of the GNU General Public License version
11.20 + * 2 along with this work; if not, write to the Free Software Foundation,
11.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
11.22 + *
11.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
11.24 + * or visit www.oracle.com if you need additional information or have any
11.25 + * questions.
11.26 + */
11.27 +
11.28 +/*
11.29 + * This file is available under and governed by the GNU General Public
11.30 + * License version 2 only, as published by the Free Software Foundation.
11.31 + * However, the following notice accompanied the original version of this
11.32 + * file:
11.33 + *
11.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
11.35 + * Expert Group and released to the public domain, as explained at
11.36 + * http://creativecommons.org/publicdomain/zero/1.0/
11.37 + */
11.38 +
11.39 +package java.util.concurrent;
11.40 +import java.util.*;
11.41 +import java.util.concurrent.atomic.*;
11.42 +
11.43 +/**
11.44 + * A scalable concurrent {@link ConcurrentNavigableMap} implementation.
11.45 + * The map is sorted according to the {@linkplain Comparable natural
11.46 + * ordering} of its keys, or by a {@link Comparator} provided at map
11.47 + * creation time, depending on which constructor is used.
11.48 + *
11.49 + * <p>This class implements a concurrent variant of <a
11.50 + * href="http://en.wikipedia.org/wiki/Skip_list" target="_top">SkipLists</a>
11.51 + * providing expected average <i>log(n)</i> time cost for the
11.52 + * <tt>containsKey</tt>, <tt>get</tt>, <tt>put</tt> and
11.53 + * <tt>remove</tt> operations and their variants. Insertion, removal,
11.54 + * update, and access operations safely execute concurrently by
11.55 + * multiple threads. Iterators are <i>weakly consistent</i>, returning
11.56 + * elements reflecting the state of the map at some point at or since
11.57 + * the creation of the iterator. They do <em>not</em> throw {@link
11.58 + * ConcurrentModificationException}, and may proceed concurrently with
11.59 + * other operations. Ascending key ordered views and their iterators
11.60 + * are faster than descending ones.
11.61 + *
11.62 + * <p>All <tt>Map.Entry</tt> pairs returned by methods in this class
11.63 + * and its views represent snapshots of mappings at the time they were
11.64 + * produced. They do <em>not</em> support the <tt>Entry.setValue</tt>
11.65 + * method. (Note however that it is possible to change mappings in the
11.66 + * associated map using <tt>put</tt>, <tt>putIfAbsent</tt>, or
11.67 + * <tt>replace</tt>, depending on exactly which effect you need.)
11.68 + *
11.69 + * <p>Beware that, unlike in most collections, the <tt>size</tt>
11.70 + * method is <em>not</em> a constant-time operation. Because of the
11.71 + * asynchronous nature of these maps, determining the current number
11.72 + * of elements requires a traversal of the elements, and so may report
11.73 + * inaccurate results if this collection is modified during traversal.
11.74 + * Additionally, the bulk operations <tt>putAll</tt>, <tt>equals</tt>,
11.75 + * <tt>toArray</tt>, <tt>containsValue</tt>, and <tt>clear</tt> are
11.76 + * <em>not</em> guaranteed to be performed atomically. For example, an
11.77 + * iterator operating concurrently with a <tt>putAll</tt> operation
11.78 + * might view only some of the added elements.
11.79 + *
11.80 + * <p>This class and its views and iterators implement all of the
11.81 + * <em>optional</em> methods of the {@link Map} and {@link Iterator}
11.82 + * interfaces. Like most other concurrent collections, this class does
11.83 + * <em>not</em> permit the use of <tt>null</tt> keys or values because some
11.84 + * null return values cannot be reliably distinguished from the absence of
11.85 + * elements.
11.86 + *
11.87 + * <p>This class is a member of the
11.88 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
11.89 + * Java Collections Framework</a>.
11.90 + *
11.91 + * @author Doug Lea
11.92 + * @param <K> the type of keys maintained by this map
11.93 + * @param <V> the type of mapped values
11.94 + * @since 1.6
11.95 + */
11.96 +public class ConcurrentSkipListMap<K,V> extends AbstractMap<K,V>
11.97 + implements ConcurrentNavigableMap<K,V>,
11.98 + Cloneable,
11.99 + java.io.Serializable {
11.100 + /*
11.101 + * This class implements a tree-like two-dimensionally linked skip
11.102 + * list in which the index levels are represented in separate
11.103 + * nodes from the base nodes holding data. There are two reasons
11.104 + * for taking this approach instead of the usual array-based
11.105 + * structure: 1) Array based implementations seem to encounter
11.106 + * more complexity and overhead 2) We can use cheaper algorithms
11.107 + * for the heavily-traversed index lists than can be used for the
11.108 + * base lists. Here's a picture of some of the basics for a
11.109 + * possible list with 2 levels of index:
11.110 + *
11.111 + * Head nodes Index nodes
11.112 + * +-+ right +-+ +-+
11.113 + * |2|---------------->| |--------------------->| |->null
11.114 + * +-+ +-+ +-+
11.115 + * | down | |
11.116 + * v v v
11.117 + * +-+ +-+ +-+ +-+ +-+ +-+
11.118 + * |1|----------->| |->| |------>| |----------->| |------>| |->null
11.119 + * +-+ +-+ +-+ +-+ +-+ +-+
11.120 + * v | | | | |
11.121 + * Nodes next v v v v v
11.122 + * +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+
11.123 + * | |->|A|->|B|->|C|->|D|->|E|->|F|->|G|->|H|->|I|->|J|->|K|->null
11.124 + * +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+
11.125 + *
11.126 + * The base lists use a variant of the HM linked ordered set
11.127 + * algorithm. See Tim Harris, "A pragmatic implementation of
11.128 + * non-blocking linked lists"
11.129 + * http://www.cl.cam.ac.uk/~tlh20/publications.html and Maged
11.130 + * Michael "High Performance Dynamic Lock-Free Hash Tables and
11.131 + * List-Based Sets"
11.132 + * http://www.research.ibm.com/people/m/michael/pubs.htm. The
11.133 + * basic idea in these lists is to mark the "next" pointers of
11.134 + * deleted nodes when deleting to avoid conflicts with concurrent
11.135 + * insertions, and when traversing to keep track of triples
11.136 + * (predecessor, node, successor) in order to detect when and how
11.137 + * to unlink these deleted nodes.
11.138 + *
11.139 + * Rather than using mark-bits to mark list deletions (which can
11.140 + * be slow and space-intensive using AtomicMarkedReference), nodes
11.141 + * use direct CAS'able next pointers. On deletion, instead of
11.142 + * marking a pointer, they splice in another node that can be
11.143 + * thought of as standing for a marked pointer (indicating this by
11.144 + * using otherwise impossible field values). Using plain nodes
11.145 + * acts roughly like "boxed" implementations of marked pointers,
11.146 + * but uses new nodes only when nodes are deleted, not for every
11.147 + * link. This requires less space and supports faster
11.148 + * traversal. Even if marked references were better supported by
11.149 + * JVMs, traversal using this technique might still be faster
11.150 + * because any search need only read ahead one more node than
11.151 + * otherwise required (to check for trailing marker) rather than
11.152 + * unmasking mark bits or whatever on each read.
11.153 + *
11.154 + * This approach maintains the essential property needed in the HM
11.155 + * algorithm of changing the next-pointer of a deleted node so
11.156 + * that any other CAS of it will fail, but implements the idea by
11.157 + * changing the pointer to point to a different node, not by
11.158 + * marking it. While it would be possible to further squeeze
11.159 + * space by defining marker nodes not to have key/value fields, it
11.160 + * isn't worth the extra type-testing overhead. The deletion
11.161 + * markers are rarely encountered during traversal and are
11.162 + * normally quickly garbage collected. (Note that this technique
11.163 + * would not work well in systems without garbage collection.)
11.164 + *
11.165 + * In addition to using deletion markers, the lists also use
11.166 + * nullness of value fields to indicate deletion, in a style
11.167 + * similar to typical lazy-deletion schemes. If a node's value is
11.168 + * null, then it is considered logically deleted and ignored even
11.169 + * though it is still reachable. This maintains proper control of
11.170 + * concurrent replace vs delete operations -- an attempted replace
11.171 + * must fail if a delete beat it by nulling field, and a delete
11.172 + * must return the last non-null value held in the field. (Note:
11.173 + * Null, rather than some special marker, is used for value fields
11.174 + * here because it just so happens to mesh with the Map API
11.175 + * requirement that method get returns null if there is no
11.176 + * mapping, which allows nodes to remain concurrently readable
11.177 + * even when deleted. Using any other marker value here would be
11.178 + * messy at best.)
11.179 + *
11.180 + * Here's the sequence of events for a deletion of node n with
11.181 + * predecessor b and successor f, initially:
11.182 + *
11.183 + * +------+ +------+ +------+
11.184 + * ... | b |------>| n |----->| f | ...
11.185 + * +------+ +------+ +------+
11.186 + *
11.187 + * 1. CAS n's value field from non-null to null.
11.188 + * From this point on, no public operations encountering
11.189 + * the node consider this mapping to exist. However, other
11.190 + * ongoing insertions and deletions might still modify
11.191 + * n's next pointer.
11.192 + *
11.193 + * 2. CAS n's next pointer to point to a new marker node.
11.194 + * From this point on, no other nodes can be appended to n.
11.195 + * which avoids deletion errors in CAS-based linked lists.
11.196 + *
11.197 + * +------+ +------+ +------+ +------+
11.198 + * ... | b |------>| n |----->|marker|------>| f | ...
11.199 + * +------+ +------+ +------+ +------+
11.200 + *
11.201 + * 3. CAS b's next pointer over both n and its marker.
11.202 + * From this point on, no new traversals will encounter n,
11.203 + * and it can eventually be GCed.
11.204 + * +------+ +------+
11.205 + * ... | b |----------------------------------->| f | ...
11.206 + * +------+ +------+
11.207 + *
11.208 + * A failure at step 1 leads to simple retry due to a lost race
11.209 + * with another operation. Steps 2-3 can fail because some other
11.210 + * thread noticed during a traversal a node with null value and
11.211 + * helped out by marking and/or unlinking. This helping-out
11.212 + * ensures that no thread can become stuck waiting for progress of
11.213 + * the deleting thread. The use of marker nodes slightly
11.214 + * complicates helping-out code because traversals must track
11.215 + * consistent reads of up to four nodes (b, n, marker, f), not
11.216 + * just (b, n, f), although the next field of a marker is
11.217 + * immutable, and once a next field is CAS'ed to point to a
11.218 + * marker, it never again changes, so this requires less care.
11.219 + *
11.220 + * Skip lists add indexing to this scheme, so that the base-level
11.221 + * traversals start close to the locations being found, inserted
11.222 + * or deleted -- usually base level traversals only traverse a few
11.223 + * nodes. This doesn't change the basic algorithm except for the
11.224 + * need to make sure base traversals start at predecessors (here,
11.225 + * b) that are not (structurally) deleted, otherwise retrying
11.226 + * after processing the deletion.
11.227 + *
11.228 + * Index levels are maintained as lists with volatile next fields,
11.229 + * using CAS to link and unlink. Races are allowed in index-list
11.230 + * operations that can (rarely) fail to link in a new index node
11.231 + * or delete one. (We can't do this of course for data nodes.)
11.232 + * However, even when this happens, the index lists remain sorted,
11.233 + * so correctly serve as indices. This can impact performance,
11.234 + * but since skip lists are probabilistic anyway, the net result
11.235 + * is that under contention, the effective "p" value may be lower
11.236 + * than its nominal value. And race windows are kept small enough
11.237 + * that in practice these failures are rare, even under a lot of
11.238 + * contention.
11.239 + *
11.240 + * The fact that retries (for both base and index lists) are
11.241 + * relatively cheap due to indexing allows some minor
11.242 + * simplifications of retry logic. Traversal restarts are
11.243 + * performed after most "helping-out" CASes. This isn't always
11.244 + * strictly necessary, but the implicit backoffs tend to help
11.245 + * reduce other downstream failed CAS's enough to outweigh restart
11.246 + * cost. This worsens the worst case, but seems to improve even
11.247 + * highly contended cases.
11.248 + *
11.249 + * Unlike most skip-list implementations, index insertion and
11.250 + * deletion here require a separate traversal pass occuring after
11.251 + * the base-level action, to add or remove index nodes. This adds
11.252 + * to single-threaded overhead, but improves contended
11.253 + * multithreaded performance by narrowing interference windows,
11.254 + * and allows deletion to ensure that all index nodes will be made
11.255 + * unreachable upon return from a public remove operation, thus
11.256 + * avoiding unwanted garbage retention. This is more important
11.257 + * here than in some other data structures because we cannot null
11.258 + * out node fields referencing user keys since they might still be
11.259 + * read by other ongoing traversals.
11.260 + *
11.261 + * Indexing uses skip list parameters that maintain good search
11.262 + * performance while using sparser-than-usual indices: The
11.263 + * hardwired parameters k=1, p=0.5 (see method randomLevel) mean
11.264 + * that about one-quarter of the nodes have indices. Of those that
11.265 + * do, half have one level, a quarter have two, and so on (see
11.266 + * Pugh's Skip List Cookbook, sec 3.4). The expected total space
11.267 + * requirement for a map is slightly less than for the current
11.268 + * implementation of java.util.TreeMap.
11.269 + *
11.270 + * Changing the level of the index (i.e, the height of the
11.271 + * tree-like structure) also uses CAS. The head index has initial
11.272 + * level/height of one. Creation of an index with height greater
11.273 + * than the current level adds a level to the head index by
11.274 + * CAS'ing on a new top-most head. To maintain good performance
11.275 + * after a lot of removals, deletion methods heuristically try to
11.276 + * reduce the height if the topmost levels appear to be empty.
11.277 + * This may encounter races in which it possible (but rare) to
11.278 + * reduce and "lose" a level just as it is about to contain an
11.279 + * index (that will then never be encountered). This does no
11.280 + * structural harm, and in practice appears to be a better option
11.281 + * than allowing unrestrained growth of levels.
11.282 + *
11.283 + * The code for all this is more verbose than you'd like. Most
11.284 + * operations entail locating an element (or position to insert an
11.285 + * element). The code to do this can't be nicely factored out
11.286 + * because subsequent uses require a snapshot of predecessor
11.287 + * and/or successor and/or value fields which can't be returned
11.288 + * all at once, at least not without creating yet another object
11.289 + * to hold them -- creating such little objects is an especially
11.290 + * bad idea for basic internal search operations because it adds
11.291 + * to GC overhead. (This is one of the few times I've wished Java
11.292 + * had macros.) Instead, some traversal code is interleaved within
11.293 + * insertion and removal operations. The control logic to handle
11.294 + * all the retry conditions is sometimes twisty. Most search is
11.295 + * broken into 2 parts. findPredecessor() searches index nodes
11.296 + * only, returning a base-level predecessor of the key. findNode()
11.297 + * finishes out the base-level search. Even with this factoring,
11.298 + * there is a fair amount of near-duplication of code to handle
11.299 + * variants.
11.300 + *
11.301 + * For explanation of algorithms sharing at least a couple of
11.302 + * features with this one, see Mikhail Fomitchev's thesis
11.303 + * (http://www.cs.yorku.ca/~mikhail/), Keir Fraser's thesis
11.304 + * (http://www.cl.cam.ac.uk/users/kaf24/), and Hakan Sundell's
11.305 + * thesis (http://www.cs.chalmers.se/~phs/).
11.306 + *
11.307 + * Given the use of tree-like index nodes, you might wonder why
11.308 + * this doesn't use some kind of search tree instead, which would
11.309 + * support somewhat faster search operations. The reason is that
11.310 + * there are no known efficient lock-free insertion and deletion
11.311 + * algorithms for search trees. The immutability of the "down"
11.312 + * links of index nodes (as opposed to mutable "left" fields in
11.313 + * true trees) makes this tractable using only CAS operations.
11.314 + *
11.315 + * Notation guide for local variables
11.316 + * Node: b, n, f for predecessor, node, successor
11.317 + * Index: q, r, d for index node, right, down.
11.318 + * t for another index node
11.319 + * Head: h
11.320 + * Levels: j
11.321 + * Keys: k, key
11.322 + * Values: v, value
11.323 + * Comparisons: c
11.324 + */
11.325 +
11.326 + private static final long serialVersionUID = -8627078645895051609L;
11.327 +
11.328 + /**
11.329 + * Generates the initial random seed for the cheaper per-instance
11.330 + * random number generators used in randomLevel.
11.331 + */
11.332 + private static final Random seedGenerator = new Random();
11.333 +
11.334 + /**
11.335 + * Special value used to identify base-level header
11.336 + */
11.337 + private static final Object BASE_HEADER = new Object();
11.338 +
11.339 + /**
11.340 + * The topmost head index of the skiplist.
11.341 + */
11.342 + private transient volatile HeadIndex<K,V> head;
11.343 +
11.344 + /**
11.345 + * The comparator used to maintain order in this map, or null
11.346 + * if using natural ordering.
11.347 + * @serial
11.348 + */
11.349 + private final Comparator<? super K> comparator;
11.350 +
11.351 + /**
11.352 + * Seed for simple random number generator. Not volatile since it
11.353 + * doesn't matter too much if different threads don't see updates.
11.354 + */
11.355 + private transient int randomSeed;
11.356 +
11.357 + /** Lazily initialized key set */
11.358 + private transient KeySet keySet;
11.359 + /** Lazily initialized entry set */
11.360 + private transient EntrySet entrySet;
11.361 + /** Lazily initialized values collection */
11.362 + private transient Values values;
11.363 + /** Lazily initialized descending key set */
11.364 + private transient ConcurrentNavigableMap<K,V> descendingMap;
11.365 +
11.366 + /**
11.367 + * Initializes or resets state. Needed by constructors, clone,
11.368 + * clear, readObject. and ConcurrentSkipListSet.clone.
11.369 + * (Note that comparator must be separately initialized.)
11.370 + */
11.371 + final void initialize() {
11.372 + keySet = null;
11.373 + entrySet = null;
11.374 + values = null;
11.375 + descendingMap = null;
11.376 + randomSeed = seedGenerator.nextInt() | 0x0100; // ensure nonzero
11.377 + head = new HeadIndex<K,V>(new Node<K,V>(null, BASE_HEADER, null),
11.378 + null, null, 1);
11.379 + }
11.380 +
11.381 + /**
11.382 + * compareAndSet head node
11.383 + */
11.384 + private boolean casHead(HeadIndex<K,V> cmp, HeadIndex<K,V> val) {
11.385 + return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
11.386 + }
11.387 +
11.388 + /* ---------------- Nodes -------------- */
11.389 +
11.390 + /**
11.391 + * Nodes hold keys and values, and are singly linked in sorted
11.392 + * order, possibly with some intervening marker nodes. The list is
11.393 + * headed by a dummy node accessible as head.node. The value field
11.394 + * is declared only as Object because it takes special non-V
11.395 + * values for marker and header nodes.
11.396 + */
11.397 + static final class Node<K,V> {
11.398 + final K key;
11.399 + volatile Object value;
11.400 + volatile Node<K,V> next;
11.401 +
11.402 + /**
11.403 + * Creates a new regular node.
11.404 + */
11.405 + Node(K key, Object value, Node<K,V> next) {
11.406 + this.key = key;
11.407 + this.value = value;
11.408 + this.next = next;
11.409 + }
11.410 +
11.411 + /**
11.412 + * Creates a new marker node. A marker is distinguished by
11.413 + * having its value field point to itself. Marker nodes also
11.414 + * have null keys, a fact that is exploited in a few places,
11.415 + * but this doesn't distinguish markers from the base-level
11.416 + * header node (head.node), which also has a null key.
11.417 + */
11.418 + Node(Node<K,V> next) {
11.419 + this.key = null;
11.420 + this.value = this;
11.421 + this.next = next;
11.422 + }
11.423 +
11.424 + /**
11.425 + * compareAndSet value field
11.426 + */
11.427 + boolean casValue(Object cmp, Object val) {
11.428 + return UNSAFE.compareAndSwapObject(this, valueOffset, cmp, val);
11.429 + }
11.430 +
11.431 + /**
11.432 + * compareAndSet next field
11.433 + */
11.434 + boolean casNext(Node<K,V> cmp, Node<K,V> val) {
11.435 + return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
11.436 + }
11.437 +
11.438 + /**
11.439 + * Returns true if this node is a marker. This method isn't
11.440 + * actually called in any current code checking for markers
11.441 + * because callers will have already read value field and need
11.442 + * to use that read (not another done here) and so directly
11.443 + * test if value points to node.
11.444 + * @param n a possibly null reference to a node
11.445 + * @return true if this node is a marker node
11.446 + */
11.447 + boolean isMarker() {
11.448 + return value == this;
11.449 + }
11.450 +
11.451 + /**
11.452 + * Returns true if this node is the header of base-level list.
11.453 + * @return true if this node is header node
11.454 + */
11.455 + boolean isBaseHeader() {
11.456 + return value == BASE_HEADER;
11.457 + }
11.458 +
11.459 + /**
11.460 + * Tries to append a deletion marker to this node.
11.461 + * @param f the assumed current successor of this node
11.462 + * @return true if successful
11.463 + */
11.464 + boolean appendMarker(Node<K,V> f) {
11.465 + return casNext(f, new Node<K,V>(f));
11.466 + }
11.467 +
11.468 + /**
11.469 + * Helps out a deletion by appending marker or unlinking from
11.470 + * predecessor. This is called during traversals when value
11.471 + * field seen to be null.
11.472 + * @param b predecessor
11.473 + * @param f successor
11.474 + */
11.475 + void helpDelete(Node<K,V> b, Node<K,V> f) {
11.476 + /*
11.477 + * Rechecking links and then doing only one of the
11.478 + * help-out stages per call tends to minimize CAS
11.479 + * interference among helping threads.
11.480 + */
11.481 + if (f == next && this == b.next) {
11.482 + if (f == null || f.value != f) // not already marked
11.483 + appendMarker(f);
11.484 + else
11.485 + b.casNext(this, f.next);
11.486 + }
11.487 + }
11.488 +
11.489 + /**
11.490 + * Returns value if this node contains a valid key-value pair,
11.491 + * else null.
11.492 + * @return this node's value if it isn't a marker or header or
11.493 + * is deleted, else null.
11.494 + */
11.495 + V getValidValue() {
11.496 + Object v = value;
11.497 + if (v == this || v == BASE_HEADER)
11.498 + return null;
11.499 + return (V)v;
11.500 + }
11.501 +
11.502 + /**
11.503 + * Creates and returns a new SimpleImmutableEntry holding current
11.504 + * mapping if this node holds a valid value, else null.
11.505 + * @return new entry or null
11.506 + */
11.507 + AbstractMap.SimpleImmutableEntry<K,V> createSnapshot() {
11.508 + V v = getValidValue();
11.509 + if (v == null)
11.510 + return null;
11.511 + return new AbstractMap.SimpleImmutableEntry<K,V>(key, v);
11.512 + }
11.513 +
11.514 + // UNSAFE mechanics
11.515 +
11.516 + private static final sun.misc.Unsafe UNSAFE;
11.517 + private static final long valueOffset;
11.518 + private static final long nextOffset;
11.519 +
11.520 + static {
11.521 + try {
11.522 + UNSAFE = sun.misc.Unsafe.getUnsafe();
11.523 + Class k = Node.class;
11.524 + valueOffset = UNSAFE.objectFieldOffset
11.525 + (k.getDeclaredField("value"));
11.526 + nextOffset = UNSAFE.objectFieldOffset
11.527 + (k.getDeclaredField("next"));
11.528 + } catch (Exception e) {
11.529 + throw new Error(e);
11.530 + }
11.531 + }
11.532 + }
11.533 +
11.534 + /* ---------------- Indexing -------------- */
11.535 +
11.536 + /**
11.537 + * Index nodes represent the levels of the skip list. Note that
11.538 + * even though both Nodes and Indexes have forward-pointing
11.539 + * fields, they have different types and are handled in different
11.540 + * ways, that can't nicely be captured by placing field in a
11.541 + * shared abstract class.
11.542 + */
11.543 + static class Index<K,V> {
11.544 + final Node<K,V> node;
11.545 + final Index<K,V> down;
11.546 + volatile Index<K,V> right;
11.547 +
11.548 + /**
11.549 + * Creates index node with given values.
11.550 + */
11.551 + Index(Node<K,V> node, Index<K,V> down, Index<K,V> right) {
11.552 + this.node = node;
11.553 + this.down = down;
11.554 + this.right = right;
11.555 + }
11.556 +
11.557 + /**
11.558 + * compareAndSet right field
11.559 + */
11.560 + final boolean casRight(Index<K,V> cmp, Index<K,V> val) {
11.561 + return UNSAFE.compareAndSwapObject(this, rightOffset, cmp, val);
11.562 + }
11.563 +
11.564 + /**
11.565 + * Returns true if the node this indexes has been deleted.
11.566 + * @return true if indexed node is known to be deleted
11.567 + */
11.568 + final boolean indexesDeletedNode() {
11.569 + return node.value == null;
11.570 + }
11.571 +
11.572 + /**
11.573 + * Tries to CAS newSucc as successor. To minimize races with
11.574 + * unlink that may lose this index node, if the node being
11.575 + * indexed is known to be deleted, it doesn't try to link in.
11.576 + * @param succ the expected current successor
11.577 + * @param newSucc the new successor
11.578 + * @return true if successful
11.579 + */
11.580 + final boolean link(Index<K,V> succ, Index<K,V> newSucc) {
11.581 + Node<K,V> n = node;
11.582 + newSucc.right = succ;
11.583 + return n.value != null && casRight(succ, newSucc);
11.584 + }
11.585 +
11.586 + /**
11.587 + * Tries to CAS right field to skip over apparent successor
11.588 + * succ. Fails (forcing a retraversal by caller) if this node
11.589 + * is known to be deleted.
11.590 + * @param succ the expected current successor
11.591 + * @return true if successful
11.592 + */
11.593 + final boolean unlink(Index<K,V> succ) {
11.594 + return !indexesDeletedNode() && casRight(succ, succ.right);
11.595 + }
11.596 +
11.597 + // Unsafe mechanics
11.598 + private static final sun.misc.Unsafe UNSAFE;
11.599 + private static final long rightOffset;
11.600 + static {
11.601 + try {
11.602 + UNSAFE = sun.misc.Unsafe.getUnsafe();
11.603 + Class k = Index.class;
11.604 + rightOffset = UNSAFE.objectFieldOffset
11.605 + (k.getDeclaredField("right"));
11.606 + } catch (Exception e) {
11.607 + throw new Error(e);
11.608 + }
11.609 + }
11.610 + }
11.611 +
11.612 + /* ---------------- Head nodes -------------- */
11.613 +
11.614 + /**
11.615 + * Nodes heading each level keep track of their level.
11.616 + */
11.617 + static final class HeadIndex<K,V> extends Index<K,V> {
11.618 + final int level;
11.619 + HeadIndex(Node<K,V> node, Index<K,V> down, Index<K,V> right, int level) {
11.620 + super(node, down, right);
11.621 + this.level = level;
11.622 + }
11.623 + }
11.624 +
11.625 + /* ---------------- Comparison utilities -------------- */
11.626 +
11.627 + /**
11.628 + * Represents a key with a comparator as a Comparable.
11.629 + *
11.630 + * Because most sorted collections seem to use natural ordering on
11.631 + * Comparables (Strings, Integers, etc), most internal methods are
11.632 + * geared to use them. This is generally faster than checking
11.633 + * per-comparison whether to use comparator or comparable because
11.634 + * it doesn't require a (Comparable) cast for each comparison.
11.635 + * (Optimizers can only sometimes remove such redundant checks
11.636 + * themselves.) When Comparators are used,
11.637 + * ComparableUsingComparators are created so that they act in the
11.638 + * same way as natural orderings. This penalizes use of
11.639 + * Comparators vs Comparables, which seems like the right
11.640 + * tradeoff.
11.641 + */
11.642 + static final class ComparableUsingComparator<K> implements Comparable<K> {
11.643 + final K actualKey;
11.644 + final Comparator<? super K> cmp;
11.645 + ComparableUsingComparator(K key, Comparator<? super K> cmp) {
11.646 + this.actualKey = key;
11.647 + this.cmp = cmp;
11.648 + }
11.649 + public int compareTo(K k2) {
11.650 + return cmp.compare(actualKey, k2);
11.651 + }
11.652 + }
11.653 +
11.654 + /**
11.655 + * If using comparator, return a ComparableUsingComparator, else
11.656 + * cast key as Comparable, which may cause ClassCastException,
11.657 + * which is propagated back to caller.
11.658 + */
11.659 + private Comparable<? super K> comparable(Object key)
11.660 + throws ClassCastException {
11.661 + if (key == null)
11.662 + throw new NullPointerException();
11.663 + if (comparator != null)
11.664 + return new ComparableUsingComparator<K>((K)key, comparator);
11.665 + else
11.666 + return (Comparable<? super K>)key;
11.667 + }
11.668 +
11.669 + /**
11.670 + * Compares using comparator or natural ordering. Used when the
11.671 + * ComparableUsingComparator approach doesn't apply.
11.672 + */
11.673 + int compare(K k1, K k2) throws ClassCastException {
11.674 + Comparator<? super K> cmp = comparator;
11.675 + if (cmp != null)
11.676 + return cmp.compare(k1, k2);
11.677 + else
11.678 + return ((Comparable<? super K>)k1).compareTo(k2);
11.679 + }
11.680 +
11.681 + /**
11.682 + * Returns true if given key greater than or equal to least and
11.683 + * strictly less than fence, bypassing either test if least or
11.684 + * fence are null. Needed mainly in submap operations.
11.685 + */
11.686 + boolean inHalfOpenRange(K key, K least, K fence) {
11.687 + if (key == null)
11.688 + throw new NullPointerException();
11.689 + return ((least == null || compare(key, least) >= 0) &&
11.690 + (fence == null || compare(key, fence) < 0));
11.691 + }
11.692 +
11.693 + /**
11.694 + * Returns true if given key greater than or equal to least and less
11.695 + * or equal to fence. Needed mainly in submap operations.
11.696 + */
11.697 + boolean inOpenRange(K key, K least, K fence) {
11.698 + if (key == null)
11.699 + throw new NullPointerException();
11.700 + return ((least == null || compare(key, least) >= 0) &&
11.701 + (fence == null || compare(key, fence) <= 0));
11.702 + }
11.703 +
11.704 + /* ---------------- Traversal -------------- */
11.705 +
11.706 + /**
11.707 + * Returns a base-level node with key strictly less than given key,
11.708 + * or the base-level header if there is no such node. Also
11.709 + * unlinks indexes to deleted nodes found along the way. Callers
11.710 + * rely on this side-effect of clearing indices to deleted nodes.
11.711 + * @param key the key
11.712 + * @return a predecessor of key
11.713 + */
11.714 + private Node<K,V> findPredecessor(Comparable<? super K> key) {
11.715 + if (key == null)
11.716 + throw new NullPointerException(); // don't postpone errors
11.717 + for (;;) {
11.718 + Index<K,V> q = head;
11.719 + Index<K,V> r = q.right;
11.720 + for (;;) {
11.721 + if (r != null) {
11.722 + Node<K,V> n = r.node;
11.723 + K k = n.key;
11.724 + if (n.value == null) {
11.725 + if (!q.unlink(r))
11.726 + break; // restart
11.727 + r = q.right; // reread r
11.728 + continue;
11.729 + }
11.730 + if (key.compareTo(k) > 0) {
11.731 + q = r;
11.732 + r = r.right;
11.733 + continue;
11.734 + }
11.735 + }
11.736 + Index<K,V> d = q.down;
11.737 + if (d != null) {
11.738 + q = d;
11.739 + r = d.right;
11.740 + } else
11.741 + return q.node;
11.742 + }
11.743 + }
11.744 + }
11.745 +
11.746 + /**
11.747 + * Returns node holding key or null if no such, clearing out any
11.748 + * deleted nodes seen along the way. Repeatedly traverses at
11.749 + * base-level looking for key starting at predecessor returned
11.750 + * from findPredecessor, processing base-level deletions as
11.751 + * encountered. Some callers rely on this side-effect of clearing
11.752 + * deleted nodes.
11.753 + *
11.754 + * Restarts occur, at traversal step centered on node n, if:
11.755 + *
11.756 + * (1) After reading n's next field, n is no longer assumed
11.757 + * predecessor b's current successor, which means that
11.758 + * we don't have a consistent 3-node snapshot and so cannot
11.759 + * unlink any subsequent deleted nodes encountered.
11.760 + *
11.761 + * (2) n's value field is null, indicating n is deleted, in
11.762 + * which case we help out an ongoing structural deletion
11.763 + * before retrying. Even though there are cases where such
11.764 + * unlinking doesn't require restart, they aren't sorted out
11.765 + * here because doing so would not usually outweigh cost of
11.766 + * restarting.
11.767 + *
11.768 + * (3) n is a marker or n's predecessor's value field is null,
11.769 + * indicating (among other possibilities) that
11.770 + * findPredecessor returned a deleted node. We can't unlink
11.771 + * the node because we don't know its predecessor, so rely
11.772 + * on another call to findPredecessor to notice and return
11.773 + * some earlier predecessor, which it will do. This check is
11.774 + * only strictly needed at beginning of loop, (and the
11.775 + * b.value check isn't strictly needed at all) but is done
11.776 + * each iteration to help avoid contention with other
11.777 + * threads by callers that will fail to be able to change
11.778 + * links, and so will retry anyway.
11.779 + *
11.780 + * The traversal loops in doPut, doRemove, and findNear all
11.781 + * include the same three kinds of checks. And specialized
11.782 + * versions appear in findFirst, and findLast and their
11.783 + * variants. They can't easily share code because each uses the
11.784 + * reads of fields held in locals occurring in the orders they
11.785 + * were performed.
11.786 + *
11.787 + * @param key the key
11.788 + * @return node holding key, or null if no such
11.789 + */
11.790 + private Node<K,V> findNode(Comparable<? super K> key) {
11.791 + for (;;) {
11.792 + Node<K,V> b = findPredecessor(key);
11.793 + Node<K,V> n = b.next;
11.794 + for (;;) {
11.795 + if (n == null)
11.796 + return null;
11.797 + Node<K,V> f = n.next;
11.798 + if (n != b.next) // inconsistent read
11.799 + break;
11.800 + Object v = n.value;
11.801 + if (v == null) { // n is deleted
11.802 + n.helpDelete(b, f);
11.803 + break;
11.804 + }
11.805 + if (v == n || b.value == null) // b is deleted
11.806 + break;
11.807 + int c = key.compareTo(n.key);
11.808 + if (c == 0)
11.809 + return n;
11.810 + if (c < 0)
11.811 + return null;
11.812 + b = n;
11.813 + n = f;
11.814 + }
11.815 + }
11.816 + }
11.817 +
11.818 + /**
11.819 + * Gets value for key using findNode.
11.820 + * @param okey the key
11.821 + * @return the value, or null if absent
11.822 + */
11.823 + private V doGet(Object okey) {
11.824 + Comparable<? super K> key = comparable(okey);
11.825 + /*
11.826 + * Loop needed here and elsewhere in case value field goes
11.827 + * null just as it is about to be returned, in which case we
11.828 + * lost a race with a deletion, so must retry.
11.829 + */
11.830 + for (;;) {
11.831 + Node<K,V> n = findNode(key);
11.832 + if (n == null)
11.833 + return null;
11.834 + Object v = n.value;
11.835 + if (v != null)
11.836 + return (V)v;
11.837 + }
11.838 + }
11.839 +
11.840 + /* ---------------- Insertion -------------- */
11.841 +
11.842 + /**
11.843 + * Main insertion method. Adds element if not present, or
11.844 + * replaces value if present and onlyIfAbsent is false.
11.845 + * @param kkey the key
11.846 + * @param value the value that must be associated with key
11.847 + * @param onlyIfAbsent if should not insert if already present
11.848 + * @return the old value, or null if newly inserted
11.849 + */
11.850 + private V doPut(K kkey, V value, boolean onlyIfAbsent) {
11.851 + Comparable<? super K> key = comparable(kkey);
11.852 + for (;;) {
11.853 + Node<K,V> b = findPredecessor(key);
11.854 + Node<K,V> n = b.next;
11.855 + for (;;) {
11.856 + if (n != null) {
11.857 + Node<K,V> f = n.next;
11.858 + if (n != b.next) // inconsistent read
11.859 + break;
11.860 + Object v = n.value;
11.861 + if (v == null) { // n is deleted
11.862 + n.helpDelete(b, f);
11.863 + break;
11.864 + }
11.865 + if (v == n || b.value == null) // b is deleted
11.866 + break;
11.867 + int c = key.compareTo(n.key);
11.868 + if (c > 0) {
11.869 + b = n;
11.870 + n = f;
11.871 + continue;
11.872 + }
11.873 + if (c == 0) {
11.874 + if (onlyIfAbsent || n.casValue(v, value))
11.875 + return (V)v;
11.876 + else
11.877 + break; // restart if lost race to replace value
11.878 + }
11.879 + // else c < 0; fall through
11.880 + }
11.881 +
11.882 + Node<K,V> z = new Node<K,V>(kkey, value, n);
11.883 + if (!b.casNext(n, z))
11.884 + break; // restart if lost race to append to b
11.885 + int level = randomLevel();
11.886 + if (level > 0)
11.887 + insertIndex(z, level);
11.888 + return null;
11.889 + }
11.890 + }
11.891 + }
11.892 +
11.893 + /**
11.894 + * Returns a random level for inserting a new node.
11.895 + * Hardwired to k=1, p=0.5, max 31 (see above and
11.896 + * Pugh's "Skip List Cookbook", sec 3.4).
11.897 + *
11.898 + * This uses the simplest of the generators described in George
11.899 + * Marsaglia's "Xorshift RNGs" paper. This is not a high-quality
11.900 + * generator but is acceptable here.
11.901 + */
11.902 + private int randomLevel() {
11.903 + int x = randomSeed;
11.904 + x ^= x << 13;
11.905 + x ^= x >>> 17;
11.906 + randomSeed = x ^= x << 5;
11.907 + if ((x & 0x80000001) != 0) // test highest and lowest bits
11.908 + return 0;
11.909 + int level = 1;
11.910 + while (((x >>>= 1) & 1) != 0) ++level;
11.911 + return level;
11.912 + }
11.913 +
11.914 + /**
11.915 + * Creates and adds index nodes for the given node.
11.916 + * @param z the node
11.917 + * @param level the level of the index
11.918 + */
11.919 + private void insertIndex(Node<K,V> z, int level) {
11.920 + HeadIndex<K,V> h = head;
11.921 + int max = h.level;
11.922 +
11.923 + if (level <= max) {
11.924 + Index<K,V> idx = null;
11.925 + for (int i = 1; i <= level; ++i)
11.926 + idx = new Index<K,V>(z, idx, null);
11.927 + addIndex(idx, h, level);
11.928 +
11.929 + } else { // Add a new level
11.930 + /*
11.931 + * To reduce interference by other threads checking for
11.932 + * empty levels in tryReduceLevel, new levels are added
11.933 + * with initialized right pointers. Which in turn requires
11.934 + * keeping levels in an array to access them while
11.935 + * creating new head index nodes from the opposite
11.936 + * direction.
11.937 + */
11.938 + level = max + 1;
11.939 + Index<K,V>[] idxs = (Index<K,V>[])new Index[level+1];
11.940 + Index<K,V> idx = null;
11.941 + for (int i = 1; i <= level; ++i)
11.942 + idxs[i] = idx = new Index<K,V>(z, idx, null);
11.943 +
11.944 + HeadIndex<K,V> oldh;
11.945 + int k;
11.946 + for (;;) {
11.947 + oldh = head;
11.948 + int oldLevel = oldh.level;
11.949 + if (level <= oldLevel) { // lost race to add level
11.950 + k = level;
11.951 + break;
11.952 + }
11.953 + HeadIndex<K,V> newh = oldh;
11.954 + Node<K,V> oldbase = oldh.node;
11.955 + for (int j = oldLevel+1; j <= level; ++j)
11.956 + newh = new HeadIndex<K,V>(oldbase, newh, idxs[j], j);
11.957 + if (casHead(oldh, newh)) {
11.958 + k = oldLevel;
11.959 + break;
11.960 + }
11.961 + }
11.962 + addIndex(idxs[k], oldh, k);
11.963 + }
11.964 + }
11.965 +
11.966 + /**
11.967 + * Adds given index nodes from given level down to 1.
11.968 + * @param idx the topmost index node being inserted
11.969 + * @param h the value of head to use to insert. This must be
11.970 + * snapshotted by callers to provide correct insertion level
11.971 + * @param indexLevel the level of the index
11.972 + */
11.973 + private void addIndex(Index<K,V> idx, HeadIndex<K,V> h, int indexLevel) {
11.974 + // Track next level to insert in case of retries
11.975 + int insertionLevel = indexLevel;
11.976 + Comparable<? super K> key = comparable(idx.node.key);
11.977 + if (key == null) throw new NullPointerException();
11.978 +
11.979 + // Similar to findPredecessor, but adding index nodes along
11.980 + // path to key.
11.981 + for (;;) {
11.982 + int j = h.level;
11.983 + Index<K,V> q = h;
11.984 + Index<K,V> r = q.right;
11.985 + Index<K,V> t = idx;
11.986 + for (;;) {
11.987 + if (r != null) {
11.988 + Node<K,V> n = r.node;
11.989 + // compare before deletion check avoids needing recheck
11.990 + int c = key.compareTo(n.key);
11.991 + if (n.value == null) {
11.992 + if (!q.unlink(r))
11.993 + break;
11.994 + r = q.right;
11.995 + continue;
11.996 + }
11.997 + if (c > 0) {
11.998 + q = r;
11.999 + r = r.right;
11.1000 + continue;
11.1001 + }
11.1002 + }
11.1003 +
11.1004 + if (j == insertionLevel) {
11.1005 + // Don't insert index if node already deleted
11.1006 + if (t.indexesDeletedNode()) {
11.1007 + findNode(key); // cleans up
11.1008 + return;
11.1009 + }
11.1010 + if (!q.link(r, t))
11.1011 + break; // restart
11.1012 + if (--insertionLevel == 0) {
11.1013 + // need final deletion check before return
11.1014 + if (t.indexesDeletedNode())
11.1015 + findNode(key);
11.1016 + return;
11.1017 + }
11.1018 + }
11.1019 +
11.1020 + if (--j >= insertionLevel && j < indexLevel)
11.1021 + t = t.down;
11.1022 + q = q.down;
11.1023 + r = q.right;
11.1024 + }
11.1025 + }
11.1026 + }
11.1027 +
11.1028 + /* ---------------- Deletion -------------- */
11.1029 +
11.1030 + /**
11.1031 + * Main deletion method. Locates node, nulls value, appends a
11.1032 + * deletion marker, unlinks predecessor, removes associated index
11.1033 + * nodes, and possibly reduces head index level.
11.1034 + *
11.1035 + * Index nodes are cleared out simply by calling findPredecessor.
11.1036 + * which unlinks indexes to deleted nodes found along path to key,
11.1037 + * which will include the indexes to this node. This is done
11.1038 + * unconditionally. We can't check beforehand whether there are
11.1039 + * index nodes because it might be the case that some or all
11.1040 + * indexes hadn't been inserted yet for this node during initial
11.1041 + * search for it, and we'd like to ensure lack of garbage
11.1042 + * retention, so must call to be sure.
11.1043 + *
11.1044 + * @param okey the key
11.1045 + * @param value if non-null, the value that must be
11.1046 + * associated with key
11.1047 + * @return the node, or null if not found
11.1048 + */
11.1049 + final V doRemove(Object okey, Object value) {
11.1050 + Comparable<? super K> key = comparable(okey);
11.1051 + for (;;) {
11.1052 + Node<K,V> b = findPredecessor(key);
11.1053 + Node<K,V> n = b.next;
11.1054 + for (;;) {
11.1055 + if (n == null)
11.1056 + return null;
11.1057 + Node<K,V> f = n.next;
11.1058 + if (n != b.next) // inconsistent read
11.1059 + break;
11.1060 + Object v = n.value;
11.1061 + if (v == null) { // n is deleted
11.1062 + n.helpDelete(b, f);
11.1063 + break;
11.1064 + }
11.1065 + if (v == n || b.value == null) // b is deleted
11.1066 + break;
11.1067 + int c = key.compareTo(n.key);
11.1068 + if (c < 0)
11.1069 + return null;
11.1070 + if (c > 0) {
11.1071 + b = n;
11.1072 + n = f;
11.1073 + continue;
11.1074 + }
11.1075 + if (value != null && !value.equals(v))
11.1076 + return null;
11.1077 + if (!n.casValue(v, null))
11.1078 + break;
11.1079 + if (!n.appendMarker(f) || !b.casNext(n, f))
11.1080 + findNode(key); // Retry via findNode
11.1081 + else {
11.1082 + findPredecessor(key); // Clean index
11.1083 + if (head.right == null)
11.1084 + tryReduceLevel();
11.1085 + }
11.1086 + return (V)v;
11.1087 + }
11.1088 + }
11.1089 + }
11.1090 +
11.1091 + /**
11.1092 + * Possibly reduce head level if it has no nodes. This method can
11.1093 + * (rarely) make mistakes, in which case levels can disappear even
11.1094 + * though they are about to contain index nodes. This impacts
11.1095 + * performance, not correctness. To minimize mistakes as well as
11.1096 + * to reduce hysteresis, the level is reduced by one only if the
11.1097 + * topmost three levels look empty. Also, if the removed level
11.1098 + * looks non-empty after CAS, we try to change it back quick
11.1099 + * before anyone notices our mistake! (This trick works pretty
11.1100 + * well because this method will practically never make mistakes
11.1101 + * unless current thread stalls immediately before first CAS, in
11.1102 + * which case it is very unlikely to stall again immediately
11.1103 + * afterwards, so will recover.)
11.1104 + *
11.1105 + * We put up with all this rather than just let levels grow
11.1106 + * because otherwise, even a small map that has undergone a large
11.1107 + * number of insertions and removals will have a lot of levels,
11.1108 + * slowing down access more than would an occasional unwanted
11.1109 + * reduction.
11.1110 + */
11.1111 + private void tryReduceLevel() {
11.1112 + HeadIndex<K,V> h = head;
11.1113 + HeadIndex<K,V> d;
11.1114 + HeadIndex<K,V> e;
11.1115 + if (h.level > 3 &&
11.1116 + (d = (HeadIndex<K,V>)h.down) != null &&
11.1117 + (e = (HeadIndex<K,V>)d.down) != null &&
11.1118 + e.right == null &&
11.1119 + d.right == null &&
11.1120 + h.right == null &&
11.1121 + casHead(h, d) && // try to set
11.1122 + h.right != null) // recheck
11.1123 + casHead(d, h); // try to backout
11.1124 + }
11.1125 +
11.1126 + /* ---------------- Finding and removing first element -------------- */
11.1127 +
11.1128 + /**
11.1129 + * Specialized variant of findNode to get first valid node.
11.1130 + * @return first node or null if empty
11.1131 + */
11.1132 + Node<K,V> findFirst() {
11.1133 + for (;;) {
11.1134 + Node<K,V> b = head.node;
11.1135 + Node<K,V> n = b.next;
11.1136 + if (n == null)
11.1137 + return null;
11.1138 + if (n.value != null)
11.1139 + return n;
11.1140 + n.helpDelete(b, n.next);
11.1141 + }
11.1142 + }
11.1143 +
11.1144 + /**
11.1145 + * Removes first entry; returns its snapshot.
11.1146 + * @return null if empty, else snapshot of first entry
11.1147 + */
11.1148 + Map.Entry<K,V> doRemoveFirstEntry() {
11.1149 + for (;;) {
11.1150 + Node<K,V> b = head.node;
11.1151 + Node<K,V> n = b.next;
11.1152 + if (n == null)
11.1153 + return null;
11.1154 + Node<K,V> f = n.next;
11.1155 + if (n != b.next)
11.1156 + continue;
11.1157 + Object v = n.value;
11.1158 + if (v == null) {
11.1159 + n.helpDelete(b, f);
11.1160 + continue;
11.1161 + }
11.1162 + if (!n.casValue(v, null))
11.1163 + continue;
11.1164 + if (!n.appendMarker(f) || !b.casNext(n, f))
11.1165 + findFirst(); // retry
11.1166 + clearIndexToFirst();
11.1167 + return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, (V)v);
11.1168 + }
11.1169 + }
11.1170 +
11.1171 + /**
11.1172 + * Clears out index nodes associated with deleted first entry.
11.1173 + */
11.1174 + private void clearIndexToFirst() {
11.1175 + for (;;) {
11.1176 + Index<K,V> q = head;
11.1177 + for (;;) {
11.1178 + Index<K,V> r = q.right;
11.1179 + if (r != null && r.indexesDeletedNode() && !q.unlink(r))
11.1180 + break;
11.1181 + if ((q = q.down) == null) {
11.1182 + if (head.right == null)
11.1183 + tryReduceLevel();
11.1184 + return;
11.1185 + }
11.1186 + }
11.1187 + }
11.1188 + }
11.1189 +
11.1190 +
11.1191 + /* ---------------- Finding and removing last element -------------- */
11.1192 +
11.1193 + /**
11.1194 + * Specialized version of find to get last valid node.
11.1195 + * @return last node or null if empty
11.1196 + */
11.1197 + Node<K,V> findLast() {
11.1198 + /*
11.1199 + * findPredecessor can't be used to traverse index level
11.1200 + * because this doesn't use comparisons. So traversals of
11.1201 + * both levels are folded together.
11.1202 + */
11.1203 + Index<K,V> q = head;
11.1204 + for (;;) {
11.1205 + Index<K,V> d, r;
11.1206 + if ((r = q.right) != null) {
11.1207 + if (r.indexesDeletedNode()) {
11.1208 + q.unlink(r);
11.1209 + q = head; // restart
11.1210 + }
11.1211 + else
11.1212 + q = r;
11.1213 + } else if ((d = q.down) != null) {
11.1214 + q = d;
11.1215 + } else {
11.1216 + Node<K,V> b = q.node;
11.1217 + Node<K,V> n = b.next;
11.1218 + for (;;) {
11.1219 + if (n == null)
11.1220 + return b.isBaseHeader() ? null : b;
11.1221 + Node<K,V> f = n.next; // inconsistent read
11.1222 + if (n != b.next)
11.1223 + break;
11.1224 + Object v = n.value;
11.1225 + if (v == null) { // n is deleted
11.1226 + n.helpDelete(b, f);
11.1227 + break;
11.1228 + }
11.1229 + if (v == n || b.value == null) // b is deleted
11.1230 + break;
11.1231 + b = n;
11.1232 + n = f;
11.1233 + }
11.1234 + q = head; // restart
11.1235 + }
11.1236 + }
11.1237 + }
11.1238 +
11.1239 + /**
11.1240 + * Specialized variant of findPredecessor to get predecessor of last
11.1241 + * valid node. Needed when removing the last entry. It is possible
11.1242 + * that all successors of returned node will have been deleted upon
11.1243 + * return, in which case this method can be retried.
11.1244 + * @return likely predecessor of last node
11.1245 + */
11.1246 + private Node<K,V> findPredecessorOfLast() {
11.1247 + for (;;) {
11.1248 + Index<K,V> q = head;
11.1249 + for (;;) {
11.1250 + Index<K,V> d, r;
11.1251 + if ((r = q.right) != null) {
11.1252 + if (r.indexesDeletedNode()) {
11.1253 + q.unlink(r);
11.1254 + break; // must restart
11.1255 + }
11.1256 + // proceed as far across as possible without overshooting
11.1257 + if (r.node.next != null) {
11.1258 + q = r;
11.1259 + continue;
11.1260 + }
11.1261 + }
11.1262 + if ((d = q.down) != null)
11.1263 + q = d;
11.1264 + else
11.1265 + return q.node;
11.1266 + }
11.1267 + }
11.1268 + }
11.1269 +
11.1270 + /**
11.1271 + * Removes last entry; returns its snapshot.
11.1272 + * Specialized variant of doRemove.
11.1273 + * @return null if empty, else snapshot of last entry
11.1274 + */
11.1275 + Map.Entry<K,V> doRemoveLastEntry() {
11.1276 + for (;;) {
11.1277 + Node<K,V> b = findPredecessorOfLast();
11.1278 + Node<K,V> n = b.next;
11.1279 + if (n == null) {
11.1280 + if (b.isBaseHeader()) // empty
11.1281 + return null;
11.1282 + else
11.1283 + continue; // all b's successors are deleted; retry
11.1284 + }
11.1285 + for (;;) {
11.1286 + Node<K,V> f = n.next;
11.1287 + if (n != b.next) // inconsistent read
11.1288 + break;
11.1289 + Object v = n.value;
11.1290 + if (v == null) { // n is deleted
11.1291 + n.helpDelete(b, f);
11.1292 + break;
11.1293 + }
11.1294 + if (v == n || b.value == null) // b is deleted
11.1295 + break;
11.1296 + if (f != null) {
11.1297 + b = n;
11.1298 + n = f;
11.1299 + continue;
11.1300 + }
11.1301 + if (!n.casValue(v, null))
11.1302 + break;
11.1303 + K key = n.key;
11.1304 + Comparable<? super K> ck = comparable(key);
11.1305 + if (!n.appendMarker(f) || !b.casNext(n, f))
11.1306 + findNode(ck); // Retry via findNode
11.1307 + else {
11.1308 + findPredecessor(ck); // Clean index
11.1309 + if (head.right == null)
11.1310 + tryReduceLevel();
11.1311 + }
11.1312 + return new AbstractMap.SimpleImmutableEntry<K,V>(key, (V)v);
11.1313 + }
11.1314 + }
11.1315 + }
11.1316 +
11.1317 + /* ---------------- Relational operations -------------- */
11.1318 +
11.1319 + // Control values OR'ed as arguments to findNear
11.1320 +
11.1321 + private static final int EQ = 1;
11.1322 + private static final int LT = 2;
11.1323 + private static final int GT = 0; // Actually checked as !LT
11.1324 +
11.1325 + /**
11.1326 + * Utility for ceiling, floor, lower, higher methods.
11.1327 + * @param kkey the key
11.1328 + * @param rel the relation -- OR'ed combination of EQ, LT, GT
11.1329 + * @return nearest node fitting relation, or null if no such
11.1330 + */
11.1331 + Node<K,V> findNear(K kkey, int rel) {
11.1332 + Comparable<? super K> key = comparable(kkey);
11.1333 + for (;;) {
11.1334 + Node<K,V> b = findPredecessor(key);
11.1335 + Node<K,V> n = b.next;
11.1336 + for (;;) {
11.1337 + if (n == null)
11.1338 + return ((rel & LT) == 0 || b.isBaseHeader()) ? null : b;
11.1339 + Node<K,V> f = n.next;
11.1340 + if (n != b.next) // inconsistent read
11.1341 + break;
11.1342 + Object v = n.value;
11.1343 + if (v == null) { // n is deleted
11.1344 + n.helpDelete(b, f);
11.1345 + break;
11.1346 + }
11.1347 + if (v == n || b.value == null) // b is deleted
11.1348 + break;
11.1349 + int c = key.compareTo(n.key);
11.1350 + if ((c == 0 && (rel & EQ) != 0) ||
11.1351 + (c < 0 && (rel & LT) == 0))
11.1352 + return n;
11.1353 + if ( c <= 0 && (rel & LT) != 0)
11.1354 + return b.isBaseHeader() ? null : b;
11.1355 + b = n;
11.1356 + n = f;
11.1357 + }
11.1358 + }
11.1359 + }
11.1360 +
11.1361 + /**
11.1362 + * Returns SimpleImmutableEntry for results of findNear.
11.1363 + * @param key the key
11.1364 + * @param rel the relation -- OR'ed combination of EQ, LT, GT
11.1365 + * @return Entry fitting relation, or null if no such
11.1366 + */
11.1367 + AbstractMap.SimpleImmutableEntry<K,V> getNear(K key, int rel) {
11.1368 + for (;;) {
11.1369 + Node<K,V> n = findNear(key, rel);
11.1370 + if (n == null)
11.1371 + return null;
11.1372 + AbstractMap.SimpleImmutableEntry<K,V> e = n.createSnapshot();
11.1373 + if (e != null)
11.1374 + return e;
11.1375 + }
11.1376 + }
11.1377 +
11.1378 +
11.1379 + /* ---------------- Constructors -------------- */
11.1380 +
11.1381 + /**
11.1382 + * Constructs a new, empty map, sorted according to the
11.1383 + * {@linkplain Comparable natural ordering} of the keys.
11.1384 + */
11.1385 + public ConcurrentSkipListMap() {
11.1386 + this.comparator = null;
11.1387 + initialize();
11.1388 + }
11.1389 +
11.1390 + /**
11.1391 + * Constructs a new, empty map, sorted according to the specified
11.1392 + * comparator.
11.1393 + *
11.1394 + * @param comparator the comparator that will be used to order this map.
11.1395 + * If <tt>null</tt>, the {@linkplain Comparable natural
11.1396 + * ordering} of the keys will be used.
11.1397 + */
11.1398 + public ConcurrentSkipListMap(Comparator<? super K> comparator) {
11.1399 + this.comparator = comparator;
11.1400 + initialize();
11.1401 + }
11.1402 +
11.1403 + /**
11.1404 + * Constructs a new map containing the same mappings as the given map,
11.1405 + * sorted according to the {@linkplain Comparable natural ordering} of
11.1406 + * the keys.
11.1407 + *
11.1408 + * @param m the map whose mappings are to be placed in this map
11.1409 + * @throws ClassCastException if the keys in <tt>m</tt> are not
11.1410 + * {@link Comparable}, or are not mutually comparable
11.1411 + * @throws NullPointerException if the specified map or any of its keys
11.1412 + * or values are null
11.1413 + */
11.1414 + public ConcurrentSkipListMap(Map<? extends K, ? extends V> m) {
11.1415 + this.comparator = null;
11.1416 + initialize();
11.1417 + putAll(m);
11.1418 + }
11.1419 +
11.1420 + /**
11.1421 + * Constructs a new map containing the same mappings and using the
11.1422 + * same ordering as the specified sorted map.
11.1423 + *
11.1424 + * @param m the sorted map whose mappings are to be placed in this
11.1425 + * map, and whose comparator is to be used to sort this map
11.1426 + * @throws NullPointerException if the specified sorted map or any of
11.1427 + * its keys or values are null
11.1428 + */
11.1429 + public ConcurrentSkipListMap(SortedMap<K, ? extends V> m) {
11.1430 + this.comparator = m.comparator();
11.1431 + initialize();
11.1432 + buildFromSorted(m);
11.1433 + }
11.1434 +
11.1435 + /**
11.1436 + * Returns a shallow copy of this <tt>ConcurrentSkipListMap</tt>
11.1437 + * instance. (The keys and values themselves are not cloned.)
11.1438 + *
11.1439 + * @return a shallow copy of this map
11.1440 + */
11.1441 + public ConcurrentSkipListMap<K,V> clone() {
11.1442 + ConcurrentSkipListMap<K,V> clone = null;
11.1443 + try {
11.1444 + clone = (ConcurrentSkipListMap<K,V>) super.clone();
11.1445 + } catch (CloneNotSupportedException e) {
11.1446 + throw new InternalError();
11.1447 + }
11.1448 +
11.1449 + clone.initialize();
11.1450 + clone.buildFromSorted(this);
11.1451 + return clone;
11.1452 + }
11.1453 +
11.1454 + /**
11.1455 + * Streamlined bulk insertion to initialize from elements of
11.1456 + * given sorted map. Call only from constructor or clone
11.1457 + * method.
11.1458 + */
11.1459 + private void buildFromSorted(SortedMap<K, ? extends V> map) {
11.1460 + if (map == null)
11.1461 + throw new NullPointerException();
11.1462 +
11.1463 + HeadIndex<K,V> h = head;
11.1464 + Node<K,V> basepred = h.node;
11.1465 +
11.1466 + // Track the current rightmost node at each level. Uses an
11.1467 + // ArrayList to avoid committing to initial or maximum level.
11.1468 + ArrayList<Index<K,V>> preds = new ArrayList<Index<K,V>>();
11.1469 +
11.1470 + // initialize
11.1471 + for (int i = 0; i <= h.level; ++i)
11.1472 + preds.add(null);
11.1473 + Index<K,V> q = h;
11.1474 + for (int i = h.level; i > 0; --i) {
11.1475 + preds.set(i, q);
11.1476 + q = q.down;
11.1477 + }
11.1478 +
11.1479 + Iterator<? extends Map.Entry<? extends K, ? extends V>> it =
11.1480 + map.entrySet().iterator();
11.1481 + while (it.hasNext()) {
11.1482 + Map.Entry<? extends K, ? extends V> e = it.next();
11.1483 + int j = randomLevel();
11.1484 + if (j > h.level) j = h.level + 1;
11.1485 + K k = e.getKey();
11.1486 + V v = e.getValue();
11.1487 + if (k == null || v == null)
11.1488 + throw new NullPointerException();
11.1489 + Node<K,V> z = new Node<K,V>(k, v, null);
11.1490 + basepred.next = z;
11.1491 + basepred = z;
11.1492 + if (j > 0) {
11.1493 + Index<K,V> idx = null;
11.1494 + for (int i = 1; i <= j; ++i) {
11.1495 + idx = new Index<K,V>(z, idx, null);
11.1496 + if (i > h.level)
11.1497 + h = new HeadIndex<K,V>(h.node, h, idx, i);
11.1498 +
11.1499 + if (i < preds.size()) {
11.1500 + preds.get(i).right = idx;
11.1501 + preds.set(i, idx);
11.1502 + } else
11.1503 + preds.add(idx);
11.1504 + }
11.1505 + }
11.1506 + }
11.1507 + head = h;
11.1508 + }
11.1509 +
11.1510 + /* ---------------- Serialization -------------- */
11.1511 +
11.1512 + /**
11.1513 + * Save the state of this map to a stream.
11.1514 + *
11.1515 + * @serialData The key (Object) and value (Object) for each
11.1516 + * key-value mapping represented by the map, followed by
11.1517 + * <tt>null</tt>. The key-value mappings are emitted in key-order
11.1518 + * (as determined by the Comparator, or by the keys' natural
11.1519 + * ordering if no Comparator).
11.1520 + */
11.1521 + private void writeObject(java.io.ObjectOutputStream s)
11.1522 + throws java.io.IOException {
11.1523 + // Write out the Comparator and any hidden stuff
11.1524 + s.defaultWriteObject();
11.1525 +
11.1526 + // Write out keys and values (alternating)
11.1527 + for (Node<K,V> n = findFirst(); n != null; n = n.next) {
11.1528 + V v = n.getValidValue();
11.1529 + if (v != null) {
11.1530 + s.writeObject(n.key);
11.1531 + s.writeObject(v);
11.1532 + }
11.1533 + }
11.1534 + s.writeObject(null);
11.1535 + }
11.1536 +
11.1537 + /**
11.1538 + * Reconstitute the map from a stream.
11.1539 + */
11.1540 + private void readObject(final java.io.ObjectInputStream s)
11.1541 + throws java.io.IOException, ClassNotFoundException {
11.1542 + // Read in the Comparator and any hidden stuff
11.1543 + s.defaultReadObject();
11.1544 + // Reset transients
11.1545 + initialize();
11.1546 +
11.1547 + /*
11.1548 + * This is nearly identical to buildFromSorted, but is
11.1549 + * distinct because readObject calls can't be nicely adapted
11.1550 + * as the kind of iterator needed by buildFromSorted. (They
11.1551 + * can be, but doing so requires type cheats and/or creation
11.1552 + * of adaptor classes.) It is simpler to just adapt the code.
11.1553 + */
11.1554 +
11.1555 + HeadIndex<K,V> h = head;
11.1556 + Node<K,V> basepred = h.node;
11.1557 + ArrayList<Index<K,V>> preds = new ArrayList<Index<K,V>>();
11.1558 + for (int i = 0; i <= h.level; ++i)
11.1559 + preds.add(null);
11.1560 + Index<K,V> q = h;
11.1561 + for (int i = h.level; i > 0; --i) {
11.1562 + preds.set(i, q);
11.1563 + q = q.down;
11.1564 + }
11.1565 +
11.1566 + for (;;) {
11.1567 + Object k = s.readObject();
11.1568 + if (k == null)
11.1569 + break;
11.1570 + Object v = s.readObject();
11.1571 + if (v == null)
11.1572 + throw new NullPointerException();
11.1573 + K key = (K) k;
11.1574 + V val = (V) v;
11.1575 + int j = randomLevel();
11.1576 + if (j > h.level) j = h.level + 1;
11.1577 + Node<K,V> z = new Node<K,V>(key, val, null);
11.1578 + basepred.next = z;
11.1579 + basepred = z;
11.1580 + if (j > 0) {
11.1581 + Index<K,V> idx = null;
11.1582 + for (int i = 1; i <= j; ++i) {
11.1583 + idx = new Index<K,V>(z, idx, null);
11.1584 + if (i > h.level)
11.1585 + h = new HeadIndex<K,V>(h.node, h, idx, i);
11.1586 +
11.1587 + if (i < preds.size()) {
11.1588 + preds.get(i).right = idx;
11.1589 + preds.set(i, idx);
11.1590 + } else
11.1591 + preds.add(idx);
11.1592 + }
11.1593 + }
11.1594 + }
11.1595 + head = h;
11.1596 + }
11.1597 +
11.1598 + /* ------ Map API methods ------ */
11.1599 +
11.1600 + /**
11.1601 + * Returns <tt>true</tt> if this map contains a mapping for the specified
11.1602 + * key.
11.1603 + *
11.1604 + * @param key key whose presence in this map is to be tested
11.1605 + * @return <tt>true</tt> if this map contains a mapping for the specified key
11.1606 + * @throws ClassCastException if the specified key cannot be compared
11.1607 + * with the keys currently in the map
11.1608 + * @throws NullPointerException if the specified key is null
11.1609 + */
11.1610 + public boolean containsKey(Object key) {
11.1611 + return doGet(key) != null;
11.1612 + }
11.1613 +
11.1614 + /**
11.1615 + * Returns the value to which the specified key is mapped,
11.1616 + * or {@code null} if this map contains no mapping for the key.
11.1617 + *
11.1618 + * <p>More formally, if this map contains a mapping from a key
11.1619 + * {@code k} to a value {@code v} such that {@code key} compares
11.1620 + * equal to {@code k} according to the map's ordering, then this
11.1621 + * method returns {@code v}; otherwise it returns {@code null}.
11.1622 + * (There can be at most one such mapping.)
11.1623 + *
11.1624 + * @throws ClassCastException if the specified key cannot be compared
11.1625 + * with the keys currently in the map
11.1626 + * @throws NullPointerException if the specified key is null
11.1627 + */
11.1628 + public V get(Object key) {
11.1629 + return doGet(key);
11.1630 + }
11.1631 +
11.1632 + /**
11.1633 + * Associates the specified value with the specified key in this map.
11.1634 + * If the map previously contained a mapping for the key, the old
11.1635 + * value is replaced.
11.1636 + *
11.1637 + * @param key key with which the specified value is to be associated
11.1638 + * @param value value to be associated with the specified key
11.1639 + * @return the previous value associated with the specified key, or
11.1640 + * <tt>null</tt> if there was no mapping for the key
11.1641 + * @throws ClassCastException if the specified key cannot be compared
11.1642 + * with the keys currently in the map
11.1643 + * @throws NullPointerException if the specified key or value is null
11.1644 + */
11.1645 + public V put(K key, V value) {
11.1646 + if (value == null)
11.1647 + throw new NullPointerException();
11.1648 + return doPut(key, value, false);
11.1649 + }
11.1650 +
11.1651 + /**
11.1652 + * Removes the mapping for the specified key from this map if present.
11.1653 + *
11.1654 + * @param key key for which mapping should be removed
11.1655 + * @return the previous value associated with the specified key, or
11.1656 + * <tt>null</tt> if there was no mapping for the key
11.1657 + * @throws ClassCastException if the specified key cannot be compared
11.1658 + * with the keys currently in the map
11.1659 + * @throws NullPointerException if the specified key is null
11.1660 + */
11.1661 + public V remove(Object key) {
11.1662 + return doRemove(key, null);
11.1663 + }
11.1664 +
11.1665 + /**
11.1666 + * Returns <tt>true</tt> if this map maps one or more keys to the
11.1667 + * specified value. This operation requires time linear in the
11.1668 + * map size. Additionally, it is possible for the map to change
11.1669 + * during execution of this method, in which case the returned
11.1670 + * result may be inaccurate.
11.1671 + *
11.1672 + * @param value value whose presence in this map is to be tested
11.1673 + * @return <tt>true</tt> if a mapping to <tt>value</tt> exists;
11.1674 + * <tt>false</tt> otherwise
11.1675 + * @throws NullPointerException if the specified value is null
11.1676 + */
11.1677 + public boolean containsValue(Object value) {
11.1678 + if (value == null)
11.1679 + throw new NullPointerException();
11.1680 + for (Node<K,V> n = findFirst(); n != null; n = n.next) {
11.1681 + V v = n.getValidValue();
11.1682 + if (v != null && value.equals(v))
11.1683 + return true;
11.1684 + }
11.1685 + return false;
11.1686 + }
11.1687 +
11.1688 + /**
11.1689 + * Returns the number of key-value mappings in this map. If this map
11.1690 + * contains more than <tt>Integer.MAX_VALUE</tt> elements, it
11.1691 + * returns <tt>Integer.MAX_VALUE</tt>.
11.1692 + *
11.1693 + * <p>Beware that, unlike in most collections, this method is
11.1694 + * <em>NOT</em> a constant-time operation. Because of the
11.1695 + * asynchronous nature of these maps, determining the current
11.1696 + * number of elements requires traversing them all to count them.
11.1697 + * Additionally, it is possible for the size to change during
11.1698 + * execution of this method, in which case the returned result
11.1699 + * will be inaccurate. Thus, this method is typically not very
11.1700 + * useful in concurrent applications.
11.1701 + *
11.1702 + * @return the number of elements in this map
11.1703 + */
11.1704 + public int size() {
11.1705 + long count = 0;
11.1706 + for (Node<K,V> n = findFirst(); n != null; n = n.next) {
11.1707 + if (n.getValidValue() != null)
11.1708 + ++count;
11.1709 + }
11.1710 + return (count >= Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int) count;
11.1711 + }
11.1712 +
11.1713 + /**
11.1714 + * Returns <tt>true</tt> if this map contains no key-value mappings.
11.1715 + * @return <tt>true</tt> if this map contains no key-value mappings
11.1716 + */
11.1717 + public boolean isEmpty() {
11.1718 + return findFirst() == null;
11.1719 + }
11.1720 +
11.1721 + /**
11.1722 + * Removes all of the mappings from this map.
11.1723 + */
11.1724 + public void clear() {
11.1725 + initialize();
11.1726 + }
11.1727 +
11.1728 + /* ---------------- View methods -------------- */
11.1729 +
11.1730 + /*
11.1731 + * Note: Lazy initialization works for views because view classes
11.1732 + * are stateless/immutable so it doesn't matter wrt correctness if
11.1733 + * more than one is created (which will only rarely happen). Even
11.1734 + * so, the following idiom conservatively ensures that the method
11.1735 + * returns the one it created if it does so, not one created by
11.1736 + * another racing thread.
11.1737 + */
11.1738 +
11.1739 + /**
11.1740 + * Returns a {@link NavigableSet} view of the keys contained in this map.
11.1741 + * The set's iterator returns the keys in ascending order.
11.1742 + * The set is backed by the map, so changes to the map are
11.1743 + * reflected in the set, and vice-versa. The set supports element
11.1744 + * removal, which removes the corresponding mapping from the map,
11.1745 + * via the {@code Iterator.remove}, {@code Set.remove},
11.1746 + * {@code removeAll}, {@code retainAll}, and {@code clear}
11.1747 + * operations. It does not support the {@code add} or {@code addAll}
11.1748 + * operations.
11.1749 + *
11.1750 + * <p>The view's {@code iterator} is a "weakly consistent" iterator
11.1751 + * that will never throw {@link ConcurrentModificationException},
11.1752 + * and guarantees to traverse elements as they existed upon
11.1753 + * construction of the iterator, and may (but is not guaranteed to)
11.1754 + * reflect any modifications subsequent to construction.
11.1755 + *
11.1756 + * <p>This method is equivalent to method {@code navigableKeySet}.
11.1757 + *
11.1758 + * @return a navigable set view of the keys in this map
11.1759 + */
11.1760 + public NavigableSet<K> keySet() {
11.1761 + KeySet ks = keySet;
11.1762 + return (ks != null) ? ks : (keySet = new KeySet(this));
11.1763 + }
11.1764 +
11.1765 + public NavigableSet<K> navigableKeySet() {
11.1766 + KeySet ks = keySet;
11.1767 + return (ks != null) ? ks : (keySet = new KeySet(this));
11.1768 + }
11.1769 +
11.1770 + /**
11.1771 + * Returns a {@link Collection} view of the values contained in this map.
11.1772 + * The collection's iterator returns the values in ascending order
11.1773 + * of the corresponding keys.
11.1774 + * The collection is backed by the map, so changes to the map are
11.1775 + * reflected in the collection, and vice-versa. The collection
11.1776 + * supports element removal, which removes the corresponding
11.1777 + * mapping from the map, via the <tt>Iterator.remove</tt>,
11.1778 + * <tt>Collection.remove</tt>, <tt>removeAll</tt>,
11.1779 + * <tt>retainAll</tt> and <tt>clear</tt> operations. It does not
11.1780 + * support the <tt>add</tt> or <tt>addAll</tt> operations.
11.1781 + *
11.1782 + * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator
11.1783 + * that will never throw {@link ConcurrentModificationException},
11.1784 + * and guarantees to traverse elements as they existed upon
11.1785 + * construction of the iterator, and may (but is not guaranteed to)
11.1786 + * reflect any modifications subsequent to construction.
11.1787 + */
11.1788 + public Collection<V> values() {
11.1789 + Values vs = values;
11.1790 + return (vs != null) ? vs : (values = new Values(this));
11.1791 + }
11.1792 +
11.1793 + /**
11.1794 + * Returns a {@link Set} view of the mappings contained in this map.
11.1795 + * The set's iterator returns the entries in ascending key order.
11.1796 + * The set is backed by the map, so changes to the map are
11.1797 + * reflected in the set, and vice-versa. The set supports element
11.1798 + * removal, which removes the corresponding mapping from the map,
11.1799 + * via the <tt>Iterator.remove</tt>, <tt>Set.remove</tt>,
11.1800 + * <tt>removeAll</tt>, <tt>retainAll</tt> and <tt>clear</tt>
11.1801 + * operations. It does not support the <tt>add</tt> or
11.1802 + * <tt>addAll</tt> operations.
11.1803 + *
11.1804 + * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator
11.1805 + * that will never throw {@link ConcurrentModificationException},
11.1806 + * and guarantees to traverse elements as they existed upon
11.1807 + * construction of the iterator, and may (but is not guaranteed to)
11.1808 + * reflect any modifications subsequent to construction.
11.1809 + *
11.1810 + * <p>The <tt>Map.Entry</tt> elements returned by
11.1811 + * <tt>iterator.next()</tt> do <em>not</em> support the
11.1812 + * <tt>setValue</tt> operation.
11.1813 + *
11.1814 + * @return a set view of the mappings contained in this map,
11.1815 + * sorted in ascending key order
11.1816 + */
11.1817 + public Set<Map.Entry<K,V>> entrySet() {
11.1818 + EntrySet es = entrySet;
11.1819 + return (es != null) ? es : (entrySet = new EntrySet(this));
11.1820 + }
11.1821 +
11.1822 + public ConcurrentNavigableMap<K,V> descendingMap() {
11.1823 + ConcurrentNavigableMap<K,V> dm = descendingMap;
11.1824 + return (dm != null) ? dm : (descendingMap = new SubMap<K,V>
11.1825 + (this, null, false, null, false, true));
11.1826 + }
11.1827 +
11.1828 + public NavigableSet<K> descendingKeySet() {
11.1829 + return descendingMap().navigableKeySet();
11.1830 + }
11.1831 +
11.1832 + /* ---------------- AbstractMap Overrides -------------- */
11.1833 +
11.1834 + /**
11.1835 + * Compares the specified object with this map for equality.
11.1836 + * Returns <tt>true</tt> if the given object is also a map and the
11.1837 + * two maps represent the same mappings. More formally, two maps
11.1838 + * <tt>m1</tt> and <tt>m2</tt> represent the same mappings if
11.1839 + * <tt>m1.entrySet().equals(m2.entrySet())</tt>. This
11.1840 + * operation may return misleading results if either map is
11.1841 + * concurrently modified during execution of this method.
11.1842 + *
11.1843 + * @param o object to be compared for equality with this map
11.1844 + * @return <tt>true</tt> if the specified object is equal to this map
11.1845 + */
11.1846 + public boolean equals(Object o) {
11.1847 + if (o == this)
11.1848 + return true;
11.1849 + if (!(o instanceof Map))
11.1850 + return false;
11.1851 + Map<?,?> m = (Map<?,?>) o;
11.1852 + try {
11.1853 + for (Map.Entry<K,V> e : this.entrySet())
11.1854 + if (! e.getValue().equals(m.get(e.getKey())))
11.1855 + return false;
11.1856 + for (Map.Entry<?,?> e : m.entrySet()) {
11.1857 + Object k = e.getKey();
11.1858 + Object v = e.getValue();
11.1859 + if (k == null || v == null || !v.equals(get(k)))
11.1860 + return false;
11.1861 + }
11.1862 + return true;
11.1863 + } catch (ClassCastException unused) {
11.1864 + return false;
11.1865 + } catch (NullPointerException unused) {
11.1866 + return false;
11.1867 + }
11.1868 + }
11.1869 +
11.1870 + /* ------ ConcurrentMap API methods ------ */
11.1871 +
11.1872 + /**
11.1873 + * {@inheritDoc}
11.1874 + *
11.1875 + * @return the previous value associated with the specified key,
11.1876 + * or <tt>null</tt> if there was no mapping for the key
11.1877 + * @throws ClassCastException if the specified key cannot be compared
11.1878 + * with the keys currently in the map
11.1879 + * @throws NullPointerException if the specified key or value is null
11.1880 + */
11.1881 + public V putIfAbsent(K key, V value) {
11.1882 + if (value == null)
11.1883 + throw new NullPointerException();
11.1884 + return doPut(key, value, true);
11.1885 + }
11.1886 +
11.1887 + /**
11.1888 + * {@inheritDoc}
11.1889 + *
11.1890 + * @throws ClassCastException if the specified key cannot be compared
11.1891 + * with the keys currently in the map
11.1892 + * @throws NullPointerException if the specified key is null
11.1893 + */
11.1894 + public boolean remove(Object key, Object value) {
11.1895 + if (key == null)
11.1896 + throw new NullPointerException();
11.1897 + if (value == null)
11.1898 + return false;
11.1899 + return doRemove(key, value) != null;
11.1900 + }
11.1901 +
11.1902 + /**
11.1903 + * {@inheritDoc}
11.1904 + *
11.1905 + * @throws ClassCastException if the specified key cannot be compared
11.1906 + * with the keys currently in the map
11.1907 + * @throws NullPointerException if any of the arguments are null
11.1908 + */
11.1909 + public boolean replace(K key, V oldValue, V newValue) {
11.1910 + if (oldValue == null || newValue == null)
11.1911 + throw new NullPointerException();
11.1912 + Comparable<? super K> k = comparable(key);
11.1913 + for (;;) {
11.1914 + Node<K,V> n = findNode(k);
11.1915 + if (n == null)
11.1916 + return false;
11.1917 + Object v = n.value;
11.1918 + if (v != null) {
11.1919 + if (!oldValue.equals(v))
11.1920 + return false;
11.1921 + if (n.casValue(v, newValue))
11.1922 + return true;
11.1923 + }
11.1924 + }
11.1925 + }
11.1926 +
11.1927 + /**
11.1928 + * {@inheritDoc}
11.1929 + *
11.1930 + * @return the previous value associated with the specified key,
11.1931 + * or <tt>null</tt> if there was no mapping for the key
11.1932 + * @throws ClassCastException if the specified key cannot be compared
11.1933 + * with the keys currently in the map
11.1934 + * @throws NullPointerException if the specified key or value is null
11.1935 + */
11.1936 + public V replace(K key, V value) {
11.1937 + if (value == null)
11.1938 + throw new NullPointerException();
11.1939 + Comparable<? super K> k = comparable(key);
11.1940 + for (;;) {
11.1941 + Node<K,V> n = findNode(k);
11.1942 + if (n == null)
11.1943 + return null;
11.1944 + Object v = n.value;
11.1945 + if (v != null && n.casValue(v, value))
11.1946 + return (V)v;
11.1947 + }
11.1948 + }
11.1949 +
11.1950 + /* ------ SortedMap API methods ------ */
11.1951 +
11.1952 + public Comparator<? super K> comparator() {
11.1953 + return comparator;
11.1954 + }
11.1955 +
11.1956 + /**
11.1957 + * @throws NoSuchElementException {@inheritDoc}
11.1958 + */
11.1959 + public K firstKey() {
11.1960 + Node<K,V> n = findFirst();
11.1961 + if (n == null)
11.1962 + throw new NoSuchElementException();
11.1963 + return n.key;
11.1964 + }
11.1965 +
11.1966 + /**
11.1967 + * @throws NoSuchElementException {@inheritDoc}
11.1968 + */
11.1969 + public K lastKey() {
11.1970 + Node<K,V> n = findLast();
11.1971 + if (n == null)
11.1972 + throw new NoSuchElementException();
11.1973 + return n.key;
11.1974 + }
11.1975 +
11.1976 + /**
11.1977 + * @throws ClassCastException {@inheritDoc}
11.1978 + * @throws NullPointerException if {@code fromKey} or {@code toKey} is null
11.1979 + * @throws IllegalArgumentException {@inheritDoc}
11.1980 + */
11.1981 + public ConcurrentNavigableMap<K,V> subMap(K fromKey,
11.1982 + boolean fromInclusive,
11.1983 + K toKey,
11.1984 + boolean toInclusive) {
11.1985 + if (fromKey == null || toKey == null)
11.1986 + throw new NullPointerException();
11.1987 + return new SubMap<K,V>
11.1988 + (this, fromKey, fromInclusive, toKey, toInclusive, false);
11.1989 + }
11.1990 +
11.1991 + /**
11.1992 + * @throws ClassCastException {@inheritDoc}
11.1993 + * @throws NullPointerException if {@code toKey} is null
11.1994 + * @throws IllegalArgumentException {@inheritDoc}
11.1995 + */
11.1996 + public ConcurrentNavigableMap<K,V> headMap(K toKey,
11.1997 + boolean inclusive) {
11.1998 + if (toKey == null)
11.1999 + throw new NullPointerException();
11.2000 + return new SubMap<K,V>
11.2001 + (this, null, false, toKey, inclusive, false);
11.2002 + }
11.2003 +
11.2004 + /**
11.2005 + * @throws ClassCastException {@inheritDoc}
11.2006 + * @throws NullPointerException if {@code fromKey} is null
11.2007 + * @throws IllegalArgumentException {@inheritDoc}
11.2008 + */
11.2009 + public ConcurrentNavigableMap<K,V> tailMap(K fromKey,
11.2010 + boolean inclusive) {
11.2011 + if (fromKey == null)
11.2012 + throw new NullPointerException();
11.2013 + return new SubMap<K,V>
11.2014 + (this, fromKey, inclusive, null, false, false);
11.2015 + }
11.2016 +
11.2017 + /**
11.2018 + * @throws ClassCastException {@inheritDoc}
11.2019 + * @throws NullPointerException if {@code fromKey} or {@code toKey} is null
11.2020 + * @throws IllegalArgumentException {@inheritDoc}
11.2021 + */
11.2022 + public ConcurrentNavigableMap<K,V> subMap(K fromKey, K toKey) {
11.2023 + return subMap(fromKey, true, toKey, false);
11.2024 + }
11.2025 +
11.2026 + /**
11.2027 + * @throws ClassCastException {@inheritDoc}
11.2028 + * @throws NullPointerException if {@code toKey} is null
11.2029 + * @throws IllegalArgumentException {@inheritDoc}
11.2030 + */
11.2031 + public ConcurrentNavigableMap<K,V> headMap(K toKey) {
11.2032 + return headMap(toKey, false);
11.2033 + }
11.2034 +
11.2035 + /**
11.2036 + * @throws ClassCastException {@inheritDoc}
11.2037 + * @throws NullPointerException if {@code fromKey} is null
11.2038 + * @throws IllegalArgumentException {@inheritDoc}
11.2039 + */
11.2040 + public ConcurrentNavigableMap<K,V> tailMap(K fromKey) {
11.2041 + return tailMap(fromKey, true);
11.2042 + }
11.2043 +
11.2044 + /* ---------------- Relational operations -------------- */
11.2045 +
11.2046 + /**
11.2047 + * Returns a key-value mapping associated with the greatest key
11.2048 + * strictly less than the given key, or <tt>null</tt> if there is
11.2049 + * no such key. The returned entry does <em>not</em> support the
11.2050 + * <tt>Entry.setValue</tt> method.
11.2051 + *
11.2052 + * @throws ClassCastException {@inheritDoc}
11.2053 + * @throws NullPointerException if the specified key is null
11.2054 + */
11.2055 + public Map.Entry<K,V> lowerEntry(K key) {
11.2056 + return getNear(key, LT);
11.2057 + }
11.2058 +
11.2059 + /**
11.2060 + * @throws ClassCastException {@inheritDoc}
11.2061 + * @throws NullPointerException if the specified key is null
11.2062 + */
11.2063 + public K lowerKey(K key) {
11.2064 + Node<K,V> n = findNear(key, LT);
11.2065 + return (n == null) ? null : n.key;
11.2066 + }
11.2067 +
11.2068 + /**
11.2069 + * Returns a key-value mapping associated with the greatest key
11.2070 + * less than or equal to the given key, or <tt>null</tt> if there
11.2071 + * is no such key. The returned entry does <em>not</em> support
11.2072 + * the <tt>Entry.setValue</tt> method.
11.2073 + *
11.2074 + * @param key the key
11.2075 + * @throws ClassCastException {@inheritDoc}
11.2076 + * @throws NullPointerException if the specified key is null
11.2077 + */
11.2078 + public Map.Entry<K,V> floorEntry(K key) {
11.2079 + return getNear(key, LT|EQ);
11.2080 + }
11.2081 +
11.2082 + /**
11.2083 + * @param key the key
11.2084 + * @throws ClassCastException {@inheritDoc}
11.2085 + * @throws NullPointerException if the specified key is null
11.2086 + */
11.2087 + public K floorKey(K key) {
11.2088 + Node<K,V> n = findNear(key, LT|EQ);
11.2089 + return (n == null) ? null : n.key;
11.2090 + }
11.2091 +
11.2092 + /**
11.2093 + * Returns a key-value mapping associated with the least key
11.2094 + * greater than or equal to the given key, or <tt>null</tt> if
11.2095 + * there is no such entry. The returned entry does <em>not</em>
11.2096 + * support the <tt>Entry.setValue</tt> method.
11.2097 + *
11.2098 + * @throws ClassCastException {@inheritDoc}
11.2099 + * @throws NullPointerException if the specified key is null
11.2100 + */
11.2101 + public Map.Entry<K,V> ceilingEntry(K key) {
11.2102 + return getNear(key, GT|EQ);
11.2103 + }
11.2104 +
11.2105 + /**
11.2106 + * @throws ClassCastException {@inheritDoc}
11.2107 + * @throws NullPointerException if the specified key is null
11.2108 + */
11.2109 + public K ceilingKey(K key) {
11.2110 + Node<K,V> n = findNear(key, GT|EQ);
11.2111 + return (n == null) ? null : n.key;
11.2112 + }
11.2113 +
11.2114 + /**
11.2115 + * Returns a key-value mapping associated with the least key
11.2116 + * strictly greater than the given key, or <tt>null</tt> if there
11.2117 + * is no such key. The returned entry does <em>not</em> support
11.2118 + * the <tt>Entry.setValue</tt> method.
11.2119 + *
11.2120 + * @param key the key
11.2121 + * @throws ClassCastException {@inheritDoc}
11.2122 + * @throws NullPointerException if the specified key is null
11.2123 + */
11.2124 + public Map.Entry<K,V> higherEntry(K key) {
11.2125 + return getNear(key, GT);
11.2126 + }
11.2127 +
11.2128 + /**
11.2129 + * @param key the key
11.2130 + * @throws ClassCastException {@inheritDoc}
11.2131 + * @throws NullPointerException if the specified key is null
11.2132 + */
11.2133 + public K higherKey(K key) {
11.2134 + Node<K,V> n = findNear(key, GT);
11.2135 + return (n == null) ? null : n.key;
11.2136 + }
11.2137 +
11.2138 + /**
11.2139 + * Returns a key-value mapping associated with the least
11.2140 + * key in this map, or <tt>null</tt> if the map is empty.
11.2141 + * The returned entry does <em>not</em> support
11.2142 + * the <tt>Entry.setValue</tt> method.
11.2143 + */
11.2144 + public Map.Entry<K,V> firstEntry() {
11.2145 + for (;;) {
11.2146 + Node<K,V> n = findFirst();
11.2147 + if (n == null)
11.2148 + return null;
11.2149 + AbstractMap.SimpleImmutableEntry<K,V> e = n.createSnapshot();
11.2150 + if (e != null)
11.2151 + return e;
11.2152 + }
11.2153 + }
11.2154 +
11.2155 + /**
11.2156 + * Returns a key-value mapping associated with the greatest
11.2157 + * key in this map, or <tt>null</tt> if the map is empty.
11.2158 + * The returned entry does <em>not</em> support
11.2159 + * the <tt>Entry.setValue</tt> method.
11.2160 + */
11.2161 + public Map.Entry<K,V> lastEntry() {
11.2162 + for (;;) {
11.2163 + Node<K,V> n = findLast();
11.2164 + if (n == null)
11.2165 + return null;
11.2166 + AbstractMap.SimpleImmutableEntry<K,V> e = n.createSnapshot();
11.2167 + if (e != null)
11.2168 + return e;
11.2169 + }
11.2170 + }
11.2171 +
11.2172 + /**
11.2173 + * Removes and returns a key-value mapping associated with
11.2174 + * the least key in this map, or <tt>null</tt> if the map is empty.
11.2175 + * The returned entry does <em>not</em> support
11.2176 + * the <tt>Entry.setValue</tt> method.
11.2177 + */
11.2178 + public Map.Entry<K,V> pollFirstEntry() {
11.2179 + return doRemoveFirstEntry();
11.2180 + }
11.2181 +
11.2182 + /**
11.2183 + * Removes and returns a key-value mapping associated with
11.2184 + * the greatest key in this map, or <tt>null</tt> if the map is empty.
11.2185 + * The returned entry does <em>not</em> support
11.2186 + * the <tt>Entry.setValue</tt> method.
11.2187 + */
11.2188 + public Map.Entry<K,V> pollLastEntry() {
11.2189 + return doRemoveLastEntry();
11.2190 + }
11.2191 +
11.2192 +
11.2193 + /* ---------------- Iterators -------------- */
11.2194 +
11.2195 + /**
11.2196 + * Base of iterator classes:
11.2197 + */
11.2198 + abstract class Iter<T> implements Iterator<T> {
11.2199 + /** the last node returned by next() */
11.2200 + Node<K,V> lastReturned;
11.2201 + /** the next node to return from next(); */
11.2202 + Node<K,V> next;
11.2203 + /** Cache of next value field to maintain weak consistency */
11.2204 + V nextValue;
11.2205 +
11.2206 + /** Initializes ascending iterator for entire range. */
11.2207 + Iter() {
11.2208 + for (;;) {
11.2209 + next = findFirst();
11.2210 + if (next == null)
11.2211 + break;
11.2212 + Object x = next.value;
11.2213 + if (x != null && x != next) {
11.2214 + nextValue = (V) x;
11.2215 + break;
11.2216 + }
11.2217 + }
11.2218 + }
11.2219 +
11.2220 + public final boolean hasNext() {
11.2221 + return next != null;
11.2222 + }
11.2223 +
11.2224 + /** Advances next to higher entry. */
11.2225 + final void advance() {
11.2226 + if (next == null)
11.2227 + throw new NoSuchElementException();
11.2228 + lastReturned = next;
11.2229 + for (;;) {
11.2230 + next = next.next;
11.2231 + if (next == null)
11.2232 + break;
11.2233 + Object x = next.value;
11.2234 + if (x != null && x != next) {
11.2235 + nextValue = (V) x;
11.2236 + break;
11.2237 + }
11.2238 + }
11.2239 + }
11.2240 +
11.2241 + public void remove() {
11.2242 + Node<K,V> l = lastReturned;
11.2243 + if (l == null)
11.2244 + throw new IllegalStateException();
11.2245 + // It would not be worth all of the overhead to directly
11.2246 + // unlink from here. Using remove is fast enough.
11.2247 + ConcurrentSkipListMap.this.remove(l.key);
11.2248 + lastReturned = null;
11.2249 + }
11.2250 +
11.2251 + }
11.2252 +
11.2253 + final class ValueIterator extends Iter<V> {
11.2254 + public V next() {
11.2255 + V v = nextValue;
11.2256 + advance();
11.2257 + return v;
11.2258 + }
11.2259 + }
11.2260 +
11.2261 + final class KeyIterator extends Iter<K> {
11.2262 + public K next() {
11.2263 + Node<K,V> n = next;
11.2264 + advance();
11.2265 + return n.key;
11.2266 + }
11.2267 + }
11.2268 +
11.2269 + final class EntryIterator extends Iter<Map.Entry<K,V>> {
11.2270 + public Map.Entry<K,V> next() {
11.2271 + Node<K,V> n = next;
11.2272 + V v = nextValue;
11.2273 + advance();
11.2274 + return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, v);
11.2275 + }
11.2276 + }
11.2277 +
11.2278 + // Factory methods for iterators needed by ConcurrentSkipListSet etc
11.2279 +
11.2280 + Iterator<K> keyIterator() {
11.2281 + return new KeyIterator();
11.2282 + }
11.2283 +
11.2284 + Iterator<V> valueIterator() {
11.2285 + return new ValueIterator();
11.2286 + }
11.2287 +
11.2288 + Iterator<Map.Entry<K,V>> entryIterator() {
11.2289 + return new EntryIterator();
11.2290 + }
11.2291 +
11.2292 + /* ---------------- View Classes -------------- */
11.2293 +
11.2294 + /*
11.2295 + * View classes are static, delegating to a ConcurrentNavigableMap
11.2296 + * to allow use by SubMaps, which outweighs the ugliness of
11.2297 + * needing type-tests for Iterator methods.
11.2298 + */
11.2299 +
11.2300 + static final <E> List<E> toList(Collection<E> c) {
11.2301 + // Using size() here would be a pessimization.
11.2302 + List<E> list = new ArrayList<E>();
11.2303 + for (E e : c)
11.2304 + list.add(e);
11.2305 + return list;
11.2306 + }
11.2307 +
11.2308 + static final class KeySet<E>
11.2309 + extends AbstractSet<E> implements NavigableSet<E> {
11.2310 + private final ConcurrentNavigableMap<E,Object> m;
11.2311 + KeySet(ConcurrentNavigableMap<E,Object> map) { m = map; }
11.2312 + public int size() { return m.size(); }
11.2313 + public boolean isEmpty() { return m.isEmpty(); }
11.2314 + public boolean contains(Object o) { return m.containsKey(o); }
11.2315 + public boolean remove(Object o) { return m.remove(o) != null; }
11.2316 + public void clear() { m.clear(); }
11.2317 + public E lower(E e) { return m.lowerKey(e); }
11.2318 + public E floor(E e) { return m.floorKey(e); }
11.2319 + public E ceiling(E e) { return m.ceilingKey(e); }
11.2320 + public E higher(E e) { return m.higherKey(e); }
11.2321 + public Comparator<? super E> comparator() { return m.comparator(); }
11.2322 + public E first() { return m.firstKey(); }
11.2323 + public E last() { return m.lastKey(); }
11.2324 + public E pollFirst() {
11.2325 + Map.Entry<E,Object> e = m.pollFirstEntry();
11.2326 + return (e == null) ? null : e.getKey();
11.2327 + }
11.2328 + public E pollLast() {
11.2329 + Map.Entry<E,Object> e = m.pollLastEntry();
11.2330 + return (e == null) ? null : e.getKey();
11.2331 + }
11.2332 + public Iterator<E> iterator() {
11.2333 + if (m instanceof ConcurrentSkipListMap)
11.2334 + return ((ConcurrentSkipListMap<E,Object>)m).keyIterator();
11.2335 + else
11.2336 + return ((ConcurrentSkipListMap.SubMap<E,Object>)m).keyIterator();
11.2337 + }
11.2338 + public boolean equals(Object o) {
11.2339 + if (o == this)
11.2340 + return true;
11.2341 + if (!(o instanceof Set))
11.2342 + return false;
11.2343 + Collection<?> c = (Collection<?>) o;
11.2344 + try {
11.2345 + return containsAll(c) && c.containsAll(this);
11.2346 + } catch (ClassCastException unused) {
11.2347 + return false;
11.2348 + } catch (NullPointerException unused) {
11.2349 + return false;
11.2350 + }
11.2351 + }
11.2352 + public Object[] toArray() { return toList(this).toArray(); }
11.2353 + public <T> T[] toArray(T[] a) { return toList(this).toArray(a); }
11.2354 + public Iterator<E> descendingIterator() {
11.2355 + return descendingSet().iterator();
11.2356 + }
11.2357 + public NavigableSet<E> subSet(E fromElement,
11.2358 + boolean fromInclusive,
11.2359 + E toElement,
11.2360 + boolean toInclusive) {
11.2361 + return new KeySet<E>(m.subMap(fromElement, fromInclusive,
11.2362 + toElement, toInclusive));
11.2363 + }
11.2364 + public NavigableSet<E> headSet(E toElement, boolean inclusive) {
11.2365 + return new KeySet<E>(m.headMap(toElement, inclusive));
11.2366 + }
11.2367 + public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
11.2368 + return new KeySet<E>(m.tailMap(fromElement, inclusive));
11.2369 + }
11.2370 + public NavigableSet<E> subSet(E fromElement, E toElement) {
11.2371 + return subSet(fromElement, true, toElement, false);
11.2372 + }
11.2373 + public NavigableSet<E> headSet(E toElement) {
11.2374 + return headSet(toElement, false);
11.2375 + }
11.2376 + public NavigableSet<E> tailSet(E fromElement) {
11.2377 + return tailSet(fromElement, true);
11.2378 + }
11.2379 + public NavigableSet<E> descendingSet() {
11.2380 + return new KeySet(m.descendingMap());
11.2381 + }
11.2382 + }
11.2383 +
11.2384 + static final class Values<E> extends AbstractCollection<E> {
11.2385 + private final ConcurrentNavigableMap<Object, E> m;
11.2386 + Values(ConcurrentNavigableMap<Object, E> map) {
11.2387 + m = map;
11.2388 + }
11.2389 + public Iterator<E> iterator() {
11.2390 + if (m instanceof ConcurrentSkipListMap)
11.2391 + return ((ConcurrentSkipListMap<Object,E>)m).valueIterator();
11.2392 + else
11.2393 + return ((SubMap<Object,E>)m).valueIterator();
11.2394 + }
11.2395 + public boolean isEmpty() {
11.2396 + return m.isEmpty();
11.2397 + }
11.2398 + public int size() {
11.2399 + return m.size();
11.2400 + }
11.2401 + public boolean contains(Object o) {
11.2402 + return m.containsValue(o);
11.2403 + }
11.2404 + public void clear() {
11.2405 + m.clear();
11.2406 + }
11.2407 + public Object[] toArray() { return toList(this).toArray(); }
11.2408 + public <T> T[] toArray(T[] a) { return toList(this).toArray(a); }
11.2409 + }
11.2410 +
11.2411 + static final class EntrySet<K1,V1> extends AbstractSet<Map.Entry<K1,V1>> {
11.2412 + private final ConcurrentNavigableMap<K1, V1> m;
11.2413 + EntrySet(ConcurrentNavigableMap<K1, V1> map) {
11.2414 + m = map;
11.2415 + }
11.2416 +
11.2417 + public Iterator<Map.Entry<K1,V1>> iterator() {
11.2418 + if (m instanceof ConcurrentSkipListMap)
11.2419 + return ((ConcurrentSkipListMap<K1,V1>)m).entryIterator();
11.2420 + else
11.2421 + return ((SubMap<K1,V1>)m).entryIterator();
11.2422 + }
11.2423 +
11.2424 + public boolean contains(Object o) {
11.2425 + if (!(o instanceof Map.Entry))
11.2426 + return false;
11.2427 + Map.Entry<K1,V1> e = (Map.Entry<K1,V1>)o;
11.2428 + V1 v = m.get(e.getKey());
11.2429 + return v != null && v.equals(e.getValue());
11.2430 + }
11.2431 + public boolean remove(Object o) {
11.2432 + if (!(o instanceof Map.Entry))
11.2433 + return false;
11.2434 + Map.Entry<K1,V1> e = (Map.Entry<K1,V1>)o;
11.2435 + return m.remove(e.getKey(),
11.2436 + e.getValue());
11.2437 + }
11.2438 + public boolean isEmpty() {
11.2439 + return m.isEmpty();
11.2440 + }
11.2441 + public int size() {
11.2442 + return m.size();
11.2443 + }
11.2444 + public void clear() {
11.2445 + m.clear();
11.2446 + }
11.2447 + public boolean equals(Object o) {
11.2448 + if (o == this)
11.2449 + return true;
11.2450 + if (!(o instanceof Set))
11.2451 + return false;
11.2452 + Collection<?> c = (Collection<?>) o;
11.2453 + try {
11.2454 + return containsAll(c) && c.containsAll(this);
11.2455 + } catch (ClassCastException unused) {
11.2456 + return false;
11.2457 + } catch (NullPointerException unused) {
11.2458 + return false;
11.2459 + }
11.2460 + }
11.2461 + public Object[] toArray() { return toList(this).toArray(); }
11.2462 + public <T> T[] toArray(T[] a) { return toList(this).toArray(a); }
11.2463 + }
11.2464 +
11.2465 + /**
11.2466 + * Submaps returned by {@link ConcurrentSkipListMap} submap operations
11.2467 + * represent a subrange of mappings of their underlying
11.2468 + * maps. Instances of this class support all methods of their
11.2469 + * underlying maps, differing in that mappings outside their range are
11.2470 + * ignored, and attempts to add mappings outside their ranges result
11.2471 + * in {@link IllegalArgumentException}. Instances of this class are
11.2472 + * constructed only using the <tt>subMap</tt>, <tt>headMap</tt>, and
11.2473 + * <tt>tailMap</tt> methods of their underlying maps.
11.2474 + *
11.2475 + * @serial include
11.2476 + */
11.2477 + static final class SubMap<K,V> extends AbstractMap<K,V>
11.2478 + implements ConcurrentNavigableMap<K,V>, Cloneable,
11.2479 + java.io.Serializable {
11.2480 + private static final long serialVersionUID = -7647078645895051609L;
11.2481 +
11.2482 + /** Underlying map */
11.2483 + private final ConcurrentSkipListMap<K,V> m;
11.2484 + /** lower bound key, or null if from start */
11.2485 + private final K lo;
11.2486 + /** upper bound key, or null if to end */
11.2487 + private final K hi;
11.2488 + /** inclusion flag for lo */
11.2489 + private final boolean loInclusive;
11.2490 + /** inclusion flag for hi */
11.2491 + private final boolean hiInclusive;
11.2492 + /** direction */
11.2493 + private final boolean isDescending;
11.2494 +
11.2495 + // Lazily initialized view holders
11.2496 + private transient KeySet<K> keySetView;
11.2497 + private transient Set<Map.Entry<K,V>> entrySetView;
11.2498 + private transient Collection<V> valuesView;
11.2499 +
11.2500 + /**
11.2501 + * Creates a new submap, initializing all fields
11.2502 + */
11.2503 + SubMap(ConcurrentSkipListMap<K,V> map,
11.2504 + K fromKey, boolean fromInclusive,
11.2505 + K toKey, boolean toInclusive,
11.2506 + boolean isDescending) {
11.2507 + if (fromKey != null && toKey != null &&
11.2508 + map.compare(fromKey, toKey) > 0)
11.2509 + throw new IllegalArgumentException("inconsistent range");
11.2510 + this.m = map;
11.2511 + this.lo = fromKey;
11.2512 + this.hi = toKey;
11.2513 + this.loInclusive = fromInclusive;
11.2514 + this.hiInclusive = toInclusive;
11.2515 + this.isDescending = isDescending;
11.2516 + }
11.2517 +
11.2518 + /* ---------------- Utilities -------------- */
11.2519 +
11.2520 + private boolean tooLow(K key) {
11.2521 + if (lo != null) {
11.2522 + int c = m.compare(key, lo);
11.2523 + if (c < 0 || (c == 0 && !loInclusive))
11.2524 + return true;
11.2525 + }
11.2526 + return false;
11.2527 + }
11.2528 +
11.2529 + private boolean tooHigh(K key) {
11.2530 + if (hi != null) {
11.2531 + int c = m.compare(key, hi);
11.2532 + if (c > 0 || (c == 0 && !hiInclusive))
11.2533 + return true;
11.2534 + }
11.2535 + return false;
11.2536 + }
11.2537 +
11.2538 + private boolean inBounds(K key) {
11.2539 + return !tooLow(key) && !tooHigh(key);
11.2540 + }
11.2541 +
11.2542 + private void checkKeyBounds(K key) throws IllegalArgumentException {
11.2543 + if (key == null)
11.2544 + throw new NullPointerException();
11.2545 + if (!inBounds(key))
11.2546 + throw new IllegalArgumentException("key out of range");
11.2547 + }
11.2548 +
11.2549 + /**
11.2550 + * Returns true if node key is less than upper bound of range
11.2551 + */
11.2552 + private boolean isBeforeEnd(ConcurrentSkipListMap.Node<K,V> n) {
11.2553 + if (n == null)
11.2554 + return false;
11.2555 + if (hi == null)
11.2556 + return true;
11.2557 + K k = n.key;
11.2558 + if (k == null) // pass by markers and headers
11.2559 + return true;
11.2560 + int c = m.compare(k, hi);
11.2561 + if (c > 0 || (c == 0 && !hiInclusive))
11.2562 + return false;
11.2563 + return true;
11.2564 + }
11.2565 +
11.2566 + /**
11.2567 + * Returns lowest node. This node might not be in range, so
11.2568 + * most usages need to check bounds
11.2569 + */
11.2570 + private ConcurrentSkipListMap.Node<K,V> loNode() {
11.2571 + if (lo == null)
11.2572 + return m.findFirst();
11.2573 + else if (loInclusive)
11.2574 + return m.findNear(lo, m.GT|m.EQ);
11.2575 + else
11.2576 + return m.findNear(lo, m.GT);
11.2577 + }
11.2578 +
11.2579 + /**
11.2580 + * Returns highest node. This node might not be in range, so
11.2581 + * most usages need to check bounds
11.2582 + */
11.2583 + private ConcurrentSkipListMap.Node<K,V> hiNode() {
11.2584 + if (hi == null)
11.2585 + return m.findLast();
11.2586 + else if (hiInclusive)
11.2587 + return m.findNear(hi, m.LT|m.EQ);
11.2588 + else
11.2589 + return m.findNear(hi, m.LT);
11.2590 + }
11.2591 +
11.2592 + /**
11.2593 + * Returns lowest absolute key (ignoring directonality)
11.2594 + */
11.2595 + private K lowestKey() {
11.2596 + ConcurrentSkipListMap.Node<K,V> n = loNode();
11.2597 + if (isBeforeEnd(n))
11.2598 + return n.key;
11.2599 + else
11.2600 + throw new NoSuchElementException();
11.2601 + }
11.2602 +
11.2603 + /**
11.2604 + * Returns highest absolute key (ignoring directonality)
11.2605 + */
11.2606 + private K highestKey() {
11.2607 + ConcurrentSkipListMap.Node<K,V> n = hiNode();
11.2608 + if (n != null) {
11.2609 + K last = n.key;
11.2610 + if (inBounds(last))
11.2611 + return last;
11.2612 + }
11.2613 + throw new NoSuchElementException();
11.2614 + }
11.2615 +
11.2616 + private Map.Entry<K,V> lowestEntry() {
11.2617 + for (;;) {
11.2618 + ConcurrentSkipListMap.Node<K,V> n = loNode();
11.2619 + if (!isBeforeEnd(n))
11.2620 + return null;
11.2621 + Map.Entry<K,V> e = n.createSnapshot();
11.2622 + if (e != null)
11.2623 + return e;
11.2624 + }
11.2625 + }
11.2626 +
11.2627 + private Map.Entry<K,V> highestEntry() {
11.2628 + for (;;) {
11.2629 + ConcurrentSkipListMap.Node<K,V> n = hiNode();
11.2630 + if (n == null || !inBounds(n.key))
11.2631 + return null;
11.2632 + Map.Entry<K,V> e = n.createSnapshot();
11.2633 + if (e != null)
11.2634 + return e;
11.2635 + }
11.2636 + }
11.2637 +
11.2638 + private Map.Entry<K,V> removeLowest() {
11.2639 + for (;;) {
11.2640 + Node<K,V> n = loNode();
11.2641 + if (n == null)
11.2642 + return null;
11.2643 + K k = n.key;
11.2644 + if (!inBounds(k))
11.2645 + return null;
11.2646 + V v = m.doRemove(k, null);
11.2647 + if (v != null)
11.2648 + return new AbstractMap.SimpleImmutableEntry<K,V>(k, v);
11.2649 + }
11.2650 + }
11.2651 +
11.2652 + private Map.Entry<K,V> removeHighest() {
11.2653 + for (;;) {
11.2654 + Node<K,V> n = hiNode();
11.2655 + if (n == null)
11.2656 + return null;
11.2657 + K k = n.key;
11.2658 + if (!inBounds(k))
11.2659 + return null;
11.2660 + V v = m.doRemove(k, null);
11.2661 + if (v != null)
11.2662 + return new AbstractMap.SimpleImmutableEntry<K,V>(k, v);
11.2663 + }
11.2664 + }
11.2665 +
11.2666 + /**
11.2667 + * Submap version of ConcurrentSkipListMap.getNearEntry
11.2668 + */
11.2669 + private Map.Entry<K,V> getNearEntry(K key, int rel) {
11.2670 + if (isDescending) { // adjust relation for direction
11.2671 + if ((rel & m.LT) == 0)
11.2672 + rel |= m.LT;
11.2673 + else
11.2674 + rel &= ~m.LT;
11.2675 + }
11.2676 + if (tooLow(key))
11.2677 + return ((rel & m.LT) != 0) ? null : lowestEntry();
11.2678 + if (tooHigh(key))
11.2679 + return ((rel & m.LT) != 0) ? highestEntry() : null;
11.2680 + for (;;) {
11.2681 + Node<K,V> n = m.findNear(key, rel);
11.2682 + if (n == null || !inBounds(n.key))
11.2683 + return null;
11.2684 + K k = n.key;
11.2685 + V v = n.getValidValue();
11.2686 + if (v != null)
11.2687 + return new AbstractMap.SimpleImmutableEntry<K,V>(k, v);
11.2688 + }
11.2689 + }
11.2690 +
11.2691 + // Almost the same as getNearEntry, except for keys
11.2692 + private K getNearKey(K key, int rel) {
11.2693 + if (isDescending) { // adjust relation for direction
11.2694 + if ((rel & m.LT) == 0)
11.2695 + rel |= m.LT;
11.2696 + else
11.2697 + rel &= ~m.LT;
11.2698 + }
11.2699 + if (tooLow(key)) {
11.2700 + if ((rel & m.LT) == 0) {
11.2701 + ConcurrentSkipListMap.Node<K,V> n = loNode();
11.2702 + if (isBeforeEnd(n))
11.2703 + return n.key;
11.2704 + }
11.2705 + return null;
11.2706 + }
11.2707 + if (tooHigh(key)) {
11.2708 + if ((rel & m.LT) != 0) {
11.2709 + ConcurrentSkipListMap.Node<K,V> n = hiNode();
11.2710 + if (n != null) {
11.2711 + K last = n.key;
11.2712 + if (inBounds(last))
11.2713 + return last;
11.2714 + }
11.2715 + }
11.2716 + return null;
11.2717 + }
11.2718 + for (;;) {
11.2719 + Node<K,V> n = m.findNear(key, rel);
11.2720 + if (n == null || !inBounds(n.key))
11.2721 + return null;
11.2722 + K k = n.key;
11.2723 + V v = n.getValidValue();
11.2724 + if (v != null)
11.2725 + return k;
11.2726 + }
11.2727 + }
11.2728 +
11.2729 + /* ---------------- Map API methods -------------- */
11.2730 +
11.2731 + public boolean containsKey(Object key) {
11.2732 + if (key == null) throw new NullPointerException();
11.2733 + K k = (K)key;
11.2734 + return inBounds(k) && m.containsKey(k);
11.2735 + }
11.2736 +
11.2737 + public V get(Object key) {
11.2738 + if (key == null) throw new NullPointerException();
11.2739 + K k = (K)key;
11.2740 + return ((!inBounds(k)) ? null : m.get(k));
11.2741 + }
11.2742 +
11.2743 + public V put(K key, V value) {
11.2744 + checkKeyBounds(key);
11.2745 + return m.put(key, value);
11.2746 + }
11.2747 +
11.2748 + public V remove(Object key) {
11.2749 + K k = (K)key;
11.2750 + return (!inBounds(k)) ? null : m.remove(k);
11.2751 + }
11.2752 +
11.2753 + public int size() {
11.2754 + long count = 0;
11.2755 + for (ConcurrentSkipListMap.Node<K,V> n = loNode();
11.2756 + isBeforeEnd(n);
11.2757 + n = n.next) {
11.2758 + if (n.getValidValue() != null)
11.2759 + ++count;
11.2760 + }
11.2761 + return count >= Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)count;
11.2762 + }
11.2763 +
11.2764 + public boolean isEmpty() {
11.2765 + return !isBeforeEnd(loNode());
11.2766 + }
11.2767 +
11.2768 + public boolean containsValue(Object value) {
11.2769 + if (value == null)
11.2770 + throw new NullPointerException();
11.2771 + for (ConcurrentSkipListMap.Node<K,V> n = loNode();
11.2772 + isBeforeEnd(n);
11.2773 + n = n.next) {
11.2774 + V v = n.getValidValue();
11.2775 + if (v != null && value.equals(v))
11.2776 + return true;
11.2777 + }
11.2778 + return false;
11.2779 + }
11.2780 +
11.2781 + public void clear() {
11.2782 + for (ConcurrentSkipListMap.Node<K,V> n = loNode();
11.2783 + isBeforeEnd(n);
11.2784 + n = n.next) {
11.2785 + if (n.getValidValue() != null)
11.2786 + m.remove(n.key);
11.2787 + }
11.2788 + }
11.2789 +
11.2790 + /* ---------------- ConcurrentMap API methods -------------- */
11.2791 +
11.2792 + public V putIfAbsent(K key, V value) {
11.2793 + checkKeyBounds(key);
11.2794 + return m.putIfAbsent(key, value);
11.2795 + }
11.2796 +
11.2797 + public boolean remove(Object key, Object value) {
11.2798 + K k = (K)key;
11.2799 + return inBounds(k) && m.remove(k, value);
11.2800 + }
11.2801 +
11.2802 + public boolean replace(K key, V oldValue, V newValue) {
11.2803 + checkKeyBounds(key);
11.2804 + return m.replace(key, oldValue, newValue);
11.2805 + }
11.2806 +
11.2807 + public V replace(K key, V value) {
11.2808 + checkKeyBounds(key);
11.2809 + return m.replace(key, value);
11.2810 + }
11.2811 +
11.2812 + /* ---------------- SortedMap API methods -------------- */
11.2813 +
11.2814 + public Comparator<? super K> comparator() {
11.2815 + Comparator<? super K> cmp = m.comparator();
11.2816 + if (isDescending)
11.2817 + return Collections.reverseOrder(cmp);
11.2818 + else
11.2819 + return cmp;
11.2820 + }
11.2821 +
11.2822 + /**
11.2823 + * Utility to create submaps, where given bounds override
11.2824 + * unbounded(null) ones and/or are checked against bounded ones.
11.2825 + */
11.2826 + private SubMap<K,V> newSubMap(K fromKey,
11.2827 + boolean fromInclusive,
11.2828 + K toKey,
11.2829 + boolean toInclusive) {
11.2830 + if (isDescending) { // flip senses
11.2831 + K tk = fromKey;
11.2832 + fromKey = toKey;
11.2833 + toKey = tk;
11.2834 + boolean ti = fromInclusive;
11.2835 + fromInclusive = toInclusive;
11.2836 + toInclusive = ti;
11.2837 + }
11.2838 + if (lo != null) {
11.2839 + if (fromKey == null) {
11.2840 + fromKey = lo;
11.2841 + fromInclusive = loInclusive;
11.2842 + }
11.2843 + else {
11.2844 + int c = m.compare(fromKey, lo);
11.2845 + if (c < 0 || (c == 0 && !loInclusive && fromInclusive))
11.2846 + throw new IllegalArgumentException("key out of range");
11.2847 + }
11.2848 + }
11.2849 + if (hi != null) {
11.2850 + if (toKey == null) {
11.2851 + toKey = hi;
11.2852 + toInclusive = hiInclusive;
11.2853 + }
11.2854 + else {
11.2855 + int c = m.compare(toKey, hi);
11.2856 + if (c > 0 || (c == 0 && !hiInclusive && toInclusive))
11.2857 + throw new IllegalArgumentException("key out of range");
11.2858 + }
11.2859 + }
11.2860 + return new SubMap<K,V>(m, fromKey, fromInclusive,
11.2861 + toKey, toInclusive, isDescending);
11.2862 + }
11.2863 +
11.2864 + public SubMap<K,V> subMap(K fromKey,
11.2865 + boolean fromInclusive,
11.2866 + K toKey,
11.2867 + boolean toInclusive) {
11.2868 + if (fromKey == null || toKey == null)
11.2869 + throw new NullPointerException();
11.2870 + return newSubMap(fromKey, fromInclusive, toKey, toInclusive);
11.2871 + }
11.2872 +
11.2873 + public SubMap<K,V> headMap(K toKey,
11.2874 + boolean inclusive) {
11.2875 + if (toKey == null)
11.2876 + throw new NullPointerException();
11.2877 + return newSubMap(null, false, toKey, inclusive);
11.2878 + }
11.2879 +
11.2880 + public SubMap<K,V> tailMap(K fromKey,
11.2881 + boolean inclusive) {
11.2882 + if (fromKey == null)
11.2883 + throw new NullPointerException();
11.2884 + return newSubMap(fromKey, inclusive, null, false);
11.2885 + }
11.2886 +
11.2887 + public SubMap<K,V> subMap(K fromKey, K toKey) {
11.2888 + return subMap(fromKey, true, toKey, false);
11.2889 + }
11.2890 +
11.2891 + public SubMap<K,V> headMap(K toKey) {
11.2892 + return headMap(toKey, false);
11.2893 + }
11.2894 +
11.2895 + public SubMap<K,V> tailMap(K fromKey) {
11.2896 + return tailMap(fromKey, true);
11.2897 + }
11.2898 +
11.2899 + public SubMap<K,V> descendingMap() {
11.2900 + return new SubMap<K,V>(m, lo, loInclusive,
11.2901 + hi, hiInclusive, !isDescending);
11.2902 + }
11.2903 +
11.2904 + /* ---------------- Relational methods -------------- */
11.2905 +
11.2906 + public Map.Entry<K,V> ceilingEntry(K key) {
11.2907 + return getNearEntry(key, (m.GT|m.EQ));
11.2908 + }
11.2909 +
11.2910 + public K ceilingKey(K key) {
11.2911 + return getNearKey(key, (m.GT|m.EQ));
11.2912 + }
11.2913 +
11.2914 + public Map.Entry<K,V> lowerEntry(K key) {
11.2915 + return getNearEntry(key, (m.LT));
11.2916 + }
11.2917 +
11.2918 + public K lowerKey(K key) {
11.2919 + return getNearKey(key, (m.LT));
11.2920 + }
11.2921 +
11.2922 + public Map.Entry<K,V> floorEntry(K key) {
11.2923 + return getNearEntry(key, (m.LT|m.EQ));
11.2924 + }
11.2925 +
11.2926 + public K floorKey(K key) {
11.2927 + return getNearKey(key, (m.LT|m.EQ));
11.2928 + }
11.2929 +
11.2930 + public Map.Entry<K,V> higherEntry(K key) {
11.2931 + return getNearEntry(key, (m.GT));
11.2932 + }
11.2933 +
11.2934 + public K higherKey(K key) {
11.2935 + return getNearKey(key, (m.GT));
11.2936 + }
11.2937 +
11.2938 + public K firstKey() {
11.2939 + return isDescending ? highestKey() : lowestKey();
11.2940 + }
11.2941 +
11.2942 + public K lastKey() {
11.2943 + return isDescending ? lowestKey() : highestKey();
11.2944 + }
11.2945 +
11.2946 + public Map.Entry<K,V> firstEntry() {
11.2947 + return isDescending ? highestEntry() : lowestEntry();
11.2948 + }
11.2949 +
11.2950 + public Map.Entry<K,V> lastEntry() {
11.2951 + return isDescending ? lowestEntry() : highestEntry();
11.2952 + }
11.2953 +
11.2954 + public Map.Entry<K,V> pollFirstEntry() {
11.2955 + return isDescending ? removeHighest() : removeLowest();
11.2956 + }
11.2957 +
11.2958 + public Map.Entry<K,V> pollLastEntry() {
11.2959 + return isDescending ? removeLowest() : removeHighest();
11.2960 + }
11.2961 +
11.2962 + /* ---------------- Submap Views -------------- */
11.2963 +
11.2964 + public NavigableSet<K> keySet() {
11.2965 + KeySet<K> ks = keySetView;
11.2966 + return (ks != null) ? ks : (keySetView = new KeySet(this));
11.2967 + }
11.2968 +
11.2969 + public NavigableSet<K> navigableKeySet() {
11.2970 + KeySet<K> ks = keySetView;
11.2971 + return (ks != null) ? ks : (keySetView = new KeySet(this));
11.2972 + }
11.2973 +
11.2974 + public Collection<V> values() {
11.2975 + Collection<V> vs = valuesView;
11.2976 + return (vs != null) ? vs : (valuesView = new Values(this));
11.2977 + }
11.2978 +
11.2979 + public Set<Map.Entry<K,V>> entrySet() {
11.2980 + Set<Map.Entry<K,V>> es = entrySetView;
11.2981 + return (es != null) ? es : (entrySetView = new EntrySet(this));
11.2982 + }
11.2983 +
11.2984 + public NavigableSet<K> descendingKeySet() {
11.2985 + return descendingMap().navigableKeySet();
11.2986 + }
11.2987 +
11.2988 + Iterator<K> keyIterator() {
11.2989 + return new SubMapKeyIterator();
11.2990 + }
11.2991 +
11.2992 + Iterator<V> valueIterator() {
11.2993 + return new SubMapValueIterator();
11.2994 + }
11.2995 +
11.2996 + Iterator<Map.Entry<K,V>> entryIterator() {
11.2997 + return new SubMapEntryIterator();
11.2998 + }
11.2999 +
11.3000 + /**
11.3001 + * Variant of main Iter class to traverse through submaps.
11.3002 + */
11.3003 + abstract class SubMapIter<T> implements Iterator<T> {
11.3004 + /** the last node returned by next() */
11.3005 + Node<K,V> lastReturned;
11.3006 + /** the next node to return from next(); */
11.3007 + Node<K,V> next;
11.3008 + /** Cache of next value field to maintain weak consistency */
11.3009 + V nextValue;
11.3010 +
11.3011 + SubMapIter() {
11.3012 + for (;;) {
11.3013 + next = isDescending ? hiNode() : loNode();
11.3014 + if (next == null)
11.3015 + break;
11.3016 + Object x = next.value;
11.3017 + if (x != null && x != next) {
11.3018 + if (! inBounds(next.key))
11.3019 + next = null;
11.3020 + else
11.3021 + nextValue = (V) x;
11.3022 + break;
11.3023 + }
11.3024 + }
11.3025 + }
11.3026 +
11.3027 + public final boolean hasNext() {
11.3028 + return next != null;
11.3029 + }
11.3030 +
11.3031 + final void advance() {
11.3032 + if (next == null)
11.3033 + throw new NoSuchElementException();
11.3034 + lastReturned = next;
11.3035 + if (isDescending)
11.3036 + descend();
11.3037 + else
11.3038 + ascend();
11.3039 + }
11.3040 +
11.3041 + private void ascend() {
11.3042 + for (;;) {
11.3043 + next = next.next;
11.3044 + if (next == null)
11.3045 + break;
11.3046 + Object x = next.value;
11.3047 + if (x != null && x != next) {
11.3048 + if (tooHigh(next.key))
11.3049 + next = null;
11.3050 + else
11.3051 + nextValue = (V) x;
11.3052 + break;
11.3053 + }
11.3054 + }
11.3055 + }
11.3056 +
11.3057 + private void descend() {
11.3058 + for (;;) {
11.3059 + next = m.findNear(lastReturned.key, LT);
11.3060 + if (next == null)
11.3061 + break;
11.3062 + Object x = next.value;
11.3063 + if (x != null && x != next) {
11.3064 + if (tooLow(next.key))
11.3065 + next = null;
11.3066 + else
11.3067 + nextValue = (V) x;
11.3068 + break;
11.3069 + }
11.3070 + }
11.3071 + }
11.3072 +
11.3073 + public void remove() {
11.3074 + Node<K,V> l = lastReturned;
11.3075 + if (l == null)
11.3076 + throw new IllegalStateException();
11.3077 + m.remove(l.key);
11.3078 + lastReturned = null;
11.3079 + }
11.3080 +
11.3081 + }
11.3082 +
11.3083 + final class SubMapValueIterator extends SubMapIter<V> {
11.3084 + public V next() {
11.3085 + V v = nextValue;
11.3086 + advance();
11.3087 + return v;
11.3088 + }
11.3089 + }
11.3090 +
11.3091 + final class SubMapKeyIterator extends SubMapIter<K> {
11.3092 + public K next() {
11.3093 + Node<K,V> n = next;
11.3094 + advance();
11.3095 + return n.key;
11.3096 + }
11.3097 + }
11.3098 +
11.3099 + final class SubMapEntryIterator extends SubMapIter<Map.Entry<K,V>> {
11.3100 + public Map.Entry<K,V> next() {
11.3101 + Node<K,V> n = next;
11.3102 + V v = nextValue;
11.3103 + advance();
11.3104 + return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, v);
11.3105 + }
11.3106 + }
11.3107 + }
11.3108 +
11.3109 + // Unsafe mechanics
11.3110 + private static final sun.misc.Unsafe UNSAFE;
11.3111 + private static final long headOffset;
11.3112 + static {
11.3113 + try {
11.3114 + UNSAFE = sun.misc.Unsafe.getUnsafe();
11.3115 + Class k = ConcurrentSkipListMap.class;
11.3116 + headOffset = UNSAFE.objectFieldOffset
11.3117 + (k.getDeclaredField("head"));
11.3118 + } catch (Exception e) {
11.3119 + throw new Error(e);
11.3120 + }
11.3121 + }
11.3122 +}
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ConcurrentSkipListSet.java Sat Mar 19 10:48:29 2016 +0100
12.3 @@ -0,0 +1,491 @@
12.4 +/*
12.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
12.6 + *
12.7 + * This code is free software; you can redistribute it and/or modify it
12.8 + * under the terms of the GNU General Public License version 2 only, as
12.9 + * published by the Free Software Foundation. Oracle designates this
12.10 + * particular file as subject to the "Classpath" exception as provided
12.11 + * by Oracle in the LICENSE file that accompanied this code.
12.12 + *
12.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
12.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12.16 + * version 2 for more details (a copy is included in the LICENSE file that
12.17 + * accompanied this code).
12.18 + *
12.19 + * You should have received a copy of the GNU General Public License version
12.20 + * 2 along with this work; if not, write to the Free Software Foundation,
12.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
12.22 + *
12.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
12.24 + * or visit www.oracle.com if you need additional information or have any
12.25 + * questions.
12.26 + */
12.27 +
12.28 +/*
12.29 + * This file is available under and governed by the GNU General Public
12.30 + * License version 2 only, as published by the Free Software Foundation.
12.31 + * However, the following notice accompanied the original version of this
12.32 + * file:
12.33 + *
12.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
12.35 + * Expert Group and released to the public domain, as explained at
12.36 + * http://creativecommons.org/publicdomain/zero/1.0/
12.37 + */
12.38 +
12.39 +package java.util.concurrent;
12.40 +import java.util.*;
12.41 +import sun.misc.Unsafe;
12.42 +
12.43 +/**
12.44 + * A scalable concurrent {@link NavigableSet} implementation based on
12.45 + * a {@link ConcurrentSkipListMap}. The elements of the set are kept
12.46 + * sorted according to their {@linkplain Comparable natural ordering},
12.47 + * or by a {@link Comparator} provided at set creation time, depending
12.48 + * on which constructor is used.
12.49 + *
12.50 + * <p>This implementation provides expected average <i>log(n)</i> time
12.51 + * cost for the <tt>contains</tt>, <tt>add</tt>, and <tt>remove</tt>
12.52 + * operations and their variants. Insertion, removal, and access
12.53 + * operations safely execute concurrently by multiple threads.
12.54 + * Iterators are <i>weakly consistent</i>, returning elements
12.55 + * reflecting the state of the set at some point at or since the
12.56 + * creation of the iterator. They do <em>not</em> throw {@link
12.57 + * ConcurrentModificationException}, and may proceed concurrently with
12.58 + * other operations. Ascending ordered views and their iterators are
12.59 + * faster than descending ones.
12.60 + *
12.61 + * <p>Beware that, unlike in most collections, the <tt>size</tt>
12.62 + * method is <em>not</em> a constant-time operation. Because of the
12.63 + * asynchronous nature of these sets, determining the current number
12.64 + * of elements requires a traversal of the elements, and so may report
12.65 + * inaccurate results if this collection is modified during traversal.
12.66 + * Additionally, the bulk operations <tt>addAll</tt>,
12.67 + * <tt>removeAll</tt>, <tt>retainAll</tt>, <tt>containsAll</tt>,
12.68 + * <tt>equals</tt>, and <tt>toArray</tt> are <em>not</em> guaranteed
12.69 + * to be performed atomically. For example, an iterator operating
12.70 + * concurrently with an <tt>addAll</tt> operation might view only some
12.71 + * of the added elements.
12.72 + *
12.73 + * <p>This class and its iterators implement all of the
12.74 + * <em>optional</em> methods of the {@link Set} and {@link Iterator}
12.75 + * interfaces. Like most other concurrent collection implementations,
12.76 + * this class does not permit the use of <tt>null</tt> elements,
12.77 + * because <tt>null</tt> arguments and return values cannot be reliably
12.78 + * distinguished from the absence of elements.
12.79 + *
12.80 + * <p>This class is a member of the
12.81 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
12.82 + * Java Collections Framework</a>.
12.83 + *
12.84 + * @author Doug Lea
12.85 + * @param <E> the type of elements maintained by this set
12.86 + * @since 1.6
12.87 + */
12.88 +public class ConcurrentSkipListSet<E>
12.89 + extends AbstractSet<E>
12.90 + implements NavigableSet<E>, Cloneable, java.io.Serializable {
12.91 +
12.92 + private static final long serialVersionUID = -2479143111061671589L;
12.93 +
12.94 + /**
12.95 + * The underlying map. Uses Boolean.TRUE as value for each
12.96 + * element. This field is declared final for the sake of thread
12.97 + * safety, which entails some ugliness in clone()
12.98 + */
12.99 + private final ConcurrentNavigableMap<E,Object> m;
12.100 +
12.101 + /**
12.102 + * Constructs a new, empty set that orders its elements according to
12.103 + * their {@linkplain Comparable natural ordering}.
12.104 + */
12.105 + public ConcurrentSkipListSet() {
12.106 + m = new ConcurrentSkipListMap<E,Object>();
12.107 + }
12.108 +
12.109 + /**
12.110 + * Constructs a new, empty set that orders its elements according to
12.111 + * the specified comparator.
12.112 + *
12.113 + * @param comparator the comparator that will be used to order this set.
12.114 + * If <tt>null</tt>, the {@linkplain Comparable natural
12.115 + * ordering} of the elements will be used.
12.116 + */
12.117 + public ConcurrentSkipListSet(Comparator<? super E> comparator) {
12.118 + m = new ConcurrentSkipListMap<E,Object>(comparator);
12.119 + }
12.120 +
12.121 + /**
12.122 + * Constructs a new set containing the elements in the specified
12.123 + * collection, that orders its elements according to their
12.124 + * {@linkplain Comparable natural ordering}.
12.125 + *
12.126 + * @param c The elements that will comprise the new set
12.127 + * @throws ClassCastException if the elements in <tt>c</tt> are
12.128 + * not {@link Comparable}, or are not mutually comparable
12.129 + * @throws NullPointerException if the specified collection or any
12.130 + * of its elements are null
12.131 + */
12.132 + public ConcurrentSkipListSet(Collection<? extends E> c) {
12.133 + m = new ConcurrentSkipListMap<E,Object>();
12.134 + addAll(c);
12.135 + }
12.136 +
12.137 + /**
12.138 + * Constructs a new set containing the same elements and using the
12.139 + * same ordering as the specified sorted set.
12.140 + *
12.141 + * @param s sorted set whose elements will comprise the new set
12.142 + * @throws NullPointerException if the specified sorted set or any
12.143 + * of its elements are null
12.144 + */
12.145 + public ConcurrentSkipListSet(SortedSet<E> s) {
12.146 + m = new ConcurrentSkipListMap<E,Object>(s.comparator());
12.147 + addAll(s);
12.148 + }
12.149 +
12.150 + /**
12.151 + * For use by submaps
12.152 + */
12.153 + ConcurrentSkipListSet(ConcurrentNavigableMap<E,Object> m) {
12.154 + this.m = m;
12.155 + }
12.156 +
12.157 + /**
12.158 + * Returns a shallow copy of this <tt>ConcurrentSkipListSet</tt>
12.159 + * instance. (The elements themselves are not cloned.)
12.160 + *
12.161 + * @return a shallow copy of this set
12.162 + */
12.163 + public ConcurrentSkipListSet<E> clone() {
12.164 + ConcurrentSkipListSet<E> clone = null;
12.165 + try {
12.166 + clone = (ConcurrentSkipListSet<E>) super.clone();
12.167 + clone.setMap(new ConcurrentSkipListMap(m));
12.168 + } catch (CloneNotSupportedException e) {
12.169 + throw new InternalError();
12.170 + }
12.171 +
12.172 + return clone;
12.173 + }
12.174 +
12.175 + /* ---------------- Set operations -------------- */
12.176 +
12.177 + /**
12.178 + * Returns the number of elements in this set. If this set
12.179 + * contains more than <tt>Integer.MAX_VALUE</tt> elements, it
12.180 + * returns <tt>Integer.MAX_VALUE</tt>.
12.181 + *
12.182 + * <p>Beware that, unlike in most collections, this method is
12.183 + * <em>NOT</em> a constant-time operation. Because of the
12.184 + * asynchronous nature of these sets, determining the current
12.185 + * number of elements requires traversing them all to count them.
12.186 + * Additionally, it is possible for the size to change during
12.187 + * execution of this method, in which case the returned result
12.188 + * will be inaccurate. Thus, this method is typically not very
12.189 + * useful in concurrent applications.
12.190 + *
12.191 + * @return the number of elements in this set
12.192 + */
12.193 + public int size() {
12.194 + return m.size();
12.195 + }
12.196 +
12.197 + /**
12.198 + * Returns <tt>true</tt> if this set contains no elements.
12.199 + * @return <tt>true</tt> if this set contains no elements
12.200 + */
12.201 + public boolean isEmpty() {
12.202 + return m.isEmpty();
12.203 + }
12.204 +
12.205 + /**
12.206 + * Returns <tt>true</tt> if this set contains the specified element.
12.207 + * More formally, returns <tt>true</tt> if and only if this set
12.208 + * contains an element <tt>e</tt> such that <tt>o.equals(e)</tt>.
12.209 + *
12.210 + * @param o object to be checked for containment in this set
12.211 + * @return <tt>true</tt> if this set contains the specified element
12.212 + * @throws ClassCastException if the specified element cannot be
12.213 + * compared with the elements currently in this set
12.214 + * @throws NullPointerException if the specified element is null
12.215 + */
12.216 + public boolean contains(Object o) {
12.217 + return m.containsKey(o);
12.218 + }
12.219 +
12.220 + /**
12.221 + * Adds the specified element to this set if it is not already present.
12.222 + * More formally, adds the specified element <tt>e</tt> to this set if
12.223 + * the set contains no element <tt>e2</tt> such that <tt>e.equals(e2)</tt>.
12.224 + * If this set already contains the element, the call leaves the set
12.225 + * unchanged and returns <tt>false</tt>.
12.226 + *
12.227 + * @param e element to be added to this set
12.228 + * @return <tt>true</tt> if this set did not already contain the
12.229 + * specified element
12.230 + * @throws ClassCastException if <tt>e</tt> cannot be compared
12.231 + * with the elements currently in this set
12.232 + * @throws NullPointerException if the specified element is null
12.233 + */
12.234 + public boolean add(E e) {
12.235 + return m.putIfAbsent(e, Boolean.TRUE) == null;
12.236 + }
12.237 +
12.238 + /**
12.239 + * Removes the specified element from this set if it is present.
12.240 + * More formally, removes an element <tt>e</tt> such that
12.241 + * <tt>o.equals(e)</tt>, if this set contains such an element.
12.242 + * Returns <tt>true</tt> if this set contained the element (or
12.243 + * equivalently, if this set changed as a result of the call).
12.244 + * (This set will not contain the element once the call returns.)
12.245 + *
12.246 + * @param o object to be removed from this set, if present
12.247 + * @return <tt>true</tt> if this set contained the specified element
12.248 + * @throws ClassCastException if <tt>o</tt> cannot be compared
12.249 + * with the elements currently in this set
12.250 + * @throws NullPointerException if the specified element is null
12.251 + */
12.252 + public boolean remove(Object o) {
12.253 + return m.remove(o, Boolean.TRUE);
12.254 + }
12.255 +
12.256 + /**
12.257 + * Removes all of the elements from this set.
12.258 + */
12.259 + public void clear() {
12.260 + m.clear();
12.261 + }
12.262 +
12.263 + /**
12.264 + * Returns an iterator over the elements in this set in ascending order.
12.265 + *
12.266 + * @return an iterator over the elements in this set in ascending order
12.267 + */
12.268 + public Iterator<E> iterator() {
12.269 + return m.navigableKeySet().iterator();
12.270 + }
12.271 +
12.272 + /**
12.273 + * Returns an iterator over the elements in this set in descending order.
12.274 + *
12.275 + * @return an iterator over the elements in this set in descending order
12.276 + */
12.277 + public Iterator<E> descendingIterator() {
12.278 + return m.descendingKeySet().iterator();
12.279 + }
12.280 +
12.281 +
12.282 + /* ---------------- AbstractSet Overrides -------------- */
12.283 +
12.284 + /**
12.285 + * Compares the specified object with this set for equality. Returns
12.286 + * <tt>true</tt> if the specified object is also a set, the two sets
12.287 + * have the same size, and every member of the specified set is
12.288 + * contained in this set (or equivalently, every member of this set is
12.289 + * contained in the specified set). This definition ensures that the
12.290 + * equals method works properly across different implementations of the
12.291 + * set interface.
12.292 + *
12.293 + * @param o the object to be compared for equality with this set
12.294 + * @return <tt>true</tt> if the specified object is equal to this set
12.295 + */
12.296 + public boolean equals(Object o) {
12.297 + // Override AbstractSet version to avoid calling size()
12.298 + if (o == this)
12.299 + return true;
12.300 + if (!(o instanceof Set))
12.301 + return false;
12.302 + Collection<?> c = (Collection<?>) o;
12.303 + try {
12.304 + return containsAll(c) && c.containsAll(this);
12.305 + } catch (ClassCastException unused) {
12.306 + return false;
12.307 + } catch (NullPointerException unused) {
12.308 + return false;
12.309 + }
12.310 + }
12.311 +
12.312 + /**
12.313 + * Removes from this set all of its elements that are contained in
12.314 + * the specified collection. If the specified collection is also
12.315 + * a set, this operation effectively modifies this set so that its
12.316 + * value is the <i>asymmetric set difference</i> of the two sets.
12.317 + *
12.318 + * @param c collection containing elements to be removed from this set
12.319 + * @return <tt>true</tt> if this set changed as a result of the call
12.320 + * @throws ClassCastException if the types of one or more elements in this
12.321 + * set are incompatible with the specified collection
12.322 + * @throws NullPointerException if the specified collection or any
12.323 + * of its elements are null
12.324 + */
12.325 + public boolean removeAll(Collection<?> c) {
12.326 + // Override AbstractSet version to avoid unnecessary call to size()
12.327 + boolean modified = false;
12.328 + for (Iterator<?> i = c.iterator(); i.hasNext(); )
12.329 + if (remove(i.next()))
12.330 + modified = true;
12.331 + return modified;
12.332 + }
12.333 +
12.334 + /* ---------------- Relational operations -------------- */
12.335 +
12.336 + /**
12.337 + * @throws ClassCastException {@inheritDoc}
12.338 + * @throws NullPointerException if the specified element is null
12.339 + */
12.340 + public E lower(E e) {
12.341 + return m.lowerKey(e);
12.342 + }
12.343 +
12.344 + /**
12.345 + * @throws ClassCastException {@inheritDoc}
12.346 + * @throws NullPointerException if the specified element is null
12.347 + */
12.348 + public E floor(E e) {
12.349 + return m.floorKey(e);
12.350 + }
12.351 +
12.352 + /**
12.353 + * @throws ClassCastException {@inheritDoc}
12.354 + * @throws NullPointerException if the specified element is null
12.355 + */
12.356 + public E ceiling(E e) {
12.357 + return m.ceilingKey(e);
12.358 + }
12.359 +
12.360 + /**
12.361 + * @throws ClassCastException {@inheritDoc}
12.362 + * @throws NullPointerException if the specified element is null
12.363 + */
12.364 + public E higher(E e) {
12.365 + return m.higherKey(e);
12.366 + }
12.367 +
12.368 + public E pollFirst() {
12.369 + Map.Entry<E,Object> e = m.pollFirstEntry();
12.370 + return (e == null) ? null : e.getKey();
12.371 + }
12.372 +
12.373 + public E pollLast() {
12.374 + Map.Entry<E,Object> e = m.pollLastEntry();
12.375 + return (e == null) ? null : e.getKey();
12.376 + }
12.377 +
12.378 +
12.379 + /* ---------------- SortedSet operations -------------- */
12.380 +
12.381 +
12.382 + public Comparator<? super E> comparator() {
12.383 + return m.comparator();
12.384 + }
12.385 +
12.386 + /**
12.387 + * @throws NoSuchElementException {@inheritDoc}
12.388 + */
12.389 + public E first() {
12.390 + return m.firstKey();
12.391 + }
12.392 +
12.393 + /**
12.394 + * @throws NoSuchElementException {@inheritDoc}
12.395 + */
12.396 + public E last() {
12.397 + return m.lastKey();
12.398 + }
12.399 +
12.400 + /**
12.401 + * @throws ClassCastException {@inheritDoc}
12.402 + * @throws NullPointerException if {@code fromElement} or
12.403 + * {@code toElement} is null
12.404 + * @throws IllegalArgumentException {@inheritDoc}
12.405 + */
12.406 + public NavigableSet<E> subSet(E fromElement,
12.407 + boolean fromInclusive,
12.408 + E toElement,
12.409 + boolean toInclusive) {
12.410 + return new ConcurrentSkipListSet<E>
12.411 + (m.subMap(fromElement, fromInclusive,
12.412 + toElement, toInclusive));
12.413 + }
12.414 +
12.415 + /**
12.416 + * @throws ClassCastException {@inheritDoc}
12.417 + * @throws NullPointerException if {@code toElement} is null
12.418 + * @throws IllegalArgumentException {@inheritDoc}
12.419 + */
12.420 + public NavigableSet<E> headSet(E toElement, boolean inclusive) {
12.421 + return new ConcurrentSkipListSet<E>(m.headMap(toElement, inclusive));
12.422 + }
12.423 +
12.424 + /**
12.425 + * @throws ClassCastException {@inheritDoc}
12.426 + * @throws NullPointerException if {@code fromElement} is null
12.427 + * @throws IllegalArgumentException {@inheritDoc}
12.428 + */
12.429 + public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
12.430 + return new ConcurrentSkipListSet<E>(m.tailMap(fromElement, inclusive));
12.431 + }
12.432 +
12.433 + /**
12.434 + * @throws ClassCastException {@inheritDoc}
12.435 + * @throws NullPointerException if {@code fromElement} or
12.436 + * {@code toElement} is null
12.437 + * @throws IllegalArgumentException {@inheritDoc}
12.438 + */
12.439 + public NavigableSet<E> subSet(E fromElement, E toElement) {
12.440 + return subSet(fromElement, true, toElement, false);
12.441 + }
12.442 +
12.443 + /**
12.444 + * @throws ClassCastException {@inheritDoc}
12.445 + * @throws NullPointerException if {@code toElement} is null
12.446 + * @throws IllegalArgumentException {@inheritDoc}
12.447 + */
12.448 + public NavigableSet<E> headSet(E toElement) {
12.449 + return headSet(toElement, false);
12.450 + }
12.451 +
12.452 + /**
12.453 + * @throws ClassCastException {@inheritDoc}
12.454 + * @throws NullPointerException if {@code fromElement} is null
12.455 + * @throws IllegalArgumentException {@inheritDoc}
12.456 + */
12.457 + public NavigableSet<E> tailSet(E fromElement) {
12.458 + return tailSet(fromElement, true);
12.459 + }
12.460 +
12.461 + /**
12.462 + * Returns a reverse order view of the elements contained in this set.
12.463 + * The descending set is backed by this set, so changes to the set are
12.464 + * reflected in the descending set, and vice-versa.
12.465 + *
12.466 + * <p>The returned set has an ordering equivalent to
12.467 + * <tt>{@link Collections#reverseOrder(Comparator) Collections.reverseOrder}(comparator())</tt>.
12.468 + * The expression {@code s.descendingSet().descendingSet()} returns a
12.469 + * view of {@code s} essentially equivalent to {@code s}.
12.470 + *
12.471 + * @return a reverse order view of this set
12.472 + */
12.473 + public NavigableSet<E> descendingSet() {
12.474 + return new ConcurrentSkipListSet(m.descendingMap());
12.475 + }
12.476 +
12.477 + // Support for resetting map in clone
12.478 + private void setMap(ConcurrentNavigableMap<E,Object> map) {
12.479 + UNSAFE.putObjectVolatile(this, mapOffset, map);
12.480 + }
12.481 +
12.482 + private static final sun.misc.Unsafe UNSAFE;
12.483 + private static final long mapOffset;
12.484 + static {
12.485 + try {
12.486 + UNSAFE = sun.misc.Unsafe.getUnsafe();
12.487 + Class k = ConcurrentSkipListSet.class;
12.488 + mapOffset = UNSAFE.objectFieldOffset
12.489 + (k.getDeclaredField("m"));
12.490 + } catch (Exception e) {
12.491 + throw new Error(e);
12.492 + }
12.493 + }
12.494 +}
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/CopyOnWriteArrayList.java Sat Mar 19 10:48:29 2016 +0100
13.3 @@ -0,0 +1,1340 @@
13.4 +/*
13.5 + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
13.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
13.7 + *
13.8 + * This code is free software; you can redistribute it and/or modify it
13.9 + * under the terms of the GNU General Public License version 2 only, as
13.10 + * published by the Free Software Foundation. Oracle designates this
13.11 + * particular file as subject to the "Classpath" exception as provided
13.12 + * by Oracle in the LICENSE file that accompanied this code.
13.13 + *
13.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
13.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13.17 + * version 2 for more details (a copy is included in the LICENSE file that
13.18 + * accompanied this code).
13.19 + *
13.20 + * You should have received a copy of the GNU General Public License version
13.21 + * 2 along with this work; if not, write to the Free Software Foundation,
13.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
13.23 + *
13.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
13.25 + * or visit www.oracle.com if you need additional information or have any
13.26 + * questions.
13.27 + */
13.28 +
13.29 +/*
13.30 + * Written by Doug Lea with assistance from members of JCP JSR-166
13.31 + * Expert Group. Adapted and released, under explicit permission,
13.32 + * from JDK ArrayList.java which carries the following copyright:
13.33 + *
13.34 + * Copyright 1997 by Sun Microsystems, Inc.,
13.35 + * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
13.36 + * All rights reserved.
13.37 + */
13.38 +
13.39 +package java.util.concurrent;
13.40 +import java.util.*;
13.41 +import java.util.concurrent.locks.*;
13.42 +import sun.misc.Unsafe;
13.43 +
13.44 +/**
13.45 + * A thread-safe variant of {@link java.util.ArrayList} in which all mutative
13.46 + * operations (<tt>add</tt>, <tt>set</tt>, and so on) are implemented by
13.47 + * making a fresh copy of the underlying array.
13.48 + *
13.49 + * <p> This is ordinarily too costly, but may be <em>more</em> efficient
13.50 + * than alternatives when traversal operations vastly outnumber
13.51 + * mutations, and is useful when you cannot or don't want to
13.52 + * synchronize traversals, yet need to preclude interference among
13.53 + * concurrent threads. The "snapshot" style iterator method uses a
13.54 + * reference to the state of the array at the point that the iterator
13.55 + * was created. This array never changes during the lifetime of the
13.56 + * iterator, so interference is impossible and the iterator is
13.57 + * guaranteed not to throw <tt>ConcurrentModificationException</tt>.
13.58 + * The iterator will not reflect additions, removals, or changes to
13.59 + * the list since the iterator was created. Element-changing
13.60 + * operations on iterators themselves (<tt>remove</tt>, <tt>set</tt>, and
13.61 + * <tt>add</tt>) are not supported. These methods throw
13.62 + * <tt>UnsupportedOperationException</tt>.
13.63 + *
13.64 + * <p>All elements are permitted, including <tt>null</tt>.
13.65 + *
13.66 + * <p>Memory consistency effects: As with other concurrent
13.67 + * collections, actions in a thread prior to placing an object into a
13.68 + * {@code CopyOnWriteArrayList}
13.69 + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
13.70 + * actions subsequent to the access or removal of that element from
13.71 + * the {@code CopyOnWriteArrayList} in another thread.
13.72 + *
13.73 + * <p>This class is a member of the
13.74 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
13.75 + * Java Collections Framework</a>.
13.76 + *
13.77 + * @since 1.5
13.78 + * @author Doug Lea
13.79 + * @param <E> the type of elements held in this collection
13.80 + */
13.81 +public class CopyOnWriteArrayList<E>
13.82 + implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
13.83 + private static final long serialVersionUID = 8673264195747942595L;
13.84 +
13.85 + /** The lock protecting all mutators */
13.86 + transient final ReentrantLock lock = new ReentrantLock();
13.87 +
13.88 + /** The array, accessed only via getArray/setArray. */
13.89 + private volatile transient Object[] array;
13.90 +
13.91 + /**
13.92 + * Gets the array. Non-private so as to also be accessible
13.93 + * from CopyOnWriteArraySet class.
13.94 + */
13.95 + final Object[] getArray() {
13.96 + return array;
13.97 + }
13.98 +
13.99 + /**
13.100 + * Sets the array.
13.101 + */
13.102 + final void setArray(Object[] a) {
13.103 + array = a;
13.104 + }
13.105 +
13.106 + /**
13.107 + * Creates an empty list.
13.108 + */
13.109 + public CopyOnWriteArrayList() {
13.110 + setArray(new Object[0]);
13.111 + }
13.112 +
13.113 + /**
13.114 + * Creates a list containing the elements of the specified
13.115 + * collection, in the order they are returned by the collection's
13.116 + * iterator.
13.117 + *
13.118 + * @param c the collection of initially held elements
13.119 + * @throws NullPointerException if the specified collection is null
13.120 + */
13.121 + public CopyOnWriteArrayList(Collection<? extends E> c) {
13.122 + Object[] elements = c.toArray();
13.123 + // c.toArray might (incorrectly) not return Object[] (see 6260652)
13.124 + if (elements.getClass() != Object[].class)
13.125 + elements = Arrays.copyOf(elements, elements.length, Object[].class);
13.126 + setArray(elements);
13.127 + }
13.128 +
13.129 + /**
13.130 + * Creates a list holding a copy of the given array.
13.131 + *
13.132 + * @param toCopyIn the array (a copy of this array is used as the
13.133 + * internal array)
13.134 + * @throws NullPointerException if the specified array is null
13.135 + */
13.136 + public CopyOnWriteArrayList(E[] toCopyIn) {
13.137 + setArray(Arrays.copyOf(toCopyIn, toCopyIn.length, Object[].class));
13.138 + }
13.139 +
13.140 + /**
13.141 + * Returns the number of elements in this list.
13.142 + *
13.143 + * @return the number of elements in this list
13.144 + */
13.145 + public int size() {
13.146 + return getArray().length;
13.147 + }
13.148 +
13.149 + /**
13.150 + * Returns <tt>true</tt> if this list contains no elements.
13.151 + *
13.152 + * @return <tt>true</tt> if this list contains no elements
13.153 + */
13.154 + public boolean isEmpty() {
13.155 + return size() == 0;
13.156 + }
13.157 +
13.158 + /**
13.159 + * Test for equality, coping with nulls.
13.160 + */
13.161 + private static boolean eq(Object o1, Object o2) {
13.162 + return (o1 == null ? o2 == null : o1.equals(o2));
13.163 + }
13.164 +
13.165 + /**
13.166 + * static version of indexOf, to allow repeated calls without
13.167 + * needing to re-acquire array each time.
13.168 + * @param o element to search for
13.169 + * @param elements the array
13.170 + * @param index first index to search
13.171 + * @param fence one past last index to search
13.172 + * @return index of element, or -1 if absent
13.173 + */
13.174 + private static int indexOf(Object o, Object[] elements,
13.175 + int index, int fence) {
13.176 + if (o == null) {
13.177 + for (int i = index; i < fence; i++)
13.178 + if (elements[i] == null)
13.179 + return i;
13.180 + } else {
13.181 + for (int i = index; i < fence; i++)
13.182 + if (o.equals(elements[i]))
13.183 + return i;
13.184 + }
13.185 + return -1;
13.186 + }
13.187 +
13.188 + /**
13.189 + * static version of lastIndexOf.
13.190 + * @param o element to search for
13.191 + * @param elements the array
13.192 + * @param index first index to search
13.193 + * @return index of element, or -1 if absent
13.194 + */
13.195 + private static int lastIndexOf(Object o, Object[] elements, int index) {
13.196 + if (o == null) {
13.197 + for (int i = index; i >= 0; i--)
13.198 + if (elements[i] == null)
13.199 + return i;
13.200 + } else {
13.201 + for (int i = index; i >= 0; i--)
13.202 + if (o.equals(elements[i]))
13.203 + return i;
13.204 + }
13.205 + return -1;
13.206 + }
13.207 +
13.208 + /**
13.209 + * Returns <tt>true</tt> if this list contains the specified element.
13.210 + * More formally, returns <tt>true</tt> if and only if this list contains
13.211 + * at least one element <tt>e</tt> such that
13.212 + * <tt>(o==null ? e==null : o.equals(e))</tt>.
13.213 + *
13.214 + * @param o element whose presence in this list is to be tested
13.215 + * @return <tt>true</tt> if this list contains the specified element
13.216 + */
13.217 + public boolean contains(Object o) {
13.218 + Object[] elements = getArray();
13.219 + return indexOf(o, elements, 0, elements.length) >= 0;
13.220 + }
13.221 +
13.222 + /**
13.223 + * {@inheritDoc}
13.224 + */
13.225 + public int indexOf(Object o) {
13.226 + Object[] elements = getArray();
13.227 + return indexOf(o, elements, 0, elements.length);
13.228 + }
13.229 +
13.230 + /**
13.231 + * Returns the index of the first occurrence of the specified element in
13.232 + * this list, searching forwards from <tt>index</tt>, or returns -1 if
13.233 + * the element is not found.
13.234 + * More formally, returns the lowest index <tt>i</tt> such that
13.235 + * <tt>(i >= index && (e==null ? get(i)==null : e.equals(get(i))))</tt>,
13.236 + * or -1 if there is no such index.
13.237 + *
13.238 + * @param e element to search for
13.239 + * @param index index to start searching from
13.240 + * @return the index of the first occurrence of the element in
13.241 + * this list at position <tt>index</tt> or later in the list;
13.242 + * <tt>-1</tt> if the element is not found.
13.243 + * @throws IndexOutOfBoundsException if the specified index is negative
13.244 + */
13.245 + public int indexOf(E e, int index) {
13.246 + Object[] elements = getArray();
13.247 + return indexOf(e, elements, index, elements.length);
13.248 + }
13.249 +
13.250 + /**
13.251 + * {@inheritDoc}
13.252 + */
13.253 + public int lastIndexOf(Object o) {
13.254 + Object[] elements = getArray();
13.255 + return lastIndexOf(o, elements, elements.length - 1);
13.256 + }
13.257 +
13.258 + /**
13.259 + * Returns the index of the last occurrence of the specified element in
13.260 + * this list, searching backwards from <tt>index</tt>, or returns -1 if
13.261 + * the element is not found.
13.262 + * More formally, returns the highest index <tt>i</tt> such that
13.263 + * <tt>(i <= index && (e==null ? get(i)==null : e.equals(get(i))))</tt>,
13.264 + * or -1 if there is no such index.
13.265 + *
13.266 + * @param e element to search for
13.267 + * @param index index to start searching backwards from
13.268 + * @return the index of the last occurrence of the element at position
13.269 + * less than or equal to <tt>index</tt> in this list;
13.270 + * -1 if the element is not found.
13.271 + * @throws IndexOutOfBoundsException if the specified index is greater
13.272 + * than or equal to the current size of this list
13.273 + */
13.274 + public int lastIndexOf(E e, int index) {
13.275 + Object[] elements = getArray();
13.276 + return lastIndexOf(e, elements, index);
13.277 + }
13.278 +
13.279 + /**
13.280 + * Returns a shallow copy of this list. (The elements themselves
13.281 + * are not copied.)
13.282 + *
13.283 + * @return a clone of this list
13.284 + */
13.285 + public Object clone() {
13.286 + try {
13.287 + CopyOnWriteArrayList c = (CopyOnWriteArrayList)(super.clone());
13.288 + c.resetLock();
13.289 + return c;
13.290 + } catch (CloneNotSupportedException e) {
13.291 + // this shouldn't happen, since we are Cloneable
13.292 + throw new InternalError();
13.293 + }
13.294 + }
13.295 +
13.296 + /**
13.297 + * Returns an array containing all of the elements in this list
13.298 + * in proper sequence (from first to last element).
13.299 + *
13.300 + * <p>The returned array will be "safe" in that no references to it are
13.301 + * maintained by this list. (In other words, this method must allocate
13.302 + * a new array). The caller is thus free to modify the returned array.
13.303 + *
13.304 + * <p>This method acts as bridge between array-based and collection-based
13.305 + * APIs.
13.306 + *
13.307 + * @return an array containing all the elements in this list
13.308 + */
13.309 + public Object[] toArray() {
13.310 + Object[] elements = getArray();
13.311 + return Arrays.copyOf(elements, elements.length);
13.312 + }
13.313 +
13.314 + /**
13.315 + * Returns an array containing all of the elements in this list in
13.316 + * proper sequence (from first to last element); the runtime type of
13.317 + * the returned array is that of the specified array. If the list fits
13.318 + * in the specified array, it is returned therein. Otherwise, a new
13.319 + * array is allocated with the runtime type of the specified array and
13.320 + * the size of this list.
13.321 + *
13.322 + * <p>If this list fits in the specified array with room to spare
13.323 + * (i.e., the array has more elements than this list), the element in
13.324 + * the array immediately following the end of the list is set to
13.325 + * <tt>null</tt>. (This is useful in determining the length of this
13.326 + * list <i>only</i> if the caller knows that this list does not contain
13.327 + * any null elements.)
13.328 + *
13.329 + * <p>Like the {@link #toArray()} method, this method acts as bridge between
13.330 + * array-based and collection-based APIs. Further, this method allows
13.331 + * precise control over the runtime type of the output array, and may,
13.332 + * under certain circumstances, be used to save allocation costs.
13.333 + *
13.334 + * <p>Suppose <tt>x</tt> is a list known to contain only strings.
13.335 + * The following code can be used to dump the list into a newly
13.336 + * allocated array of <tt>String</tt>:
13.337 + *
13.338 + * <pre>
13.339 + * String[] y = x.toArray(new String[0]);</pre>
13.340 + *
13.341 + * Note that <tt>toArray(new Object[0])</tt> is identical in function to
13.342 + * <tt>toArray()</tt>.
13.343 + *
13.344 + * @param a the array into which the elements of the list are to
13.345 + * be stored, if it is big enough; otherwise, a new array of the
13.346 + * same runtime type is allocated for this purpose.
13.347 + * @return an array containing all the elements in this list
13.348 + * @throws ArrayStoreException if the runtime type of the specified array
13.349 + * is not a supertype of the runtime type of every element in
13.350 + * this list
13.351 + * @throws NullPointerException if the specified array is null
13.352 + */
13.353 + @SuppressWarnings("unchecked")
13.354 + public <T> T[] toArray(T a[]) {
13.355 + Object[] elements = getArray();
13.356 + int len = elements.length;
13.357 + if (a.length < len)
13.358 + return (T[]) Arrays.copyOf(elements, len, a.getClass());
13.359 + else {
13.360 + System.arraycopy(elements, 0, a, 0, len);
13.361 + if (a.length > len)
13.362 + a[len] = null;
13.363 + return a;
13.364 + }
13.365 + }
13.366 +
13.367 + // Positional Access Operations
13.368 +
13.369 + @SuppressWarnings("unchecked")
13.370 + private E get(Object[] a, int index) {
13.371 + return (E) a[index];
13.372 + }
13.373 +
13.374 + /**
13.375 + * {@inheritDoc}
13.376 + *
13.377 + * @throws IndexOutOfBoundsException {@inheritDoc}
13.378 + */
13.379 + public E get(int index) {
13.380 + return get(getArray(), index);
13.381 + }
13.382 +
13.383 + /**
13.384 + * Replaces the element at the specified position in this list with the
13.385 + * specified element.
13.386 + *
13.387 + * @throws IndexOutOfBoundsException {@inheritDoc}
13.388 + */
13.389 + public E set(int index, E element) {
13.390 + final ReentrantLock lock = this.lock;
13.391 + lock.lock();
13.392 + try {
13.393 + Object[] elements = getArray();
13.394 + E oldValue = get(elements, index);
13.395 +
13.396 + if (oldValue != element) {
13.397 + int len = elements.length;
13.398 + Object[] newElements = Arrays.copyOf(elements, len);
13.399 + newElements[index] = element;
13.400 + setArray(newElements);
13.401 + } else {
13.402 + // Not quite a no-op; ensures volatile write semantics
13.403 + setArray(elements);
13.404 + }
13.405 + return oldValue;
13.406 + } finally {
13.407 + lock.unlock();
13.408 + }
13.409 + }
13.410 +
13.411 + /**
13.412 + * Appends the specified element to the end of this list.
13.413 + *
13.414 + * @param e element to be appended to this list
13.415 + * @return <tt>true</tt> (as specified by {@link Collection#add})
13.416 + */
13.417 + public boolean add(E e) {
13.418 + final ReentrantLock lock = this.lock;
13.419 + lock.lock();
13.420 + try {
13.421 + Object[] elements = getArray();
13.422 + int len = elements.length;
13.423 + Object[] newElements = Arrays.copyOf(elements, len + 1);
13.424 + newElements[len] = e;
13.425 + setArray(newElements);
13.426 + return true;
13.427 + } finally {
13.428 + lock.unlock();
13.429 + }
13.430 + }
13.431 +
13.432 + /**
13.433 + * Inserts the specified element at the specified position in this
13.434 + * list. Shifts the element currently at that position (if any) and
13.435 + * any subsequent elements to the right (adds one to their indices).
13.436 + *
13.437 + * @throws IndexOutOfBoundsException {@inheritDoc}
13.438 + */
13.439 + public void add(int index, E element) {
13.440 + final ReentrantLock lock = this.lock;
13.441 + lock.lock();
13.442 + try {
13.443 + Object[] elements = getArray();
13.444 + int len = elements.length;
13.445 + if (index > len || index < 0)
13.446 + throw new IndexOutOfBoundsException("Index: "+index+
13.447 + ", Size: "+len);
13.448 + Object[] newElements;
13.449 + int numMoved = len - index;
13.450 + if (numMoved == 0)
13.451 + newElements = Arrays.copyOf(elements, len + 1);
13.452 + else {
13.453 + newElements = new Object[len + 1];
13.454 + System.arraycopy(elements, 0, newElements, 0, index);
13.455 + System.arraycopy(elements, index, newElements, index + 1,
13.456 + numMoved);
13.457 + }
13.458 + newElements[index] = element;
13.459 + setArray(newElements);
13.460 + } finally {
13.461 + lock.unlock();
13.462 + }
13.463 + }
13.464 +
13.465 + /**
13.466 + * Removes the element at the specified position in this list.
13.467 + * Shifts any subsequent elements to the left (subtracts one from their
13.468 + * indices). Returns the element that was removed from the list.
13.469 + *
13.470 + * @throws IndexOutOfBoundsException {@inheritDoc}
13.471 + */
13.472 + public E remove(int index) {
13.473 + final ReentrantLock lock = this.lock;
13.474 + lock.lock();
13.475 + try {
13.476 + Object[] elements = getArray();
13.477 + int len = elements.length;
13.478 + E oldValue = get(elements, index);
13.479 + int numMoved = len - index - 1;
13.480 + if (numMoved == 0)
13.481 + setArray(Arrays.copyOf(elements, len - 1));
13.482 + else {
13.483 + Object[] newElements = new Object[len - 1];
13.484 + System.arraycopy(elements, 0, newElements, 0, index);
13.485 + System.arraycopy(elements, index + 1, newElements, index,
13.486 + numMoved);
13.487 + setArray(newElements);
13.488 + }
13.489 + return oldValue;
13.490 + } finally {
13.491 + lock.unlock();
13.492 + }
13.493 + }
13.494 +
13.495 + /**
13.496 + * Removes the first occurrence of the specified element from this list,
13.497 + * if it is present. If this list does not contain the element, it is
13.498 + * unchanged. More formally, removes the element with the lowest index
13.499 + * <tt>i</tt> such that
13.500 + * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>
13.501 + * (if such an element exists). Returns <tt>true</tt> if this list
13.502 + * contained the specified element (or equivalently, if this list
13.503 + * changed as a result of the call).
13.504 + *
13.505 + * @param o element to be removed from this list, if present
13.506 + * @return <tt>true</tt> if this list contained the specified element
13.507 + */
13.508 + public boolean remove(Object o) {
13.509 + final ReentrantLock lock = this.lock;
13.510 + lock.lock();
13.511 + try {
13.512 + Object[] elements = getArray();
13.513 + int len = elements.length;
13.514 + if (len != 0) {
13.515 + // Copy while searching for element to remove
13.516 + // This wins in the normal case of element being present
13.517 + int newlen = len - 1;
13.518 + Object[] newElements = new Object[newlen];
13.519 +
13.520 + for (int i = 0; i < newlen; ++i) {
13.521 + if (eq(o, elements[i])) {
13.522 + // found one; copy remaining and exit
13.523 + for (int k = i + 1; k < len; ++k)
13.524 + newElements[k-1] = elements[k];
13.525 + setArray(newElements);
13.526 + return true;
13.527 + } else
13.528 + newElements[i] = elements[i];
13.529 + }
13.530 +
13.531 + // special handling for last cell
13.532 + if (eq(o, elements[newlen])) {
13.533 + setArray(newElements);
13.534 + return true;
13.535 + }
13.536 + }
13.537 + return false;
13.538 + } finally {
13.539 + lock.unlock();
13.540 + }
13.541 + }
13.542 +
13.543 + /**
13.544 + * Removes from this list all of the elements whose index is between
13.545 + * <tt>fromIndex</tt>, inclusive, and <tt>toIndex</tt>, exclusive.
13.546 + * Shifts any succeeding elements to the left (reduces their index).
13.547 + * This call shortens the list by <tt>(toIndex - fromIndex)</tt> elements.
13.548 + * (If <tt>toIndex==fromIndex</tt>, this operation has no effect.)
13.549 + *
13.550 + * @param fromIndex index of first element to be removed
13.551 + * @param toIndex index after last element to be removed
13.552 + * @throws IndexOutOfBoundsException if fromIndex or toIndex out of range
13.553 + * ({@code{fromIndex < 0 || toIndex > size() || toIndex < fromIndex})
13.554 + */
13.555 + private void removeRange(int fromIndex, int toIndex) {
13.556 + final ReentrantLock lock = this.lock;
13.557 + lock.lock();
13.558 + try {
13.559 + Object[] elements = getArray();
13.560 + int len = elements.length;
13.561 +
13.562 + if (fromIndex < 0 || toIndex > len || toIndex < fromIndex)
13.563 + throw new IndexOutOfBoundsException();
13.564 + int newlen = len - (toIndex - fromIndex);
13.565 + int numMoved = len - toIndex;
13.566 + if (numMoved == 0)
13.567 + setArray(Arrays.copyOf(elements, newlen));
13.568 + else {
13.569 + Object[] newElements = new Object[newlen];
13.570 + System.arraycopy(elements, 0, newElements, 0, fromIndex);
13.571 + System.arraycopy(elements, toIndex, newElements,
13.572 + fromIndex, numMoved);
13.573 + setArray(newElements);
13.574 + }
13.575 + } finally {
13.576 + lock.unlock();
13.577 + }
13.578 + }
13.579 +
13.580 + /**
13.581 + * Append the element if not present.
13.582 + *
13.583 + * @param e element to be added to this list, if absent
13.584 + * @return <tt>true</tt> if the element was added
13.585 + */
13.586 + public boolean addIfAbsent(E e) {
13.587 + final ReentrantLock lock = this.lock;
13.588 + lock.lock();
13.589 + try {
13.590 + // Copy while checking if already present.
13.591 + // This wins in the most common case where it is not present
13.592 + Object[] elements = getArray();
13.593 + int len = elements.length;
13.594 + Object[] newElements = new Object[len + 1];
13.595 + for (int i = 0; i < len; ++i) {
13.596 + if (eq(e, elements[i]))
13.597 + return false; // exit, throwing away copy
13.598 + else
13.599 + newElements[i] = elements[i];
13.600 + }
13.601 + newElements[len] = e;
13.602 + setArray(newElements);
13.603 + return true;
13.604 + } finally {
13.605 + lock.unlock();
13.606 + }
13.607 + }
13.608 +
13.609 + /**
13.610 + * Returns <tt>true</tt> if this list contains all of the elements of the
13.611 + * specified collection.
13.612 + *
13.613 + * @param c collection to be checked for containment in this list
13.614 + * @return <tt>true</tt> if this list contains all of the elements of the
13.615 + * specified collection
13.616 + * @throws NullPointerException if the specified collection is null
13.617 + * @see #contains(Object)
13.618 + */
13.619 + public boolean containsAll(Collection<?> c) {
13.620 + Object[] elements = getArray();
13.621 + int len = elements.length;
13.622 + for (Object e : c) {
13.623 + if (indexOf(e, elements, 0, len) < 0)
13.624 + return false;
13.625 + }
13.626 + return true;
13.627 + }
13.628 +
13.629 + /**
13.630 + * Removes from this list all of its elements that are contained in
13.631 + * the specified collection. This is a particularly expensive operation
13.632 + * in this class because of the need for an internal temporary array.
13.633 + *
13.634 + * @param c collection containing elements to be removed from this list
13.635 + * @return <tt>true</tt> if this list changed as a result of the call
13.636 + * @throws ClassCastException if the class of an element of this list
13.637 + * is incompatible with the specified collection
13.638 + * (<a href="../Collection.html#optional-restrictions">optional</a>)
13.639 + * @throws NullPointerException if this list contains a null element and the
13.640 + * specified collection does not permit null elements
13.641 + * (<a href="../Collection.html#optional-restrictions">optional</a>),
13.642 + * or if the specified collection is null
13.643 + * @see #remove(Object)
13.644 + */
13.645 + public boolean removeAll(Collection<?> c) {
13.646 + final ReentrantLock lock = this.lock;
13.647 + lock.lock();
13.648 + try {
13.649 + Object[] elements = getArray();
13.650 + int len = elements.length;
13.651 + if (len != 0) {
13.652 + // temp array holds those elements we know we want to keep
13.653 + int newlen = 0;
13.654 + Object[] temp = new Object[len];
13.655 + for (int i = 0; i < len; ++i) {
13.656 + Object element = elements[i];
13.657 + if (!c.contains(element))
13.658 + temp[newlen++] = element;
13.659 + }
13.660 + if (newlen != len) {
13.661 + setArray(Arrays.copyOf(temp, newlen));
13.662 + return true;
13.663 + }
13.664 + }
13.665 + return false;
13.666 + } finally {
13.667 + lock.unlock();
13.668 + }
13.669 + }
13.670 +
13.671 + /**
13.672 + * Retains only the elements in this list that are contained in the
13.673 + * specified collection. In other words, removes from this list all of
13.674 + * its elements that are not contained in the specified collection.
13.675 + *
13.676 + * @param c collection containing elements to be retained in this list
13.677 + * @return <tt>true</tt> if this list changed as a result of the call
13.678 + * @throws ClassCastException if the class of an element of this list
13.679 + * is incompatible with the specified collection
13.680 + * (<a href="../Collection.html#optional-restrictions">optional</a>)
13.681 + * @throws NullPointerException if this list contains a null element and the
13.682 + * specified collection does not permit null elements
13.683 + * (<a href="../Collection.html#optional-restrictions">optional</a>),
13.684 + * or if the specified collection is null
13.685 + * @see #remove(Object)
13.686 + */
13.687 + public boolean retainAll(Collection<?> c) {
13.688 + final ReentrantLock lock = this.lock;
13.689 + lock.lock();
13.690 + try {
13.691 + Object[] elements = getArray();
13.692 + int len = elements.length;
13.693 + if (len != 0) {
13.694 + // temp array holds those elements we know we want to keep
13.695 + int newlen = 0;
13.696 + Object[] temp = new Object[len];
13.697 + for (int i = 0; i < len; ++i) {
13.698 + Object element = elements[i];
13.699 + if (c.contains(element))
13.700 + temp[newlen++] = element;
13.701 + }
13.702 + if (newlen != len) {
13.703 + setArray(Arrays.copyOf(temp, newlen));
13.704 + return true;
13.705 + }
13.706 + }
13.707 + return false;
13.708 + } finally {
13.709 + lock.unlock();
13.710 + }
13.711 + }
13.712 +
13.713 + /**
13.714 + * Appends all of the elements in the specified collection that
13.715 + * are not already contained in this list, to the end of
13.716 + * this list, in the order that they are returned by the
13.717 + * specified collection's iterator.
13.718 + *
13.719 + * @param c collection containing elements to be added to this list
13.720 + * @return the number of elements added
13.721 + * @throws NullPointerException if the specified collection is null
13.722 + * @see #addIfAbsent(Object)
13.723 + */
13.724 + public int addAllAbsent(Collection<? extends E> c) {
13.725 + Object[] cs = c.toArray();
13.726 + if (cs.length == 0)
13.727 + return 0;
13.728 + Object[] uniq = new Object[cs.length];
13.729 + final ReentrantLock lock = this.lock;
13.730 + lock.lock();
13.731 + try {
13.732 + Object[] elements = getArray();
13.733 + int len = elements.length;
13.734 + int added = 0;
13.735 + for (int i = 0; i < cs.length; ++i) { // scan for duplicates
13.736 + Object e = cs[i];
13.737 + if (indexOf(e, elements, 0, len) < 0 &&
13.738 + indexOf(e, uniq, 0, added) < 0)
13.739 + uniq[added++] = e;
13.740 + }
13.741 + if (added > 0) {
13.742 + Object[] newElements = Arrays.copyOf(elements, len + added);
13.743 + System.arraycopy(uniq, 0, newElements, len, added);
13.744 + setArray(newElements);
13.745 + }
13.746 + return added;
13.747 + } finally {
13.748 + lock.unlock();
13.749 + }
13.750 + }
13.751 +
13.752 + /**
13.753 + * Removes all of the elements from this list.
13.754 + * The list will be empty after this call returns.
13.755 + */
13.756 + public void clear() {
13.757 + final ReentrantLock lock = this.lock;
13.758 + lock.lock();
13.759 + try {
13.760 + setArray(new Object[0]);
13.761 + } finally {
13.762 + lock.unlock();
13.763 + }
13.764 + }
13.765 +
13.766 + /**
13.767 + * Appends all of the elements in the specified collection to the end
13.768 + * of this list, in the order that they are returned by the specified
13.769 + * collection's iterator.
13.770 + *
13.771 + * @param c collection containing elements to be added to this list
13.772 + * @return <tt>true</tt> if this list changed as a result of the call
13.773 + * @throws NullPointerException if the specified collection is null
13.774 + * @see #add(Object)
13.775 + */
13.776 + public boolean addAll(Collection<? extends E> c) {
13.777 + Object[] cs = c.toArray();
13.778 + if (cs.length == 0)
13.779 + return false;
13.780 + final ReentrantLock lock = this.lock;
13.781 + lock.lock();
13.782 + try {
13.783 + Object[] elements = getArray();
13.784 + int len = elements.length;
13.785 + Object[] newElements = Arrays.copyOf(elements, len + cs.length);
13.786 + System.arraycopy(cs, 0, newElements, len, cs.length);
13.787 + setArray(newElements);
13.788 + return true;
13.789 + } finally {
13.790 + lock.unlock();
13.791 + }
13.792 + }
13.793 +
13.794 + /**
13.795 + * Inserts all of the elements in the specified collection into this
13.796 + * list, starting at the specified position. Shifts the element
13.797 + * currently at that position (if any) and any subsequent elements to
13.798 + * the right (increases their indices). The new elements will appear
13.799 + * in this list in the order that they are returned by the
13.800 + * specified collection's iterator.
13.801 + *
13.802 + * @param index index at which to insert the first element
13.803 + * from the specified collection
13.804 + * @param c collection containing elements to be added to this list
13.805 + * @return <tt>true</tt> if this list changed as a result of the call
13.806 + * @throws IndexOutOfBoundsException {@inheritDoc}
13.807 + * @throws NullPointerException if the specified collection is null
13.808 + * @see #add(int,Object)
13.809 + */
13.810 + public boolean addAll(int index, Collection<? extends E> c) {
13.811 + Object[] cs = c.toArray();
13.812 + final ReentrantLock lock = this.lock;
13.813 + lock.lock();
13.814 + try {
13.815 + Object[] elements = getArray();
13.816 + int len = elements.length;
13.817 + if (index > len || index < 0)
13.818 + throw new IndexOutOfBoundsException("Index: "+index+
13.819 + ", Size: "+len);
13.820 + if (cs.length == 0)
13.821 + return false;
13.822 + int numMoved = len - index;
13.823 + Object[] newElements;
13.824 + if (numMoved == 0)
13.825 + newElements = Arrays.copyOf(elements, len + cs.length);
13.826 + else {
13.827 + newElements = new Object[len + cs.length];
13.828 + System.arraycopy(elements, 0, newElements, 0, index);
13.829 + System.arraycopy(elements, index,
13.830 + newElements, index + cs.length,
13.831 + numMoved);
13.832 + }
13.833 + System.arraycopy(cs, 0, newElements, index, cs.length);
13.834 + setArray(newElements);
13.835 + return true;
13.836 + } finally {
13.837 + lock.unlock();
13.838 + }
13.839 + }
13.840 +
13.841 + /**
13.842 + * Saves the state of the list to a stream (that is, serializes it).
13.843 + *
13.844 + * @serialData The length of the array backing the list is emitted
13.845 + * (int), followed by all of its elements (each an Object)
13.846 + * in the proper order.
13.847 + * @param s the stream
13.848 + */
13.849 + private void writeObject(java.io.ObjectOutputStream s)
13.850 + throws java.io.IOException{
13.851 +
13.852 + s.defaultWriteObject();
13.853 +
13.854 + Object[] elements = getArray();
13.855 + // Write out array length
13.856 + s.writeInt(elements.length);
13.857 +
13.858 + // Write out all elements in the proper order.
13.859 + for (Object element : elements)
13.860 + s.writeObject(element);
13.861 + }
13.862 +
13.863 + /**
13.864 + * Reconstitutes the list from a stream (that is, deserializes it).
13.865 + *
13.866 + * @param s the stream
13.867 + */
13.868 + private void readObject(java.io.ObjectInputStream s)
13.869 + throws java.io.IOException, ClassNotFoundException {
13.870 +
13.871 + s.defaultReadObject();
13.872 +
13.873 + // bind to new lock
13.874 + resetLock();
13.875 +
13.876 + // Read in array length and allocate array
13.877 + int len = s.readInt();
13.878 + Object[] elements = new Object[len];
13.879 +
13.880 + // Read in all elements in the proper order.
13.881 + for (int i = 0; i < len; i++)
13.882 + elements[i] = s.readObject();
13.883 + setArray(elements);
13.884 + }
13.885 +
13.886 + /**
13.887 + * Returns a string representation of this list. The string
13.888 + * representation consists of the string representations of the list's
13.889 + * elements in the order they are returned by its iterator, enclosed in
13.890 + * square brackets (<tt>"[]"</tt>). Adjacent elements are separated by
13.891 + * the characters <tt>", "</tt> (comma and space). Elements are
13.892 + * converted to strings as by {@link String#valueOf(Object)}.
13.893 + *
13.894 + * @return a string representation of this list
13.895 + */
13.896 + public String toString() {
13.897 + return Arrays.toString(getArray());
13.898 + }
13.899 +
13.900 + /**
13.901 + * Compares the specified object with this list for equality.
13.902 + * Returns {@code true} if the specified object is the same object
13.903 + * as this object, or if it is also a {@link List} and the sequence
13.904 + * of elements returned by an {@linkplain List#iterator() iterator}
13.905 + * over the specified list is the same as the sequence returned by
13.906 + * an iterator over this list. The two sequences are considered to
13.907 + * be the same if they have the same length and corresponding
13.908 + * elements at the same position in the sequence are <em>equal</em>.
13.909 + * Two elements {@code e1} and {@code e2} are considered
13.910 + * <em>equal</em> if {@code (e1==null ? e2==null : e1.equals(e2))}.
13.911 + *
13.912 + * @param o the object to be compared for equality with this list
13.913 + * @return {@code true} if the specified object is equal to this list
13.914 + */
13.915 + public boolean equals(Object o) {
13.916 + if (o == this)
13.917 + return true;
13.918 + if (!(o instanceof List))
13.919 + return false;
13.920 +
13.921 + List<?> list = (List<?>)(o);
13.922 + Iterator<?> it = list.iterator();
13.923 + Object[] elements = getArray();
13.924 + int len = elements.length;
13.925 + for (int i = 0; i < len; ++i)
13.926 + if (!it.hasNext() || !eq(elements[i], it.next()))
13.927 + return false;
13.928 + if (it.hasNext())
13.929 + return false;
13.930 + return true;
13.931 + }
13.932 +
13.933 + /**
13.934 + * Returns the hash code value for this list.
13.935 + *
13.936 + * <p>This implementation uses the definition in {@link List#hashCode}.
13.937 + *
13.938 + * @return the hash code value for this list
13.939 + */
13.940 + public int hashCode() {
13.941 + int hashCode = 1;
13.942 + Object[] elements = getArray();
13.943 + int len = elements.length;
13.944 + for (int i = 0; i < len; ++i) {
13.945 + Object obj = elements[i];
13.946 + hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
13.947 + }
13.948 + return hashCode;
13.949 + }
13.950 +
13.951 + /**
13.952 + * Returns an iterator over the elements in this list in proper sequence.
13.953 + *
13.954 + * <p>The returned iterator provides a snapshot of the state of the list
13.955 + * when the iterator was constructed. No synchronization is needed while
13.956 + * traversing the iterator. The iterator does <em>NOT</em> support the
13.957 + * <tt>remove</tt> method.
13.958 + *
13.959 + * @return an iterator over the elements in this list in proper sequence
13.960 + */
13.961 + public Iterator<E> iterator() {
13.962 + return new COWIterator<E>(getArray(), 0);
13.963 + }
13.964 +
13.965 + /**
13.966 + * {@inheritDoc}
13.967 + *
13.968 + * <p>The returned iterator provides a snapshot of the state of the list
13.969 + * when the iterator was constructed. No synchronization is needed while
13.970 + * traversing the iterator. The iterator does <em>NOT</em> support the
13.971 + * <tt>remove</tt>, <tt>set</tt> or <tt>add</tt> methods.
13.972 + */
13.973 + public ListIterator<E> listIterator() {
13.974 + return new COWIterator<E>(getArray(), 0);
13.975 + }
13.976 +
13.977 + /**
13.978 + * {@inheritDoc}
13.979 + *
13.980 + * <p>The returned iterator provides a snapshot of the state of the list
13.981 + * when the iterator was constructed. No synchronization is needed while
13.982 + * traversing the iterator. The iterator does <em>NOT</em> support the
13.983 + * <tt>remove</tt>, <tt>set</tt> or <tt>add</tt> methods.
13.984 + *
13.985 + * @throws IndexOutOfBoundsException {@inheritDoc}
13.986 + */
13.987 + public ListIterator<E> listIterator(final int index) {
13.988 + Object[] elements = getArray();
13.989 + int len = elements.length;
13.990 + if (index<0 || index>len)
13.991 + throw new IndexOutOfBoundsException("Index: "+index);
13.992 +
13.993 + return new COWIterator<E>(elements, index);
13.994 + }
13.995 +
13.996 + private static class COWIterator<E> implements ListIterator<E> {
13.997 + /** Snapshot of the array */
13.998 + private final Object[] snapshot;
13.999 + /** Index of element to be returned by subsequent call to next. */
13.1000 + private int cursor;
13.1001 +
13.1002 + private COWIterator(Object[] elements, int initialCursor) {
13.1003 + cursor = initialCursor;
13.1004 + snapshot = elements;
13.1005 + }
13.1006 +
13.1007 + public boolean hasNext() {
13.1008 + return cursor < snapshot.length;
13.1009 + }
13.1010 +
13.1011 + public boolean hasPrevious() {
13.1012 + return cursor > 0;
13.1013 + }
13.1014 +
13.1015 + @SuppressWarnings("unchecked")
13.1016 + public E next() {
13.1017 + if (! hasNext())
13.1018 + throw new NoSuchElementException();
13.1019 + return (E) snapshot[cursor++];
13.1020 + }
13.1021 +
13.1022 + @SuppressWarnings("unchecked")
13.1023 + public E previous() {
13.1024 + if (! hasPrevious())
13.1025 + throw new NoSuchElementException();
13.1026 + return (E) snapshot[--cursor];
13.1027 + }
13.1028 +
13.1029 + public int nextIndex() {
13.1030 + return cursor;
13.1031 + }
13.1032 +
13.1033 + public int previousIndex() {
13.1034 + return cursor-1;
13.1035 + }
13.1036 +
13.1037 + /**
13.1038 + * Not supported. Always throws UnsupportedOperationException.
13.1039 + * @throws UnsupportedOperationException always; <tt>remove</tt>
13.1040 + * is not supported by this iterator.
13.1041 + */
13.1042 + public void remove() {
13.1043 + throw new UnsupportedOperationException();
13.1044 + }
13.1045 +
13.1046 + /**
13.1047 + * Not supported. Always throws UnsupportedOperationException.
13.1048 + * @throws UnsupportedOperationException always; <tt>set</tt>
13.1049 + * is not supported by this iterator.
13.1050 + */
13.1051 + public void set(E e) {
13.1052 + throw new UnsupportedOperationException();
13.1053 + }
13.1054 +
13.1055 + /**
13.1056 + * Not supported. Always throws UnsupportedOperationException.
13.1057 + * @throws UnsupportedOperationException always; <tt>add</tt>
13.1058 + * is not supported by this iterator.
13.1059 + */
13.1060 + public void add(E e) {
13.1061 + throw new UnsupportedOperationException();
13.1062 + }
13.1063 + }
13.1064 +
13.1065 + /**
13.1066 + * Returns a view of the portion of this list between
13.1067 + * <tt>fromIndex</tt>, inclusive, and <tt>toIndex</tt>, exclusive.
13.1068 + * The returned list is backed by this list, so changes in the
13.1069 + * returned list are reflected in this list.
13.1070 + *
13.1071 + * <p>The semantics of the list returned by this method become
13.1072 + * undefined if the backing list (i.e., this list) is modified in
13.1073 + * any way other than via the returned list.
13.1074 + *
13.1075 + * @param fromIndex low endpoint (inclusive) of the subList
13.1076 + * @param toIndex high endpoint (exclusive) of the subList
13.1077 + * @return a view of the specified range within this list
13.1078 + * @throws IndexOutOfBoundsException {@inheritDoc}
13.1079 + */
13.1080 + public List<E> subList(int fromIndex, int toIndex) {
13.1081 + final ReentrantLock lock = this.lock;
13.1082 + lock.lock();
13.1083 + try {
13.1084 + Object[] elements = getArray();
13.1085 + int len = elements.length;
13.1086 + if (fromIndex < 0 || toIndex > len || fromIndex > toIndex)
13.1087 + throw new IndexOutOfBoundsException();
13.1088 + return new COWSubList<E>(this, fromIndex, toIndex);
13.1089 + } finally {
13.1090 + lock.unlock();
13.1091 + }
13.1092 + }
13.1093 +
13.1094 + /**
13.1095 + * Sublist for CopyOnWriteArrayList.
13.1096 + * This class extends AbstractList merely for convenience, to
13.1097 + * avoid having to define addAll, etc. This doesn't hurt, but
13.1098 + * is wasteful. This class does not need or use modCount
13.1099 + * mechanics in AbstractList, but does need to check for
13.1100 + * concurrent modification using similar mechanics. On each
13.1101 + * operation, the array that we expect the backing list to use
13.1102 + * is checked and updated. Since we do this for all of the
13.1103 + * base operations invoked by those defined in AbstractList,
13.1104 + * all is well. While inefficient, this is not worth
13.1105 + * improving. The kinds of list operations inherited from
13.1106 + * AbstractList are already so slow on COW sublists that
13.1107 + * adding a bit more space/time doesn't seem even noticeable.
13.1108 + */
13.1109 + private static class COWSubList<E>
13.1110 + extends AbstractList<E>
13.1111 + implements RandomAccess
13.1112 + {
13.1113 + private final CopyOnWriteArrayList<E> l;
13.1114 + private final int offset;
13.1115 + private int size;
13.1116 + private Object[] expectedArray;
13.1117 +
13.1118 + // only call this holding l's lock
13.1119 + COWSubList(CopyOnWriteArrayList<E> list,
13.1120 + int fromIndex, int toIndex) {
13.1121 + l = list;
13.1122 + expectedArray = l.getArray();
13.1123 + offset = fromIndex;
13.1124 + size = toIndex - fromIndex;
13.1125 + }
13.1126 +
13.1127 + // only call this holding l's lock
13.1128 + private void checkForComodification() {
13.1129 + if (l.getArray() != expectedArray)
13.1130 + throw new ConcurrentModificationException();
13.1131 + }
13.1132 +
13.1133 + // only call this holding l's lock
13.1134 + private void rangeCheck(int index) {
13.1135 + if (index<0 || index>=size)
13.1136 + throw new IndexOutOfBoundsException("Index: "+index+
13.1137 + ",Size: "+size);
13.1138 + }
13.1139 +
13.1140 + public E set(int index, E element) {
13.1141 + final ReentrantLock lock = l.lock;
13.1142 + lock.lock();
13.1143 + try {
13.1144 + rangeCheck(index);
13.1145 + checkForComodification();
13.1146 + E x = l.set(index+offset, element);
13.1147 + expectedArray = l.getArray();
13.1148 + return x;
13.1149 + } finally {
13.1150 + lock.unlock();
13.1151 + }
13.1152 + }
13.1153 +
13.1154 + public E get(int index) {
13.1155 + final ReentrantLock lock = l.lock;
13.1156 + lock.lock();
13.1157 + try {
13.1158 + rangeCheck(index);
13.1159 + checkForComodification();
13.1160 + return l.get(index+offset);
13.1161 + } finally {
13.1162 + lock.unlock();
13.1163 + }
13.1164 + }
13.1165 +
13.1166 + public int size() {
13.1167 + final ReentrantLock lock = l.lock;
13.1168 + lock.lock();
13.1169 + try {
13.1170 + checkForComodification();
13.1171 + return size;
13.1172 + } finally {
13.1173 + lock.unlock();
13.1174 + }
13.1175 + }
13.1176 +
13.1177 + public void add(int index, E element) {
13.1178 + final ReentrantLock lock = l.lock;
13.1179 + lock.lock();
13.1180 + try {
13.1181 + checkForComodification();
13.1182 + if (index<0 || index>size)
13.1183 + throw new IndexOutOfBoundsException();
13.1184 + l.add(index+offset, element);
13.1185 + expectedArray = l.getArray();
13.1186 + size++;
13.1187 + } finally {
13.1188 + lock.unlock();
13.1189 + }
13.1190 + }
13.1191 +
13.1192 + public void clear() {
13.1193 + final ReentrantLock lock = l.lock;
13.1194 + lock.lock();
13.1195 + try {
13.1196 + checkForComodification();
13.1197 + l.removeRange(offset, offset+size);
13.1198 + expectedArray = l.getArray();
13.1199 + size = 0;
13.1200 + } finally {
13.1201 + lock.unlock();
13.1202 + }
13.1203 + }
13.1204 +
13.1205 + public E remove(int index) {
13.1206 + final ReentrantLock lock = l.lock;
13.1207 + lock.lock();
13.1208 + try {
13.1209 + rangeCheck(index);
13.1210 + checkForComodification();
13.1211 + E result = l.remove(index+offset);
13.1212 + expectedArray = l.getArray();
13.1213 + size--;
13.1214 + return result;
13.1215 + } finally {
13.1216 + lock.unlock();
13.1217 + }
13.1218 + }
13.1219 +
13.1220 + public boolean remove(Object o) {
13.1221 + int index = indexOf(o);
13.1222 + if (index == -1)
13.1223 + return false;
13.1224 + remove(index);
13.1225 + return true;
13.1226 + }
13.1227 +
13.1228 + public Iterator<E> iterator() {
13.1229 + final ReentrantLock lock = l.lock;
13.1230 + lock.lock();
13.1231 + try {
13.1232 + checkForComodification();
13.1233 + return new COWSubListIterator<E>(l, 0, offset, size);
13.1234 + } finally {
13.1235 + lock.unlock();
13.1236 + }
13.1237 + }
13.1238 +
13.1239 + public ListIterator<E> listIterator(final int index) {
13.1240 + final ReentrantLock lock = l.lock;
13.1241 + lock.lock();
13.1242 + try {
13.1243 + checkForComodification();
13.1244 + if (index<0 || index>size)
13.1245 + throw new IndexOutOfBoundsException("Index: "+index+
13.1246 + ", Size: "+size);
13.1247 + return new COWSubListIterator<E>(l, index, offset, size);
13.1248 + } finally {
13.1249 + lock.unlock();
13.1250 + }
13.1251 + }
13.1252 +
13.1253 + public List<E> subList(int fromIndex, int toIndex) {
13.1254 + final ReentrantLock lock = l.lock;
13.1255 + lock.lock();
13.1256 + try {
13.1257 + checkForComodification();
13.1258 + if (fromIndex<0 || toIndex>size)
13.1259 + throw new IndexOutOfBoundsException();
13.1260 + return new COWSubList<E>(l, fromIndex + offset,
13.1261 + toIndex + offset);
13.1262 + } finally {
13.1263 + lock.unlock();
13.1264 + }
13.1265 + }
13.1266 +
13.1267 + }
13.1268 +
13.1269 +
13.1270 + private static class COWSubListIterator<E> implements ListIterator<E> {
13.1271 + private final ListIterator<E> i;
13.1272 + private final int index;
13.1273 + private final int offset;
13.1274 + private final int size;
13.1275 +
13.1276 + COWSubListIterator(List<E> l, int index, int offset,
13.1277 + int size) {
13.1278 + this.index = index;
13.1279 + this.offset = offset;
13.1280 + this.size = size;
13.1281 + i = l.listIterator(index+offset);
13.1282 + }
13.1283 +
13.1284 + public boolean hasNext() {
13.1285 + return nextIndex() < size;
13.1286 + }
13.1287 +
13.1288 + public E next() {
13.1289 + if (hasNext())
13.1290 + return i.next();
13.1291 + else
13.1292 + throw new NoSuchElementException();
13.1293 + }
13.1294 +
13.1295 + public boolean hasPrevious() {
13.1296 + return previousIndex() >= 0;
13.1297 + }
13.1298 +
13.1299 + public E previous() {
13.1300 + if (hasPrevious())
13.1301 + return i.previous();
13.1302 + else
13.1303 + throw new NoSuchElementException();
13.1304 + }
13.1305 +
13.1306 + public int nextIndex() {
13.1307 + return i.nextIndex() - offset;
13.1308 + }
13.1309 +
13.1310 + public int previousIndex() {
13.1311 + return i.previousIndex() - offset;
13.1312 + }
13.1313 +
13.1314 + public void remove() {
13.1315 + throw new UnsupportedOperationException();
13.1316 + }
13.1317 +
13.1318 + public void set(E e) {
13.1319 + throw new UnsupportedOperationException();
13.1320 + }
13.1321 +
13.1322 + public void add(E e) {
13.1323 + throw new UnsupportedOperationException();
13.1324 + }
13.1325 + }
13.1326 +
13.1327 + // Support for resetting lock while deserializing
13.1328 + private void resetLock() {
13.1329 + UNSAFE.putObjectVolatile(this, lockOffset, new ReentrantLock());
13.1330 + }
13.1331 + private static final sun.misc.Unsafe UNSAFE;
13.1332 + private static final long lockOffset;
13.1333 + static {
13.1334 + try {
13.1335 + UNSAFE = sun.misc.Unsafe.getUnsafe();
13.1336 + Class k = CopyOnWriteArrayList.class;
13.1337 + lockOffset = UNSAFE.objectFieldOffset
13.1338 + (k.getDeclaredField("lock"));
13.1339 + } catch (Exception e) {
13.1340 + throw new Error(e);
13.1341 + }
13.1342 + }
13.1343 +}
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/CopyOnWriteArraySet.java Sat Mar 19 10:48:29 2016 +0100
14.3 @@ -0,0 +1,392 @@
14.4 +/*
14.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
14.6 + *
14.7 + * This code is free software; you can redistribute it and/or modify it
14.8 + * under the terms of the GNU General Public License version 2 only, as
14.9 + * published by the Free Software Foundation. Oracle designates this
14.10 + * particular file as subject to the "Classpath" exception as provided
14.11 + * by Oracle in the LICENSE file that accompanied this code.
14.12 + *
14.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
14.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14.16 + * version 2 for more details (a copy is included in the LICENSE file that
14.17 + * accompanied this code).
14.18 + *
14.19 + * You should have received a copy of the GNU General Public License version
14.20 + * 2 along with this work; if not, write to the Free Software Foundation,
14.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
14.22 + *
14.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
14.24 + * or visit www.oracle.com if you need additional information or have any
14.25 + * questions.
14.26 + */
14.27 +
14.28 +/*
14.29 + * This file is available under and governed by the GNU General Public
14.30 + * License version 2 only, as published by the Free Software Foundation.
14.31 + * However, the following notice accompanied the original version of this
14.32 + * file:
14.33 + *
14.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
14.35 + * Expert Group and released to the public domain, as explained at
14.36 + * http://creativecommons.org/publicdomain/zero/1.0/
14.37 + */
14.38 +
14.39 +package java.util.concurrent;
14.40 +import java.util.*;
14.41 +
14.42 +/**
14.43 + * A {@link java.util.Set} that uses an internal {@link CopyOnWriteArrayList}
14.44 + * for all of its operations. Thus, it shares the same basic properties:
14.45 + * <ul>
14.46 + * <li>It is best suited for applications in which set sizes generally
14.47 + * stay small, read-only operations
14.48 + * vastly outnumber mutative operations, and you need
14.49 + * to prevent interference among threads during traversal.
14.50 + * <li>It is thread-safe.
14.51 + * <li>Mutative operations (<tt>add</tt>, <tt>set</tt>, <tt>remove</tt>, etc.)
14.52 + * are expensive since they usually entail copying the entire underlying
14.53 + * array.
14.54 + * <li>Iterators do not support the mutative <tt>remove</tt> operation.
14.55 + * <li>Traversal via iterators is fast and cannot encounter
14.56 + * interference from other threads. Iterators rely on
14.57 + * unchanging snapshots of the array at the time the iterators were
14.58 + * constructed.
14.59 + * </ul>
14.60 + *
14.61 + * <p> <b>Sample Usage.</b> The following code sketch uses a
14.62 + * copy-on-write set to maintain a set of Handler objects that
14.63 + * perform some action upon state updates.
14.64 + *
14.65 + * <pre> {@code
14.66 + * class Handler { void handle(); ... }
14.67 + *
14.68 + * class X {
14.69 + * private final CopyOnWriteArraySet<Handler> handlers
14.70 + * = new CopyOnWriteArraySet<Handler>();
14.71 + * public void addHandler(Handler h) { handlers.add(h); }
14.72 + *
14.73 + * private long internalState;
14.74 + * private synchronized void changeState() { internalState = ...; }
14.75 + *
14.76 + * public void update() {
14.77 + * changeState();
14.78 + * for (Handler handler : handlers)
14.79 + * handler.handle();
14.80 + * }
14.81 + * }}</pre>
14.82 + *
14.83 + * <p>This class is a member of the
14.84 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
14.85 + * Java Collections Framework</a>.
14.86 + *
14.87 + * @see CopyOnWriteArrayList
14.88 + * @since 1.5
14.89 + * @author Doug Lea
14.90 + * @param <E> the type of elements held in this collection
14.91 + */
14.92 +public class CopyOnWriteArraySet<E> extends AbstractSet<E>
14.93 + implements java.io.Serializable {
14.94 + private static final long serialVersionUID = 5457747651344034263L;
14.95 +
14.96 + private final CopyOnWriteArrayList<E> al;
14.97 +
14.98 + /**
14.99 + * Creates an empty set.
14.100 + */
14.101 + public CopyOnWriteArraySet() {
14.102 + al = new CopyOnWriteArrayList<E>();
14.103 + }
14.104 +
14.105 + /**
14.106 + * Creates a set containing all of the elements of the specified
14.107 + * collection.
14.108 + *
14.109 + * @param c the collection of elements to initially contain
14.110 + * @throws NullPointerException if the specified collection is null
14.111 + */
14.112 + public CopyOnWriteArraySet(Collection<? extends E> c) {
14.113 + al = new CopyOnWriteArrayList<E>();
14.114 + al.addAllAbsent(c);
14.115 + }
14.116 +
14.117 + /**
14.118 + * Returns the number of elements in this set.
14.119 + *
14.120 + * @return the number of elements in this set
14.121 + */
14.122 + public int size() {
14.123 + return al.size();
14.124 + }
14.125 +
14.126 + /**
14.127 + * Returns <tt>true</tt> if this set contains no elements.
14.128 + *
14.129 + * @return <tt>true</tt> if this set contains no elements
14.130 + */
14.131 + public boolean isEmpty() {
14.132 + return al.isEmpty();
14.133 + }
14.134 +
14.135 + /**
14.136 + * Returns <tt>true</tt> if this set contains the specified element.
14.137 + * More formally, returns <tt>true</tt> if and only if this set
14.138 + * contains an element <tt>e</tt> such that
14.139 + * <tt>(o==null ? e==null : o.equals(e))</tt>.
14.140 + *
14.141 + * @param o element whose presence in this set is to be tested
14.142 + * @return <tt>true</tt> if this set contains the specified element
14.143 + */
14.144 + public boolean contains(Object o) {
14.145 + return al.contains(o);
14.146 + }
14.147 +
14.148 + /**
14.149 + * Returns an array containing all of the elements in this set.
14.150 + * If this set makes any guarantees as to what order its elements
14.151 + * are returned by its iterator, this method must return the
14.152 + * elements in the same order.
14.153 + *
14.154 + * <p>The returned array will be "safe" in that no references to it
14.155 + * are maintained by this set. (In other words, this method must
14.156 + * allocate a new array even if this set is backed by an array).
14.157 + * The caller is thus free to modify the returned array.
14.158 + *
14.159 + * <p>This method acts as bridge between array-based and collection-based
14.160 + * APIs.
14.161 + *
14.162 + * @return an array containing all the elements in this set
14.163 + */
14.164 + public Object[] toArray() {
14.165 + return al.toArray();
14.166 + }
14.167 +
14.168 + /**
14.169 + * Returns an array containing all of the elements in this set; the
14.170 + * runtime type of the returned array is that of the specified array.
14.171 + * If the set fits in the specified array, it is returned therein.
14.172 + * Otherwise, a new array is allocated with the runtime type of the
14.173 + * specified array and the size of this set.
14.174 + *
14.175 + * <p>If this set fits in the specified array with room to spare
14.176 + * (i.e., the array has more elements than this set), the element in
14.177 + * the array immediately following the end of the set is set to
14.178 + * <tt>null</tt>. (This is useful in determining the length of this
14.179 + * set <i>only</i> if the caller knows that this set does not contain
14.180 + * any null elements.)
14.181 + *
14.182 + * <p>If this set makes any guarantees as to what order its elements
14.183 + * are returned by its iterator, this method must return the elements
14.184 + * in the same order.
14.185 + *
14.186 + * <p>Like the {@link #toArray()} method, this method acts as bridge between
14.187 + * array-based and collection-based APIs. Further, this method allows
14.188 + * precise control over the runtime type of the output array, and may,
14.189 + * under certain circumstances, be used to save allocation costs.
14.190 + *
14.191 + * <p>Suppose <tt>x</tt> is a set known to contain only strings.
14.192 + * The following code can be used to dump the set into a newly allocated
14.193 + * array of <tt>String</tt>:
14.194 + *
14.195 + * <pre>
14.196 + * String[] y = x.toArray(new String[0]);</pre>
14.197 + *
14.198 + * Note that <tt>toArray(new Object[0])</tt> is identical in function to
14.199 + * <tt>toArray()</tt>.
14.200 + *
14.201 + * @param a the array into which the elements of this set are to be
14.202 + * stored, if it is big enough; otherwise, a new array of the same
14.203 + * runtime type is allocated for this purpose.
14.204 + * @return an array containing all the elements in this set
14.205 + * @throws ArrayStoreException if the runtime type of the specified array
14.206 + * is not a supertype of the runtime type of every element in this
14.207 + * set
14.208 + * @throws NullPointerException if the specified array is null
14.209 + */
14.210 + public <T> T[] toArray(T[] a) {
14.211 + return al.toArray(a);
14.212 + }
14.213 +
14.214 + /**
14.215 + * Removes all of the elements from this set.
14.216 + * The set will be empty after this call returns.
14.217 + */
14.218 + public void clear() {
14.219 + al.clear();
14.220 + }
14.221 +
14.222 + /**
14.223 + * Removes the specified element from this set if it is present.
14.224 + * More formally, removes an element <tt>e</tt> such that
14.225 + * <tt>(o==null ? e==null : o.equals(e))</tt>,
14.226 + * if this set contains such an element. Returns <tt>true</tt> if
14.227 + * this set contained the element (or equivalently, if this set
14.228 + * changed as a result of the call). (This set will not contain the
14.229 + * element once the call returns.)
14.230 + *
14.231 + * @param o object to be removed from this set, if present
14.232 + * @return <tt>true</tt> if this set contained the specified element
14.233 + */
14.234 + public boolean remove(Object o) {
14.235 + return al.remove(o);
14.236 + }
14.237 +
14.238 + /**
14.239 + * Adds the specified element to this set if it is not already present.
14.240 + * More formally, adds the specified element <tt>e</tt> to this set if
14.241 + * the set contains no element <tt>e2</tt> such that
14.242 + * <tt>(e==null ? e2==null : e.equals(e2))</tt>.
14.243 + * If this set already contains the element, the call leaves the set
14.244 + * unchanged and returns <tt>false</tt>.
14.245 + *
14.246 + * @param e element to be added to this set
14.247 + * @return <tt>true</tt> if this set did not already contain the specified
14.248 + * element
14.249 + */
14.250 + public boolean add(E e) {
14.251 + return al.addIfAbsent(e);
14.252 + }
14.253 +
14.254 + /**
14.255 + * Returns <tt>true</tt> if this set contains all of the elements of the
14.256 + * specified collection. If the specified collection is also a set, this
14.257 + * method returns <tt>true</tt> if it is a <i>subset</i> of this set.
14.258 + *
14.259 + * @param c collection to be checked for containment in this set
14.260 + * @return <tt>true</tt> if this set contains all of the elements of the
14.261 + * specified collection
14.262 + * @throws NullPointerException if the specified collection is null
14.263 + * @see #contains(Object)
14.264 + */
14.265 + public boolean containsAll(Collection<?> c) {
14.266 + return al.containsAll(c);
14.267 + }
14.268 +
14.269 + /**
14.270 + * Adds all of the elements in the specified collection to this set if
14.271 + * they're not already present. If the specified collection is also a
14.272 + * set, the <tt>addAll</tt> operation effectively modifies this set so
14.273 + * that its value is the <i>union</i> of the two sets. The behavior of
14.274 + * this operation is undefined if the specified collection is modified
14.275 + * while the operation is in progress.
14.276 + *
14.277 + * @param c collection containing elements to be added to this set
14.278 + * @return <tt>true</tt> if this set changed as a result of the call
14.279 + * @throws NullPointerException if the specified collection is null
14.280 + * @see #add(Object)
14.281 + */
14.282 + public boolean addAll(Collection<? extends E> c) {
14.283 + return al.addAllAbsent(c) > 0;
14.284 + }
14.285 +
14.286 + /**
14.287 + * Removes from this set all of its elements that are contained in the
14.288 + * specified collection. If the specified collection is also a set,
14.289 + * this operation effectively modifies this set so that its value is the
14.290 + * <i>asymmetric set difference</i> of the two sets.
14.291 + *
14.292 + * @param c collection containing elements to be removed from this set
14.293 + * @return <tt>true</tt> if this set changed as a result of the call
14.294 + * @throws ClassCastException if the class of an element of this set
14.295 + * is incompatible with the specified collection (optional)
14.296 + * @throws NullPointerException if this set contains a null element and the
14.297 + * specified collection does not permit null elements (optional),
14.298 + * or if the specified collection is null
14.299 + * @see #remove(Object)
14.300 + */
14.301 + public boolean removeAll(Collection<?> c) {
14.302 + return al.removeAll(c);
14.303 + }
14.304 +
14.305 + /**
14.306 + * Retains only the elements in this set that are contained in the
14.307 + * specified collection. In other words, removes from this set all of
14.308 + * its elements that are not contained in the specified collection. If
14.309 + * the specified collection is also a set, this operation effectively
14.310 + * modifies this set so that its value is the <i>intersection</i> of the
14.311 + * two sets.
14.312 + *
14.313 + * @param c collection containing elements to be retained in this set
14.314 + * @return <tt>true</tt> if this set changed as a result of the call
14.315 + * @throws ClassCastException if the class of an element of this set
14.316 + * is incompatible with the specified collection (optional)
14.317 + * @throws NullPointerException if this set contains a null element and the
14.318 + * specified collection does not permit null elements (optional),
14.319 + * or if the specified collection is null
14.320 + * @see #remove(Object)
14.321 + */
14.322 + public boolean retainAll(Collection<?> c) {
14.323 + return al.retainAll(c);
14.324 + }
14.325 +
14.326 + /**
14.327 + * Returns an iterator over the elements contained in this set
14.328 + * in the order in which these elements were added.
14.329 + *
14.330 + * <p>The returned iterator provides a snapshot of the state of the set
14.331 + * when the iterator was constructed. No synchronization is needed while
14.332 + * traversing the iterator. The iterator does <em>NOT</em> support the
14.333 + * <tt>remove</tt> method.
14.334 + *
14.335 + * @return an iterator over the elements in this set
14.336 + */
14.337 + public Iterator<E> iterator() {
14.338 + return al.iterator();
14.339 + }
14.340 +
14.341 + /**
14.342 + * Compares the specified object with this set for equality.
14.343 + * Returns {@code true} if the specified object is the same object
14.344 + * as this object, or if it is also a {@link Set} and the elements
14.345 + * returned by an {@linkplain List#iterator() iterator} over the
14.346 + * specified set are the same as the elements returned by an
14.347 + * iterator over this set. More formally, the two iterators are
14.348 + * considered to return the same elements if they return the same
14.349 + * number of elements and for every element {@code e1} returned by
14.350 + * the iterator over the specified set, there is an element
14.351 + * {@code e2} returned by the iterator over this set such that
14.352 + * {@code (e1==null ? e2==null : e1.equals(e2))}.
14.353 + *
14.354 + * @param o object to be compared for equality with this set
14.355 + * @return {@code true} if the specified object is equal to this set
14.356 + */
14.357 + public boolean equals(Object o) {
14.358 + if (o == this)
14.359 + return true;
14.360 + if (!(o instanceof Set))
14.361 + return false;
14.362 + Set<?> set = (Set<?>)(o);
14.363 + Iterator<?> it = set.iterator();
14.364 +
14.365 + // Uses O(n^2) algorithm that is only appropriate
14.366 + // for small sets, which CopyOnWriteArraySets should be.
14.367 +
14.368 + // Use a single snapshot of underlying array
14.369 + Object[] elements = al.getArray();
14.370 + int len = elements.length;
14.371 + // Mark matched elements to avoid re-checking
14.372 + boolean[] matched = new boolean[len];
14.373 + int k = 0;
14.374 + outer: while (it.hasNext()) {
14.375 + if (++k > len)
14.376 + return false;
14.377 + Object x = it.next();
14.378 + for (int i = 0; i < len; ++i) {
14.379 + if (!matched[i] && eq(x, elements[i])) {
14.380 + matched[i] = true;
14.381 + continue outer;
14.382 + }
14.383 + }
14.384 + return false;
14.385 + }
14.386 + return k == len;
14.387 + }
14.388 +
14.389 + /**
14.390 + * Test for equality, coping with nulls.
14.391 + */
14.392 + private static boolean eq(Object o1, Object o2) {
14.393 + return (o1 == null ? o2 == null : o1.equals(o2));
14.394 + }
14.395 +}
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/CountDownLatch.java Sat Mar 19 10:48:29 2016 +0100
15.3 @@ -0,0 +1,320 @@
15.4 +/*
15.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
15.6 + *
15.7 + * This code is free software; you can redistribute it and/or modify it
15.8 + * under the terms of the GNU General Public License version 2 only, as
15.9 + * published by the Free Software Foundation. Oracle designates this
15.10 + * particular file as subject to the "Classpath" exception as provided
15.11 + * by Oracle in the LICENSE file that accompanied this code.
15.12 + *
15.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
15.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15.16 + * version 2 for more details (a copy is included in the LICENSE file that
15.17 + * accompanied this code).
15.18 + *
15.19 + * You should have received a copy of the GNU General Public License version
15.20 + * 2 along with this work; if not, write to the Free Software Foundation,
15.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
15.22 + *
15.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
15.24 + * or visit www.oracle.com if you need additional information or have any
15.25 + * questions.
15.26 + */
15.27 +
15.28 +/*
15.29 + * This file is available under and governed by the GNU General Public
15.30 + * License version 2 only, as published by the Free Software Foundation.
15.31 + * However, the following notice accompanied the original version of this
15.32 + * file:
15.33 + *
15.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
15.35 + * Expert Group and released to the public domain, as explained at
15.36 + * http://creativecommons.org/publicdomain/zero/1.0/
15.37 + */
15.38 +
15.39 +package java.util.concurrent;
15.40 +import java.util.concurrent.locks.*;
15.41 +import java.util.concurrent.atomic.*;
15.42 +
15.43 +/**
15.44 + * A synchronization aid that allows one or more threads to wait until
15.45 + * a set of operations being performed in other threads completes.
15.46 + *
15.47 + * <p>A {@code CountDownLatch} is initialized with a given <em>count</em>.
15.48 + * The {@link #await await} methods block until the current count reaches
15.49 + * zero due to invocations of the {@link #countDown} method, after which
15.50 + * all waiting threads are released and any subsequent invocations of
15.51 + * {@link #await await} return immediately. This is a one-shot phenomenon
15.52 + * -- the count cannot be reset. If you need a version that resets the
15.53 + * count, consider using a {@link CyclicBarrier}.
15.54 + *
15.55 + * <p>A {@code CountDownLatch} is a versatile synchronization tool
15.56 + * and can be used for a number of purposes. A
15.57 + * {@code CountDownLatch} initialized with a count of one serves as a
15.58 + * simple on/off latch, or gate: all threads invoking {@link #await await}
15.59 + * wait at the gate until it is opened by a thread invoking {@link
15.60 + * #countDown}. A {@code CountDownLatch} initialized to <em>N</em>
15.61 + * can be used to make one thread wait until <em>N</em> threads have
15.62 + * completed some action, or some action has been completed N times.
15.63 + *
15.64 + * <p>A useful property of a {@code CountDownLatch} is that it
15.65 + * doesn't require that threads calling {@code countDown} wait for
15.66 + * the count to reach zero before proceeding, it simply prevents any
15.67 + * thread from proceeding past an {@link #await await} until all
15.68 + * threads could pass.
15.69 + *
15.70 + * <p><b>Sample usage:</b> Here is a pair of classes in which a group
15.71 + * of worker threads use two countdown latches:
15.72 + * <ul>
15.73 + * <li>The first is a start signal that prevents any worker from proceeding
15.74 + * until the driver is ready for them to proceed;
15.75 + * <li>The second is a completion signal that allows the driver to wait
15.76 + * until all workers have completed.
15.77 + * </ul>
15.78 + *
15.79 + * <pre>
15.80 + * class Driver { // ...
15.81 + * void main() throws InterruptedException {
15.82 + * CountDownLatch startSignal = new CountDownLatch(1);
15.83 + * CountDownLatch doneSignal = new CountDownLatch(N);
15.84 + *
15.85 + * for (int i = 0; i < N; ++i) // create and start threads
15.86 + * new Thread(new Worker(startSignal, doneSignal)).start();
15.87 + *
15.88 + * doSomethingElse(); // don't let run yet
15.89 + * startSignal.countDown(); // let all threads proceed
15.90 + * doSomethingElse();
15.91 + * doneSignal.await(); // wait for all to finish
15.92 + * }
15.93 + * }
15.94 + *
15.95 + * class Worker implements Runnable {
15.96 + * private final CountDownLatch startSignal;
15.97 + * private final CountDownLatch doneSignal;
15.98 + * Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
15.99 + * this.startSignal = startSignal;
15.100 + * this.doneSignal = doneSignal;
15.101 + * }
15.102 + * public void run() {
15.103 + * try {
15.104 + * startSignal.await();
15.105 + * doWork();
15.106 + * doneSignal.countDown();
15.107 + * } catch (InterruptedException ex) {} // return;
15.108 + * }
15.109 + *
15.110 + * void doWork() { ... }
15.111 + * }
15.112 + *
15.113 + * </pre>
15.114 + *
15.115 + * <p>Another typical usage would be to divide a problem into N parts,
15.116 + * describe each part with a Runnable that executes that portion and
15.117 + * counts down on the latch, and queue all the Runnables to an
15.118 + * Executor. When all sub-parts are complete, the coordinating thread
15.119 + * will be able to pass through await. (When threads must repeatedly
15.120 + * count down in this way, instead use a {@link CyclicBarrier}.)
15.121 + *
15.122 + * <pre>
15.123 + * class Driver2 { // ...
15.124 + * void main() throws InterruptedException {
15.125 + * CountDownLatch doneSignal = new CountDownLatch(N);
15.126 + * Executor e = ...
15.127 + *
15.128 + * for (int i = 0; i < N; ++i) // create and start threads
15.129 + * e.execute(new WorkerRunnable(doneSignal, i));
15.130 + *
15.131 + * doneSignal.await(); // wait for all to finish
15.132 + * }
15.133 + * }
15.134 + *
15.135 + * class WorkerRunnable implements Runnable {
15.136 + * private final CountDownLatch doneSignal;
15.137 + * private final int i;
15.138 + * WorkerRunnable(CountDownLatch doneSignal, int i) {
15.139 + * this.doneSignal = doneSignal;
15.140 + * this.i = i;
15.141 + * }
15.142 + * public void run() {
15.143 + * try {
15.144 + * doWork(i);
15.145 + * doneSignal.countDown();
15.146 + * } catch (InterruptedException ex) {} // return;
15.147 + * }
15.148 + *
15.149 + * void doWork() { ... }
15.150 + * }
15.151 + *
15.152 + * </pre>
15.153 + *
15.154 + * <p>Memory consistency effects: Until the count reaches
15.155 + * zero, actions in a thread prior to calling
15.156 + * {@code countDown()}
15.157 + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
15.158 + * actions following a successful return from a corresponding
15.159 + * {@code await()} in another thread.
15.160 + *
15.161 + * @since 1.5
15.162 + * @author Doug Lea
15.163 + */
15.164 +public class CountDownLatch {
15.165 + /**
15.166 + * Synchronization control For CountDownLatch.
15.167 + * Uses AQS state to represent count.
15.168 + */
15.169 + private static final class Sync extends AbstractQueuedSynchronizer {
15.170 + private static final long serialVersionUID = 4982264981922014374L;
15.171 +
15.172 + Sync(int count) {
15.173 + setState(count);
15.174 + }
15.175 +
15.176 + int getCount() {
15.177 + return getState();
15.178 + }
15.179 +
15.180 + protected int tryAcquireShared(int acquires) {
15.181 + return (getState() == 0) ? 1 : -1;
15.182 + }
15.183 +
15.184 + protected boolean tryReleaseShared(int releases) {
15.185 + // Decrement count; signal when transition to zero
15.186 + for (;;) {
15.187 + int c = getState();
15.188 + if (c == 0)
15.189 + return false;
15.190 + int nextc = c-1;
15.191 + if (compareAndSetState(c, nextc))
15.192 + return nextc == 0;
15.193 + }
15.194 + }
15.195 + }
15.196 +
15.197 + private final Sync sync;
15.198 +
15.199 + /**
15.200 + * Constructs a {@code CountDownLatch} initialized with the given count.
15.201 + *
15.202 + * @param count the number of times {@link #countDown} must be invoked
15.203 + * before threads can pass through {@link #await}
15.204 + * @throws IllegalArgumentException if {@code count} is negative
15.205 + */
15.206 + public CountDownLatch(int count) {
15.207 + if (count < 0) throw new IllegalArgumentException("count < 0");
15.208 + this.sync = new Sync(count);
15.209 + }
15.210 +
15.211 + /**
15.212 + * Causes the current thread to wait until the latch has counted down to
15.213 + * zero, unless the thread is {@linkplain Thread#interrupt interrupted}.
15.214 + *
15.215 + * <p>If the current count is zero then this method returns immediately.
15.216 + *
15.217 + * <p>If the current count is greater than zero then the current
15.218 + * thread becomes disabled for thread scheduling purposes and lies
15.219 + * dormant until one of two things happen:
15.220 + * <ul>
15.221 + * <li>The count reaches zero due to invocations of the
15.222 + * {@link #countDown} method; or
15.223 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
15.224 + * the current thread.
15.225 + * </ul>
15.226 + *
15.227 + * <p>If the current thread:
15.228 + * <ul>
15.229 + * <li>has its interrupted status set on entry to this method; or
15.230 + * <li>is {@linkplain Thread#interrupt interrupted} while waiting,
15.231 + * </ul>
15.232 + * then {@link InterruptedException} is thrown and the current thread's
15.233 + * interrupted status is cleared.
15.234 + *
15.235 + * @throws InterruptedException if the current thread is interrupted
15.236 + * while waiting
15.237 + */
15.238 + public void await() throws InterruptedException {
15.239 + sync.acquireSharedInterruptibly(1);
15.240 + }
15.241 +
15.242 + /**
15.243 + * Causes the current thread to wait until the latch has counted down to
15.244 + * zero, unless the thread is {@linkplain Thread#interrupt interrupted},
15.245 + * or the specified waiting time elapses.
15.246 + *
15.247 + * <p>If the current count is zero then this method returns immediately
15.248 + * with the value {@code true}.
15.249 + *
15.250 + * <p>If the current count is greater than zero then the current
15.251 + * thread becomes disabled for thread scheduling purposes and lies
15.252 + * dormant until one of three things happen:
15.253 + * <ul>
15.254 + * <li>The count reaches zero due to invocations of the
15.255 + * {@link #countDown} method; or
15.256 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
15.257 + * the current thread; or
15.258 + * <li>The specified waiting time elapses.
15.259 + * </ul>
15.260 + *
15.261 + * <p>If the count reaches zero then the method returns with the
15.262 + * value {@code true}.
15.263 + *
15.264 + * <p>If the current thread:
15.265 + * <ul>
15.266 + * <li>has its interrupted status set on entry to this method; or
15.267 + * <li>is {@linkplain Thread#interrupt interrupted} while waiting,
15.268 + * </ul>
15.269 + * then {@link InterruptedException} is thrown and the current thread's
15.270 + * interrupted status is cleared.
15.271 + *
15.272 + * <p>If the specified waiting time elapses then the value {@code false}
15.273 + * is returned. If the time is less than or equal to zero, the method
15.274 + * will not wait at all.
15.275 + *
15.276 + * @param timeout the maximum time to wait
15.277 + * @param unit the time unit of the {@code timeout} argument
15.278 + * @return {@code true} if the count reached zero and {@code false}
15.279 + * if the waiting time elapsed before the count reached zero
15.280 + * @throws InterruptedException if the current thread is interrupted
15.281 + * while waiting
15.282 + */
15.283 + public boolean await(long timeout, TimeUnit unit)
15.284 + throws InterruptedException {
15.285 + return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
15.286 + }
15.287 +
15.288 + /**
15.289 + * Decrements the count of the latch, releasing all waiting threads if
15.290 + * the count reaches zero.
15.291 + *
15.292 + * <p>If the current count is greater than zero then it is decremented.
15.293 + * If the new count is zero then all waiting threads are re-enabled for
15.294 + * thread scheduling purposes.
15.295 + *
15.296 + * <p>If the current count equals zero then nothing happens.
15.297 + */
15.298 + public void countDown() {
15.299 + sync.releaseShared(1);
15.300 + }
15.301 +
15.302 + /**
15.303 + * Returns the current count.
15.304 + *
15.305 + * <p>This method is typically used for debugging and testing purposes.
15.306 + *
15.307 + * @return the current count
15.308 + */
15.309 + public long getCount() {
15.310 + return sync.getCount();
15.311 + }
15.312 +
15.313 + /**
15.314 + * Returns a string identifying this latch, as well as its state.
15.315 + * The state, in brackets, includes the String {@code "Count ="}
15.316 + * followed by the current count.
15.317 + *
15.318 + * @return a string identifying this latch, as well as its state
15.319 + */
15.320 + public String toString() {
15.321 + return super.toString() + "[Count = " + sync.getCount() + "]";
15.322 + }
15.323 +}
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
16.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/CyclicBarrier.java Sat Mar 19 10:48:29 2016 +0100
16.3 @@ -0,0 +1,483 @@
16.4 +/*
16.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
16.6 + *
16.7 + * This code is free software; you can redistribute it and/or modify it
16.8 + * under the terms of the GNU General Public License version 2 only, as
16.9 + * published by the Free Software Foundation. Oracle designates this
16.10 + * particular file as subject to the "Classpath" exception as provided
16.11 + * by Oracle in the LICENSE file that accompanied this code.
16.12 + *
16.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
16.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16.16 + * version 2 for more details (a copy is included in the LICENSE file that
16.17 + * accompanied this code).
16.18 + *
16.19 + * You should have received a copy of the GNU General Public License version
16.20 + * 2 along with this work; if not, write to the Free Software Foundation,
16.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
16.22 + *
16.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
16.24 + * or visit www.oracle.com if you need additional information or have any
16.25 + * questions.
16.26 + */
16.27 +
16.28 +/*
16.29 + * This file is available under and governed by the GNU General Public
16.30 + * License version 2 only, as published by the Free Software Foundation.
16.31 + * However, the following notice accompanied the original version of this
16.32 + * file:
16.33 + *
16.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
16.35 + * Expert Group and released to the public domain, as explained at
16.36 + * http://creativecommons.org/publicdomain/zero/1.0/
16.37 + */
16.38 +
16.39 +package java.util.concurrent;
16.40 +import java.util.concurrent.locks.*;
16.41 +
16.42 +/**
16.43 + * A synchronization aid that allows a set of threads to all wait for
16.44 + * each other to reach a common barrier point. CyclicBarriers are
16.45 + * useful in programs involving a fixed sized party of threads that
16.46 + * must occasionally wait for each other. The barrier is called
16.47 + * <em>cyclic</em> because it can be re-used after the waiting threads
16.48 + * are released.
16.49 + *
16.50 + * <p>A <tt>CyclicBarrier</tt> supports an optional {@link Runnable} command
16.51 + * that is run once per barrier point, after the last thread in the party
16.52 + * arrives, but before any threads are released.
16.53 + * This <em>barrier action</em> is useful
16.54 + * for updating shared-state before any of the parties continue.
16.55 + *
16.56 + * <p><b>Sample usage:</b> Here is an example of
16.57 + * using a barrier in a parallel decomposition design:
16.58 + * <pre>
16.59 + * class Solver {
16.60 + * final int N;
16.61 + * final float[][] data;
16.62 + * final CyclicBarrier barrier;
16.63 + *
16.64 + * class Worker implements Runnable {
16.65 + * int myRow;
16.66 + * Worker(int row) { myRow = row; }
16.67 + * public void run() {
16.68 + * while (!done()) {
16.69 + * processRow(myRow);
16.70 + *
16.71 + * try {
16.72 + * barrier.await();
16.73 + * } catch (InterruptedException ex) {
16.74 + * return;
16.75 + * } catch (BrokenBarrierException ex) {
16.76 + * return;
16.77 + * }
16.78 + * }
16.79 + * }
16.80 + * }
16.81 + *
16.82 + * public Solver(float[][] matrix) {
16.83 + * data = matrix;
16.84 + * N = matrix.length;
16.85 + * barrier = new CyclicBarrier(N,
16.86 + * new Runnable() {
16.87 + * public void run() {
16.88 + * mergeRows(...);
16.89 + * }
16.90 + * });
16.91 + * for (int i = 0; i < N; ++i)
16.92 + * new Thread(new Worker(i)).start();
16.93 + *
16.94 + * waitUntilDone();
16.95 + * }
16.96 + * }
16.97 + * </pre>
16.98 + * Here, each worker thread processes a row of the matrix then waits at the
16.99 + * barrier until all rows have been processed. When all rows are processed
16.100 + * the supplied {@link Runnable} barrier action is executed and merges the
16.101 + * rows. If the merger
16.102 + * determines that a solution has been found then <tt>done()</tt> will return
16.103 + * <tt>true</tt> and each worker will terminate.
16.104 + *
16.105 + * <p>If the barrier action does not rely on the parties being suspended when
16.106 + * it is executed, then any of the threads in the party could execute that
16.107 + * action when it is released. To facilitate this, each invocation of
16.108 + * {@link #await} returns the arrival index of that thread at the barrier.
16.109 + * You can then choose which thread should execute the barrier action, for
16.110 + * example:
16.111 + * <pre> if (barrier.await() == 0) {
16.112 + * // log the completion of this iteration
16.113 + * }</pre>
16.114 + *
16.115 + * <p>The <tt>CyclicBarrier</tt> uses an all-or-none breakage model
16.116 + * for failed synchronization attempts: If a thread leaves a barrier
16.117 + * point prematurely because of interruption, failure, or timeout, all
16.118 + * other threads waiting at that barrier point will also leave
16.119 + * abnormally via {@link BrokenBarrierException} (or
16.120 + * {@link InterruptedException} if they too were interrupted at about
16.121 + * the same time).
16.122 + *
16.123 + * <p>Memory consistency effects: Actions in a thread prior to calling
16.124 + * {@code await()}
16.125 + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
16.126 + * actions that are part of the barrier action, which in turn
16.127 + * <i>happen-before</i> actions following a successful return from the
16.128 + * corresponding {@code await()} in other threads.
16.129 + *
16.130 + * @since 1.5
16.131 + * @see CountDownLatch
16.132 + *
16.133 + * @author Doug Lea
16.134 + */
16.135 +public class CyclicBarrier {
16.136 + /**
16.137 + * Each use of the barrier is represented as a generation instance.
16.138 + * The generation changes whenever the barrier is tripped, or
16.139 + * is reset. There can be many generations associated with threads
16.140 + * using the barrier - due to the non-deterministic way the lock
16.141 + * may be allocated to waiting threads - but only one of these
16.142 + * can be active at a time (the one to which <tt>count</tt> applies)
16.143 + * and all the rest are either broken or tripped.
16.144 + * There need not be an active generation if there has been a break
16.145 + * but no subsequent reset.
16.146 + */
16.147 + private static class Generation {
16.148 + boolean broken = false;
16.149 + }
16.150 +
16.151 + /** The lock for guarding barrier entry */
16.152 + private final ReentrantLock lock = new ReentrantLock();
16.153 + /** Condition to wait on until tripped */
16.154 + private final Condition trip = lock.newCondition();
16.155 + /** The number of parties */
16.156 + private final int parties;
16.157 + /* The command to run when tripped */
16.158 + private final Runnable barrierCommand;
16.159 + /** The current generation */
16.160 + private Generation generation = new Generation();
16.161 +
16.162 + /**
16.163 + * Number of parties still waiting. Counts down from parties to 0
16.164 + * on each generation. It is reset to parties on each new
16.165 + * generation or when broken.
16.166 + */
16.167 + private int count;
16.168 +
16.169 + /**
16.170 + * Updates state on barrier trip and wakes up everyone.
16.171 + * Called only while holding lock.
16.172 + */
16.173 + private void nextGeneration() {
16.174 + // signal completion of last generation
16.175 + trip.signalAll();
16.176 + // set up next generation
16.177 + count = parties;
16.178 + generation = new Generation();
16.179 + }
16.180 +
16.181 + /**
16.182 + * Sets current barrier generation as broken and wakes up everyone.
16.183 + * Called only while holding lock.
16.184 + */
16.185 + private void breakBarrier() {
16.186 + generation.broken = true;
16.187 + count = parties;
16.188 + trip.signalAll();
16.189 + }
16.190 +
16.191 + /**
16.192 + * Main barrier code, covering the various policies.
16.193 + */
16.194 + private int dowait(boolean timed, long nanos)
16.195 + throws InterruptedException, BrokenBarrierException,
16.196 + TimeoutException {
16.197 + final ReentrantLock lock = this.lock;
16.198 + lock.lock();
16.199 + try {
16.200 + final Generation g = generation;
16.201 +
16.202 + if (g.broken)
16.203 + throw new BrokenBarrierException();
16.204 +
16.205 + if (Thread.interrupted()) {
16.206 + breakBarrier();
16.207 + throw new InterruptedException();
16.208 + }
16.209 +
16.210 + int index = --count;
16.211 + if (index == 0) { // tripped
16.212 + boolean ranAction = false;
16.213 + try {
16.214 + final Runnable command = barrierCommand;
16.215 + if (command != null)
16.216 + command.run();
16.217 + ranAction = true;
16.218 + nextGeneration();
16.219 + return 0;
16.220 + } finally {
16.221 + if (!ranAction)
16.222 + breakBarrier();
16.223 + }
16.224 + }
16.225 +
16.226 + // loop until tripped, broken, interrupted, or timed out
16.227 + for (;;) {
16.228 + try {
16.229 + if (!timed)
16.230 + trip.await();
16.231 + else if (nanos > 0L)
16.232 + nanos = trip.awaitNanos(nanos);
16.233 + } catch (InterruptedException ie) {
16.234 + if (g == generation && ! g.broken) {
16.235 + breakBarrier();
16.236 + throw ie;
16.237 + } else {
16.238 + // We're about to finish waiting even if we had not
16.239 + // been interrupted, so this interrupt is deemed to
16.240 + // "belong" to subsequent execution.
16.241 + Thread.currentThread().interrupt();
16.242 + }
16.243 + }
16.244 +
16.245 + if (g.broken)
16.246 + throw new BrokenBarrierException();
16.247 +
16.248 + if (g != generation)
16.249 + return index;
16.250 +
16.251 + if (timed && nanos <= 0L) {
16.252 + breakBarrier();
16.253 + throw new TimeoutException();
16.254 + }
16.255 + }
16.256 + } finally {
16.257 + lock.unlock();
16.258 + }
16.259 + }
16.260 +
16.261 + /**
16.262 + * Creates a new <tt>CyclicBarrier</tt> that will trip when the
16.263 + * given number of parties (threads) are waiting upon it, and which
16.264 + * will execute the given barrier action when the barrier is tripped,
16.265 + * performed by the last thread entering the barrier.
16.266 + *
16.267 + * @param parties the number of threads that must invoke {@link #await}
16.268 + * before the barrier is tripped
16.269 + * @param barrierAction the command to execute when the barrier is
16.270 + * tripped, or {@code null} if there is no action
16.271 + * @throws IllegalArgumentException if {@code parties} is less than 1
16.272 + */
16.273 + public CyclicBarrier(int parties, Runnable barrierAction) {
16.274 + if (parties <= 0) throw new IllegalArgumentException();
16.275 + this.parties = parties;
16.276 + this.count = parties;
16.277 + this.barrierCommand = barrierAction;
16.278 + }
16.279 +
16.280 + /**
16.281 + * Creates a new <tt>CyclicBarrier</tt> that will trip when the
16.282 + * given number of parties (threads) are waiting upon it, and
16.283 + * does not perform a predefined action when the barrier is tripped.
16.284 + *
16.285 + * @param parties the number of threads that must invoke {@link #await}
16.286 + * before the barrier is tripped
16.287 + * @throws IllegalArgumentException if {@code parties} is less than 1
16.288 + */
16.289 + public CyclicBarrier(int parties) {
16.290 + this(parties, null);
16.291 + }
16.292 +
16.293 + /**
16.294 + * Returns the number of parties required to trip this barrier.
16.295 + *
16.296 + * @return the number of parties required to trip this barrier
16.297 + */
16.298 + public int getParties() {
16.299 + return parties;
16.300 + }
16.301 +
16.302 + /**
16.303 + * Waits until all {@linkplain #getParties parties} have invoked
16.304 + * <tt>await</tt> on this barrier.
16.305 + *
16.306 + * <p>If the current thread is not the last to arrive then it is
16.307 + * disabled for thread scheduling purposes and lies dormant until
16.308 + * one of the following things happens:
16.309 + * <ul>
16.310 + * <li>The last thread arrives; or
16.311 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
16.312 + * the current thread; or
16.313 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
16.314 + * one of the other waiting threads; or
16.315 + * <li>Some other thread times out while waiting for barrier; or
16.316 + * <li>Some other thread invokes {@link #reset} on this barrier.
16.317 + * </ul>
16.318 + *
16.319 + * <p>If the current thread:
16.320 + * <ul>
16.321 + * <li>has its interrupted status set on entry to this method; or
16.322 + * <li>is {@linkplain Thread#interrupt interrupted} while waiting
16.323 + * </ul>
16.324 + * then {@link InterruptedException} is thrown and the current thread's
16.325 + * interrupted status is cleared.
16.326 + *
16.327 + * <p>If the barrier is {@link #reset} while any thread is waiting,
16.328 + * or if the barrier {@linkplain #isBroken is broken} when
16.329 + * <tt>await</tt> is invoked, or while any thread is waiting, then
16.330 + * {@link BrokenBarrierException} is thrown.
16.331 + *
16.332 + * <p>If any thread is {@linkplain Thread#interrupt interrupted} while waiting,
16.333 + * then all other waiting threads will throw
16.334 + * {@link BrokenBarrierException} and the barrier is placed in the broken
16.335 + * state.
16.336 + *
16.337 + * <p>If the current thread is the last thread to arrive, and a
16.338 + * non-null barrier action was supplied in the constructor, then the
16.339 + * current thread runs the action before allowing the other threads to
16.340 + * continue.
16.341 + * If an exception occurs during the barrier action then that exception
16.342 + * will be propagated in the current thread and the barrier is placed in
16.343 + * the broken state.
16.344 + *
16.345 + * @return the arrival index of the current thread, where index
16.346 + * <tt>{@link #getParties()} - 1</tt> indicates the first
16.347 + * to arrive and zero indicates the last to arrive
16.348 + * @throws InterruptedException if the current thread was interrupted
16.349 + * while waiting
16.350 + * @throws BrokenBarrierException if <em>another</em> thread was
16.351 + * interrupted or timed out while the current thread was
16.352 + * waiting, or the barrier was reset, or the barrier was
16.353 + * broken when {@code await} was called, or the barrier
16.354 + * action (if present) failed due an exception.
16.355 + */
16.356 + public int await() throws InterruptedException, BrokenBarrierException {
16.357 + try {
16.358 + return dowait(false, 0L);
16.359 + } catch (TimeoutException toe) {
16.360 + throw new Error(toe); // cannot happen;
16.361 + }
16.362 + }
16.363 +
16.364 + /**
16.365 + * Waits until all {@linkplain #getParties parties} have invoked
16.366 + * <tt>await</tt> on this barrier, or the specified waiting time elapses.
16.367 + *
16.368 + * <p>If the current thread is not the last to arrive then it is
16.369 + * disabled for thread scheduling purposes and lies dormant until
16.370 + * one of the following things happens:
16.371 + * <ul>
16.372 + * <li>The last thread arrives; or
16.373 + * <li>The specified timeout elapses; or
16.374 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
16.375 + * the current thread; or
16.376 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
16.377 + * one of the other waiting threads; or
16.378 + * <li>Some other thread times out while waiting for barrier; or
16.379 + * <li>Some other thread invokes {@link #reset} on this barrier.
16.380 + * </ul>
16.381 + *
16.382 + * <p>If the current thread:
16.383 + * <ul>
16.384 + * <li>has its interrupted status set on entry to this method; or
16.385 + * <li>is {@linkplain Thread#interrupt interrupted} while waiting
16.386 + * </ul>
16.387 + * then {@link InterruptedException} is thrown and the current thread's
16.388 + * interrupted status is cleared.
16.389 + *
16.390 + * <p>If the specified waiting time elapses then {@link TimeoutException}
16.391 + * is thrown. If the time is less than or equal to zero, the
16.392 + * method will not wait at all.
16.393 + *
16.394 + * <p>If the barrier is {@link #reset} while any thread is waiting,
16.395 + * or if the barrier {@linkplain #isBroken is broken} when
16.396 + * <tt>await</tt> is invoked, or while any thread is waiting, then
16.397 + * {@link BrokenBarrierException} is thrown.
16.398 + *
16.399 + * <p>If any thread is {@linkplain Thread#interrupt interrupted} while
16.400 + * waiting, then all other waiting threads will throw {@link
16.401 + * BrokenBarrierException} and the barrier is placed in the broken
16.402 + * state.
16.403 + *
16.404 + * <p>If the current thread is the last thread to arrive, and a
16.405 + * non-null barrier action was supplied in the constructor, then the
16.406 + * current thread runs the action before allowing the other threads to
16.407 + * continue.
16.408 + * If an exception occurs during the barrier action then that exception
16.409 + * will be propagated in the current thread and the barrier is placed in
16.410 + * the broken state.
16.411 + *
16.412 + * @param timeout the time to wait for the barrier
16.413 + * @param unit the time unit of the timeout parameter
16.414 + * @return the arrival index of the current thread, where index
16.415 + * <tt>{@link #getParties()} - 1</tt> indicates the first
16.416 + * to arrive and zero indicates the last to arrive
16.417 + * @throws InterruptedException if the current thread was interrupted
16.418 + * while waiting
16.419 + * @throws TimeoutException if the specified timeout elapses
16.420 + * @throws BrokenBarrierException if <em>another</em> thread was
16.421 + * interrupted or timed out while the current thread was
16.422 + * waiting, or the barrier was reset, or the barrier was broken
16.423 + * when {@code await} was called, or the barrier action (if
16.424 + * present) failed due an exception
16.425 + */
16.426 + public int await(long timeout, TimeUnit unit)
16.427 + throws InterruptedException,
16.428 + BrokenBarrierException,
16.429 + TimeoutException {
16.430 + return dowait(true, unit.toNanos(timeout));
16.431 + }
16.432 +
16.433 + /**
16.434 + * Queries if this barrier is in a broken state.
16.435 + *
16.436 + * @return {@code true} if one or more parties broke out of this
16.437 + * barrier due to interruption or timeout since
16.438 + * construction or the last reset, or a barrier action
16.439 + * failed due to an exception; {@code false} otherwise.
16.440 + */
16.441 + public boolean isBroken() {
16.442 + final ReentrantLock lock = this.lock;
16.443 + lock.lock();
16.444 + try {
16.445 + return generation.broken;
16.446 + } finally {
16.447 + lock.unlock();
16.448 + }
16.449 + }
16.450 +
16.451 + /**
16.452 + * Resets the barrier to its initial state. If any parties are
16.453 + * currently waiting at the barrier, they will return with a
16.454 + * {@link BrokenBarrierException}. Note that resets <em>after</em>
16.455 + * a breakage has occurred for other reasons can be complicated to
16.456 + * carry out; threads need to re-synchronize in some other way,
16.457 + * and choose one to perform the reset. It may be preferable to
16.458 + * instead create a new barrier for subsequent use.
16.459 + */
16.460 + public void reset() {
16.461 + final ReentrantLock lock = this.lock;
16.462 + lock.lock();
16.463 + try {
16.464 + breakBarrier(); // break the current generation
16.465 + nextGeneration(); // start a new generation
16.466 + } finally {
16.467 + lock.unlock();
16.468 + }
16.469 + }
16.470 +
16.471 + /**
16.472 + * Returns the number of parties currently waiting at the barrier.
16.473 + * This method is primarily useful for debugging and assertions.
16.474 + *
16.475 + * @return the number of parties currently blocked in {@link #await}
16.476 + */
16.477 + public int getNumberWaiting() {
16.478 + final ReentrantLock lock = this.lock;
16.479 + lock.lock();
16.480 + try {
16.481 + return parties - count;
16.482 + } finally {
16.483 + lock.unlock();
16.484 + }
16.485 + }
16.486 +}
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
17.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/DelayQueue.java Sat Mar 19 10:48:29 2016 +0100
17.3 @@ -0,0 +1,546 @@
17.4 +/*
17.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
17.6 + *
17.7 + * This code is free software; you can redistribute it and/or modify it
17.8 + * under the terms of the GNU General Public License version 2 only, as
17.9 + * published by the Free Software Foundation. Oracle designates this
17.10 + * particular file as subject to the "Classpath" exception as provided
17.11 + * by Oracle in the LICENSE file that accompanied this code.
17.12 + *
17.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
17.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17.16 + * version 2 for more details (a copy is included in the LICENSE file that
17.17 + * accompanied this code).
17.18 + *
17.19 + * You should have received a copy of the GNU General Public License version
17.20 + * 2 along with this work; if not, write to the Free Software Foundation,
17.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17.22 + *
17.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
17.24 + * or visit www.oracle.com if you need additional information or have any
17.25 + * questions.
17.26 + */
17.27 +
17.28 +/*
17.29 + * This file is available under and governed by the GNU General Public
17.30 + * License version 2 only, as published by the Free Software Foundation.
17.31 + * However, the following notice accompanied the original version of this
17.32 + * file:
17.33 + *
17.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
17.35 + * Expert Group and released to the public domain, as explained at
17.36 + * http://creativecommons.org/publicdomain/zero/1.0/
17.37 + */
17.38 +
17.39 +
17.40 +package java.util.concurrent;
17.41 +import java.util.concurrent.locks.*;
17.42 +import java.util.*;
17.43 +
17.44 +/**
17.45 + * An unbounded {@linkplain BlockingQueue blocking queue} of
17.46 + * <tt>Delayed</tt> elements, in which an element can only be taken
17.47 + * when its delay has expired. The <em>head</em> of the queue is that
17.48 + * <tt>Delayed</tt> element whose delay expired furthest in the
17.49 + * past. If no delay has expired there is no head and <tt>poll</tt>
17.50 + * will return <tt>null</tt>. Expiration occurs when an element's
17.51 + * <tt>getDelay(TimeUnit.NANOSECONDS)</tt> method returns a value less
17.52 + * than or equal to zero. Even though unexpired elements cannot be
17.53 + * removed using <tt>take</tt> or <tt>poll</tt>, they are otherwise
17.54 + * treated as normal elements. For example, the <tt>size</tt> method
17.55 + * returns the count of both expired and unexpired elements.
17.56 + * This queue does not permit null elements.
17.57 + *
17.58 + * <p>This class and its iterator implement all of the
17.59 + * <em>optional</em> methods of the {@link Collection} and {@link
17.60 + * Iterator} interfaces.
17.61 + *
17.62 + * <p>This class is a member of the
17.63 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
17.64 + * Java Collections Framework</a>.
17.65 + *
17.66 + * @since 1.5
17.67 + * @author Doug Lea
17.68 + * @param <E> the type of elements held in this collection
17.69 + */
17.70 +
17.71 +public class DelayQueue<E extends Delayed> extends AbstractQueue<E>
17.72 + implements BlockingQueue<E> {
17.73 +
17.74 + private transient final ReentrantLock lock = new ReentrantLock();
17.75 + private final PriorityQueue<E> q = new PriorityQueue<E>();
17.76 +
17.77 + /**
17.78 + * Thread designated to wait for the element at the head of
17.79 + * the queue. This variant of the Leader-Follower pattern
17.80 + * (http://www.cs.wustl.edu/~schmidt/POSA/POSA2/) serves to
17.81 + * minimize unnecessary timed waiting. When a thread becomes
17.82 + * the leader, it waits only for the next delay to elapse, but
17.83 + * other threads await indefinitely. The leader thread must
17.84 + * signal some other thread before returning from take() or
17.85 + * poll(...), unless some other thread becomes leader in the
17.86 + * interim. Whenever the head of the queue is replaced with
17.87 + * an element with an earlier expiration time, the leader
17.88 + * field is invalidated by being reset to null, and some
17.89 + * waiting thread, but not necessarily the current leader, is
17.90 + * signalled. So waiting threads must be prepared to acquire
17.91 + * and lose leadership while waiting.
17.92 + */
17.93 + private Thread leader = null;
17.94 +
17.95 + /**
17.96 + * Condition signalled when a newer element becomes available
17.97 + * at the head of the queue or a new thread may need to
17.98 + * become leader.
17.99 + */
17.100 + private final Condition available = lock.newCondition();
17.101 +
17.102 + /**
17.103 + * Creates a new <tt>DelayQueue</tt> that is initially empty.
17.104 + */
17.105 + public DelayQueue() {}
17.106 +
17.107 + /**
17.108 + * Creates a <tt>DelayQueue</tt> initially containing the elements of the
17.109 + * given collection of {@link Delayed} instances.
17.110 + *
17.111 + * @param c the collection of elements to initially contain
17.112 + * @throws NullPointerException if the specified collection or any
17.113 + * of its elements are null
17.114 + */
17.115 + public DelayQueue(Collection<? extends E> c) {
17.116 + this.addAll(c);
17.117 + }
17.118 +
17.119 + /**
17.120 + * Inserts the specified element into this delay queue.
17.121 + *
17.122 + * @param e the element to add
17.123 + * @return <tt>true</tt> (as specified by {@link Collection#add})
17.124 + * @throws NullPointerException if the specified element is null
17.125 + */
17.126 + public boolean add(E e) {
17.127 + return offer(e);
17.128 + }
17.129 +
17.130 + /**
17.131 + * Inserts the specified element into this delay queue.
17.132 + *
17.133 + * @param e the element to add
17.134 + * @return <tt>true</tt>
17.135 + * @throws NullPointerException if the specified element is null
17.136 + */
17.137 + public boolean offer(E e) {
17.138 + final ReentrantLock lock = this.lock;
17.139 + lock.lock();
17.140 + try {
17.141 + q.offer(e);
17.142 + if (q.peek() == e) {
17.143 + leader = null;
17.144 + available.signal();
17.145 + }
17.146 + return true;
17.147 + } finally {
17.148 + lock.unlock();
17.149 + }
17.150 + }
17.151 +
17.152 + /**
17.153 + * Inserts the specified element into this delay queue. As the queue is
17.154 + * unbounded this method will never block.
17.155 + *
17.156 + * @param e the element to add
17.157 + * @throws NullPointerException {@inheritDoc}
17.158 + */
17.159 + public void put(E e) {
17.160 + offer(e);
17.161 + }
17.162 +
17.163 + /**
17.164 + * Inserts the specified element into this delay queue. As the queue is
17.165 + * unbounded this method will never block.
17.166 + *
17.167 + * @param e the element to add
17.168 + * @param timeout This parameter is ignored as the method never blocks
17.169 + * @param unit This parameter is ignored as the method never blocks
17.170 + * @return <tt>true</tt>
17.171 + * @throws NullPointerException {@inheritDoc}
17.172 + */
17.173 + public boolean offer(E e, long timeout, TimeUnit unit) {
17.174 + return offer(e);
17.175 + }
17.176 +
17.177 + /**
17.178 + * Retrieves and removes the head of this queue, or returns <tt>null</tt>
17.179 + * if this queue has no elements with an expired delay.
17.180 + *
17.181 + * @return the head of this queue, or <tt>null</tt> if this
17.182 + * queue has no elements with an expired delay
17.183 + */
17.184 + public E poll() {
17.185 + final ReentrantLock lock = this.lock;
17.186 + lock.lock();
17.187 + try {
17.188 + E first = q.peek();
17.189 + if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
17.190 + return null;
17.191 + else
17.192 + return q.poll();
17.193 + } finally {
17.194 + lock.unlock();
17.195 + }
17.196 + }
17.197 +
17.198 + /**
17.199 + * Retrieves and removes the head of this queue, waiting if necessary
17.200 + * until an element with an expired delay is available on this queue.
17.201 + *
17.202 + * @return the head of this queue
17.203 + * @throws InterruptedException {@inheritDoc}
17.204 + */
17.205 + public E take() throws InterruptedException {
17.206 + final ReentrantLock lock = this.lock;
17.207 + lock.lockInterruptibly();
17.208 + try {
17.209 + for (;;) {
17.210 + E first = q.peek();
17.211 + if (first == null)
17.212 + available.await();
17.213 + else {
17.214 + long delay = first.getDelay(TimeUnit.NANOSECONDS);
17.215 + if (delay <= 0)
17.216 + return q.poll();
17.217 + else if (leader != null)
17.218 + available.await();
17.219 + else {
17.220 + Thread thisThread = Thread.currentThread();
17.221 + leader = thisThread;
17.222 + try {
17.223 + available.awaitNanos(delay);
17.224 + } finally {
17.225 + if (leader == thisThread)
17.226 + leader = null;
17.227 + }
17.228 + }
17.229 + }
17.230 + }
17.231 + } finally {
17.232 + if (leader == null && q.peek() != null)
17.233 + available.signal();
17.234 + lock.unlock();
17.235 + }
17.236 + }
17.237 +
17.238 + /**
17.239 + * Retrieves and removes the head of this queue, waiting if necessary
17.240 + * until an element with an expired delay is available on this queue,
17.241 + * or the specified wait time expires.
17.242 + *
17.243 + * @return the head of this queue, or <tt>null</tt> if the
17.244 + * specified waiting time elapses before an element with
17.245 + * an expired delay becomes available
17.246 + * @throws InterruptedException {@inheritDoc}
17.247 + */
17.248 + public E poll(long timeout, TimeUnit unit) throws InterruptedException {
17.249 + long nanos = unit.toNanos(timeout);
17.250 + final ReentrantLock lock = this.lock;
17.251 + lock.lockInterruptibly();
17.252 + try {
17.253 + for (;;) {
17.254 + E first = q.peek();
17.255 + if (first == null) {
17.256 + if (nanos <= 0)
17.257 + return null;
17.258 + else
17.259 + nanos = available.awaitNanos(nanos);
17.260 + } else {
17.261 + long delay = first.getDelay(TimeUnit.NANOSECONDS);
17.262 + if (delay <= 0)
17.263 + return q.poll();
17.264 + if (nanos <= 0)
17.265 + return null;
17.266 + if (nanos < delay || leader != null)
17.267 + nanos = available.awaitNanos(nanos);
17.268 + else {
17.269 + Thread thisThread = Thread.currentThread();
17.270 + leader = thisThread;
17.271 + try {
17.272 + long timeLeft = available.awaitNanos(delay);
17.273 + nanos -= delay - timeLeft;
17.274 + } finally {
17.275 + if (leader == thisThread)
17.276 + leader = null;
17.277 + }
17.278 + }
17.279 + }
17.280 + }
17.281 + } finally {
17.282 + if (leader == null && q.peek() != null)
17.283 + available.signal();
17.284 + lock.unlock();
17.285 + }
17.286 + }
17.287 +
17.288 + /**
17.289 + * Retrieves, but does not remove, the head of this queue, or
17.290 + * returns <tt>null</tt> if this queue is empty. Unlike
17.291 + * <tt>poll</tt>, if no expired elements are available in the queue,
17.292 + * this method returns the element that will expire next,
17.293 + * if one exists.
17.294 + *
17.295 + * @return the head of this queue, or <tt>null</tt> if this
17.296 + * queue is empty.
17.297 + */
17.298 + public E peek() {
17.299 + final ReentrantLock lock = this.lock;
17.300 + lock.lock();
17.301 + try {
17.302 + return q.peek();
17.303 + } finally {
17.304 + lock.unlock();
17.305 + }
17.306 + }
17.307 +
17.308 + public int size() {
17.309 + final ReentrantLock lock = this.lock;
17.310 + lock.lock();
17.311 + try {
17.312 + return q.size();
17.313 + } finally {
17.314 + lock.unlock();
17.315 + }
17.316 + }
17.317 +
17.318 + /**
17.319 + * @throws UnsupportedOperationException {@inheritDoc}
17.320 + * @throws ClassCastException {@inheritDoc}
17.321 + * @throws NullPointerException {@inheritDoc}
17.322 + * @throws IllegalArgumentException {@inheritDoc}
17.323 + */
17.324 + public int drainTo(Collection<? super E> c) {
17.325 + if (c == null)
17.326 + throw new NullPointerException();
17.327 + if (c == this)
17.328 + throw new IllegalArgumentException();
17.329 + final ReentrantLock lock = this.lock;
17.330 + lock.lock();
17.331 + try {
17.332 + int n = 0;
17.333 + for (;;) {
17.334 + E first = q.peek();
17.335 + if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
17.336 + break;
17.337 + c.add(q.poll());
17.338 + ++n;
17.339 + }
17.340 + return n;
17.341 + } finally {
17.342 + lock.unlock();
17.343 + }
17.344 + }
17.345 +
17.346 + /**
17.347 + * @throws UnsupportedOperationException {@inheritDoc}
17.348 + * @throws ClassCastException {@inheritDoc}
17.349 + * @throws NullPointerException {@inheritDoc}
17.350 + * @throws IllegalArgumentException {@inheritDoc}
17.351 + */
17.352 + public int drainTo(Collection<? super E> c, int maxElements) {
17.353 + if (c == null)
17.354 + throw new NullPointerException();
17.355 + if (c == this)
17.356 + throw new IllegalArgumentException();
17.357 + if (maxElements <= 0)
17.358 + return 0;
17.359 + final ReentrantLock lock = this.lock;
17.360 + lock.lock();
17.361 + try {
17.362 + int n = 0;
17.363 + while (n < maxElements) {
17.364 + E first = q.peek();
17.365 + if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
17.366 + break;
17.367 + c.add(q.poll());
17.368 + ++n;
17.369 + }
17.370 + return n;
17.371 + } finally {
17.372 + lock.unlock();
17.373 + }
17.374 + }
17.375 +
17.376 + /**
17.377 + * Atomically removes all of the elements from this delay queue.
17.378 + * The queue will be empty after this call returns.
17.379 + * Elements with an unexpired delay are not waited for; they are
17.380 + * simply discarded from the queue.
17.381 + */
17.382 + public void clear() {
17.383 + final ReentrantLock lock = this.lock;
17.384 + lock.lock();
17.385 + try {
17.386 + q.clear();
17.387 + } finally {
17.388 + lock.unlock();
17.389 + }
17.390 + }
17.391 +
17.392 + /**
17.393 + * Always returns <tt>Integer.MAX_VALUE</tt> because
17.394 + * a <tt>DelayQueue</tt> is not capacity constrained.
17.395 + *
17.396 + * @return <tt>Integer.MAX_VALUE</tt>
17.397 + */
17.398 + public int remainingCapacity() {
17.399 + return Integer.MAX_VALUE;
17.400 + }
17.401 +
17.402 + /**
17.403 + * Returns an array containing all of the elements in this queue.
17.404 + * The returned array elements are in no particular order.
17.405 + *
17.406 + * <p>The returned array will be "safe" in that no references to it are
17.407 + * maintained by this queue. (In other words, this method must allocate
17.408 + * a new array). The caller is thus free to modify the returned array.
17.409 + *
17.410 + * <p>This method acts as bridge between array-based and collection-based
17.411 + * APIs.
17.412 + *
17.413 + * @return an array containing all of the elements in this queue
17.414 + */
17.415 + public Object[] toArray() {
17.416 + final ReentrantLock lock = this.lock;
17.417 + lock.lock();
17.418 + try {
17.419 + return q.toArray();
17.420 + } finally {
17.421 + lock.unlock();
17.422 + }
17.423 + }
17.424 +
17.425 + /**
17.426 + * Returns an array containing all of the elements in this queue; the
17.427 + * runtime type of the returned array is that of the specified array.
17.428 + * The returned array elements are in no particular order.
17.429 + * If the queue fits in the specified array, it is returned therein.
17.430 + * Otherwise, a new array is allocated with the runtime type of the
17.431 + * specified array and the size of this queue.
17.432 + *
17.433 + * <p>If this queue fits in the specified array with room to spare
17.434 + * (i.e., the array has more elements than this queue), the element in
17.435 + * the array immediately following the end of the queue is set to
17.436 + * <tt>null</tt>.
17.437 + *
17.438 + * <p>Like the {@link #toArray()} method, this method acts as bridge between
17.439 + * array-based and collection-based APIs. Further, this method allows
17.440 + * precise control over the runtime type of the output array, and may,
17.441 + * under certain circumstances, be used to save allocation costs.
17.442 + *
17.443 + * <p>The following code can be used to dump a delay queue into a newly
17.444 + * allocated array of <tt>Delayed</tt>:
17.445 + *
17.446 + * <pre>
17.447 + * Delayed[] a = q.toArray(new Delayed[0]);</pre>
17.448 + *
17.449 + * Note that <tt>toArray(new Object[0])</tt> is identical in function to
17.450 + * <tt>toArray()</tt>.
17.451 + *
17.452 + * @param a the array into which the elements of the queue are to
17.453 + * be stored, if it is big enough; otherwise, a new array of the
17.454 + * same runtime type is allocated for this purpose
17.455 + * @return an array containing all of the elements in this queue
17.456 + * @throws ArrayStoreException if the runtime type of the specified array
17.457 + * is not a supertype of the runtime type of every element in
17.458 + * this queue
17.459 + * @throws NullPointerException if the specified array is null
17.460 + */
17.461 + public <T> T[] toArray(T[] a) {
17.462 + final ReentrantLock lock = this.lock;
17.463 + lock.lock();
17.464 + try {
17.465 + return q.toArray(a);
17.466 + } finally {
17.467 + lock.unlock();
17.468 + }
17.469 + }
17.470 +
17.471 + /**
17.472 + * Removes a single instance of the specified element from this
17.473 + * queue, if it is present, whether or not it has expired.
17.474 + */
17.475 + public boolean remove(Object o) {
17.476 + final ReentrantLock lock = this.lock;
17.477 + lock.lock();
17.478 + try {
17.479 + return q.remove(o);
17.480 + } finally {
17.481 + lock.unlock();
17.482 + }
17.483 + }
17.484 +
17.485 + /**
17.486 + * Returns an iterator over all the elements (both expired and
17.487 + * unexpired) in this queue. The iterator does not return the
17.488 + * elements in any particular order.
17.489 + *
17.490 + * <p>The returned iterator is a "weakly consistent" iterator that
17.491 + * will never throw {@link java.util.ConcurrentModificationException
17.492 + * ConcurrentModificationException}, and guarantees to traverse
17.493 + * elements as they existed upon construction of the iterator, and
17.494 + * may (but is not guaranteed to) reflect any modifications
17.495 + * subsequent to construction.
17.496 + *
17.497 + * @return an iterator over the elements in this queue
17.498 + */
17.499 + public Iterator<E> iterator() {
17.500 + return new Itr(toArray());
17.501 + }
17.502 +
17.503 + /**
17.504 + * Snapshot iterator that works off copy of underlying q array.
17.505 + */
17.506 + private class Itr implements Iterator<E> {
17.507 + final Object[] array; // Array of all elements
17.508 + int cursor; // index of next element to return;
17.509 + int lastRet; // index of last element, or -1 if no such
17.510 +
17.511 + Itr(Object[] array) {
17.512 + lastRet = -1;
17.513 + this.array = array;
17.514 + }
17.515 +
17.516 + public boolean hasNext() {
17.517 + return cursor < array.length;
17.518 + }
17.519 +
17.520 + @SuppressWarnings("unchecked")
17.521 + public E next() {
17.522 + if (cursor >= array.length)
17.523 + throw new NoSuchElementException();
17.524 + lastRet = cursor;
17.525 + return (E)array[cursor++];
17.526 + }
17.527 +
17.528 + public void remove() {
17.529 + if (lastRet < 0)
17.530 + throw new IllegalStateException();
17.531 + Object x = array[lastRet];
17.532 + lastRet = -1;
17.533 + // Traverse underlying queue to find == element,
17.534 + // not just a .equals element.
17.535 + lock.lock();
17.536 + try {
17.537 + for (Iterator it = q.iterator(); it.hasNext(); ) {
17.538 + if (it.next() == x) {
17.539 + it.remove();
17.540 + return;
17.541 + }
17.542 + }
17.543 + } finally {
17.544 + lock.unlock();
17.545 + }
17.546 + }
17.547 + }
17.548 +
17.549 +}
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
18.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/Delayed.java Sat Mar 19 10:48:29 2016 +0100
18.3 @@ -0,0 +1,62 @@
18.4 +/*
18.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
18.6 + *
18.7 + * This code is free software; you can redistribute it and/or modify it
18.8 + * under the terms of the GNU General Public License version 2 only, as
18.9 + * published by the Free Software Foundation. Oracle designates this
18.10 + * particular file as subject to the "Classpath" exception as provided
18.11 + * by Oracle in the LICENSE file that accompanied this code.
18.12 + *
18.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
18.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18.16 + * version 2 for more details (a copy is included in the LICENSE file that
18.17 + * accompanied this code).
18.18 + *
18.19 + * You should have received a copy of the GNU General Public License version
18.20 + * 2 along with this work; if not, write to the Free Software Foundation,
18.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18.22 + *
18.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
18.24 + * or visit www.oracle.com if you need additional information or have any
18.25 + * questions.
18.26 + */
18.27 +
18.28 +/*
18.29 + * This file is available under and governed by the GNU General Public
18.30 + * License version 2 only, as published by the Free Software Foundation.
18.31 + * However, the following notice accompanied the original version of this
18.32 + * file:
18.33 + *
18.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
18.35 + * Expert Group and released to the public domain, as explained at
18.36 + * http://creativecommons.org/publicdomain/zero/1.0/
18.37 + */
18.38 +
18.39 +package java.util.concurrent;
18.40 +
18.41 +import java.util.*;
18.42 +
18.43 +/**
18.44 + * A mix-in style interface for marking objects that should be
18.45 + * acted upon after a given delay.
18.46 + *
18.47 + * <p>An implementation of this interface must define a
18.48 + * <tt>compareTo</tt> method that provides an ordering consistent with
18.49 + * its <tt>getDelay</tt> method.
18.50 + *
18.51 + * @since 1.5
18.52 + * @author Doug Lea
18.53 + */
18.54 +public interface Delayed extends Comparable<Delayed> {
18.55 +
18.56 + /**
18.57 + * Returns the remaining delay associated with this object, in the
18.58 + * given time unit.
18.59 + *
18.60 + * @param unit the time unit
18.61 + * @return the remaining delay; zero or negative values indicate
18.62 + * that the delay has already elapsed
18.63 + */
18.64 + long getDelay(TimeUnit unit);
18.65 +}
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
19.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/Exchanger.java Sat Mar 19 10:48:29 2016 +0100
19.3 @@ -0,0 +1,687 @@
19.4 +/*
19.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
19.6 + *
19.7 + * This code is free software; you can redistribute it and/or modify it
19.8 + * under the terms of the GNU General Public License version 2 only, as
19.9 + * published by the Free Software Foundation. Oracle designates this
19.10 + * particular file as subject to the "Classpath" exception as provided
19.11 + * by Oracle in the LICENSE file that accompanied this code.
19.12 + *
19.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
19.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19.16 + * version 2 for more details (a copy is included in the LICENSE file that
19.17 + * accompanied this code).
19.18 + *
19.19 + * You should have received a copy of the GNU General Public License version
19.20 + * 2 along with this work; if not, write to the Free Software Foundation,
19.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19.22 + *
19.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19.24 + * or visit www.oracle.com if you need additional information or have any
19.25 + * questions.
19.26 + */
19.27 +
19.28 +/*
19.29 + * This file is available under and governed by the GNU General Public
19.30 + * License version 2 only, as published by the Free Software Foundation.
19.31 + * However, the following notice accompanied the original version of this
19.32 + * file:
19.33 + *
19.34 + * Written by Doug Lea, Bill Scherer, and Michael Scott with
19.35 + * assistance from members of JCP JSR-166 Expert Group and released to
19.36 + * the public domain, as explained at
19.37 + * http://creativecommons.org/publicdomain/zero/1.0/
19.38 + */
19.39 +
19.40 +package java.util.concurrent;
19.41 +import java.util.concurrent.atomic.*;
19.42 +import java.util.concurrent.locks.LockSupport;
19.43 +
19.44 +/**
19.45 + * A synchronization point at which threads can pair and swap elements
19.46 + * within pairs. Each thread presents some object on entry to the
19.47 + * {@link #exchange exchange} method, matches with a partner thread,
19.48 + * and receives its partner's object on return. An Exchanger may be
19.49 + * viewed as a bidirectional form of a {@link SynchronousQueue}.
19.50 + * Exchangers may be useful in applications such as genetic algorithms
19.51 + * and pipeline designs.
19.52 + *
19.53 + * <p><b>Sample Usage:</b>
19.54 + * Here are the highlights of a class that uses an {@code Exchanger}
19.55 + * to swap buffers between threads so that the thread filling the
19.56 + * buffer gets a freshly emptied one when it needs it, handing off the
19.57 + * filled one to the thread emptying the buffer.
19.58 + * <pre>{@code
19.59 + * class FillAndEmpty {
19.60 + * Exchanger<DataBuffer> exchanger = new Exchanger<DataBuffer>();
19.61 + * DataBuffer initialEmptyBuffer = ... a made-up type
19.62 + * DataBuffer initialFullBuffer = ...
19.63 + *
19.64 + * class FillingLoop implements Runnable {
19.65 + * public void run() {
19.66 + * DataBuffer currentBuffer = initialEmptyBuffer;
19.67 + * try {
19.68 + * while (currentBuffer != null) {
19.69 + * addToBuffer(currentBuffer);
19.70 + * if (currentBuffer.isFull())
19.71 + * currentBuffer = exchanger.exchange(currentBuffer);
19.72 + * }
19.73 + * } catch (InterruptedException ex) { ... handle ... }
19.74 + * }
19.75 + * }
19.76 + *
19.77 + * class EmptyingLoop implements Runnable {
19.78 + * public void run() {
19.79 + * DataBuffer currentBuffer = initialFullBuffer;
19.80 + * try {
19.81 + * while (currentBuffer != null) {
19.82 + * takeFromBuffer(currentBuffer);
19.83 + * if (currentBuffer.isEmpty())
19.84 + * currentBuffer = exchanger.exchange(currentBuffer);
19.85 + * }
19.86 + * } catch (InterruptedException ex) { ... handle ...}
19.87 + * }
19.88 + * }
19.89 + *
19.90 + * void start() {
19.91 + * new Thread(new FillingLoop()).start();
19.92 + * new Thread(new EmptyingLoop()).start();
19.93 + * }
19.94 + * }
19.95 + * }</pre>
19.96 + *
19.97 + * <p>Memory consistency effects: For each pair of threads that
19.98 + * successfully exchange objects via an {@code Exchanger}, actions
19.99 + * prior to the {@code exchange()} in each thread
19.100 + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
19.101 + * those subsequent to a return from the corresponding {@code exchange()}
19.102 + * in the other thread.
19.103 + *
19.104 + * @since 1.5
19.105 + * @author Doug Lea and Bill Scherer and Michael Scott
19.106 + * @param <V> The type of objects that may be exchanged
19.107 + */
19.108 +public class Exchanger<V> {
19.109 + /*
19.110 + * Algorithm Description:
19.111 + *
19.112 + * The basic idea is to maintain a "slot", which is a reference to
19.113 + * a Node containing both an Item to offer and a "hole" waiting to
19.114 + * get filled in. If an incoming "occupying" thread sees that the
19.115 + * slot is null, it CAS'es (compareAndSets) a Node there and waits
19.116 + * for another to invoke exchange. That second "fulfilling" thread
19.117 + * sees that the slot is non-null, and so CASes it back to null,
19.118 + * also exchanging items by CASing the hole, plus waking up the
19.119 + * occupying thread if it is blocked. In each case CAS'es may
19.120 + * fail because a slot at first appears non-null but is null upon
19.121 + * CAS, or vice-versa. So threads may need to retry these
19.122 + * actions.
19.123 + *
19.124 + * This simple approach works great when there are only a few
19.125 + * threads using an Exchanger, but performance rapidly
19.126 + * deteriorates due to CAS contention on the single slot when
19.127 + * there are lots of threads using an exchanger. So instead we use
19.128 + * an "arena"; basically a kind of hash table with a dynamically
19.129 + * varying number of slots, any one of which can be used by
19.130 + * threads performing an exchange. Incoming threads pick slots
19.131 + * based on a hash of their Thread ids. If an incoming thread
19.132 + * fails to CAS in its chosen slot, it picks an alternative slot
19.133 + * instead. And similarly from there. If a thread successfully
19.134 + * CASes into a slot but no other thread arrives, it tries
19.135 + * another, heading toward the zero slot, which always exists even
19.136 + * if the table shrinks. The particular mechanics controlling this
19.137 + * are as follows:
19.138 + *
19.139 + * Waiting: Slot zero is special in that it is the only slot that
19.140 + * exists when there is no contention. A thread occupying slot
19.141 + * zero will block if no thread fulfills it after a short spin.
19.142 + * In other cases, occupying threads eventually give up and try
19.143 + * another slot. Waiting threads spin for a while (a period that
19.144 + * should be a little less than a typical context-switch time)
19.145 + * before either blocking (if slot zero) or giving up (if other
19.146 + * slots) and restarting. There is no reason for threads to block
19.147 + * unless there are unlikely to be any other threads present.
19.148 + * Occupants are mainly avoiding memory contention so sit there
19.149 + * quietly polling for a shorter period than it would take to
19.150 + * block and then unblock them. Non-slot-zero waits that elapse
19.151 + * because of lack of other threads waste around one extra
19.152 + * context-switch time per try, which is still on average much
19.153 + * faster than alternative approaches.
19.154 + *
19.155 + * Sizing: Usually, using only a few slots suffices to reduce
19.156 + * contention. Especially with small numbers of threads, using
19.157 + * too many slots can lead to just as poor performance as using
19.158 + * too few of them, and there's not much room for error. The
19.159 + * variable "max" maintains the number of slots actually in
19.160 + * use. It is increased when a thread sees too many CAS
19.161 + * failures. (This is analogous to resizing a regular hash table
19.162 + * based on a target load factor, except here, growth steps are
19.163 + * just one-by-one rather than proportional.) Growth requires
19.164 + * contention failures in each of three tried slots. Requiring
19.165 + * multiple failures for expansion copes with the fact that some
19.166 + * failed CASes are not due to contention but instead to simple
19.167 + * races between two threads or thread pre-emptions occurring
19.168 + * between reading and CASing. Also, very transient peak
19.169 + * contention can be much higher than the average sustainable
19.170 + * levels. An attempt to decrease the max limit is usually made
19.171 + * when a non-slot-zero wait elapses without being fulfilled.
19.172 + * Threads experiencing elapsed waits move closer to zero, so
19.173 + * eventually find existing (or future) threads even if the table
19.174 + * has been shrunk due to inactivity. The chosen mechanics and
19.175 + * thresholds for growing and shrinking are intrinsically
19.176 + * entangled with indexing and hashing inside the exchange code,
19.177 + * and can't be nicely abstracted out.
19.178 + *
19.179 + * Hashing: Each thread picks its initial slot to use in accord
19.180 + * with a simple hashcode. The sequence is the same on each
19.181 + * encounter by any given thread, but effectively random across
19.182 + * threads. Using arenas encounters the classic cost vs quality
19.183 + * tradeoffs of all hash tables. Here, we use a one-step FNV-1a
19.184 + * hash code based on the current thread's Thread.getId(), along
19.185 + * with a cheap approximation to a mod operation to select an
19.186 + * index. The downside of optimizing index selection in this way
19.187 + * is that the code is hardwired to use a maximum table size of
19.188 + * 32. But this value more than suffices for known platforms and
19.189 + * applications.
19.190 + *
19.191 + * Probing: On sensed contention of a selected slot, we probe
19.192 + * sequentially through the table, analogously to linear probing
19.193 + * after collision in a hash table. (We move circularly, in
19.194 + * reverse order, to mesh best with table growth and shrinkage
19.195 + * rules.) Except that to minimize the effects of false-alarms
19.196 + * and cache thrashing, we try the first selected slot twice
19.197 + * before moving.
19.198 + *
19.199 + * Padding: Even with contention management, slots are heavily
19.200 + * contended, so use cache-padding to avoid poor memory
19.201 + * performance. Because of this, slots are lazily constructed
19.202 + * only when used, to avoid wasting this space unnecessarily.
19.203 + * While isolation of locations is not much of an issue at first
19.204 + * in an application, as time goes on and garbage-collectors
19.205 + * perform compaction, slots are very likely to be moved adjacent
19.206 + * to each other, which can cause much thrashing of cache lines on
19.207 + * MPs unless padding is employed.
19.208 + *
19.209 + * This is an improvement of the algorithm described in the paper
19.210 + * "A Scalable Elimination-based Exchange Channel" by William
19.211 + * Scherer, Doug Lea, and Michael Scott in Proceedings of SCOOL05
19.212 + * workshop. Available at: http://hdl.handle.net/1802/2104
19.213 + */
19.214 +
19.215 + /** The number of CPUs, for sizing and spin control */
19.216 + private static final int NCPU = Runtime.getRuntime().availableProcessors();
19.217 +
19.218 + /**
19.219 + * The capacity of the arena. Set to a value that provides more
19.220 + * than enough space to handle contention. On small machines
19.221 + * most slots won't be used, but it is still not wasted because
19.222 + * the extra space provides some machine-level address padding
19.223 + * to minimize interference with heavily CAS'ed Slot locations.
19.224 + * And on very large machines, performance eventually becomes
19.225 + * bounded by memory bandwidth, not numbers of threads/CPUs.
19.226 + * This constant cannot be changed without also modifying
19.227 + * indexing and hashing algorithms.
19.228 + */
19.229 + private static final int CAPACITY = 32;
19.230 +
19.231 + /**
19.232 + * The value of "max" that will hold all threads without
19.233 + * contention. When this value is less than CAPACITY, some
19.234 + * otherwise wasted expansion can be avoided.
19.235 + */
19.236 + private static final int FULL =
19.237 + Math.max(0, Math.min(CAPACITY, NCPU / 2) - 1);
19.238 +
19.239 + /**
19.240 + * The number of times to spin (doing nothing except polling a
19.241 + * memory location) before blocking or giving up while waiting to
19.242 + * be fulfilled. Should be zero on uniprocessors. On
19.243 + * multiprocessors, this value should be large enough so that two
19.244 + * threads exchanging items as fast as possible block only when
19.245 + * one of them is stalled (due to GC or preemption), but not much
19.246 + * longer, to avoid wasting CPU resources. Seen differently, this
19.247 + * value is a little over half the number of cycles of an average
19.248 + * context switch time on most systems. The value here is
19.249 + * approximately the average of those across a range of tested
19.250 + * systems.
19.251 + */
19.252 + private static final int SPINS = (NCPU == 1) ? 0 : 2000;
19.253 +
19.254 + /**
19.255 + * The number of times to spin before blocking in timed waits.
19.256 + * Timed waits spin more slowly because checking the time takes
19.257 + * time. The best value relies mainly on the relative rate of
19.258 + * System.nanoTime vs memory accesses. The value is empirically
19.259 + * derived to work well across a variety of systems.
19.260 + */
19.261 + private static final int TIMED_SPINS = SPINS / 20;
19.262 +
19.263 + /**
19.264 + * Sentinel item representing cancellation of a wait due to
19.265 + * interruption, timeout, or elapsed spin-waits. This value is
19.266 + * placed in holes on cancellation, and used as a return value
19.267 + * from waiting methods to indicate failure to set or get hole.
19.268 + */
19.269 + private static final Object CANCEL = new Object();
19.270 +
19.271 + /**
19.272 + * Value representing null arguments/returns from public
19.273 + * methods. This disambiguates from internal requirement that
19.274 + * holes start out as null to mean they are not yet set.
19.275 + */
19.276 + private static final Object NULL_ITEM = new Object();
19.277 +
19.278 + /**
19.279 + * Nodes hold partially exchanged data. This class
19.280 + * opportunistically subclasses AtomicReference to represent the
19.281 + * hole. So get() returns hole, and compareAndSet CAS'es value
19.282 + * into hole. This class cannot be parameterized as "V" because
19.283 + * of the use of non-V CANCEL sentinels.
19.284 + */
19.285 + private static final class Node extends AtomicReference<Object> {
19.286 + /** The element offered by the Thread creating this node. */
19.287 + public final Object item;
19.288 +
19.289 + /** The Thread waiting to be signalled; null until waiting. */
19.290 + public volatile Thread waiter;
19.291 +
19.292 + /**
19.293 + * Creates node with given item and empty hole.
19.294 + * @param item the item
19.295 + */
19.296 + public Node(Object item) {
19.297 + this.item = item;
19.298 + }
19.299 + }
19.300 +
19.301 + /**
19.302 + * A Slot is an AtomicReference with heuristic padding to lessen
19.303 + * cache effects of this heavily CAS'ed location. While the
19.304 + * padding adds noticeable space, all slots are created only on
19.305 + * demand, and there will be more than one of them only when it
19.306 + * would improve throughput more than enough to outweigh using
19.307 + * extra space.
19.308 + */
19.309 + private static final class Slot extends AtomicReference<Object> {
19.310 + // Improve likelihood of isolation on <= 64 byte cache lines
19.311 + long q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, qa, qb, qc, qd, qe;
19.312 + }
19.313 +
19.314 + /**
19.315 + * Slot array. Elements are lazily initialized when needed.
19.316 + * Declared volatile to enable double-checked lazy construction.
19.317 + */
19.318 + private volatile Slot[] arena = new Slot[CAPACITY];
19.319 +
19.320 + /**
19.321 + * The maximum slot index being used. The value sometimes
19.322 + * increases when a thread experiences too many CAS contentions,
19.323 + * and sometimes decreases when a spin-wait elapses. Changes
19.324 + * are performed only via compareAndSet, to avoid stale values
19.325 + * when a thread happens to stall right before setting.
19.326 + */
19.327 + private final AtomicInteger max = new AtomicInteger();
19.328 +
19.329 + /**
19.330 + * Main exchange function, handling the different policy variants.
19.331 + * Uses Object, not "V" as argument and return value to simplify
19.332 + * handling of sentinel values. Callers from public methods decode
19.333 + * and cast accordingly.
19.334 + *
19.335 + * @param item the (non-null) item to exchange
19.336 + * @param timed true if the wait is timed
19.337 + * @param nanos if timed, the maximum wait time
19.338 + * @return the other thread's item, or CANCEL if interrupted or timed out
19.339 + */
19.340 + private Object doExchange(Object item, boolean timed, long nanos) {
19.341 + Node me = new Node(item); // Create in case occupying
19.342 + int index = hashIndex(); // Index of current slot
19.343 + int fails = 0; // Number of CAS failures
19.344 +
19.345 + for (;;) {
19.346 + Object y; // Contents of current slot
19.347 + Slot slot = arena[index];
19.348 + if (slot == null) // Lazily initialize slots
19.349 + createSlot(index); // Continue loop to reread
19.350 + else if ((y = slot.get()) != null && // Try to fulfill
19.351 + slot.compareAndSet(y, null)) {
19.352 + Node you = (Node)y; // Transfer item
19.353 + if (you.compareAndSet(null, item)) {
19.354 + LockSupport.unpark(you.waiter);
19.355 + return you.item;
19.356 + } // Else cancelled; continue
19.357 + }
19.358 + else if (y == null && // Try to occupy
19.359 + slot.compareAndSet(null, me)) {
19.360 + if (index == 0) // Blocking wait for slot 0
19.361 + return timed ?
19.362 + awaitNanos(me, slot, nanos) :
19.363 + await(me, slot);
19.364 + Object v = spinWait(me, slot); // Spin wait for non-0
19.365 + if (v != CANCEL)
19.366 + return v;
19.367 + me = new Node(item); // Throw away cancelled node
19.368 + int m = max.get();
19.369 + if (m > (index >>>= 1)) // Decrease index
19.370 + max.compareAndSet(m, m - 1); // Maybe shrink table
19.371 + }
19.372 + else if (++fails > 1) { // Allow 2 fails on 1st slot
19.373 + int m = max.get();
19.374 + if (fails > 3 && m < FULL && max.compareAndSet(m, m + 1))
19.375 + index = m + 1; // Grow on 3rd failed slot
19.376 + else if (--index < 0)
19.377 + index = m; // Circularly traverse
19.378 + }
19.379 + }
19.380 + }
19.381 +
19.382 + /**
19.383 + * Returns a hash index for the current thread. Uses a one-step
19.384 + * FNV-1a hash code (http://www.isthe.com/chongo/tech/comp/fnv/)
19.385 + * based on the current thread's Thread.getId(). These hash codes
19.386 + * have more uniform distribution properties with respect to small
19.387 + * moduli (here 1-31) than do other simple hashing functions.
19.388 + *
19.389 + * <p>To return an index between 0 and max, we use a cheap
19.390 + * approximation to a mod operation, that also corrects for bias
19.391 + * due to non-power-of-2 remaindering (see {@link
19.392 + * java.util.Random#nextInt}). Bits of the hashcode are masked
19.393 + * with "nbits", the ceiling power of two of table size (looked up
19.394 + * in a table packed into three ints). If too large, this is
19.395 + * retried after rotating the hash by nbits bits, while forcing new
19.396 + * top bit to 0, which guarantees eventual termination (although
19.397 + * with a non-random-bias). This requires an average of less than
19.398 + * 2 tries for all table sizes, and has a maximum 2% difference
19.399 + * from perfectly uniform slot probabilities when applied to all
19.400 + * possible hash codes for sizes less than 32.
19.401 + *
19.402 + * @return a per-thread-random index, 0 <= index < max
19.403 + */
19.404 + private final int hashIndex() {
19.405 + long id = Thread.currentThread().getId();
19.406 + int hash = (((int)(id ^ (id >>> 32))) ^ 0x811c9dc5) * 0x01000193;
19.407 +
19.408 + int m = max.get();
19.409 + int nbits = (((0xfffffc00 >> m) & 4) | // Compute ceil(log2(m+1))
19.410 + ((0x000001f8 >>> m) & 2) | // The constants hold
19.411 + ((0xffff00f2 >>> m) & 1)); // a lookup table
19.412 + int index;
19.413 + while ((index = hash & ((1 << nbits) - 1)) > m) // May retry on
19.414 + hash = (hash >>> nbits) | (hash << (33 - nbits)); // non-power-2 m
19.415 + return index;
19.416 + }
19.417 +
19.418 + /**
19.419 + * Creates a new slot at given index. Called only when the slot
19.420 + * appears to be null. Relies on double-check using builtin
19.421 + * locks, since they rarely contend. This in turn relies on the
19.422 + * arena array being declared volatile.
19.423 + *
19.424 + * @param index the index to add slot at
19.425 + */
19.426 + private void createSlot(int index) {
19.427 + // Create slot outside of lock to narrow sync region
19.428 + Slot newSlot = new Slot();
19.429 + Slot[] a = arena;
19.430 + synchronized (a) {
19.431 + if (a[index] == null)
19.432 + a[index] = newSlot;
19.433 + }
19.434 + }
19.435 +
19.436 + /**
19.437 + * Tries to cancel a wait for the given node waiting in the given
19.438 + * slot, if so, helping clear the node from its slot to avoid
19.439 + * garbage retention.
19.440 + *
19.441 + * @param node the waiting node
19.442 + * @param the slot it is waiting in
19.443 + * @return true if successfully cancelled
19.444 + */
19.445 + private static boolean tryCancel(Node node, Slot slot) {
19.446 + if (!node.compareAndSet(null, CANCEL))
19.447 + return false;
19.448 + if (slot.get() == node) // pre-check to minimize contention
19.449 + slot.compareAndSet(node, null);
19.450 + return true;
19.451 + }
19.452 +
19.453 + // Three forms of waiting. Each just different enough not to merge
19.454 + // code with others.
19.455 +
19.456 + /**
19.457 + * Spin-waits for hole for a non-0 slot. Fails if spin elapses
19.458 + * before hole filled. Does not check interrupt, relying on check
19.459 + * in public exchange method to abort if interrupted on entry.
19.460 + *
19.461 + * @param node the waiting node
19.462 + * @return on success, the hole; on failure, CANCEL
19.463 + */
19.464 + private static Object spinWait(Node node, Slot slot) {
19.465 + int spins = SPINS;
19.466 + for (;;) {
19.467 + Object v = node.get();
19.468 + if (v != null)
19.469 + return v;
19.470 + else if (spins > 0)
19.471 + --spins;
19.472 + else
19.473 + tryCancel(node, slot);
19.474 + }
19.475 + }
19.476 +
19.477 + /**
19.478 + * Waits for (by spinning and/or blocking) and gets the hole
19.479 + * filled in by another thread. Fails if interrupted before
19.480 + * hole filled.
19.481 + *
19.482 + * When a node/thread is about to block, it sets its waiter field
19.483 + * and then rechecks state at least one more time before actually
19.484 + * parking, thus covering race vs fulfiller noticing that waiter
19.485 + * is non-null so should be woken.
19.486 + *
19.487 + * Thread interruption status is checked only surrounding calls to
19.488 + * park. The caller is assumed to have checked interrupt status
19.489 + * on entry.
19.490 + *
19.491 + * @param node the waiting node
19.492 + * @return on success, the hole; on failure, CANCEL
19.493 + */
19.494 + private static Object await(Node node, Slot slot) {
19.495 + Thread w = Thread.currentThread();
19.496 + int spins = SPINS;
19.497 + for (;;) {
19.498 + Object v = node.get();
19.499 + if (v != null)
19.500 + return v;
19.501 + else if (spins > 0) // Spin-wait phase
19.502 + --spins;
19.503 + else if (node.waiter == null) // Set up to block next
19.504 + node.waiter = w;
19.505 + else if (w.isInterrupted()) // Abort on interrupt
19.506 + tryCancel(node, slot);
19.507 + else // Block
19.508 + LockSupport.park(node);
19.509 + }
19.510 + }
19.511 +
19.512 + /**
19.513 + * Waits for (at index 0) and gets the hole filled in by another
19.514 + * thread. Fails if timed out or interrupted before hole filled.
19.515 + * Same basic logic as untimed version, but a bit messier.
19.516 + *
19.517 + * @param node the waiting node
19.518 + * @param nanos the wait time
19.519 + * @return on success, the hole; on failure, CANCEL
19.520 + */
19.521 + private Object awaitNanos(Node node, Slot slot, long nanos) {
19.522 + int spins = TIMED_SPINS;
19.523 + long lastTime = 0;
19.524 + Thread w = null;
19.525 + for (;;) {
19.526 + Object v = node.get();
19.527 + if (v != null)
19.528 + return v;
19.529 + long now = System.nanoTime();
19.530 + if (w == null)
19.531 + w = Thread.currentThread();
19.532 + else
19.533 + nanos -= now - lastTime;
19.534 + lastTime = now;
19.535 + if (nanos > 0) {
19.536 + if (spins > 0)
19.537 + --spins;
19.538 + else if (node.waiter == null)
19.539 + node.waiter = w;
19.540 + else if (w.isInterrupted())
19.541 + tryCancel(node, slot);
19.542 + else
19.543 + LockSupport.parkNanos(node, nanos);
19.544 + }
19.545 + else if (tryCancel(node, slot) && !w.isInterrupted())
19.546 + return scanOnTimeout(node);
19.547 + }
19.548 + }
19.549 +
19.550 + /**
19.551 + * Sweeps through arena checking for any waiting threads. Called
19.552 + * only upon return from timeout while waiting in slot 0. When a
19.553 + * thread gives up on a timed wait, it is possible that a
19.554 + * previously-entered thread is still waiting in some other
19.555 + * slot. So we scan to check for any. This is almost always
19.556 + * overkill, but decreases the likelihood of timeouts when there
19.557 + * are other threads present to far less than that in lock-based
19.558 + * exchangers in which earlier-arriving threads may still be
19.559 + * waiting on entry locks.
19.560 + *
19.561 + * @param node the waiting node
19.562 + * @return another thread's item, or CANCEL
19.563 + */
19.564 + private Object scanOnTimeout(Node node) {
19.565 + Object y;
19.566 + for (int j = arena.length - 1; j >= 0; --j) {
19.567 + Slot slot = arena[j];
19.568 + if (slot != null) {
19.569 + while ((y = slot.get()) != null) {
19.570 + if (slot.compareAndSet(y, null)) {
19.571 + Node you = (Node)y;
19.572 + if (you.compareAndSet(null, node.item)) {
19.573 + LockSupport.unpark(you.waiter);
19.574 + return you.item;
19.575 + }
19.576 + }
19.577 + }
19.578 + }
19.579 + }
19.580 + return CANCEL;
19.581 + }
19.582 +
19.583 + /**
19.584 + * Creates a new Exchanger.
19.585 + */
19.586 + public Exchanger() {
19.587 + }
19.588 +
19.589 + /**
19.590 + * Waits for another thread to arrive at this exchange point (unless
19.591 + * the current thread is {@linkplain Thread#interrupt interrupted}),
19.592 + * and then transfers the given object to it, receiving its object
19.593 + * in return.
19.594 + *
19.595 + * <p>If another thread is already waiting at the exchange point then
19.596 + * it is resumed for thread scheduling purposes and receives the object
19.597 + * passed in by the current thread. The current thread returns immediately,
19.598 + * receiving the object passed to the exchange by that other thread.
19.599 + *
19.600 + * <p>If no other thread is already waiting at the exchange then the
19.601 + * current thread is disabled for thread scheduling purposes and lies
19.602 + * dormant until one of two things happens:
19.603 + * <ul>
19.604 + * <li>Some other thread enters the exchange; or
19.605 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
19.606 + * the current thread.
19.607 + * </ul>
19.608 + * <p>If the current thread:
19.609 + * <ul>
19.610 + * <li>has its interrupted status set on entry to this method; or
19.611 + * <li>is {@linkplain Thread#interrupt interrupted} while waiting
19.612 + * for the exchange,
19.613 + * </ul>
19.614 + * then {@link InterruptedException} is thrown and the current thread's
19.615 + * interrupted status is cleared.
19.616 + *
19.617 + * @param x the object to exchange
19.618 + * @return the object provided by the other thread
19.619 + * @throws InterruptedException if the current thread was
19.620 + * interrupted while waiting
19.621 + */
19.622 + public V exchange(V x) throws InterruptedException {
19.623 + if (!Thread.interrupted()) {
19.624 + Object v = doExchange((x == null) ? NULL_ITEM : x, false, 0);
19.625 + if (v == NULL_ITEM)
19.626 + return null;
19.627 + if (v != CANCEL)
19.628 + return (V)v;
19.629 + Thread.interrupted(); // Clear interrupt status on IE throw
19.630 + }
19.631 + throw new InterruptedException();
19.632 + }
19.633 +
19.634 + /**
19.635 + * Waits for another thread to arrive at this exchange point (unless
19.636 + * the current thread is {@linkplain Thread#interrupt interrupted} or
19.637 + * the specified waiting time elapses), and then transfers the given
19.638 + * object to it, receiving its object in return.
19.639 + *
19.640 + * <p>If another thread is already waiting at the exchange point then
19.641 + * it is resumed for thread scheduling purposes and receives the object
19.642 + * passed in by the current thread. The current thread returns immediately,
19.643 + * receiving the object passed to the exchange by that other thread.
19.644 + *
19.645 + * <p>If no other thread is already waiting at the exchange then the
19.646 + * current thread is disabled for thread scheduling purposes and lies
19.647 + * dormant until one of three things happens:
19.648 + * <ul>
19.649 + * <li>Some other thread enters the exchange; or
19.650 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
19.651 + * the current thread; or
19.652 + * <li>The specified waiting time elapses.
19.653 + * </ul>
19.654 + * <p>If the current thread:
19.655 + * <ul>
19.656 + * <li>has its interrupted status set on entry to this method; or
19.657 + * <li>is {@linkplain Thread#interrupt interrupted} while waiting
19.658 + * for the exchange,
19.659 + * </ul>
19.660 + * then {@link InterruptedException} is thrown and the current thread's
19.661 + * interrupted status is cleared.
19.662 + *
19.663 + * <p>If the specified waiting time elapses then {@link
19.664 + * TimeoutException} is thrown. If the time is less than or equal
19.665 + * to zero, the method will not wait at all.
19.666 + *
19.667 + * @param x the object to exchange
19.668 + * @param timeout the maximum time to wait
19.669 + * @param unit the time unit of the <tt>timeout</tt> argument
19.670 + * @return the object provided by the other thread
19.671 + * @throws InterruptedException if the current thread was
19.672 + * interrupted while waiting
19.673 + * @throws TimeoutException if the specified waiting time elapses
19.674 + * before another thread enters the exchange
19.675 + */
19.676 + public V exchange(V x, long timeout, TimeUnit unit)
19.677 + throws InterruptedException, TimeoutException {
19.678 + if (!Thread.interrupted()) {
19.679 + Object v = doExchange((x == null) ? NULL_ITEM : x,
19.680 + true, unit.toNanos(timeout));
19.681 + if (v == NULL_ITEM)
19.682 + return null;
19.683 + if (v != CANCEL)
19.684 + return (V)v;
19.685 + if (!Thread.interrupted())
19.686 + throw new TimeoutException();
19.687 + }
19.688 + throw new InterruptedException();
19.689 + }
19.690 +}
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
20.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ExecutionException.java Sat Mar 19 10:48:29 2016 +0100
20.3 @@ -0,0 +1,94 @@
20.4 +/*
20.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
20.6 + *
20.7 + * This code is free software; you can redistribute it and/or modify it
20.8 + * under the terms of the GNU General Public License version 2 only, as
20.9 + * published by the Free Software Foundation. Oracle designates this
20.10 + * particular file as subject to the "Classpath" exception as provided
20.11 + * by Oracle in the LICENSE file that accompanied this code.
20.12 + *
20.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
20.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20.16 + * version 2 for more details (a copy is included in the LICENSE file that
20.17 + * accompanied this code).
20.18 + *
20.19 + * You should have received a copy of the GNU General Public License version
20.20 + * 2 along with this work; if not, write to the Free Software Foundation,
20.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20.22 + *
20.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20.24 + * or visit www.oracle.com if you need additional information or have any
20.25 + * questions.
20.26 + */
20.27 +
20.28 +/*
20.29 + * This file is available under and governed by the GNU General Public
20.30 + * License version 2 only, as published by the Free Software Foundation.
20.31 + * However, the following notice accompanied the original version of this
20.32 + * file:
20.33 + *
20.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
20.35 + * Expert Group and released to the public domain, as explained at
20.36 + * http://creativecommons.org/publicdomain/zero/1.0/
20.37 + */
20.38 +
20.39 +package java.util.concurrent;
20.40 +
20.41 +/**
20.42 + * Exception thrown when attempting to retrieve the result of a task
20.43 + * that aborted by throwing an exception. This exception can be
20.44 + * inspected using the {@link #getCause()} method.
20.45 + *
20.46 + * @see Future
20.47 + * @since 1.5
20.48 + * @author Doug Lea
20.49 + */
20.50 +public class ExecutionException extends Exception {
20.51 + private static final long serialVersionUID = 7830266012832686185L;
20.52 +
20.53 + /**
20.54 + * Constructs an <tt>ExecutionException</tt> with no detail message.
20.55 + * The cause is not initialized, and may subsequently be
20.56 + * initialized by a call to {@link #initCause(Throwable) initCause}.
20.57 + */
20.58 + protected ExecutionException() { }
20.59 +
20.60 + /**
20.61 + * Constructs an <tt>ExecutionException</tt> with the specified detail
20.62 + * message. The cause is not initialized, and may subsequently be
20.63 + * initialized by a call to {@link #initCause(Throwable) initCause}.
20.64 + *
20.65 + * @param message the detail message
20.66 + */
20.67 + protected ExecutionException(String message) {
20.68 + super(message);
20.69 + }
20.70 +
20.71 + /**
20.72 + * Constructs an <tt>ExecutionException</tt> with the specified detail
20.73 + * message and cause.
20.74 + *
20.75 + * @param message the detail message
20.76 + * @param cause the cause (which is saved for later retrieval by the
20.77 + * {@link #getCause()} method)
20.78 + */
20.79 + public ExecutionException(String message, Throwable cause) {
20.80 + super(message, cause);
20.81 + }
20.82 +
20.83 + /**
20.84 + * Constructs an <tt>ExecutionException</tt> with the specified cause.
20.85 + * The detail message is set to:
20.86 + * <pre>
20.87 + * (cause == null ? null : cause.toString())</pre>
20.88 + * (which typically contains the class and detail message of
20.89 + * <tt>cause</tt>).
20.90 + *
20.91 + * @param cause the cause (which is saved for later retrieval by the
20.92 + * {@link #getCause()} method)
20.93 + */
20.94 + public ExecutionException(Throwable cause) {
20.95 + super(cause);
20.96 + }
20.97 +}
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
21.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ExecutorCompletionService.java Sat Mar 19 10:48:29 2016 +0100
21.3 @@ -0,0 +1,205 @@
21.4 +/*
21.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
21.6 + *
21.7 + * This code is free software; you can redistribute it and/or modify it
21.8 + * under the terms of the GNU General Public License version 2 only, as
21.9 + * published by the Free Software Foundation. Oracle designates this
21.10 + * particular file as subject to the "Classpath" exception as provided
21.11 + * by Oracle in the LICENSE file that accompanied this code.
21.12 + *
21.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
21.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21.16 + * version 2 for more details (a copy is included in the LICENSE file that
21.17 + * accompanied this code).
21.18 + *
21.19 + * You should have received a copy of the GNU General Public License version
21.20 + * 2 along with this work; if not, write to the Free Software Foundation,
21.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21.22 + *
21.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21.24 + * or visit www.oracle.com if you need additional information or have any
21.25 + * questions.
21.26 + */
21.27 +
21.28 +/*
21.29 + * This file is available under and governed by the GNU General Public
21.30 + * License version 2 only, as published by the Free Software Foundation.
21.31 + * However, the following notice accompanied the original version of this
21.32 + * file:
21.33 + *
21.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
21.35 + * Expert Group and released to the public domain, as explained at
21.36 + * http://creativecommons.org/publicdomain/zero/1.0/
21.37 + */
21.38 +
21.39 +package java.util.concurrent;
21.40 +
21.41 +/**
21.42 + * A {@link CompletionService} that uses a supplied {@link Executor}
21.43 + * to execute tasks. This class arranges that submitted tasks are,
21.44 + * upon completion, placed on a queue accessible using {@code take}.
21.45 + * The class is lightweight enough to be suitable for transient use
21.46 + * when processing groups of tasks.
21.47 + *
21.48 + * <p>
21.49 + *
21.50 + * <b>Usage Examples.</b>
21.51 + *
21.52 + * Suppose you have a set of solvers for a certain problem, each
21.53 + * returning a value of some type {@code Result}, and would like to
21.54 + * run them concurrently, processing the results of each of them that
21.55 + * return a non-null value, in some method {@code use(Result r)}. You
21.56 + * could write this as:
21.57 + *
21.58 + * <pre> {@code
21.59 + * void solve(Executor e,
21.60 + * Collection<Callable<Result>> solvers)
21.61 + * throws InterruptedException, ExecutionException {
21.62 + * CompletionService<Result> ecs
21.63 + * = new ExecutorCompletionService<Result>(e);
21.64 + * for (Callable<Result> s : solvers)
21.65 + * ecs.submit(s);
21.66 + * int n = solvers.size();
21.67 + * for (int i = 0; i < n; ++i) {
21.68 + * Result r = ecs.take().get();
21.69 + * if (r != null)
21.70 + * use(r);
21.71 + * }
21.72 + * }}</pre>
21.73 + *
21.74 + * Suppose instead that you would like to use the first non-null result
21.75 + * of the set of tasks, ignoring any that encounter exceptions,
21.76 + * and cancelling all other tasks when the first one is ready:
21.77 + *
21.78 + * <pre> {@code
21.79 + * void solve(Executor e,
21.80 + * Collection<Callable<Result>> solvers)
21.81 + * throws InterruptedException {
21.82 + * CompletionService<Result> ecs
21.83 + * = new ExecutorCompletionService<Result>(e);
21.84 + * int n = solvers.size();
21.85 + * List<Future<Result>> futures
21.86 + * = new ArrayList<Future<Result>>(n);
21.87 + * Result result = null;
21.88 + * try {
21.89 + * for (Callable<Result> s : solvers)
21.90 + * futures.add(ecs.submit(s));
21.91 + * for (int i = 0; i < n; ++i) {
21.92 + * try {
21.93 + * Result r = ecs.take().get();
21.94 + * if (r != null) {
21.95 + * result = r;
21.96 + * break;
21.97 + * }
21.98 + * } catch (ExecutionException ignore) {}
21.99 + * }
21.100 + * }
21.101 + * finally {
21.102 + * for (Future<Result> f : futures)
21.103 + * f.cancel(true);
21.104 + * }
21.105 + *
21.106 + * if (result != null)
21.107 + * use(result);
21.108 + * }}</pre>
21.109 + */
21.110 +public class ExecutorCompletionService<V> implements CompletionService<V> {
21.111 + private final Executor executor;
21.112 + private final AbstractExecutorService aes;
21.113 + private final BlockingQueue<Future<V>> completionQueue;
21.114 +
21.115 + /**
21.116 + * FutureTask extension to enqueue upon completion
21.117 + */
21.118 + private class QueueingFuture extends FutureTask<Void> {
21.119 + QueueingFuture(RunnableFuture<V> task) {
21.120 + super(task, null);
21.121 + this.task = task;
21.122 + }
21.123 + protected void done() { completionQueue.add(task); }
21.124 + private final Future<V> task;
21.125 + }
21.126 +
21.127 + private RunnableFuture<V> newTaskFor(Callable<V> task) {
21.128 + if (aes == null)
21.129 + return new FutureTask<V>(task);
21.130 + else
21.131 + return aes.newTaskFor(task);
21.132 + }
21.133 +
21.134 + private RunnableFuture<V> newTaskFor(Runnable task, V result) {
21.135 + if (aes == null)
21.136 + return new FutureTask<V>(task, result);
21.137 + else
21.138 + return aes.newTaskFor(task, result);
21.139 + }
21.140 +
21.141 + /**
21.142 + * Creates an ExecutorCompletionService using the supplied
21.143 + * executor for base task execution and a
21.144 + * {@link LinkedBlockingQueue} as a completion queue.
21.145 + *
21.146 + * @param executor the executor to use
21.147 + * @throws NullPointerException if executor is {@code null}
21.148 + */
21.149 + public ExecutorCompletionService(Executor executor) {
21.150 + if (executor == null)
21.151 + throw new NullPointerException();
21.152 + this.executor = executor;
21.153 + this.aes = (executor instanceof AbstractExecutorService) ?
21.154 + (AbstractExecutorService) executor : null;
21.155 + this.completionQueue = new LinkedBlockingQueue<Future<V>>();
21.156 + }
21.157 +
21.158 + /**
21.159 + * Creates an ExecutorCompletionService using the supplied
21.160 + * executor for base task execution and the supplied queue as its
21.161 + * completion queue.
21.162 + *
21.163 + * @param executor the executor to use
21.164 + * @param completionQueue the queue to use as the completion queue
21.165 + * normally one dedicated for use by this service. This
21.166 + * queue is treated as unbounded -- failed attempted
21.167 + * {@code Queue.add} operations for completed taskes cause
21.168 + * them not to be retrievable.
21.169 + * @throws NullPointerException if executor or completionQueue are {@code null}
21.170 + */
21.171 + public ExecutorCompletionService(Executor executor,
21.172 + BlockingQueue<Future<V>> completionQueue) {
21.173 + if (executor == null || completionQueue == null)
21.174 + throw new NullPointerException();
21.175 + this.executor = executor;
21.176 + this.aes = (executor instanceof AbstractExecutorService) ?
21.177 + (AbstractExecutorService) executor : null;
21.178 + this.completionQueue = completionQueue;
21.179 + }
21.180 +
21.181 + public Future<V> submit(Callable<V> task) {
21.182 + if (task == null) throw new NullPointerException();
21.183 + RunnableFuture<V> f = newTaskFor(task);
21.184 + executor.execute(new QueueingFuture(f));
21.185 + return f;
21.186 + }
21.187 +
21.188 + public Future<V> submit(Runnable task, V result) {
21.189 + if (task == null) throw new NullPointerException();
21.190 + RunnableFuture<V> f = newTaskFor(task, result);
21.191 + executor.execute(new QueueingFuture(f));
21.192 + return f;
21.193 + }
21.194 +
21.195 + public Future<V> take() throws InterruptedException {
21.196 + return completionQueue.take();
21.197 + }
21.198 +
21.199 + public Future<V> poll() {
21.200 + return completionQueue.poll();
21.201 + }
21.202 +
21.203 + public Future<V> poll(long timeout, TimeUnit unit)
21.204 + throws InterruptedException {
21.205 + return completionQueue.poll(timeout, unit);
21.206 + }
21.207 +
21.208 +}
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
22.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ExecutorService.java Sat Mar 19 10:48:29 2016 +0100
22.3 @@ -0,0 +1,370 @@
22.4 +/*
22.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
22.6 + *
22.7 + * This code is free software; you can redistribute it and/or modify it
22.8 + * under the terms of the GNU General Public License version 2 only, as
22.9 + * published by the Free Software Foundation. Oracle designates this
22.10 + * particular file as subject to the "Classpath" exception as provided
22.11 + * by Oracle in the LICENSE file that accompanied this code.
22.12 + *
22.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
22.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
22.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22.16 + * version 2 for more details (a copy is included in the LICENSE file that
22.17 + * accompanied this code).
22.18 + *
22.19 + * You should have received a copy of the GNU General Public License version
22.20 + * 2 along with this work; if not, write to the Free Software Foundation,
22.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
22.22 + *
22.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22.24 + * or visit www.oracle.com if you need additional information or have any
22.25 + * questions.
22.26 + */
22.27 +
22.28 +/*
22.29 + * This file is available under and governed by the GNU General Public
22.30 + * License version 2 only, as published by the Free Software Foundation.
22.31 + * However, the following notice accompanied the original version of this
22.32 + * file:
22.33 + *
22.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
22.35 + * Expert Group and released to the public domain, as explained at
22.36 + * http://creativecommons.org/publicdomain/zero/1.0/
22.37 + */
22.38 +
22.39 +package java.util.concurrent;
22.40 +import java.util.List;
22.41 +import java.util.Collection;
22.42 +import java.security.PrivilegedAction;
22.43 +import java.security.PrivilegedExceptionAction;
22.44 +
22.45 +/**
22.46 + * An {@link Executor} that provides methods to manage termination and
22.47 + * methods that can produce a {@link Future} for tracking progress of
22.48 + * one or more asynchronous tasks.
22.49 + *
22.50 + * <p> An <tt>ExecutorService</tt> can be shut down, which will cause
22.51 + * it to reject new tasks. Two different methods are provided for
22.52 + * shutting down an <tt>ExecutorService</tt>. The {@link #shutdown}
22.53 + * method will allow previously submitted tasks to execute before
22.54 + * terminating, while the {@link #shutdownNow} method prevents waiting
22.55 + * tasks from starting and attempts to stop currently executing tasks.
22.56 + * Upon termination, an executor has no tasks actively executing, no
22.57 + * tasks awaiting execution, and no new tasks can be submitted. An
22.58 + * unused <tt>ExecutorService</tt> should be shut down to allow
22.59 + * reclamation of its resources.
22.60 + *
22.61 + * <p> Method <tt>submit</tt> extends base method {@link
22.62 + * Executor#execute} by creating and returning a {@link Future} that
22.63 + * can be used to cancel execution and/or wait for completion.
22.64 + * Methods <tt>invokeAny</tt> and <tt>invokeAll</tt> perform the most
22.65 + * commonly useful forms of bulk execution, executing a collection of
22.66 + * tasks and then waiting for at least one, or all, to
22.67 + * complete. (Class {@link ExecutorCompletionService} can be used to
22.68 + * write customized variants of these methods.)
22.69 + *
22.70 + * <p>The {@link Executors} class provides factory methods for the
22.71 + * executor services provided in this package.
22.72 + *
22.73 + * <h3>Usage Examples</h3>
22.74 + *
22.75 + * Here is a sketch of a network service in which threads in a thread
22.76 + * pool service incoming requests. It uses the preconfigured {@link
22.77 + * Executors#newFixedThreadPool} factory method:
22.78 + *
22.79 + * <pre>
22.80 + * class NetworkService implements Runnable {
22.81 + * private final ServerSocket serverSocket;
22.82 + * private final ExecutorService pool;
22.83 + *
22.84 + * public NetworkService(int port, int poolSize)
22.85 + * throws IOException {
22.86 + * serverSocket = new ServerSocket(port);
22.87 + * pool = Executors.newFixedThreadPool(poolSize);
22.88 + * }
22.89 + *
22.90 + * public void run() { // run the service
22.91 + * try {
22.92 + * for (;;) {
22.93 + * pool.execute(new Handler(serverSocket.accept()));
22.94 + * }
22.95 + * } catch (IOException ex) {
22.96 + * pool.shutdown();
22.97 + * }
22.98 + * }
22.99 + * }
22.100 + *
22.101 + * class Handler implements Runnable {
22.102 + * private final Socket socket;
22.103 + * Handler(Socket socket) { this.socket = socket; }
22.104 + * public void run() {
22.105 + * // read and service request on socket
22.106 + * }
22.107 + * }
22.108 + * </pre>
22.109 + *
22.110 + * The following method shuts down an <tt>ExecutorService</tt> in two phases,
22.111 + * first by calling <tt>shutdown</tt> to reject incoming tasks, and then
22.112 + * calling <tt>shutdownNow</tt>, if necessary, to cancel any lingering tasks:
22.113 + *
22.114 + * <pre>
22.115 + * void shutdownAndAwaitTermination(ExecutorService pool) {
22.116 + * pool.shutdown(); // Disable new tasks from being submitted
22.117 + * try {
22.118 + * // Wait a while for existing tasks to terminate
22.119 + * if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
22.120 + * pool.shutdownNow(); // Cancel currently executing tasks
22.121 + * // Wait a while for tasks to respond to being cancelled
22.122 + * if (!pool.awaitTermination(60, TimeUnit.SECONDS))
22.123 + * System.err.println("Pool did not terminate");
22.124 + * }
22.125 + * } catch (InterruptedException ie) {
22.126 + * // (Re-)Cancel if current thread also interrupted
22.127 + * pool.shutdownNow();
22.128 + * // Preserve interrupt status
22.129 + * Thread.currentThread().interrupt();
22.130 + * }
22.131 + * }
22.132 + * </pre>
22.133 + *
22.134 + * <p>Memory consistency effects: Actions in a thread prior to the
22.135 + * submission of a {@code Runnable} or {@code Callable} task to an
22.136 + * {@code ExecutorService}
22.137 + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
22.138 + * any actions taken by that task, which in turn <i>happen-before</i> the
22.139 + * result is retrieved via {@code Future.get()}.
22.140 + *
22.141 + * @since 1.5
22.142 + * @author Doug Lea
22.143 + */
22.144 +public interface ExecutorService extends Executor {
22.145 +
22.146 + /**
22.147 + * Initiates an orderly shutdown in which previously submitted
22.148 + * tasks are executed, but no new tasks will be accepted.
22.149 + * Invocation has no additional effect if already shut down.
22.150 + *
22.151 + * <p>This method does not wait for previously submitted tasks to
22.152 + * complete execution. Use {@link #awaitTermination awaitTermination}
22.153 + * to do that.
22.154 + *
22.155 + * @throws SecurityException if a security manager exists and
22.156 + * shutting down this ExecutorService may manipulate
22.157 + * threads that the caller is not permitted to modify
22.158 + * because it does not hold {@link
22.159 + * java.lang.RuntimePermission}<tt>("modifyThread")</tt>,
22.160 + * or the security manager's <tt>checkAccess</tt> method
22.161 + * denies access.
22.162 + */
22.163 + void shutdown();
22.164 +
22.165 + /**
22.166 + * Attempts to stop all actively executing tasks, halts the
22.167 + * processing of waiting tasks, and returns a list of the tasks
22.168 + * that were awaiting execution.
22.169 + *
22.170 + * <p>This method does not wait for actively executing tasks to
22.171 + * terminate. Use {@link #awaitTermination awaitTermination} to
22.172 + * do that.
22.173 + *
22.174 + * <p>There are no guarantees beyond best-effort attempts to stop
22.175 + * processing actively executing tasks. For example, typical
22.176 + * implementations will cancel via {@link Thread#interrupt}, so any
22.177 + * task that fails to respond to interrupts may never terminate.
22.178 + *
22.179 + * @return list of tasks that never commenced execution
22.180 + * @throws SecurityException if a security manager exists and
22.181 + * shutting down this ExecutorService may manipulate
22.182 + * threads that the caller is not permitted to modify
22.183 + * because it does not hold {@link
22.184 + * java.lang.RuntimePermission}<tt>("modifyThread")</tt>,
22.185 + * or the security manager's <tt>checkAccess</tt> method
22.186 + * denies access.
22.187 + */
22.188 + List<Runnable> shutdownNow();
22.189 +
22.190 + /**
22.191 + * Returns <tt>true</tt> if this executor has been shut down.
22.192 + *
22.193 + * @return <tt>true</tt> if this executor has been shut down
22.194 + */
22.195 + boolean isShutdown();
22.196 +
22.197 + /**
22.198 + * Returns <tt>true</tt> if all tasks have completed following shut down.
22.199 + * Note that <tt>isTerminated</tt> is never <tt>true</tt> unless
22.200 + * either <tt>shutdown</tt> or <tt>shutdownNow</tt> was called first.
22.201 + *
22.202 + * @return <tt>true</tt> if all tasks have completed following shut down
22.203 + */
22.204 + boolean isTerminated();
22.205 +
22.206 + /**
22.207 + * Blocks until all tasks have completed execution after a shutdown
22.208 + * request, or the timeout occurs, or the current thread is
22.209 + * interrupted, whichever happens first.
22.210 + *
22.211 + * @param timeout the maximum time to wait
22.212 + * @param unit the time unit of the timeout argument
22.213 + * @return <tt>true</tt> if this executor terminated and
22.214 + * <tt>false</tt> if the timeout elapsed before termination
22.215 + * @throws InterruptedException if interrupted while waiting
22.216 + */
22.217 + boolean awaitTermination(long timeout, TimeUnit unit)
22.218 + throws InterruptedException;
22.219 +
22.220 +
22.221 + /**
22.222 + * Submits a value-returning task for execution and returns a
22.223 + * Future representing the pending results of the task. The
22.224 + * Future's <tt>get</tt> method will return the task's result upon
22.225 + * successful completion.
22.226 + *
22.227 + * <p>
22.228 + * If you would like to immediately block waiting
22.229 + * for a task, you can use constructions of the form
22.230 + * <tt>result = exec.submit(aCallable).get();</tt>
22.231 + *
22.232 + * <p> Note: The {@link Executors} class includes a set of methods
22.233 + * that can convert some other common closure-like objects,
22.234 + * for example, {@link java.security.PrivilegedAction} to
22.235 + * {@link Callable} form so they can be submitted.
22.236 + *
22.237 + * @param task the task to submit
22.238 + * @return a Future representing pending completion of the task
22.239 + * @throws RejectedExecutionException if the task cannot be
22.240 + * scheduled for execution
22.241 + * @throws NullPointerException if the task is null
22.242 + */
22.243 + <T> Future<T> submit(Callable<T> task);
22.244 +
22.245 + /**
22.246 + * Submits a Runnable task for execution and returns a Future
22.247 + * representing that task. The Future's <tt>get</tt> method will
22.248 + * return the given result upon successful completion.
22.249 + *
22.250 + * @param task the task to submit
22.251 + * @param result the result to return
22.252 + * @return a Future representing pending completion of the task
22.253 + * @throws RejectedExecutionException if the task cannot be
22.254 + * scheduled for execution
22.255 + * @throws NullPointerException if the task is null
22.256 + */
22.257 + <T> Future<T> submit(Runnable task, T result);
22.258 +
22.259 + /**
22.260 + * Submits a Runnable task for execution and returns a Future
22.261 + * representing that task. The Future's <tt>get</tt> method will
22.262 + * return <tt>null</tt> upon <em>successful</em> completion.
22.263 + *
22.264 + * @param task the task to submit
22.265 + * @return a Future representing pending completion of the task
22.266 + * @throws RejectedExecutionException if the task cannot be
22.267 + * scheduled for execution
22.268 + * @throws NullPointerException if the task is null
22.269 + */
22.270 + Future<?> submit(Runnable task);
22.271 +
22.272 + /**
22.273 + * Executes the given tasks, returning a list of Futures holding
22.274 + * their status and results when all complete.
22.275 + * {@link Future#isDone} is <tt>true</tt> for each
22.276 + * element of the returned list.
22.277 + * Note that a <em>completed</em> task could have
22.278 + * terminated either normally or by throwing an exception.
22.279 + * The results of this method are undefined if the given
22.280 + * collection is modified while this operation is in progress.
22.281 + *
22.282 + * @param tasks the collection of tasks
22.283 + * @return A list of Futures representing the tasks, in the same
22.284 + * sequential order as produced by the iterator for the
22.285 + * given task list, each of which has completed.
22.286 + * @throws InterruptedException if interrupted while waiting, in
22.287 + * which case unfinished tasks are cancelled.
22.288 + * @throws NullPointerException if tasks or any of its elements are <tt>null</tt>
22.289 + * @throws RejectedExecutionException if any task cannot be
22.290 + * scheduled for execution
22.291 + */
22.292 +
22.293 + <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
22.294 + throws InterruptedException;
22.295 +
22.296 + /**
22.297 + * Executes the given tasks, returning a list of Futures holding
22.298 + * their status and results
22.299 + * when all complete or the timeout expires, whichever happens first.
22.300 + * {@link Future#isDone} is <tt>true</tt> for each
22.301 + * element of the returned list.
22.302 + * Upon return, tasks that have not completed are cancelled.
22.303 + * Note that a <em>completed</em> task could have
22.304 + * terminated either normally or by throwing an exception.
22.305 + * The results of this method are undefined if the given
22.306 + * collection is modified while this operation is in progress.
22.307 + *
22.308 + * @param tasks the collection of tasks
22.309 + * @param timeout the maximum time to wait
22.310 + * @param unit the time unit of the timeout argument
22.311 + * @return a list of Futures representing the tasks, in the same
22.312 + * sequential order as produced by the iterator for the
22.313 + * given task list. If the operation did not time out,
22.314 + * each task will have completed. If it did time out, some
22.315 + * of these tasks will not have completed.
22.316 + * @throws InterruptedException if interrupted while waiting, in
22.317 + * which case unfinished tasks are cancelled
22.318 + * @throws NullPointerException if tasks, any of its elements, or
22.319 + * unit are <tt>null</tt>
22.320 + * @throws RejectedExecutionException if any task cannot be scheduled
22.321 + * for execution
22.322 + */
22.323 + <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
22.324 + long timeout, TimeUnit unit)
22.325 + throws InterruptedException;
22.326 +
22.327 + /**
22.328 + * Executes the given tasks, returning the result
22.329 + * of one that has completed successfully (i.e., without throwing
22.330 + * an exception), if any do. Upon normal or exceptional return,
22.331 + * tasks that have not completed are cancelled.
22.332 + * The results of this method are undefined if the given
22.333 + * collection is modified while this operation is in progress.
22.334 + *
22.335 + * @param tasks the collection of tasks
22.336 + * @return the result returned by one of the tasks
22.337 + * @throws InterruptedException if interrupted while waiting
22.338 + * @throws NullPointerException if tasks or any element task
22.339 + * subject to execution is <tt>null</tt>
22.340 + * @throws IllegalArgumentException if tasks is empty
22.341 + * @throws ExecutionException if no task successfully completes
22.342 + * @throws RejectedExecutionException if tasks cannot be scheduled
22.343 + * for execution
22.344 + */
22.345 + <T> T invokeAny(Collection<? extends Callable<T>> tasks)
22.346 + throws InterruptedException, ExecutionException;
22.347 +
22.348 + /**
22.349 + * Executes the given tasks, returning the result
22.350 + * of one that has completed successfully (i.e., without throwing
22.351 + * an exception), if any do before the given timeout elapses.
22.352 + * Upon normal or exceptional return, tasks that have not
22.353 + * completed are cancelled.
22.354 + * The results of this method are undefined if the given
22.355 + * collection is modified while this operation is in progress.
22.356 + *
22.357 + * @param tasks the collection of tasks
22.358 + * @param timeout the maximum time to wait
22.359 + * @param unit the time unit of the timeout argument
22.360 + * @return the result returned by one of the tasks.
22.361 + * @throws InterruptedException if interrupted while waiting
22.362 + * @throws NullPointerException if tasks, or unit, or any element
22.363 + * task subject to execution is <tt>null</tt>
22.364 + * @throws TimeoutException if the given timeout elapses before
22.365 + * any task successfully completes
22.366 + * @throws ExecutionException if no task successfully completes
22.367 + * @throws RejectedExecutionException if tasks cannot be scheduled
22.368 + * for execution
22.369 + */
22.370 + <T> T invokeAny(Collection<? extends Callable<T>> tasks,
22.371 + long timeout, TimeUnit unit)
22.372 + throws InterruptedException, ExecutionException, TimeoutException;
22.373 +}
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
23.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/Executors.java Sat Mar 19 10:48:29 2016 +0100
23.3 @@ -0,0 +1,706 @@
23.4 +/*
23.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
23.6 + *
23.7 + * This code is free software; you can redistribute it and/or modify it
23.8 + * under the terms of the GNU General Public License version 2 only, as
23.9 + * published by the Free Software Foundation. Oracle designates this
23.10 + * particular file as subject to the "Classpath" exception as provided
23.11 + * by Oracle in the LICENSE file that accompanied this code.
23.12 + *
23.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
23.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23.16 + * version 2 for more details (a copy is included in the LICENSE file that
23.17 + * accompanied this code).
23.18 + *
23.19 + * You should have received a copy of the GNU General Public License version
23.20 + * 2 along with this work; if not, write to the Free Software Foundation,
23.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
23.22 + *
23.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23.24 + * or visit www.oracle.com if you need additional information or have any
23.25 + * questions.
23.26 + */
23.27 +
23.28 +/*
23.29 + * This file is available under and governed by the GNU General Public
23.30 + * License version 2 only, as published by the Free Software Foundation.
23.31 + * However, the following notice accompanied the original version of this
23.32 + * file:
23.33 + *
23.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
23.35 + * Expert Group and released to the public domain, as explained at
23.36 + * http://creativecommons.org/publicdomain/zero/1.0/
23.37 + */
23.38 +
23.39 +package java.util.concurrent;
23.40 +import java.util.*;
23.41 +import java.util.concurrent.atomic.AtomicInteger;
23.42 +import java.security.AccessControlContext;
23.43 +import java.security.AccessController;
23.44 +import java.security.PrivilegedAction;
23.45 +import java.security.PrivilegedExceptionAction;
23.46 +import java.security.PrivilegedActionException;
23.47 +import java.security.AccessControlException;
23.48 +import sun.security.util.SecurityConstants;
23.49 +
23.50 +/**
23.51 + * Factory and utility methods for {@link Executor}, {@link
23.52 + * ExecutorService}, {@link ScheduledExecutorService}, {@link
23.53 + * ThreadFactory}, and {@link Callable} classes defined in this
23.54 + * package. This class supports the following kinds of methods:
23.55 + *
23.56 + * <ul>
23.57 + * <li> Methods that create and return an {@link ExecutorService}
23.58 + * set up with commonly useful configuration settings.
23.59 + * <li> Methods that create and return a {@link ScheduledExecutorService}
23.60 + * set up with commonly useful configuration settings.
23.61 + * <li> Methods that create and return a "wrapped" ExecutorService, that
23.62 + * disables reconfiguration by making implementation-specific methods
23.63 + * inaccessible.
23.64 + * <li> Methods that create and return a {@link ThreadFactory}
23.65 + * that sets newly created threads to a known state.
23.66 + * <li> Methods that create and return a {@link Callable}
23.67 + * out of other closure-like forms, so they can be used
23.68 + * in execution methods requiring <tt>Callable</tt>.
23.69 + * </ul>
23.70 + *
23.71 + * @since 1.5
23.72 + * @author Doug Lea
23.73 + */
23.74 +public class Executors {
23.75 +
23.76 + /**
23.77 + * Creates a thread pool that reuses a fixed number of threads
23.78 + * operating off a shared unbounded queue. At any point, at most
23.79 + * <tt>nThreads</tt> threads will be active processing tasks.
23.80 + * If additional tasks are submitted when all threads are active,
23.81 + * they will wait in the queue until a thread is available.
23.82 + * If any thread terminates due to a failure during execution
23.83 + * prior to shutdown, a new one will take its place if needed to
23.84 + * execute subsequent tasks. The threads in the pool will exist
23.85 + * until it is explicitly {@link ExecutorService#shutdown shutdown}.
23.86 + *
23.87 + * @param nThreads the number of threads in the pool
23.88 + * @return the newly created thread pool
23.89 + * @throws IllegalArgumentException if {@code nThreads <= 0}
23.90 + */
23.91 + public static ExecutorService newFixedThreadPool(int nThreads) {
23.92 + return new ThreadPoolExecutor(nThreads, nThreads,
23.93 + 0L, TimeUnit.MILLISECONDS,
23.94 + new LinkedBlockingQueue<Runnable>());
23.95 + }
23.96 +
23.97 + /**
23.98 + * Creates a thread pool that reuses a fixed number of threads
23.99 + * operating off a shared unbounded queue, using the provided
23.100 + * ThreadFactory to create new threads when needed. At any point,
23.101 + * at most <tt>nThreads</tt> threads will be active processing
23.102 + * tasks. If additional tasks are submitted when all threads are
23.103 + * active, they will wait in the queue until a thread is
23.104 + * available. If any thread terminates due to a failure during
23.105 + * execution prior to shutdown, a new one will take its place if
23.106 + * needed to execute subsequent tasks. The threads in the pool will
23.107 + * exist until it is explicitly {@link ExecutorService#shutdown
23.108 + * shutdown}.
23.109 + *
23.110 + * @param nThreads the number of threads in the pool
23.111 + * @param threadFactory the factory to use when creating new threads
23.112 + * @return the newly created thread pool
23.113 + * @throws NullPointerException if threadFactory is null
23.114 + * @throws IllegalArgumentException if {@code nThreads <= 0}
23.115 + */
23.116 + public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
23.117 + return new ThreadPoolExecutor(nThreads, nThreads,
23.118 + 0L, TimeUnit.MILLISECONDS,
23.119 + new LinkedBlockingQueue<Runnable>(),
23.120 + threadFactory);
23.121 + }
23.122 +
23.123 + /**
23.124 + * Creates an Executor that uses a single worker thread operating
23.125 + * off an unbounded queue. (Note however that if this single
23.126 + * thread terminates due to a failure during execution prior to
23.127 + * shutdown, a new one will take its place if needed to execute
23.128 + * subsequent tasks.) Tasks are guaranteed to execute
23.129 + * sequentially, and no more than one task will be active at any
23.130 + * given time. Unlike the otherwise equivalent
23.131 + * <tt>newFixedThreadPool(1)</tt> the returned executor is
23.132 + * guaranteed not to be reconfigurable to use additional threads.
23.133 + *
23.134 + * @return the newly created single-threaded Executor
23.135 + */
23.136 + public static ExecutorService newSingleThreadExecutor() {
23.137 + return new FinalizableDelegatedExecutorService
23.138 + (new ThreadPoolExecutor(1, 1,
23.139 + 0L, TimeUnit.MILLISECONDS,
23.140 + new LinkedBlockingQueue<Runnable>()));
23.141 + }
23.142 +
23.143 + /**
23.144 + * Creates an Executor that uses a single worker thread operating
23.145 + * off an unbounded queue, and uses the provided ThreadFactory to
23.146 + * create a new thread when needed. Unlike the otherwise
23.147 + * equivalent <tt>newFixedThreadPool(1, threadFactory)</tt> the
23.148 + * returned executor is guaranteed not to be reconfigurable to use
23.149 + * additional threads.
23.150 + *
23.151 + * @param threadFactory the factory to use when creating new
23.152 + * threads
23.153 + *
23.154 + * @return the newly created single-threaded Executor
23.155 + * @throws NullPointerException if threadFactory is null
23.156 + */
23.157 + public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
23.158 + return new FinalizableDelegatedExecutorService
23.159 + (new ThreadPoolExecutor(1, 1,
23.160 + 0L, TimeUnit.MILLISECONDS,
23.161 + new LinkedBlockingQueue<Runnable>(),
23.162 + threadFactory));
23.163 + }
23.164 +
23.165 + /**
23.166 + * Creates a thread pool that creates new threads as needed, but
23.167 + * will reuse previously constructed threads when they are
23.168 + * available. These pools will typically improve the performance
23.169 + * of programs that execute many short-lived asynchronous tasks.
23.170 + * Calls to <tt>execute</tt> will reuse previously constructed
23.171 + * threads if available. If no existing thread is available, a new
23.172 + * thread will be created and added to the pool. Threads that have
23.173 + * not been used for sixty seconds are terminated and removed from
23.174 + * the cache. Thus, a pool that remains idle for long enough will
23.175 + * not consume any resources. Note that pools with similar
23.176 + * properties but different details (for example, timeout parameters)
23.177 + * may be created using {@link ThreadPoolExecutor} constructors.
23.178 + *
23.179 + * @return the newly created thread pool
23.180 + */
23.181 + public static ExecutorService newCachedThreadPool() {
23.182 + return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
23.183 + 60L, TimeUnit.SECONDS,
23.184 + new SynchronousQueue<Runnable>());
23.185 + }
23.186 +
23.187 + /**
23.188 + * Creates a thread pool that creates new threads as needed, but
23.189 + * will reuse previously constructed threads when they are
23.190 + * available, and uses the provided
23.191 + * ThreadFactory to create new threads when needed.
23.192 + * @param threadFactory the factory to use when creating new threads
23.193 + * @return the newly created thread pool
23.194 + * @throws NullPointerException if threadFactory is null
23.195 + */
23.196 + public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
23.197 + return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
23.198 + 60L, TimeUnit.SECONDS,
23.199 + new SynchronousQueue<Runnable>(),
23.200 + threadFactory);
23.201 + }
23.202 +
23.203 + /**
23.204 + * Creates a single-threaded executor that can schedule commands
23.205 + * to run after a given delay, or to execute periodically.
23.206 + * (Note however that if this single
23.207 + * thread terminates due to a failure during execution prior to
23.208 + * shutdown, a new one will take its place if needed to execute
23.209 + * subsequent tasks.) Tasks are guaranteed to execute
23.210 + * sequentially, and no more than one task will be active at any
23.211 + * given time. Unlike the otherwise equivalent
23.212 + * <tt>newScheduledThreadPool(1)</tt> the returned executor is
23.213 + * guaranteed not to be reconfigurable to use additional threads.
23.214 + * @return the newly created scheduled executor
23.215 + */
23.216 + public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
23.217 + return new DelegatedScheduledExecutorService
23.218 + (new ScheduledThreadPoolExecutor(1));
23.219 + }
23.220 +
23.221 + /**
23.222 + * Creates a single-threaded executor that can schedule commands
23.223 + * to run after a given delay, or to execute periodically. (Note
23.224 + * however that if this single thread terminates due to a failure
23.225 + * during execution prior to shutdown, a new one will take its
23.226 + * place if needed to execute subsequent tasks.) Tasks are
23.227 + * guaranteed to execute sequentially, and no more than one task
23.228 + * will be active at any given time. Unlike the otherwise
23.229 + * equivalent <tt>newScheduledThreadPool(1, threadFactory)</tt>
23.230 + * the returned executor is guaranteed not to be reconfigurable to
23.231 + * use additional threads.
23.232 + * @param threadFactory the factory to use when creating new
23.233 + * threads
23.234 + * @return a newly created scheduled executor
23.235 + * @throws NullPointerException if threadFactory is null
23.236 + */
23.237 + public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) {
23.238 + return new DelegatedScheduledExecutorService
23.239 + (new ScheduledThreadPoolExecutor(1, threadFactory));
23.240 + }
23.241 +
23.242 + /**
23.243 + * Creates a thread pool that can schedule commands to run after a
23.244 + * given delay, or to execute periodically.
23.245 + * @param corePoolSize the number of threads to keep in the pool,
23.246 + * even if they are idle.
23.247 + * @return a newly created scheduled thread pool
23.248 + * @throws IllegalArgumentException if {@code corePoolSize < 0}
23.249 + */
23.250 + public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
23.251 + return new ScheduledThreadPoolExecutor(corePoolSize);
23.252 + }
23.253 +
23.254 + /**
23.255 + * Creates a thread pool that can schedule commands to run after a
23.256 + * given delay, or to execute periodically.
23.257 + * @param corePoolSize the number of threads to keep in the pool,
23.258 + * even if they are idle.
23.259 + * @param threadFactory the factory to use when the executor
23.260 + * creates a new thread.
23.261 + * @return a newly created scheduled thread pool
23.262 + * @throws IllegalArgumentException if {@code corePoolSize < 0}
23.263 + * @throws NullPointerException if threadFactory is null
23.264 + */
23.265 + public static ScheduledExecutorService newScheduledThreadPool(
23.266 + int corePoolSize, ThreadFactory threadFactory) {
23.267 + return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
23.268 + }
23.269 +
23.270 +
23.271 + /**
23.272 + * Returns an object that delegates all defined {@link
23.273 + * ExecutorService} methods to the given executor, but not any
23.274 + * other methods that might otherwise be accessible using
23.275 + * casts. This provides a way to safely "freeze" configuration and
23.276 + * disallow tuning of a given concrete implementation.
23.277 + * @param executor the underlying implementation
23.278 + * @return an <tt>ExecutorService</tt> instance
23.279 + * @throws NullPointerException if executor null
23.280 + */
23.281 + public static ExecutorService unconfigurableExecutorService(ExecutorService executor) {
23.282 + if (executor == null)
23.283 + throw new NullPointerException();
23.284 + return new DelegatedExecutorService(executor);
23.285 + }
23.286 +
23.287 + /**
23.288 + * Returns an object that delegates all defined {@link
23.289 + * ScheduledExecutorService} methods to the given executor, but
23.290 + * not any other methods that might otherwise be accessible using
23.291 + * casts. This provides a way to safely "freeze" configuration and
23.292 + * disallow tuning of a given concrete implementation.
23.293 + * @param executor the underlying implementation
23.294 + * @return a <tt>ScheduledExecutorService</tt> instance
23.295 + * @throws NullPointerException if executor null
23.296 + */
23.297 + public static ScheduledExecutorService unconfigurableScheduledExecutorService(ScheduledExecutorService executor) {
23.298 + if (executor == null)
23.299 + throw new NullPointerException();
23.300 + return new DelegatedScheduledExecutorService(executor);
23.301 + }
23.302 +
23.303 + /**
23.304 + * Returns a default thread factory used to create new threads.
23.305 + * This factory creates all new threads used by an Executor in the
23.306 + * same {@link ThreadGroup}. If there is a {@link
23.307 + * java.lang.SecurityManager}, it uses the group of {@link
23.308 + * System#getSecurityManager}, else the group of the thread
23.309 + * invoking this <tt>defaultThreadFactory</tt> method. Each new
23.310 + * thread is created as a non-daemon thread with priority set to
23.311 + * the smaller of <tt>Thread.NORM_PRIORITY</tt> and the maximum
23.312 + * priority permitted in the thread group. New threads have names
23.313 + * accessible via {@link Thread#getName} of
23.314 + * <em>pool-N-thread-M</em>, where <em>N</em> is the sequence
23.315 + * number of this factory, and <em>M</em> is the sequence number
23.316 + * of the thread created by this factory.
23.317 + * @return a thread factory
23.318 + */
23.319 + public static ThreadFactory defaultThreadFactory() {
23.320 + return new DefaultThreadFactory();
23.321 + }
23.322 +
23.323 + /**
23.324 + * Returns a thread factory used to create new threads that
23.325 + * have the same permissions as the current thread.
23.326 + * This factory creates threads with the same settings as {@link
23.327 + * Executors#defaultThreadFactory}, additionally setting the
23.328 + * AccessControlContext and contextClassLoader of new threads to
23.329 + * be the same as the thread invoking this
23.330 + * <tt>privilegedThreadFactory</tt> method. A new
23.331 + * <tt>privilegedThreadFactory</tt> can be created within an
23.332 + * {@link AccessController#doPrivileged} action setting the
23.333 + * current thread's access control context to create threads with
23.334 + * the selected permission settings holding within that action.
23.335 + *
23.336 + * <p> Note that while tasks running within such threads will have
23.337 + * the same access control and class loader settings as the
23.338 + * current thread, they need not have the same {@link
23.339 + * java.lang.ThreadLocal} or {@link
23.340 + * java.lang.InheritableThreadLocal} values. If necessary,
23.341 + * particular values of thread locals can be set or reset before
23.342 + * any task runs in {@link ThreadPoolExecutor} subclasses using
23.343 + * {@link ThreadPoolExecutor#beforeExecute}. Also, if it is
23.344 + * necessary to initialize worker threads to have the same
23.345 + * InheritableThreadLocal settings as some other designated
23.346 + * thread, you can create a custom ThreadFactory in which that
23.347 + * thread waits for and services requests to create others that
23.348 + * will inherit its values.
23.349 + *
23.350 + * @return a thread factory
23.351 + * @throws AccessControlException if the current access control
23.352 + * context does not have permission to both get and set context
23.353 + * class loader.
23.354 + */
23.355 + public static ThreadFactory privilegedThreadFactory() {
23.356 + return new PrivilegedThreadFactory();
23.357 + }
23.358 +
23.359 + /**
23.360 + * Returns a {@link Callable} object that, when
23.361 + * called, runs the given task and returns the given result. This
23.362 + * can be useful when applying methods requiring a
23.363 + * <tt>Callable</tt> to an otherwise resultless action.
23.364 + * @param task the task to run
23.365 + * @param result the result to return
23.366 + * @return a callable object
23.367 + * @throws NullPointerException if task null
23.368 + */
23.369 + public static <T> Callable<T> callable(Runnable task, T result) {
23.370 + if (task == null)
23.371 + throw new NullPointerException();
23.372 + return new RunnableAdapter<T>(task, result);
23.373 + }
23.374 +
23.375 + /**
23.376 + * Returns a {@link Callable} object that, when
23.377 + * called, runs the given task and returns <tt>null</tt>.
23.378 + * @param task the task to run
23.379 + * @return a callable object
23.380 + * @throws NullPointerException if task null
23.381 + */
23.382 + public static Callable<Object> callable(Runnable task) {
23.383 + if (task == null)
23.384 + throw new NullPointerException();
23.385 + return new RunnableAdapter<Object>(task, null);
23.386 + }
23.387 +
23.388 + /**
23.389 + * Returns a {@link Callable} object that, when
23.390 + * called, runs the given privileged action and returns its result.
23.391 + * @param action the privileged action to run
23.392 + * @return a callable object
23.393 + * @throws NullPointerException if action null
23.394 + */
23.395 + public static Callable<Object> callable(final PrivilegedAction<?> action) {
23.396 + if (action == null)
23.397 + throw new NullPointerException();
23.398 + return new Callable<Object>() {
23.399 + public Object call() { return action.run(); }};
23.400 + }
23.401 +
23.402 + /**
23.403 + * Returns a {@link Callable} object that, when
23.404 + * called, runs the given privileged exception action and returns
23.405 + * its result.
23.406 + * @param action the privileged exception action to run
23.407 + * @return a callable object
23.408 + * @throws NullPointerException if action null
23.409 + */
23.410 + public static Callable<Object> callable(final PrivilegedExceptionAction<?> action) {
23.411 + if (action == null)
23.412 + throw new NullPointerException();
23.413 + return new Callable<Object>() {
23.414 + public Object call() throws Exception { return action.run(); }};
23.415 + }
23.416 +
23.417 + /**
23.418 + * Returns a {@link Callable} object that will, when
23.419 + * called, execute the given <tt>callable</tt> under the current
23.420 + * access control context. This method should normally be
23.421 + * invoked within an {@link AccessController#doPrivileged} action
23.422 + * to create callables that will, if possible, execute under the
23.423 + * selected permission settings holding within that action; or if
23.424 + * not possible, throw an associated {@link
23.425 + * AccessControlException}.
23.426 + * @param callable the underlying task
23.427 + * @return a callable object
23.428 + * @throws NullPointerException if callable null
23.429 + *
23.430 + */
23.431 + public static <T> Callable<T> privilegedCallable(Callable<T> callable) {
23.432 + if (callable == null)
23.433 + throw new NullPointerException();
23.434 + return new PrivilegedCallable<T>(callable);
23.435 + }
23.436 +
23.437 + /**
23.438 + * Returns a {@link Callable} object that will, when
23.439 + * called, execute the given <tt>callable</tt> under the current
23.440 + * access control context, with the current context class loader
23.441 + * as the context class loader. This method should normally be
23.442 + * invoked within an {@link AccessController#doPrivileged} action
23.443 + * to create callables that will, if possible, execute under the
23.444 + * selected permission settings holding within that action; or if
23.445 + * not possible, throw an associated {@link
23.446 + * AccessControlException}.
23.447 + * @param callable the underlying task
23.448 + *
23.449 + * @return a callable object
23.450 + * @throws NullPointerException if callable null
23.451 + * @throws AccessControlException if the current access control
23.452 + * context does not have permission to both set and get context
23.453 + * class loader.
23.454 + */
23.455 + public static <T> Callable<T> privilegedCallableUsingCurrentClassLoader(Callable<T> callable) {
23.456 + if (callable == null)
23.457 + throw new NullPointerException();
23.458 + return new PrivilegedCallableUsingCurrentClassLoader<T>(callable);
23.459 + }
23.460 +
23.461 + // Non-public classes supporting the public methods
23.462 +
23.463 + /**
23.464 + * A callable that runs given task and returns given result
23.465 + */
23.466 + static final class RunnableAdapter<T> implements Callable<T> {
23.467 + final Runnable task;
23.468 + final T result;
23.469 + RunnableAdapter(Runnable task, T result) {
23.470 + this.task = task;
23.471 + this.result = result;
23.472 + }
23.473 + public T call() {
23.474 + task.run();
23.475 + return result;
23.476 + }
23.477 + }
23.478 +
23.479 + /**
23.480 + * A callable that runs under established access control settings
23.481 + */
23.482 + static final class PrivilegedCallable<T> implements Callable<T> {
23.483 + private final Callable<T> task;
23.484 + private final AccessControlContext acc;
23.485 +
23.486 + PrivilegedCallable(Callable<T> task) {
23.487 + this.task = task;
23.488 + this.acc = AccessController.getContext();
23.489 + }
23.490 +
23.491 + public T call() throws Exception {
23.492 + try {
23.493 + return AccessController.doPrivileged(
23.494 + new PrivilegedExceptionAction<T>() {
23.495 + public T run() throws Exception {
23.496 + return task.call();
23.497 + }
23.498 + }, acc);
23.499 + } catch (PrivilegedActionException e) {
23.500 + throw e.getException();
23.501 + }
23.502 + }
23.503 + }
23.504 +
23.505 + /**
23.506 + * A callable that runs under established access control settings and
23.507 + * current ClassLoader
23.508 + */
23.509 + static final class PrivilegedCallableUsingCurrentClassLoader<T> implements Callable<T> {
23.510 + private final Callable<T> task;
23.511 + private final AccessControlContext acc;
23.512 + private final ClassLoader ccl;
23.513 +
23.514 + PrivilegedCallableUsingCurrentClassLoader(Callable<T> task) {
23.515 + SecurityManager sm = System.getSecurityManager();
23.516 + if (sm != null) {
23.517 + // Calls to getContextClassLoader from this class
23.518 + // never trigger a security check, but we check
23.519 + // whether our callers have this permission anyways.
23.520 + sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
23.521 +
23.522 + // Whether setContextClassLoader turns out to be necessary
23.523 + // or not, we fail fast if permission is not available.
23.524 + sm.checkPermission(new RuntimePermission("setContextClassLoader"));
23.525 + }
23.526 + this.task = task;
23.527 + this.acc = AccessController.getContext();
23.528 + this.ccl = Thread.currentThread().getContextClassLoader();
23.529 + }
23.530 +
23.531 + public T call() throws Exception {
23.532 + try {
23.533 + return AccessController.doPrivileged(
23.534 + new PrivilegedExceptionAction<T>() {
23.535 + public T run() throws Exception {
23.536 + ClassLoader savedcl = null;
23.537 + Thread t = Thread.currentThread();
23.538 + try {
23.539 + ClassLoader cl = t.getContextClassLoader();
23.540 + if (ccl != cl) {
23.541 + t.setContextClassLoader(ccl);
23.542 + savedcl = cl;
23.543 + }
23.544 + return task.call();
23.545 + } finally {
23.546 + if (savedcl != null)
23.547 + t.setContextClassLoader(savedcl);
23.548 + }
23.549 + }
23.550 + }, acc);
23.551 + } catch (PrivilegedActionException e) {
23.552 + throw e.getException();
23.553 + }
23.554 + }
23.555 + }
23.556 +
23.557 + /**
23.558 + * The default thread factory
23.559 + */
23.560 + static class DefaultThreadFactory implements ThreadFactory {
23.561 + private static final AtomicInteger poolNumber = new AtomicInteger(1);
23.562 + private final ThreadGroup group;
23.563 + private final AtomicInteger threadNumber = new AtomicInteger(1);
23.564 + private final String namePrefix;
23.565 +
23.566 + DefaultThreadFactory() {
23.567 + SecurityManager s = System.getSecurityManager();
23.568 + group = (s != null) ? s.getThreadGroup() :
23.569 + Thread.currentThread().getThreadGroup();
23.570 + namePrefix = "pool-" +
23.571 + poolNumber.getAndIncrement() +
23.572 + "-thread-";
23.573 + }
23.574 +
23.575 + public Thread newThread(Runnable r) {
23.576 + Thread t = new Thread(group, r,
23.577 + namePrefix + threadNumber.getAndIncrement(),
23.578 + 0);
23.579 + if (t.isDaemon())
23.580 + t.setDaemon(false);
23.581 + if (t.getPriority() != Thread.NORM_PRIORITY)
23.582 + t.setPriority(Thread.NORM_PRIORITY);
23.583 + return t;
23.584 + }
23.585 + }
23.586 +
23.587 + /**
23.588 + * Thread factory capturing access control context and class loader
23.589 + */
23.590 + static class PrivilegedThreadFactory extends DefaultThreadFactory {
23.591 + private final AccessControlContext acc;
23.592 + private final ClassLoader ccl;
23.593 +
23.594 + PrivilegedThreadFactory() {
23.595 + super();
23.596 + SecurityManager sm = System.getSecurityManager();
23.597 + if (sm != null) {
23.598 + // Calls to getContextClassLoader from this class
23.599 + // never trigger a security check, but we check
23.600 + // whether our callers have this permission anyways.
23.601 + sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
23.602 +
23.603 + // Fail fast
23.604 + sm.checkPermission(new RuntimePermission("setContextClassLoader"));
23.605 + }
23.606 + this.acc = AccessController.getContext();
23.607 + this.ccl = Thread.currentThread().getContextClassLoader();
23.608 + }
23.609 +
23.610 + public Thread newThread(final Runnable r) {
23.611 + return super.newThread(new Runnable() {
23.612 + public void run() {
23.613 + AccessController.doPrivileged(new PrivilegedAction<Void>() {
23.614 + public Void run() {
23.615 + Thread.currentThread().setContextClassLoader(ccl);
23.616 + r.run();
23.617 + return null;
23.618 + }
23.619 + }, acc);
23.620 + }
23.621 + });
23.622 + }
23.623 + }
23.624 +
23.625 + /**
23.626 + * A wrapper class that exposes only the ExecutorService methods
23.627 + * of an ExecutorService implementation.
23.628 + */
23.629 + static class DelegatedExecutorService extends AbstractExecutorService {
23.630 + private final ExecutorService e;
23.631 + DelegatedExecutorService(ExecutorService executor) { e = executor; }
23.632 + public void execute(Runnable command) { e.execute(command); }
23.633 + public void shutdown() { e.shutdown(); }
23.634 + public List<Runnable> shutdownNow() { return e.shutdownNow(); }
23.635 + public boolean isShutdown() { return e.isShutdown(); }
23.636 + public boolean isTerminated() { return e.isTerminated(); }
23.637 + public boolean awaitTermination(long timeout, TimeUnit unit)
23.638 + throws InterruptedException {
23.639 + return e.awaitTermination(timeout, unit);
23.640 + }
23.641 + public Future<?> submit(Runnable task) {
23.642 + return e.submit(task);
23.643 + }
23.644 + public <T> Future<T> submit(Callable<T> task) {
23.645 + return e.submit(task);
23.646 + }
23.647 + public <T> Future<T> submit(Runnable task, T result) {
23.648 + return e.submit(task, result);
23.649 + }
23.650 + public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
23.651 + throws InterruptedException {
23.652 + return e.invokeAll(tasks);
23.653 + }
23.654 + public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
23.655 + long timeout, TimeUnit unit)
23.656 + throws InterruptedException {
23.657 + return e.invokeAll(tasks, timeout, unit);
23.658 + }
23.659 + public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
23.660 + throws InterruptedException, ExecutionException {
23.661 + return e.invokeAny(tasks);
23.662 + }
23.663 + public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
23.664 + long timeout, TimeUnit unit)
23.665 + throws InterruptedException, ExecutionException, TimeoutException {
23.666 + return e.invokeAny(tasks, timeout, unit);
23.667 + }
23.668 + }
23.669 +
23.670 + static class FinalizableDelegatedExecutorService
23.671 + extends DelegatedExecutorService {
23.672 + FinalizableDelegatedExecutorService(ExecutorService executor) {
23.673 + super(executor);
23.674 + }
23.675 + protected void finalize() {
23.676 + super.shutdown();
23.677 + }
23.678 + }
23.679 +
23.680 + /**
23.681 + * A wrapper class that exposes only the ScheduledExecutorService
23.682 + * methods of a ScheduledExecutorService implementation.
23.683 + */
23.684 + static class DelegatedScheduledExecutorService
23.685 + extends DelegatedExecutorService
23.686 + implements ScheduledExecutorService {
23.687 + private final ScheduledExecutorService e;
23.688 + DelegatedScheduledExecutorService(ScheduledExecutorService executor) {
23.689 + super(executor);
23.690 + e = executor;
23.691 + }
23.692 + public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
23.693 + return e.schedule(command, delay, unit);
23.694 + }
23.695 + public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) {
23.696 + return e.schedule(callable, delay, unit);
23.697 + }
23.698 + public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) {
23.699 + return e.scheduleAtFixedRate(command, initialDelay, period, unit);
23.700 + }
23.701 + public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) {
23.702 + return e.scheduleWithFixedDelay(command, initialDelay, delay, unit);
23.703 + }
23.704 + }
23.705 +
23.706 +
23.707 + /** Cannot instantiate. */
23.708 + private Executors() {}
23.709 +}
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
24.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ForkJoinPool.java Sat Mar 19 10:48:29 2016 +0100
24.3 @@ -0,0 +1,2177 @@
24.4 +/*
24.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
24.6 + *
24.7 + * This code is free software; you can redistribute it and/or modify it
24.8 + * under the terms of the GNU General Public License version 2 only, as
24.9 + * published by the Free Software Foundation. Oracle designates this
24.10 + * particular file as subject to the "Classpath" exception as provided
24.11 + * by Oracle in the LICENSE file that accompanied this code.
24.12 + *
24.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
24.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
24.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24.16 + * version 2 for more details (a copy is included in the LICENSE file that
24.17 + * accompanied this code).
24.18 + *
24.19 + * You should have received a copy of the GNU General Public License version
24.20 + * 2 along with this work; if not, write to the Free Software Foundation,
24.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24.22 + *
24.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
24.24 + * or visit www.oracle.com if you need additional information or have any
24.25 + * questions.
24.26 + */
24.27 +
24.28 +/*
24.29 + * This file is available under and governed by the GNU General Public
24.30 + * License version 2 only, as published by the Free Software Foundation.
24.31 + * However, the following notice accompanied the original version of this
24.32 + * file:
24.33 + *
24.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
24.35 + * Expert Group and released to the public domain, as explained at
24.36 + * http://creativecommons.org/publicdomain/zero/1.0/
24.37 + */
24.38 +
24.39 +package java.util.concurrent;
24.40 +
24.41 +import java.util.ArrayList;
24.42 +import java.util.Arrays;
24.43 +import java.util.Collection;
24.44 +import java.util.Collections;
24.45 +import java.util.List;
24.46 +import java.util.Random;
24.47 +import java.util.concurrent.AbstractExecutorService;
24.48 +import java.util.concurrent.Callable;
24.49 +import java.util.concurrent.ExecutorService;
24.50 +import java.util.concurrent.Future;
24.51 +import java.util.concurrent.RejectedExecutionException;
24.52 +import java.util.concurrent.RunnableFuture;
24.53 +import java.util.concurrent.TimeUnit;
24.54 +import java.util.concurrent.TimeoutException;
24.55 +import java.util.concurrent.atomic.AtomicInteger;
24.56 +import java.util.concurrent.locks.LockSupport;
24.57 +import java.util.concurrent.locks.ReentrantLock;
24.58 +import java.util.concurrent.locks.Condition;
24.59 +
24.60 +/**
24.61 + * An {@link ExecutorService} for running {@link ForkJoinTask}s.
24.62 + * A {@code ForkJoinPool} provides the entry point for submissions
24.63 + * from non-{@code ForkJoinTask} clients, as well as management and
24.64 + * monitoring operations.
24.65 + *
24.66 + * <p>A {@code ForkJoinPool} differs from other kinds of {@link
24.67 + * ExecutorService} mainly by virtue of employing
24.68 + * <em>work-stealing</em>: all threads in the pool attempt to find and
24.69 + * execute subtasks created by other active tasks (eventually blocking
24.70 + * waiting for work if none exist). This enables efficient processing
24.71 + * when most tasks spawn other subtasks (as do most {@code
24.72 + * ForkJoinTask}s). When setting <em>asyncMode</em> to true in
24.73 + * constructors, {@code ForkJoinPool}s may also be appropriate for use
24.74 + * with event-style tasks that are never joined.
24.75 + *
24.76 + * <p>A {@code ForkJoinPool} is constructed with a given target
24.77 + * parallelism level; by default, equal to the number of available
24.78 + * processors. The pool attempts to maintain enough active (or
24.79 + * available) threads by dynamically adding, suspending, or resuming
24.80 + * internal worker threads, even if some tasks are stalled waiting to
24.81 + * join others. However, no such adjustments are guaranteed in the
24.82 + * face of blocked IO or other unmanaged synchronization. The nested
24.83 + * {@link ManagedBlocker} interface enables extension of the kinds of
24.84 + * synchronization accommodated.
24.85 + *
24.86 + * <p>In addition to execution and lifecycle control methods, this
24.87 + * class provides status check methods (for example
24.88 + * {@link #getStealCount}) that are intended to aid in developing,
24.89 + * tuning, and monitoring fork/join applications. Also, method
24.90 + * {@link #toString} returns indications of pool state in a
24.91 + * convenient form for informal monitoring.
24.92 + *
24.93 + * <p> As is the case with other ExecutorServices, there are three
24.94 + * main task execution methods summarized in the following
24.95 + * table. These are designed to be used by clients not already engaged
24.96 + * in fork/join computations in the current pool. The main forms of
24.97 + * these methods accept instances of {@code ForkJoinTask}, but
24.98 + * overloaded forms also allow mixed execution of plain {@code
24.99 + * Runnable}- or {@code Callable}- based activities as well. However,
24.100 + * tasks that are already executing in a pool should normally
24.101 + * <em>NOT</em> use these pool execution methods, but instead use the
24.102 + * within-computation forms listed in the table.
24.103 + *
24.104 + * <table BORDER CELLPADDING=3 CELLSPACING=1>
24.105 + * <tr>
24.106 + * <td></td>
24.107 + * <td ALIGN=CENTER> <b>Call from non-fork/join clients</b></td>
24.108 + * <td ALIGN=CENTER> <b>Call from within fork/join computations</b></td>
24.109 + * </tr>
24.110 + * <tr>
24.111 + * <td> <b>Arrange async execution</td>
24.112 + * <td> {@link #execute(ForkJoinTask)}</td>
24.113 + * <td> {@link ForkJoinTask#fork}</td>
24.114 + * </tr>
24.115 + * <tr>
24.116 + * <td> <b>Await and obtain result</td>
24.117 + * <td> {@link #invoke(ForkJoinTask)}</td>
24.118 + * <td> {@link ForkJoinTask#invoke}</td>
24.119 + * </tr>
24.120 + * <tr>
24.121 + * <td> <b>Arrange exec and obtain Future</td>
24.122 + * <td> {@link #submit(ForkJoinTask)}</td>
24.123 + * <td> {@link ForkJoinTask#fork} (ForkJoinTasks <em>are</em> Futures)</td>
24.124 + * </tr>
24.125 + * </table>
24.126 + *
24.127 + * <p><b>Sample Usage.</b> Normally a single {@code ForkJoinPool} is
24.128 + * used for all parallel task execution in a program or subsystem.
24.129 + * Otherwise, use would not usually outweigh the construction and
24.130 + * bookkeeping overhead of creating a large set of threads. For
24.131 + * example, a common pool could be used for the {@code SortTasks}
24.132 + * illustrated in {@link RecursiveAction}. Because {@code
24.133 + * ForkJoinPool} uses threads in {@linkplain java.lang.Thread#isDaemon
24.134 + * daemon} mode, there is typically no need to explicitly {@link
24.135 + * #shutdown} such a pool upon program exit.
24.136 + *
24.137 + * <pre>
24.138 + * static final ForkJoinPool mainPool = new ForkJoinPool();
24.139 + * ...
24.140 + * public void sort(long[] array) {
24.141 + * mainPool.invoke(new SortTask(array, 0, array.length));
24.142 + * }
24.143 + * </pre>
24.144 + *
24.145 + * <p><b>Implementation notes</b>: This implementation restricts the
24.146 + * maximum number of running threads to 32767. Attempts to create
24.147 + * pools with greater than the maximum number result in
24.148 + * {@code IllegalArgumentException}.
24.149 + *
24.150 + * <p>This implementation rejects submitted tasks (that is, by throwing
24.151 + * {@link RejectedExecutionException}) only when the pool is shut down
24.152 + * or internal resources have been exhausted.
24.153 + *
24.154 + * @since 1.7
24.155 + * @author Doug Lea
24.156 + */
24.157 +public class ForkJoinPool extends AbstractExecutorService {
24.158 +
24.159 + /*
24.160 + * Implementation Overview
24.161 + *
24.162 + * This class provides the central bookkeeping and control for a
24.163 + * set of worker threads: Submissions from non-FJ threads enter
24.164 + * into a submission queue. Workers take these tasks and typically
24.165 + * split them into subtasks that may be stolen by other workers.
24.166 + * Preference rules give first priority to processing tasks from
24.167 + * their own queues (LIFO or FIFO, depending on mode), then to
24.168 + * randomized FIFO steals of tasks in other worker queues, and
24.169 + * lastly to new submissions.
24.170 + *
24.171 + * The main throughput advantages of work-stealing stem from
24.172 + * decentralized control -- workers mostly take tasks from
24.173 + * themselves or each other. We cannot negate this in the
24.174 + * implementation of other management responsibilities. The main
24.175 + * tactic for avoiding bottlenecks is packing nearly all
24.176 + * essentially atomic control state into a single 64bit volatile
24.177 + * variable ("ctl"). This variable is read on the order of 10-100
24.178 + * times as often as it is modified (always via CAS). (There is
24.179 + * some additional control state, for example variable "shutdown"
24.180 + * for which we can cope with uncoordinated updates.) This
24.181 + * streamlines synchronization and control at the expense of messy
24.182 + * constructions needed to repack status bits upon updates.
24.183 + * Updates tend not to contend with each other except during
24.184 + * bursts while submitted tasks begin or end. In some cases when
24.185 + * they do contend, threads can instead do something else
24.186 + * (usually, scan for tasks) until contention subsides.
24.187 + *
24.188 + * To enable packing, we restrict maximum parallelism to (1<<15)-1
24.189 + * (which is far in excess of normal operating range) to allow
24.190 + * ids, counts, and their negations (used for thresholding) to fit
24.191 + * into 16bit fields.
24.192 + *
24.193 + * Recording Workers. Workers are recorded in the "workers" array
24.194 + * that is created upon pool construction and expanded if (rarely)
24.195 + * necessary. This is an array as opposed to some other data
24.196 + * structure to support index-based random steals by workers.
24.197 + * Updates to the array recording new workers and unrecording
24.198 + * terminated ones are protected from each other by a seqLock
24.199 + * (scanGuard) but the array is otherwise concurrently readable,
24.200 + * and accessed directly by workers. To simplify index-based
24.201 + * operations, the array size is always a power of two, and all
24.202 + * readers must tolerate null slots. To avoid flailing during
24.203 + * start-up, the array is presized to hold twice #parallelism
24.204 + * workers (which is unlikely to need further resizing during
24.205 + * execution). But to avoid dealing with so many null slots,
24.206 + * variable scanGuard includes a mask for the nearest power of two
24.207 + * that contains all current workers. All worker thread creation
24.208 + * is on-demand, triggered by task submissions, replacement of
24.209 + * terminated workers, and/or compensation for blocked
24.210 + * workers. However, all other support code is set up to work with
24.211 + * other policies. To ensure that we do not hold on to worker
24.212 + * references that would prevent GC, ALL accesses to workers are
24.213 + * via indices into the workers array (which is one source of some
24.214 + * of the messy code constructions here). In essence, the workers
24.215 + * array serves as a weak reference mechanism. Thus for example
24.216 + * the wait queue field of ctl stores worker indices, not worker
24.217 + * references. Access to the workers in associated methods (for
24.218 + * example signalWork) must both index-check and null-check the
24.219 + * IDs. All such accesses ignore bad IDs by returning out early
24.220 + * from what they are doing, since this can only be associated
24.221 + * with termination, in which case it is OK to give up.
24.222 + *
24.223 + * All uses of the workers array, as well as queue arrays, check
24.224 + * that the array is non-null (even if previously non-null). This
24.225 + * allows nulling during termination, which is currently not
24.226 + * necessary, but remains an option for resource-revocation-based
24.227 + * shutdown schemes.
24.228 + *
24.229 + * Wait Queuing. Unlike HPC work-stealing frameworks, we cannot
24.230 + * let workers spin indefinitely scanning for tasks when none can
24.231 + * be found immediately, and we cannot start/resume workers unless
24.232 + * there appear to be tasks available. On the other hand, we must
24.233 + * quickly prod them into action when new tasks are submitted or
24.234 + * generated. We park/unpark workers after placing in an event
24.235 + * wait queue when they cannot find work. This "queue" is actually
24.236 + * a simple Treiber stack, headed by the "id" field of ctl, plus a
24.237 + * 15bit counter value to both wake up waiters (by advancing their
24.238 + * count) and avoid ABA effects. Successors are held in worker
24.239 + * field "nextWait". Queuing deals with several intrinsic races,
24.240 + * mainly that a task-producing thread can miss seeing (and
24.241 + * signalling) another thread that gave up looking for work but
24.242 + * has not yet entered the wait queue. We solve this by requiring
24.243 + * a full sweep of all workers both before (in scan()) and after
24.244 + * (in tryAwaitWork()) a newly waiting worker is added to the wait
24.245 + * queue. During a rescan, the worker might release some other
24.246 + * queued worker rather than itself, which has the same net
24.247 + * effect. Because enqueued workers may actually be rescanning
24.248 + * rather than waiting, we set and clear the "parked" field of
24.249 + * ForkJoinWorkerThread to reduce unnecessary calls to unpark.
24.250 + * (Use of the parked field requires a secondary recheck to avoid
24.251 + * missed signals.)
24.252 + *
24.253 + * Signalling. We create or wake up workers only when there
24.254 + * appears to be at least one task they might be able to find and
24.255 + * execute. When a submission is added or another worker adds a
24.256 + * task to a queue that previously had two or fewer tasks, they
24.257 + * signal waiting workers (or trigger creation of new ones if
24.258 + * fewer than the given parallelism level -- see signalWork).
24.259 + * These primary signals are buttressed by signals during rescans
24.260 + * as well as those performed when a worker steals a task and
24.261 + * notices that there are more tasks too; together these cover the
24.262 + * signals needed in cases when more than two tasks are pushed
24.263 + * but untaken.
24.264 + *
24.265 + * Trimming workers. To release resources after periods of lack of
24.266 + * use, a worker starting to wait when the pool is quiescent will
24.267 + * time out and terminate if the pool has remained quiescent for
24.268 + * SHRINK_RATE nanosecs. This will slowly propagate, eventually
24.269 + * terminating all workers after long periods of non-use.
24.270 + *
24.271 + * Submissions. External submissions are maintained in an
24.272 + * array-based queue that is structured identically to
24.273 + * ForkJoinWorkerThread queues except for the use of
24.274 + * submissionLock in method addSubmission. Unlike the case for
24.275 + * worker queues, multiple external threads can add new
24.276 + * submissions, so adding requires a lock.
24.277 + *
24.278 + * Compensation. Beyond work-stealing support and lifecycle
24.279 + * control, the main responsibility of this framework is to take
24.280 + * actions when one worker is waiting to join a task stolen (or
24.281 + * always held by) another. Because we are multiplexing many
24.282 + * tasks on to a pool of workers, we can't just let them block (as
24.283 + * in Thread.join). We also cannot just reassign the joiner's
24.284 + * run-time stack with another and replace it later, which would
24.285 + * be a form of "continuation", that even if possible is not
24.286 + * necessarily a good idea since we sometimes need both an
24.287 + * unblocked task and its continuation to progress. Instead we
24.288 + * combine two tactics:
24.289 + *
24.290 + * Helping: Arranging for the joiner to execute some task that it
24.291 + * would be running if the steal had not occurred. Method
24.292 + * ForkJoinWorkerThread.joinTask tracks joining->stealing
24.293 + * links to try to find such a task.
24.294 + *
24.295 + * Compensating: Unless there are already enough live threads,
24.296 + * method tryPreBlock() may create or re-activate a spare
24.297 + * thread to compensate for blocked joiners until they
24.298 + * unblock.
24.299 + *
24.300 + * The ManagedBlocker extension API can't use helping so relies
24.301 + * only on compensation in method awaitBlocker.
24.302 + *
24.303 + * It is impossible to keep exactly the target parallelism number
24.304 + * of threads running at any given time. Determining the
24.305 + * existence of conservatively safe helping targets, the
24.306 + * availability of already-created spares, and the apparent need
24.307 + * to create new spares are all racy and require heuristic
24.308 + * guidance, so we rely on multiple retries of each. Currently,
24.309 + * in keeping with on-demand signalling policy, we compensate only
24.310 + * if blocking would leave less than one active (non-waiting,
24.311 + * non-blocked) worker. Additionally, to avoid some false alarms
24.312 + * due to GC, lagging counters, system activity, etc, compensated
24.313 + * blocking for joins is only attempted after rechecks stabilize
24.314 + * (retries are interspersed with Thread.yield, for good
24.315 + * citizenship). The variable blockedCount, incremented before
24.316 + * blocking and decremented after, is sometimes needed to
24.317 + * distinguish cases of waiting for work vs blocking on joins or
24.318 + * other managed sync. Both cases are equivalent for most pool
24.319 + * control, so we can update non-atomically. (Additionally,
24.320 + * contention on blockedCount alleviates some contention on ctl).
24.321 + *
24.322 + * Shutdown and Termination. A call to shutdownNow atomically sets
24.323 + * the ctl stop bit and then (non-atomically) sets each workers
24.324 + * "terminate" status, cancels all unprocessed tasks, and wakes up
24.325 + * all waiting workers. Detecting whether termination should
24.326 + * commence after a non-abrupt shutdown() call requires more work
24.327 + * and bookkeeping. We need consensus about quiesence (i.e., that
24.328 + * there is no more work) which is reflected in active counts so
24.329 + * long as there are no current blockers, as well as possible
24.330 + * re-evaluations during independent changes in blocking or
24.331 + * quiescing workers.
24.332 + *
24.333 + * Style notes: There is a lot of representation-level coupling
24.334 + * among classes ForkJoinPool, ForkJoinWorkerThread, and
24.335 + * ForkJoinTask. Most fields of ForkJoinWorkerThread maintain
24.336 + * data structures managed by ForkJoinPool, so are directly
24.337 + * accessed. Conversely we allow access to "workers" array by
24.338 + * workers, and direct access to ForkJoinTask.status by both
24.339 + * ForkJoinPool and ForkJoinWorkerThread. There is little point
24.340 + * trying to reduce this, since any associated future changes in
24.341 + * representations will need to be accompanied by algorithmic
24.342 + * changes anyway. All together, these low-level implementation
24.343 + * choices produce as much as a factor of 4 performance
24.344 + * improvement compared to naive implementations, and enable the
24.345 + * processing of billions of tasks per second, at the expense of
24.346 + * some ugliness.
24.347 + *
24.348 + * Methods signalWork() and scan() are the main bottlenecks so are
24.349 + * especially heavily micro-optimized/mangled. There are lots of
24.350 + * inline assignments (of form "while ((local = field) != 0)")
24.351 + * which are usually the simplest way to ensure the required read
24.352 + * orderings (which are sometimes critical). This leads to a
24.353 + * "C"-like style of listing declarations of these locals at the
24.354 + * heads of methods or blocks. There are several occurrences of
24.355 + * the unusual "do {} while (!cas...)" which is the simplest way
24.356 + * to force an update of a CAS'ed variable. There are also other
24.357 + * coding oddities that help some methods perform reasonably even
24.358 + * when interpreted (not compiled).
24.359 + *
24.360 + * The order of declarations in this file is: (1) declarations of
24.361 + * statics (2) fields (along with constants used when unpacking
24.362 + * some of them), listed in an order that tends to reduce
24.363 + * contention among them a bit under most JVMs. (3) internal
24.364 + * control methods (4) callbacks and other support for
24.365 + * ForkJoinTask and ForkJoinWorkerThread classes, (5) exported
24.366 + * methods (plus a few little helpers). (6) static block
24.367 + * initializing all statics in a minimally dependent order.
24.368 + */
24.369 +
24.370 + /**
24.371 + * Factory for creating new {@link ForkJoinWorkerThread}s.
24.372 + * A {@code ForkJoinWorkerThreadFactory} must be defined and used
24.373 + * for {@code ForkJoinWorkerThread} subclasses that extend base
24.374 + * functionality or initialize threads with different contexts.
24.375 + */
24.376 + public static interface ForkJoinWorkerThreadFactory {
24.377 + /**
24.378 + * Returns a new worker thread operating in the given pool.
24.379 + *
24.380 + * @param pool the pool this thread works in
24.381 + * @throws NullPointerException if the pool is null
24.382 + */
24.383 + public ForkJoinWorkerThread newThread(ForkJoinPool pool);
24.384 + }
24.385 +
24.386 + /**
24.387 + * Default ForkJoinWorkerThreadFactory implementation; creates a
24.388 + * new ForkJoinWorkerThread.
24.389 + */
24.390 + static class DefaultForkJoinWorkerThreadFactory
24.391 + implements ForkJoinWorkerThreadFactory {
24.392 + public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
24.393 + return new ForkJoinWorkerThread(pool);
24.394 + }
24.395 + }
24.396 +
24.397 + /**
24.398 + * Creates a new ForkJoinWorkerThread. This factory is used unless
24.399 + * overridden in ForkJoinPool constructors.
24.400 + */
24.401 + public static final ForkJoinWorkerThreadFactory
24.402 + defaultForkJoinWorkerThreadFactory;
24.403 +
24.404 + /**
24.405 + * Permission required for callers of methods that may start or
24.406 + * kill threads.
24.407 + */
24.408 + private static final RuntimePermission modifyThreadPermission;
24.409 +
24.410 + /**
24.411 + * If there is a security manager, makes sure caller has
24.412 + * permission to modify threads.
24.413 + */
24.414 + private static void checkPermission() {
24.415 + SecurityManager security = System.getSecurityManager();
24.416 + if (security != null)
24.417 + security.checkPermission(modifyThreadPermission);
24.418 + }
24.419 +
24.420 + /**
24.421 + * Generator for assigning sequence numbers as pool names.
24.422 + */
24.423 + private static final AtomicInteger poolNumberGenerator;
24.424 +
24.425 + /**
24.426 + * Generator for initial random seeds for worker victim
24.427 + * selection. This is used only to create initial seeds. Random
24.428 + * steals use a cheaper xorshift generator per steal attempt. We
24.429 + * don't expect much contention on seedGenerator, so just use a
24.430 + * plain Random.
24.431 + */
24.432 + static final Random workerSeedGenerator;
24.433 +
24.434 + /**
24.435 + * Array holding all worker threads in the pool. Initialized upon
24.436 + * construction. Array size must be a power of two. Updates and
24.437 + * replacements are protected by scanGuard, but the array is
24.438 + * always kept in a consistent enough state to be randomly
24.439 + * accessed without locking by workers performing work-stealing,
24.440 + * as well as other traversal-based methods in this class, so long
24.441 + * as reads memory-acquire by first reading ctl. All readers must
24.442 + * tolerate that some array slots may be null.
24.443 + */
24.444 + ForkJoinWorkerThread[] workers;
24.445 +
24.446 + /**
24.447 + * Initial size for submission queue array. Must be a power of
24.448 + * two. In many applications, these always stay small so we use a
24.449 + * small initial cap.
24.450 + */
24.451 + private static final int INITIAL_QUEUE_CAPACITY = 8;
24.452 +
24.453 + /**
24.454 + * Maximum size for submission queue array. Must be a power of two
24.455 + * less than or equal to 1 << (31 - width of array entry) to
24.456 + * ensure lack of index wraparound, but is capped at a lower
24.457 + * value to help users trap runaway computations.
24.458 + */
24.459 + private static final int MAXIMUM_QUEUE_CAPACITY = 1 << 24; // 16M
24.460 +
24.461 + /**
24.462 + * Array serving as submission queue. Initialized upon construction.
24.463 + */
24.464 + private ForkJoinTask<?>[] submissionQueue;
24.465 +
24.466 + /**
24.467 + * Lock protecting submissions array for addSubmission
24.468 + */
24.469 + private final ReentrantLock submissionLock;
24.470 +
24.471 + /**
24.472 + * Condition for awaitTermination, using submissionLock for
24.473 + * convenience.
24.474 + */
24.475 + private final Condition termination;
24.476 +
24.477 + /**
24.478 + * Creation factory for worker threads.
24.479 + */
24.480 + private final ForkJoinWorkerThreadFactory factory;
24.481 +
24.482 + /**
24.483 + * The uncaught exception handler used when any worker abruptly
24.484 + * terminates.
24.485 + */
24.486 + final Thread.UncaughtExceptionHandler ueh;
24.487 +
24.488 + /**
24.489 + * Prefix for assigning names to worker threads
24.490 + */
24.491 + private final String workerNamePrefix;
24.492 +
24.493 + /**
24.494 + * Sum of per-thread steal counts, updated only when threads are
24.495 + * idle or terminating.
24.496 + */
24.497 + private volatile long stealCount;
24.498 +
24.499 + /**
24.500 + * Main pool control -- a long packed with:
24.501 + * AC: Number of active running workers minus target parallelism (16 bits)
24.502 + * TC: Number of total workers minus target parallelism (16bits)
24.503 + * ST: true if pool is terminating (1 bit)
24.504 + * EC: the wait count of top waiting thread (15 bits)
24.505 + * ID: ~poolIndex of top of Treiber stack of waiting threads (16 bits)
24.506 + *
24.507 + * When convenient, we can extract the upper 32 bits of counts and
24.508 + * the lower 32 bits of queue state, u = (int)(ctl >>> 32) and e =
24.509 + * (int)ctl. The ec field is never accessed alone, but always
24.510 + * together with id and st. The offsets of counts by the target
24.511 + * parallelism and the positionings of fields makes it possible to
24.512 + * perform the most common checks via sign tests of fields: When
24.513 + * ac is negative, there are not enough active workers, when tc is
24.514 + * negative, there are not enough total workers, when id is
24.515 + * negative, there is at least one waiting worker, and when e is
24.516 + * negative, the pool is terminating. To deal with these possibly
24.517 + * negative fields, we use casts in and out of "short" and/or
24.518 + * signed shifts to maintain signedness.
24.519 + */
24.520 + volatile long ctl;
24.521 +
24.522 + // bit positions/shifts for fields
24.523 + private static final int AC_SHIFT = 48;
24.524 + private static final int TC_SHIFT = 32;
24.525 + private static final int ST_SHIFT = 31;
24.526 + private static final int EC_SHIFT = 16;
24.527 +
24.528 + // bounds
24.529 + private static final int MAX_ID = 0x7fff; // max poolIndex
24.530 + private static final int SMASK = 0xffff; // mask short bits
24.531 + private static final int SHORT_SIGN = 1 << 15;
24.532 + private static final int INT_SIGN = 1 << 31;
24.533 +
24.534 + // masks
24.535 + private static final long STOP_BIT = 0x0001L << ST_SHIFT;
24.536 + private static final long AC_MASK = ((long)SMASK) << AC_SHIFT;
24.537 + private static final long TC_MASK = ((long)SMASK) << TC_SHIFT;
24.538 +
24.539 + // units for incrementing and decrementing
24.540 + private static final long TC_UNIT = 1L << TC_SHIFT;
24.541 + private static final long AC_UNIT = 1L << AC_SHIFT;
24.542 +
24.543 + // masks and units for dealing with u = (int)(ctl >>> 32)
24.544 + private static final int UAC_SHIFT = AC_SHIFT - 32;
24.545 + private static final int UTC_SHIFT = TC_SHIFT - 32;
24.546 + private static final int UAC_MASK = SMASK << UAC_SHIFT;
24.547 + private static final int UTC_MASK = SMASK << UTC_SHIFT;
24.548 + private static final int UAC_UNIT = 1 << UAC_SHIFT;
24.549 + private static final int UTC_UNIT = 1 << UTC_SHIFT;
24.550 +
24.551 + // masks and units for dealing with e = (int)ctl
24.552 + private static final int E_MASK = 0x7fffffff; // no STOP_BIT
24.553 + private static final int EC_UNIT = 1 << EC_SHIFT;
24.554 +
24.555 + /**
24.556 + * The target parallelism level.
24.557 + */
24.558 + final int parallelism;
24.559 +
24.560 + /**
24.561 + * Index (mod submission queue length) of next element to take
24.562 + * from submission queue. Usage is identical to that for
24.563 + * per-worker queues -- see ForkJoinWorkerThread internal
24.564 + * documentation.
24.565 + */
24.566 + volatile int queueBase;
24.567 +
24.568 + /**
24.569 + * Index (mod submission queue length) of next element to add
24.570 + * in submission queue. Usage is identical to that for
24.571 + * per-worker queues -- see ForkJoinWorkerThread internal
24.572 + * documentation.
24.573 + */
24.574 + int queueTop;
24.575 +
24.576 + /**
24.577 + * True when shutdown() has been called.
24.578 + */
24.579 + volatile boolean shutdown;
24.580 +
24.581 + /**
24.582 + * True if use local fifo, not default lifo, for local polling
24.583 + * Read by, and replicated by ForkJoinWorkerThreads
24.584 + */
24.585 + final boolean locallyFifo;
24.586 +
24.587 + /**
24.588 + * The number of threads in ForkJoinWorkerThreads.helpQuiescePool.
24.589 + * When non-zero, suppresses automatic shutdown when active
24.590 + * counts become zero.
24.591 + */
24.592 + volatile int quiescerCount;
24.593 +
24.594 + /**
24.595 + * The number of threads blocked in join.
24.596 + */
24.597 + volatile int blockedCount;
24.598 +
24.599 + /**
24.600 + * Counter for worker Thread names (unrelated to their poolIndex)
24.601 + */
24.602 + private volatile int nextWorkerNumber;
24.603 +
24.604 + /**
24.605 + * The index for the next created worker. Accessed under scanGuard.
24.606 + */
24.607 + private int nextWorkerIndex;
24.608 +
24.609 + /**
24.610 + * SeqLock and index masking for updates to workers array. Locked
24.611 + * when SG_UNIT is set. Unlocking clears bit by adding
24.612 + * SG_UNIT. Staleness of read-only operations can be checked by
24.613 + * comparing scanGuard to value before the reads. The low 16 bits
24.614 + * (i.e, anding with SMASK) hold (the smallest power of two
24.615 + * covering all worker indices, minus one, and is used to avoid
24.616 + * dealing with large numbers of null slots when the workers array
24.617 + * is overallocated.
24.618 + */
24.619 + volatile int scanGuard;
24.620 +
24.621 + private static final int SG_UNIT = 1 << 16;
24.622 +
24.623 + /**
24.624 + * The wakeup interval (in nanoseconds) for a worker waiting for a
24.625 + * task when the pool is quiescent to instead try to shrink the
24.626 + * number of workers. The exact value does not matter too
24.627 + * much. It must be short enough to release resources during
24.628 + * sustained periods of idleness, but not so short that threads
24.629 + * are continually re-created.
24.630 + */
24.631 + private static final long SHRINK_RATE =
24.632 + 4L * 1000L * 1000L * 1000L; // 4 seconds
24.633 +
24.634 + /**
24.635 + * Top-level loop for worker threads: On each step: if the
24.636 + * previous step swept through all queues and found no tasks, or
24.637 + * there are excess threads, then possibly blocks. Otherwise,
24.638 + * scans for and, if found, executes a task. Returns when pool
24.639 + * and/or worker terminate.
24.640 + *
24.641 + * @param w the worker
24.642 + */
24.643 + final void work(ForkJoinWorkerThread w) {
24.644 + boolean swept = false; // true on empty scans
24.645 + long c;
24.646 + while (!w.terminate && (int)(c = ctl) >= 0) {
24.647 + int a; // active count
24.648 + if (!swept && (a = (int)(c >> AC_SHIFT)) <= 0)
24.649 + swept = scan(w, a);
24.650 + else if (tryAwaitWork(w, c))
24.651 + swept = false;
24.652 + }
24.653 + }
24.654 +
24.655 + // Signalling
24.656 +
24.657 + /**
24.658 + * Wakes up or creates a worker.
24.659 + */
24.660 + final void signalWork() {
24.661 + /*
24.662 + * The while condition is true if: (there is are too few total
24.663 + * workers OR there is at least one waiter) AND (there are too
24.664 + * few active workers OR the pool is terminating). The value
24.665 + * of e distinguishes the remaining cases: zero (no waiters)
24.666 + * for create, negative if terminating (in which case do
24.667 + * nothing), else release a waiter. The secondary checks for
24.668 + * release (non-null array etc) can fail if the pool begins
24.669 + * terminating after the test, and don't impose any added cost
24.670 + * because JVMs must perform null and bounds checks anyway.
24.671 + */
24.672 + long c; int e, u;
24.673 + while ((((e = (int)(c = ctl)) | (u = (int)(c >>> 32))) &
24.674 + (INT_SIGN|SHORT_SIGN)) == (INT_SIGN|SHORT_SIGN) && e >= 0) {
24.675 + if (e > 0) { // release a waiting worker
24.676 + int i; ForkJoinWorkerThread w; ForkJoinWorkerThread[] ws;
24.677 + if ((ws = workers) == null ||
24.678 + (i = ~e & SMASK) >= ws.length ||
24.679 + (w = ws[i]) == null)
24.680 + break;
24.681 + long nc = (((long)(w.nextWait & E_MASK)) |
24.682 + ((long)(u + UAC_UNIT) << 32));
24.683 + if (w.eventCount == e &&
24.684 + UNSAFE.compareAndSwapLong(this, ctlOffset, c, nc)) {
24.685 + w.eventCount = (e + EC_UNIT) & E_MASK;
24.686 + if (w.parked)
24.687 + UNSAFE.unpark(w);
24.688 + break;
24.689 + }
24.690 + }
24.691 + else if (UNSAFE.compareAndSwapLong
24.692 + (this, ctlOffset, c,
24.693 + (long)(((u + UTC_UNIT) & UTC_MASK) |
24.694 + ((u + UAC_UNIT) & UAC_MASK)) << 32)) {
24.695 + addWorker();
24.696 + break;
24.697 + }
24.698 + }
24.699 + }
24.700 +
24.701 + /**
24.702 + * Variant of signalWork to help release waiters on rescans.
24.703 + * Tries once to release a waiter if active count < 0.
24.704 + *
24.705 + * @return false if failed due to contention, else true
24.706 + */
24.707 + private boolean tryReleaseWaiter() {
24.708 + long c; int e, i; ForkJoinWorkerThread w; ForkJoinWorkerThread[] ws;
24.709 + if ((e = (int)(c = ctl)) > 0 &&
24.710 + (int)(c >> AC_SHIFT) < 0 &&
24.711 + (ws = workers) != null &&
24.712 + (i = ~e & SMASK) < ws.length &&
24.713 + (w = ws[i]) != null) {
24.714 + long nc = ((long)(w.nextWait & E_MASK) |
24.715 + ((c + AC_UNIT) & (AC_MASK|TC_MASK)));
24.716 + if (w.eventCount != e ||
24.717 + !UNSAFE.compareAndSwapLong(this, ctlOffset, c, nc))
24.718 + return false;
24.719 + w.eventCount = (e + EC_UNIT) & E_MASK;
24.720 + if (w.parked)
24.721 + UNSAFE.unpark(w);
24.722 + }
24.723 + return true;
24.724 + }
24.725 +
24.726 + // Scanning for tasks
24.727 +
24.728 + /**
24.729 + * Scans for and, if found, executes one task. Scans start at a
24.730 + * random index of workers array, and randomly select the first
24.731 + * (2*#workers)-1 probes, and then, if all empty, resort to 2
24.732 + * circular sweeps, which is necessary to check quiescence. and
24.733 + * taking a submission only if no stealable tasks were found. The
24.734 + * steal code inside the loop is a specialized form of
24.735 + * ForkJoinWorkerThread.deqTask, followed bookkeeping to support
24.736 + * helpJoinTask and signal propagation. The code for submission
24.737 + * queues is almost identical. On each steal, the worker completes
24.738 + * not only the task, but also all local tasks that this task may
24.739 + * have generated. On detecting staleness or contention when
24.740 + * trying to take a task, this method returns without finishing
24.741 + * sweep, which allows global state rechecks before retry.
24.742 + *
24.743 + * @param w the worker
24.744 + * @param a the number of active workers
24.745 + * @return true if swept all queues without finding a task
24.746 + */
24.747 + private boolean scan(ForkJoinWorkerThread w, int a) {
24.748 + int g = scanGuard; // mask 0 avoids useless scans if only one active
24.749 + int m = (parallelism == 1 - a && blockedCount == 0) ? 0 : g & SMASK;
24.750 + ForkJoinWorkerThread[] ws = workers;
24.751 + if (ws == null || ws.length <= m) // staleness check
24.752 + return false;
24.753 + for (int r = w.seed, k = r, j = -(m + m); j <= m + m; ++j) {
24.754 + ForkJoinTask<?> t; ForkJoinTask<?>[] q; int b, i;
24.755 + ForkJoinWorkerThread v = ws[k & m];
24.756 + if (v != null && (b = v.queueBase) != v.queueTop &&
24.757 + (q = v.queue) != null && (i = (q.length - 1) & b) >= 0) {
24.758 + long u = (i << ASHIFT) + ABASE;
24.759 + if ((t = q[i]) != null && v.queueBase == b &&
24.760 + UNSAFE.compareAndSwapObject(q, u, t, null)) {
24.761 + int d = (v.queueBase = b + 1) - v.queueTop;
24.762 + v.stealHint = w.poolIndex;
24.763 + if (d != 0)
24.764 + signalWork(); // propagate if nonempty
24.765 + w.execTask(t);
24.766 + }
24.767 + r ^= r << 13; r ^= r >>> 17; w.seed = r ^ (r << 5);
24.768 + return false; // store next seed
24.769 + }
24.770 + else if (j < 0) { // xorshift
24.771 + r ^= r << 13; r ^= r >>> 17; k = r ^= r << 5;
24.772 + }
24.773 + else
24.774 + ++k;
24.775 + }
24.776 + if (scanGuard != g) // staleness check
24.777 + return false;
24.778 + else { // try to take submission
24.779 + ForkJoinTask<?> t; ForkJoinTask<?>[] q; int b, i;
24.780 + if ((b = queueBase) != queueTop &&
24.781 + (q = submissionQueue) != null &&
24.782 + (i = (q.length - 1) & b) >= 0) {
24.783 + long u = (i << ASHIFT) + ABASE;
24.784 + if ((t = q[i]) != null && queueBase == b &&
24.785 + UNSAFE.compareAndSwapObject(q, u, t, null)) {
24.786 + queueBase = b + 1;
24.787 + w.execTask(t);
24.788 + }
24.789 + return false;
24.790 + }
24.791 + return true; // all queues empty
24.792 + }
24.793 + }
24.794 +
24.795 + /**
24.796 + * Tries to enqueue worker w in wait queue and await change in
24.797 + * worker's eventCount. If the pool is quiescent and there is
24.798 + * more than one worker, possibly terminates worker upon exit.
24.799 + * Otherwise, before blocking, rescans queues to avoid missed
24.800 + * signals. Upon finding work, releases at least one worker
24.801 + * (which may be the current worker). Rescans restart upon
24.802 + * detected staleness or failure to release due to
24.803 + * contention. Note the unusual conventions about Thread.interrupt
24.804 + * here and elsewhere: Because interrupts are used solely to alert
24.805 + * threads to check termination, which is checked here anyway, we
24.806 + * clear status (using Thread.interrupted) before any call to
24.807 + * park, so that park does not immediately return due to status
24.808 + * being set via some other unrelated call to interrupt in user
24.809 + * code.
24.810 + *
24.811 + * @param w the calling worker
24.812 + * @param c the ctl value on entry
24.813 + * @return true if waited or another thread was released upon enq
24.814 + */
24.815 + private boolean tryAwaitWork(ForkJoinWorkerThread w, long c) {
24.816 + int v = w.eventCount;
24.817 + w.nextWait = (int)c; // w's successor record
24.818 + long nc = (long)(v & E_MASK) | ((c - AC_UNIT) & (AC_MASK|TC_MASK));
24.819 + if (ctl != c || !UNSAFE.compareAndSwapLong(this, ctlOffset, c, nc)) {
24.820 + long d = ctl; // return true if lost to a deq, to force scan
24.821 + return (int)d != (int)c && ((d - c) & AC_MASK) >= 0L;
24.822 + }
24.823 + for (int sc = w.stealCount; sc != 0;) { // accumulate stealCount
24.824 + long s = stealCount;
24.825 + if (UNSAFE.compareAndSwapLong(this, stealCountOffset, s, s + sc))
24.826 + sc = w.stealCount = 0;
24.827 + else if (w.eventCount != v)
24.828 + return true; // update next time
24.829 + }
24.830 + if ((!shutdown || !tryTerminate(false)) &&
24.831 + (int)c != 0 && parallelism + (int)(nc >> AC_SHIFT) == 0 &&
24.832 + blockedCount == 0 && quiescerCount == 0)
24.833 + idleAwaitWork(w, nc, c, v); // quiescent
24.834 + for (boolean rescanned = false;;) {
24.835 + if (w.eventCount != v)
24.836 + return true;
24.837 + if (!rescanned) {
24.838 + int g = scanGuard, m = g & SMASK;
24.839 + ForkJoinWorkerThread[] ws = workers;
24.840 + if (ws != null && m < ws.length) {
24.841 + rescanned = true;
24.842 + for (int i = 0; i <= m; ++i) {
24.843 + ForkJoinWorkerThread u = ws[i];
24.844 + if (u != null) {
24.845 + if (u.queueBase != u.queueTop &&
24.846 + !tryReleaseWaiter())
24.847 + rescanned = false; // contended
24.848 + if (w.eventCount != v)
24.849 + return true;
24.850 + }
24.851 + }
24.852 + }
24.853 + if (scanGuard != g || // stale
24.854 + (queueBase != queueTop && !tryReleaseWaiter()))
24.855 + rescanned = false;
24.856 + if (!rescanned)
24.857 + Thread.yield(); // reduce contention
24.858 + else
24.859 + Thread.interrupted(); // clear before park
24.860 + }
24.861 + else {
24.862 + w.parked = true; // must recheck
24.863 + if (w.eventCount != v) {
24.864 + w.parked = false;
24.865 + return true;
24.866 + }
24.867 + LockSupport.park(this);
24.868 + rescanned = w.parked = false;
24.869 + }
24.870 + }
24.871 + }
24.872 +
24.873 + /**
24.874 + * If inactivating worker w has caused pool to become
24.875 + * quiescent, check for pool termination, and wait for event
24.876 + * for up to SHRINK_RATE nanosecs (rescans are unnecessary in
24.877 + * this case because quiescence reflects consensus about lack
24.878 + * of work). On timeout, if ctl has not changed, terminate the
24.879 + * worker. Upon its termination (see deregisterWorker), it may
24.880 + * wake up another worker to possibly repeat this process.
24.881 + *
24.882 + * @param w the calling worker
24.883 + * @param currentCtl the ctl value after enqueuing w
24.884 + * @param prevCtl the ctl value if w terminated
24.885 + * @param v the eventCount w awaits change
24.886 + */
24.887 + private void idleAwaitWork(ForkJoinWorkerThread w, long currentCtl,
24.888 + long prevCtl, int v) {
24.889 + if (w.eventCount == v) {
24.890 + if (shutdown)
24.891 + tryTerminate(false);
24.892 + ForkJoinTask.helpExpungeStaleExceptions(); // help clean weak refs
24.893 + while (ctl == currentCtl) {
24.894 + long startTime = System.nanoTime();
24.895 + w.parked = true;
24.896 + if (w.eventCount == v) // must recheck
24.897 + LockSupport.parkNanos(this, SHRINK_RATE);
24.898 + w.parked = false;
24.899 + if (w.eventCount != v)
24.900 + break;
24.901 + else if (System.nanoTime() - startTime <
24.902 + SHRINK_RATE - (SHRINK_RATE / 10)) // timing slop
24.903 + Thread.interrupted(); // spurious wakeup
24.904 + else if (UNSAFE.compareAndSwapLong(this, ctlOffset,
24.905 + currentCtl, prevCtl)) {
24.906 + w.terminate = true; // restore previous
24.907 + w.eventCount = ((int)currentCtl + EC_UNIT) & E_MASK;
24.908 + break;
24.909 + }
24.910 + }
24.911 + }
24.912 + }
24.913 +
24.914 + // Submissions
24.915 +
24.916 + /**
24.917 + * Enqueues the given task in the submissionQueue. Same idea as
24.918 + * ForkJoinWorkerThread.pushTask except for use of submissionLock.
24.919 + *
24.920 + * @param t the task
24.921 + */
24.922 + private void addSubmission(ForkJoinTask<?> t) {
24.923 + final ReentrantLock lock = this.submissionLock;
24.924 + lock.lock();
24.925 + try {
24.926 + ForkJoinTask<?>[] q; int s, m;
24.927 + if ((q = submissionQueue) != null) { // ignore if queue removed
24.928 + long u = (((s = queueTop) & (m = q.length-1)) << ASHIFT)+ABASE;
24.929 + UNSAFE.putOrderedObject(q, u, t);
24.930 + queueTop = s + 1;
24.931 + if (s - queueBase == m)
24.932 + growSubmissionQueue();
24.933 + }
24.934 + } finally {
24.935 + lock.unlock();
24.936 + }
24.937 + signalWork();
24.938 + }
24.939 +
24.940 + // (pollSubmission is defined below with exported methods)
24.941 +
24.942 + /**
24.943 + * Creates or doubles submissionQueue array.
24.944 + * Basically identical to ForkJoinWorkerThread version.
24.945 + */
24.946 + private void growSubmissionQueue() {
24.947 + ForkJoinTask<?>[] oldQ = submissionQueue;
24.948 + int size = oldQ != null ? oldQ.length << 1 : INITIAL_QUEUE_CAPACITY;
24.949 + if (size > MAXIMUM_QUEUE_CAPACITY)
24.950 + throw new RejectedExecutionException("Queue capacity exceeded");
24.951 + if (size < INITIAL_QUEUE_CAPACITY)
24.952 + size = INITIAL_QUEUE_CAPACITY;
24.953 + ForkJoinTask<?>[] q = submissionQueue = new ForkJoinTask<?>[size];
24.954 + int mask = size - 1;
24.955 + int top = queueTop;
24.956 + int oldMask;
24.957 + if (oldQ != null && (oldMask = oldQ.length - 1) >= 0) {
24.958 + for (int b = queueBase; b != top; ++b) {
24.959 + long u = ((b & oldMask) << ASHIFT) + ABASE;
24.960 + Object x = UNSAFE.getObjectVolatile(oldQ, u);
24.961 + if (x != null && UNSAFE.compareAndSwapObject(oldQ, u, x, null))
24.962 + UNSAFE.putObjectVolatile
24.963 + (q, ((b & mask) << ASHIFT) + ABASE, x);
24.964 + }
24.965 + }
24.966 + }
24.967 +
24.968 + // Blocking support
24.969 +
24.970 + /**
24.971 + * Tries to increment blockedCount, decrement active count
24.972 + * (sometimes implicitly) and possibly release or create a
24.973 + * compensating worker in preparation for blocking. Fails
24.974 + * on contention or termination.
24.975 + *
24.976 + * @return true if the caller can block, else should recheck and retry
24.977 + */
24.978 + private boolean tryPreBlock() {
24.979 + int b = blockedCount;
24.980 + if (UNSAFE.compareAndSwapInt(this, blockedCountOffset, b, b + 1)) {
24.981 + int pc = parallelism;
24.982 + do {
24.983 + ForkJoinWorkerThread[] ws; ForkJoinWorkerThread w;
24.984 + int e, ac, tc, rc, i;
24.985 + long c = ctl;
24.986 + int u = (int)(c >>> 32);
24.987 + if ((e = (int)c) < 0) {
24.988 + // skip -- terminating
24.989 + }
24.990 + else if ((ac = (u >> UAC_SHIFT)) <= 0 && e != 0 &&
24.991 + (ws = workers) != null &&
24.992 + (i = ~e & SMASK) < ws.length &&
24.993 + (w = ws[i]) != null) {
24.994 + long nc = ((long)(w.nextWait & E_MASK) |
24.995 + (c & (AC_MASK|TC_MASK)));
24.996 + if (w.eventCount == e &&
24.997 + UNSAFE.compareAndSwapLong(this, ctlOffset, c, nc)) {
24.998 + w.eventCount = (e + EC_UNIT) & E_MASK;
24.999 + if (w.parked)
24.1000 + UNSAFE.unpark(w);
24.1001 + return true; // release an idle worker
24.1002 + }
24.1003 + }
24.1004 + else if ((tc = (short)(u >>> UTC_SHIFT)) >= 0 && ac + pc > 1) {
24.1005 + long nc = ((c - AC_UNIT) & AC_MASK) | (c & ~AC_MASK);
24.1006 + if (UNSAFE.compareAndSwapLong(this, ctlOffset, c, nc))
24.1007 + return true; // no compensation needed
24.1008 + }
24.1009 + else if (tc + pc < MAX_ID) {
24.1010 + long nc = ((c + TC_UNIT) & TC_MASK) | (c & ~TC_MASK);
24.1011 + if (UNSAFE.compareAndSwapLong(this, ctlOffset, c, nc)) {
24.1012 + addWorker();
24.1013 + return true; // create a replacement
24.1014 + }
24.1015 + }
24.1016 + // try to back out on any failure and let caller retry
24.1017 + } while (!UNSAFE.compareAndSwapInt(this, blockedCountOffset,
24.1018 + b = blockedCount, b - 1));
24.1019 + }
24.1020 + return false;
24.1021 + }
24.1022 +
24.1023 + /**
24.1024 + * Decrements blockedCount and increments active count
24.1025 + */
24.1026 + private void postBlock() {
24.1027 + long c;
24.1028 + do {} while (!UNSAFE.compareAndSwapLong(this, ctlOffset, // no mask
24.1029 + c = ctl, c + AC_UNIT));
24.1030 + int b;
24.1031 + do {} while (!UNSAFE.compareAndSwapInt(this, blockedCountOffset,
24.1032 + b = blockedCount, b - 1));
24.1033 + }
24.1034 +
24.1035 + /**
24.1036 + * Possibly blocks waiting for the given task to complete, or
24.1037 + * cancels the task if terminating. Fails to wait if contended.
24.1038 + *
24.1039 + * @param joinMe the task
24.1040 + */
24.1041 + final void tryAwaitJoin(ForkJoinTask<?> joinMe) {
24.1042 + int s;
24.1043 + Thread.interrupted(); // clear interrupts before checking termination
24.1044 + if (joinMe.status >= 0) {
24.1045 + if (tryPreBlock()) {
24.1046 + joinMe.tryAwaitDone(0L);
24.1047 + postBlock();
24.1048 + }
24.1049 + else if ((ctl & STOP_BIT) != 0L)
24.1050 + joinMe.cancelIgnoringExceptions();
24.1051 + }
24.1052 + }
24.1053 +
24.1054 + /**
24.1055 + * Possibly blocks the given worker waiting for joinMe to
24.1056 + * complete or timeout
24.1057 + *
24.1058 + * @param joinMe the task
24.1059 + * @param millis the wait time for underlying Object.wait
24.1060 + */
24.1061 + final void timedAwaitJoin(ForkJoinTask<?> joinMe, long nanos) {
24.1062 + while (joinMe.status >= 0) {
24.1063 + Thread.interrupted();
24.1064 + if ((ctl & STOP_BIT) != 0L) {
24.1065 + joinMe.cancelIgnoringExceptions();
24.1066 + break;
24.1067 + }
24.1068 + if (tryPreBlock()) {
24.1069 + long last = System.nanoTime();
24.1070 + while (joinMe.status >= 0) {
24.1071 + long millis = TimeUnit.NANOSECONDS.toMillis(nanos);
24.1072 + if (millis <= 0)
24.1073 + break;
24.1074 + joinMe.tryAwaitDone(millis);
24.1075 + if (joinMe.status < 0)
24.1076 + break;
24.1077 + if ((ctl & STOP_BIT) != 0L) {
24.1078 + joinMe.cancelIgnoringExceptions();
24.1079 + break;
24.1080 + }
24.1081 + long now = System.nanoTime();
24.1082 + nanos -= now - last;
24.1083 + last = now;
24.1084 + }
24.1085 + postBlock();
24.1086 + break;
24.1087 + }
24.1088 + }
24.1089 + }
24.1090 +
24.1091 + /**
24.1092 + * If necessary, compensates for blocker, and blocks
24.1093 + */
24.1094 + private void awaitBlocker(ManagedBlocker blocker)
24.1095 + throws InterruptedException {
24.1096 + while (!blocker.isReleasable()) {
24.1097 + if (tryPreBlock()) {
24.1098 + try {
24.1099 + do {} while (!blocker.isReleasable() && !blocker.block());
24.1100 + } finally {
24.1101 + postBlock();
24.1102 + }
24.1103 + break;
24.1104 + }
24.1105 + }
24.1106 + }
24.1107 +
24.1108 + // Creating, registering and deregistring workers
24.1109 +
24.1110 + /**
24.1111 + * Tries to create and start a worker; minimally rolls back counts
24.1112 + * on failure.
24.1113 + */
24.1114 + private void addWorker() {
24.1115 + Throwable ex = null;
24.1116 + ForkJoinWorkerThread t = null;
24.1117 + try {
24.1118 + t = factory.newThread(this);
24.1119 + } catch (Throwable e) {
24.1120 + ex = e;
24.1121 + }
24.1122 + if (t == null) { // null or exceptional factory return
24.1123 + long c; // adjust counts
24.1124 + do {} while (!UNSAFE.compareAndSwapLong
24.1125 + (this, ctlOffset, c = ctl,
24.1126 + (((c - AC_UNIT) & AC_MASK) |
24.1127 + ((c - TC_UNIT) & TC_MASK) |
24.1128 + (c & ~(AC_MASK|TC_MASK)))));
24.1129 + // Propagate exception if originating from an external caller
24.1130 + if (!tryTerminate(false) && ex != null &&
24.1131 + !(Thread.currentThread() instanceof ForkJoinWorkerThread))
24.1132 + UNSAFE.throwException(ex);
24.1133 + }
24.1134 + else
24.1135 + t.start();
24.1136 + }
24.1137 +
24.1138 + /**
24.1139 + * Callback from ForkJoinWorkerThread constructor to assign a
24.1140 + * public name
24.1141 + */
24.1142 + final String nextWorkerName() {
24.1143 + for (int n;;) {
24.1144 + if (UNSAFE.compareAndSwapInt(this, nextWorkerNumberOffset,
24.1145 + n = nextWorkerNumber, ++n))
24.1146 + return workerNamePrefix + n;
24.1147 + }
24.1148 + }
24.1149 +
24.1150 + /**
24.1151 + * Callback from ForkJoinWorkerThread constructor to
24.1152 + * determine its poolIndex and record in workers array.
24.1153 + *
24.1154 + * @param w the worker
24.1155 + * @return the worker's pool index
24.1156 + */
24.1157 + final int registerWorker(ForkJoinWorkerThread w) {
24.1158 + /*
24.1159 + * In the typical case, a new worker acquires the lock, uses
24.1160 + * next available index and returns quickly. Since we should
24.1161 + * not block callers (ultimately from signalWork or
24.1162 + * tryPreBlock) waiting for the lock needed to do this, we
24.1163 + * instead help release other workers while waiting for the
24.1164 + * lock.
24.1165 + */
24.1166 + for (int g;;) {
24.1167 + ForkJoinWorkerThread[] ws;
24.1168 + if (((g = scanGuard) & SG_UNIT) == 0 &&
24.1169 + UNSAFE.compareAndSwapInt(this, scanGuardOffset,
24.1170 + g, g | SG_UNIT)) {
24.1171 + int k = nextWorkerIndex;
24.1172 + try {
24.1173 + if ((ws = workers) != null) { // ignore on shutdown
24.1174 + int n = ws.length;
24.1175 + if (k < 0 || k >= n || ws[k] != null) {
24.1176 + for (k = 0; k < n && ws[k] != null; ++k)
24.1177 + ;
24.1178 + if (k == n)
24.1179 + ws = workers = Arrays.copyOf(ws, n << 1);
24.1180 + }
24.1181 + ws[k] = w;
24.1182 + nextWorkerIndex = k + 1;
24.1183 + int m = g & SMASK;
24.1184 + g = (k > m) ? ((m << 1) + 1) & SMASK : g + (SG_UNIT<<1);
24.1185 + }
24.1186 + } finally {
24.1187 + scanGuard = g;
24.1188 + }
24.1189 + return k;
24.1190 + }
24.1191 + else if ((ws = workers) != null) { // help release others
24.1192 + for (ForkJoinWorkerThread u : ws) {
24.1193 + if (u != null && u.queueBase != u.queueTop) {
24.1194 + if (tryReleaseWaiter())
24.1195 + break;
24.1196 + }
24.1197 + }
24.1198 + }
24.1199 + }
24.1200 + }
24.1201 +
24.1202 + /**
24.1203 + * Final callback from terminating worker. Removes record of
24.1204 + * worker from array, and adjusts counts. If pool is shutting
24.1205 + * down, tries to complete termination.
24.1206 + *
24.1207 + * @param w the worker
24.1208 + */
24.1209 + final void deregisterWorker(ForkJoinWorkerThread w, Throwable ex) {
24.1210 + int idx = w.poolIndex;
24.1211 + int sc = w.stealCount;
24.1212 + int steps = 0;
24.1213 + // Remove from array, adjust worker counts and collect steal count.
24.1214 + // We can intermix failed removes or adjusts with steal updates
24.1215 + do {
24.1216 + long s, c;
24.1217 + int g;
24.1218 + if (steps == 0 && ((g = scanGuard) & SG_UNIT) == 0 &&
24.1219 + UNSAFE.compareAndSwapInt(this, scanGuardOffset,
24.1220 + g, g |= SG_UNIT)) {
24.1221 + ForkJoinWorkerThread[] ws = workers;
24.1222 + if (ws != null && idx >= 0 &&
24.1223 + idx < ws.length && ws[idx] == w)
24.1224 + ws[idx] = null; // verify
24.1225 + nextWorkerIndex = idx;
24.1226 + scanGuard = g + SG_UNIT;
24.1227 + steps = 1;
24.1228 + }
24.1229 + if (steps == 1 &&
24.1230 + UNSAFE.compareAndSwapLong(this, ctlOffset, c = ctl,
24.1231 + (((c - AC_UNIT) & AC_MASK) |
24.1232 + ((c - TC_UNIT) & TC_MASK) |
24.1233 + (c & ~(AC_MASK|TC_MASK)))))
24.1234 + steps = 2;
24.1235 + if (sc != 0 &&
24.1236 + UNSAFE.compareAndSwapLong(this, stealCountOffset,
24.1237 + s = stealCount, s + sc))
24.1238 + sc = 0;
24.1239 + } while (steps != 2 || sc != 0);
24.1240 + if (!tryTerminate(false)) {
24.1241 + if (ex != null) // possibly replace if died abnormally
24.1242 + signalWork();
24.1243 + else
24.1244 + tryReleaseWaiter();
24.1245 + }
24.1246 + }
24.1247 +
24.1248 + // Shutdown and termination
24.1249 +
24.1250 + /**
24.1251 + * Possibly initiates and/or completes termination.
24.1252 + *
24.1253 + * @param now if true, unconditionally terminate, else only
24.1254 + * if shutdown and empty queue and no active workers
24.1255 + * @return true if now terminating or terminated
24.1256 + */
24.1257 + private boolean tryTerminate(boolean now) {
24.1258 + long c;
24.1259 + while (((c = ctl) & STOP_BIT) == 0) {
24.1260 + if (!now) {
24.1261 + if ((int)(c >> AC_SHIFT) != -parallelism)
24.1262 + return false;
24.1263 + if (!shutdown || blockedCount != 0 || quiescerCount != 0 ||
24.1264 + queueBase != queueTop) {
24.1265 + if (ctl == c) // staleness check
24.1266 + return false;
24.1267 + continue;
24.1268 + }
24.1269 + }
24.1270 + if (UNSAFE.compareAndSwapLong(this, ctlOffset, c, c | STOP_BIT))
24.1271 + startTerminating();
24.1272 + }
24.1273 + if ((short)(c >>> TC_SHIFT) == -parallelism) { // signal when 0 workers
24.1274 + final ReentrantLock lock = this.submissionLock;
24.1275 + lock.lock();
24.1276 + try {
24.1277 + termination.signalAll();
24.1278 + } finally {
24.1279 + lock.unlock();
24.1280 + }
24.1281 + }
24.1282 + return true;
24.1283 + }
24.1284 +
24.1285 + /**
24.1286 + * Runs up to three passes through workers: (0) Setting
24.1287 + * termination status for each worker, followed by wakeups up to
24.1288 + * queued workers; (1) helping cancel tasks; (2) interrupting
24.1289 + * lagging threads (likely in external tasks, but possibly also
24.1290 + * blocked in joins). Each pass repeats previous steps because of
24.1291 + * potential lagging thread creation.
24.1292 + */
24.1293 + private void startTerminating() {
24.1294 + cancelSubmissions();
24.1295 + for (int pass = 0; pass < 3; ++pass) {
24.1296 + ForkJoinWorkerThread[] ws = workers;
24.1297 + if (ws != null) {
24.1298 + for (ForkJoinWorkerThread w : ws) {
24.1299 + if (w != null) {
24.1300 + w.terminate = true;
24.1301 + if (pass > 0) {
24.1302 + w.cancelTasks();
24.1303 + if (pass > 1 && !w.isInterrupted()) {
24.1304 + try {
24.1305 + w.interrupt();
24.1306 + } catch (SecurityException ignore) {
24.1307 + }
24.1308 + }
24.1309 + }
24.1310 + }
24.1311 + }
24.1312 + terminateWaiters();
24.1313 + }
24.1314 + }
24.1315 + }
24.1316 +
24.1317 + /**
24.1318 + * Polls and cancels all submissions. Called only during termination.
24.1319 + */
24.1320 + private void cancelSubmissions() {
24.1321 + while (queueBase != queueTop) {
24.1322 + ForkJoinTask<?> task = pollSubmission();
24.1323 + if (task != null) {
24.1324 + try {
24.1325 + task.cancel(false);
24.1326 + } catch (Throwable ignore) {
24.1327 + }
24.1328 + }
24.1329 + }
24.1330 + }
24.1331 +
24.1332 + /**
24.1333 + * Tries to set the termination status of waiting workers, and
24.1334 + * then wakes them up (after which they will terminate).
24.1335 + */
24.1336 + private void terminateWaiters() {
24.1337 + ForkJoinWorkerThread[] ws = workers;
24.1338 + if (ws != null) {
24.1339 + ForkJoinWorkerThread w; long c; int i, e;
24.1340 + int n = ws.length;
24.1341 + while ((i = ~(e = (int)(c = ctl)) & SMASK) < n &&
24.1342 + (w = ws[i]) != null && w.eventCount == (e & E_MASK)) {
24.1343 + if (UNSAFE.compareAndSwapLong(this, ctlOffset, c,
24.1344 + (long)(w.nextWait & E_MASK) |
24.1345 + ((c + AC_UNIT) & AC_MASK) |
24.1346 + (c & (TC_MASK|STOP_BIT)))) {
24.1347 + w.terminate = true;
24.1348 + w.eventCount = e + EC_UNIT;
24.1349 + if (w.parked)
24.1350 + UNSAFE.unpark(w);
24.1351 + }
24.1352 + }
24.1353 + }
24.1354 + }
24.1355 +
24.1356 + // misc ForkJoinWorkerThread support
24.1357 +
24.1358 + /**
24.1359 + * Increment or decrement quiescerCount. Needed only to prevent
24.1360 + * triggering shutdown if a worker is transiently inactive while
24.1361 + * checking quiescence.
24.1362 + *
24.1363 + * @param delta 1 for increment, -1 for decrement
24.1364 + */
24.1365 + final void addQuiescerCount(int delta) {
24.1366 + int c;
24.1367 + do {} while (!UNSAFE.compareAndSwapInt(this, quiescerCountOffset,
24.1368 + c = quiescerCount, c + delta));
24.1369 + }
24.1370 +
24.1371 + /**
24.1372 + * Directly increment or decrement active count without
24.1373 + * queuing. This method is used to transiently assert inactivation
24.1374 + * while checking quiescence.
24.1375 + *
24.1376 + * @param delta 1 for increment, -1 for decrement
24.1377 + */
24.1378 + final void addActiveCount(int delta) {
24.1379 + long d = delta < 0 ? -AC_UNIT : AC_UNIT;
24.1380 + long c;
24.1381 + do {} while (!UNSAFE.compareAndSwapLong(this, ctlOffset, c = ctl,
24.1382 + ((c + d) & AC_MASK) |
24.1383 + (c & ~AC_MASK)));
24.1384 + }
24.1385 +
24.1386 + /**
24.1387 + * Returns the approximate (non-atomic) number of idle threads per
24.1388 + * active thread.
24.1389 + */
24.1390 + final int idlePerActive() {
24.1391 + // Approximate at powers of two for small values, saturate past 4
24.1392 + int p = parallelism;
24.1393 + int a = p + (int)(ctl >> AC_SHIFT);
24.1394 + return (a > (p >>>= 1) ? 0 :
24.1395 + a > (p >>>= 1) ? 1 :
24.1396 + a > (p >>>= 1) ? 2 :
24.1397 + a > (p >>>= 1) ? 4 :
24.1398 + 8);
24.1399 + }
24.1400 +
24.1401 + // Exported methods
24.1402 +
24.1403 + // Constructors
24.1404 +
24.1405 + /**
24.1406 + * Creates a {@code ForkJoinPool} with parallelism equal to {@link
24.1407 + * java.lang.Runtime#availableProcessors}, using the {@linkplain
24.1408 + * #defaultForkJoinWorkerThreadFactory default thread factory},
24.1409 + * no UncaughtExceptionHandler, and non-async LIFO processing mode.
24.1410 + *
24.1411 + * @throws SecurityException if a security manager exists and
24.1412 + * the caller is not permitted to modify threads
24.1413 + * because it does not hold {@link
24.1414 + * java.lang.RuntimePermission}{@code ("modifyThread")}
24.1415 + */
24.1416 + public ForkJoinPool() {
24.1417 + this(Runtime.getRuntime().availableProcessors(),
24.1418 + defaultForkJoinWorkerThreadFactory, null, false);
24.1419 + }
24.1420 +
24.1421 + /**
24.1422 + * Creates a {@code ForkJoinPool} with the indicated parallelism
24.1423 + * level, the {@linkplain
24.1424 + * #defaultForkJoinWorkerThreadFactory default thread factory},
24.1425 + * no UncaughtExceptionHandler, and non-async LIFO processing mode.
24.1426 + *
24.1427 + * @param parallelism the parallelism level
24.1428 + * @throws IllegalArgumentException if parallelism less than or
24.1429 + * equal to zero, or greater than implementation limit
24.1430 + * @throws SecurityException if a security manager exists and
24.1431 + * the caller is not permitted to modify threads
24.1432 + * because it does not hold {@link
24.1433 + * java.lang.RuntimePermission}{@code ("modifyThread")}
24.1434 + */
24.1435 + public ForkJoinPool(int parallelism) {
24.1436 + this(parallelism, defaultForkJoinWorkerThreadFactory, null, false);
24.1437 + }
24.1438 +
24.1439 + /**
24.1440 + * Creates a {@code ForkJoinPool} with the given parameters.
24.1441 + *
24.1442 + * @param parallelism the parallelism level. For default value,
24.1443 + * use {@link java.lang.Runtime#availableProcessors}.
24.1444 + * @param factory the factory for creating new threads. For default value,
24.1445 + * use {@link #defaultForkJoinWorkerThreadFactory}.
24.1446 + * @param handler the handler for internal worker threads that
24.1447 + * terminate due to unrecoverable errors encountered while executing
24.1448 + * tasks. For default value, use {@code null}.
24.1449 + * @param asyncMode if true,
24.1450 + * establishes local first-in-first-out scheduling mode for forked
24.1451 + * tasks that are never joined. This mode may be more appropriate
24.1452 + * than default locally stack-based mode in applications in which
24.1453 + * worker threads only process event-style asynchronous tasks.
24.1454 + * For default value, use {@code false}.
24.1455 + * @throws IllegalArgumentException if parallelism less than or
24.1456 + * equal to zero, or greater than implementation limit
24.1457 + * @throws NullPointerException if the factory is null
24.1458 + * @throws SecurityException if a security manager exists and
24.1459 + * the caller is not permitted to modify threads
24.1460 + * because it does not hold {@link
24.1461 + * java.lang.RuntimePermission}{@code ("modifyThread")}
24.1462 + */
24.1463 + public ForkJoinPool(int parallelism,
24.1464 + ForkJoinWorkerThreadFactory factory,
24.1465 + Thread.UncaughtExceptionHandler handler,
24.1466 + boolean asyncMode) {
24.1467 + checkPermission();
24.1468 + if (factory == null)
24.1469 + throw new NullPointerException();
24.1470 + if (parallelism <= 0 || parallelism > MAX_ID)
24.1471 + throw new IllegalArgumentException();
24.1472 + this.parallelism = parallelism;
24.1473 + this.factory = factory;
24.1474 + this.ueh = handler;
24.1475 + this.locallyFifo = asyncMode;
24.1476 + long np = (long)(-parallelism); // offset ctl counts
24.1477 + this.ctl = ((np << AC_SHIFT) & AC_MASK) | ((np << TC_SHIFT) & TC_MASK);
24.1478 + this.submissionQueue = new ForkJoinTask<?>[INITIAL_QUEUE_CAPACITY];
24.1479 + // initialize workers array with room for 2*parallelism if possible
24.1480 + int n = parallelism << 1;
24.1481 + if (n >= MAX_ID)
24.1482 + n = MAX_ID;
24.1483 + else { // See Hackers Delight, sec 3.2, where n < (1 << 16)
24.1484 + n |= n >>> 1; n |= n >>> 2; n |= n >>> 4; n |= n >>> 8;
24.1485 + }
24.1486 + workers = new ForkJoinWorkerThread[n + 1];
24.1487 + this.submissionLock = new ReentrantLock();
24.1488 + this.termination = submissionLock.newCondition();
24.1489 + StringBuilder sb = new StringBuilder("ForkJoinPool-");
24.1490 + sb.append(poolNumberGenerator.incrementAndGet());
24.1491 + sb.append("-worker-");
24.1492 + this.workerNamePrefix = sb.toString();
24.1493 + }
24.1494 +
24.1495 + // Execution methods
24.1496 +
24.1497 + /**
24.1498 + * Performs the given task, returning its result upon completion.
24.1499 + * If the computation encounters an unchecked Exception or Error,
24.1500 + * it is rethrown as the outcome of this invocation. Rethrown
24.1501 + * exceptions behave in the same way as regular exceptions, but,
24.1502 + * when possible, contain stack traces (as displayed for example
24.1503 + * using {@code ex.printStackTrace()}) of both the current thread
24.1504 + * as well as the thread actually encountering the exception;
24.1505 + * minimally only the latter.
24.1506 + *
24.1507 + * @param task the task
24.1508 + * @return the task's result
24.1509 + * @throws NullPointerException if the task is null
24.1510 + * @throws RejectedExecutionException if the task cannot be
24.1511 + * scheduled for execution
24.1512 + */
24.1513 + public <T> T invoke(ForkJoinTask<T> task) {
24.1514 + Thread t = Thread.currentThread();
24.1515 + if (task == null)
24.1516 + throw new NullPointerException();
24.1517 + if (shutdown)
24.1518 + throw new RejectedExecutionException();
24.1519 + if ((t instanceof ForkJoinWorkerThread) &&
24.1520 + ((ForkJoinWorkerThread)t).pool == this)
24.1521 + return task.invoke(); // bypass submit if in same pool
24.1522 + else {
24.1523 + addSubmission(task);
24.1524 + return task.join();
24.1525 + }
24.1526 + }
24.1527 +
24.1528 + /**
24.1529 + * Unless terminating, forks task if within an ongoing FJ
24.1530 + * computation in the current pool, else submits as external task.
24.1531 + */
24.1532 + private <T> void forkOrSubmit(ForkJoinTask<T> task) {
24.1533 + ForkJoinWorkerThread w;
24.1534 + Thread t = Thread.currentThread();
24.1535 + if (shutdown)
24.1536 + throw new RejectedExecutionException();
24.1537 + if ((t instanceof ForkJoinWorkerThread) &&
24.1538 + (w = (ForkJoinWorkerThread)t).pool == this)
24.1539 + w.pushTask(task);
24.1540 + else
24.1541 + addSubmission(task);
24.1542 + }
24.1543 +
24.1544 + /**
24.1545 + * Arranges for (asynchronous) execution of the given task.
24.1546 + *
24.1547 + * @param task the task
24.1548 + * @throws NullPointerException if the task is null
24.1549 + * @throws RejectedExecutionException if the task cannot be
24.1550 + * scheduled for execution
24.1551 + */
24.1552 + public void execute(ForkJoinTask<?> task) {
24.1553 + if (task == null)
24.1554 + throw new NullPointerException();
24.1555 + forkOrSubmit(task);
24.1556 + }
24.1557 +
24.1558 + // AbstractExecutorService methods
24.1559 +
24.1560 + /**
24.1561 + * @throws NullPointerException if the task is null
24.1562 + * @throws RejectedExecutionException if the task cannot be
24.1563 + * scheduled for execution
24.1564 + */
24.1565 + public void execute(Runnable task) {
24.1566 + if (task == null)
24.1567 + throw new NullPointerException();
24.1568 + ForkJoinTask<?> job;
24.1569 + if (task instanceof ForkJoinTask<?>) // avoid re-wrap
24.1570 + job = (ForkJoinTask<?>) task;
24.1571 + else
24.1572 + job = ForkJoinTask.adapt(task, null);
24.1573 + forkOrSubmit(job);
24.1574 + }
24.1575 +
24.1576 + /**
24.1577 + * Submits a ForkJoinTask for execution.
24.1578 + *
24.1579 + * @param task the task to submit
24.1580 + * @return the task
24.1581 + * @throws NullPointerException if the task is null
24.1582 + * @throws RejectedExecutionException if the task cannot be
24.1583 + * scheduled for execution
24.1584 + */
24.1585 + public <T> ForkJoinTask<T> submit(ForkJoinTask<T> task) {
24.1586 + if (task == null)
24.1587 + throw new NullPointerException();
24.1588 + forkOrSubmit(task);
24.1589 + return task;
24.1590 + }
24.1591 +
24.1592 + /**
24.1593 + * @throws NullPointerException if the task is null
24.1594 + * @throws RejectedExecutionException if the task cannot be
24.1595 + * scheduled for execution
24.1596 + */
24.1597 + public <T> ForkJoinTask<T> submit(Callable<T> task) {
24.1598 + if (task == null)
24.1599 + throw new NullPointerException();
24.1600 + ForkJoinTask<T> job = ForkJoinTask.adapt(task);
24.1601 + forkOrSubmit(job);
24.1602 + return job;
24.1603 + }
24.1604 +
24.1605 + /**
24.1606 + * @throws NullPointerException if the task is null
24.1607 + * @throws RejectedExecutionException if the task cannot be
24.1608 + * scheduled for execution
24.1609 + */
24.1610 + public <T> ForkJoinTask<T> submit(Runnable task, T result) {
24.1611 + if (task == null)
24.1612 + throw new NullPointerException();
24.1613 + ForkJoinTask<T> job = ForkJoinTask.adapt(task, result);
24.1614 + forkOrSubmit(job);
24.1615 + return job;
24.1616 + }
24.1617 +
24.1618 + /**
24.1619 + * @throws NullPointerException if the task is null
24.1620 + * @throws RejectedExecutionException if the task cannot be
24.1621 + * scheduled for execution
24.1622 + */
24.1623 + public ForkJoinTask<?> submit(Runnable task) {
24.1624 + if (task == null)
24.1625 + throw new NullPointerException();
24.1626 + ForkJoinTask<?> job;
24.1627 + if (task instanceof ForkJoinTask<?>) // avoid re-wrap
24.1628 + job = (ForkJoinTask<?>) task;
24.1629 + else
24.1630 + job = ForkJoinTask.adapt(task, null);
24.1631 + forkOrSubmit(job);
24.1632 + return job;
24.1633 + }
24.1634 +
24.1635 + /**
24.1636 + * @throws NullPointerException {@inheritDoc}
24.1637 + * @throws RejectedExecutionException {@inheritDoc}
24.1638 + */
24.1639 + public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) {
24.1640 + ArrayList<ForkJoinTask<T>> forkJoinTasks =
24.1641 + new ArrayList<ForkJoinTask<T>>(tasks.size());
24.1642 + for (Callable<T> task : tasks)
24.1643 + forkJoinTasks.add(ForkJoinTask.adapt(task));
24.1644 + invoke(new InvokeAll<T>(forkJoinTasks));
24.1645 +
24.1646 + @SuppressWarnings({"unchecked", "rawtypes"})
24.1647 + List<Future<T>> futures = (List<Future<T>>) (List) forkJoinTasks;
24.1648 + return futures;
24.1649 + }
24.1650 +
24.1651 + static final class InvokeAll<T> extends RecursiveAction {
24.1652 + final ArrayList<ForkJoinTask<T>> tasks;
24.1653 + InvokeAll(ArrayList<ForkJoinTask<T>> tasks) { this.tasks = tasks; }
24.1654 + public void compute() {
24.1655 + try { invokeAll(tasks); }
24.1656 + catch (Exception ignore) {}
24.1657 + }
24.1658 + private static final long serialVersionUID = -7914297376763021607L;
24.1659 + }
24.1660 +
24.1661 + /**
24.1662 + * Returns the factory used for constructing new workers.
24.1663 + *
24.1664 + * @return the factory used for constructing new workers
24.1665 + */
24.1666 + public ForkJoinWorkerThreadFactory getFactory() {
24.1667 + return factory;
24.1668 + }
24.1669 +
24.1670 + /**
24.1671 + * Returns the handler for internal worker threads that terminate
24.1672 + * due to unrecoverable errors encountered while executing tasks.
24.1673 + *
24.1674 + * @return the handler, or {@code null} if none
24.1675 + */
24.1676 + public Thread.UncaughtExceptionHandler getUncaughtExceptionHandler() {
24.1677 + return ueh;
24.1678 + }
24.1679 +
24.1680 + /**
24.1681 + * Returns the targeted parallelism level of this pool.
24.1682 + *
24.1683 + * @return the targeted parallelism level of this pool
24.1684 + */
24.1685 + public int getParallelism() {
24.1686 + return parallelism;
24.1687 + }
24.1688 +
24.1689 + /**
24.1690 + * Returns the number of worker threads that have started but not
24.1691 + * yet terminated. The result returned by this method may differ
24.1692 + * from {@link #getParallelism} when threads are created to
24.1693 + * maintain parallelism when others are cooperatively blocked.
24.1694 + *
24.1695 + * @return the number of worker threads
24.1696 + */
24.1697 + public int getPoolSize() {
24.1698 + return parallelism + (short)(ctl >>> TC_SHIFT);
24.1699 + }
24.1700 +
24.1701 + /**
24.1702 + * Returns {@code true} if this pool uses local first-in-first-out
24.1703 + * scheduling mode for forked tasks that are never joined.
24.1704 + *
24.1705 + * @return {@code true} if this pool uses async mode
24.1706 + */
24.1707 + public boolean getAsyncMode() {
24.1708 + return locallyFifo;
24.1709 + }
24.1710 +
24.1711 + /**
24.1712 + * Returns an estimate of the number of worker threads that are
24.1713 + * not blocked waiting to join tasks or for other managed
24.1714 + * synchronization. This method may overestimate the
24.1715 + * number of running threads.
24.1716 + *
24.1717 + * @return the number of worker threads
24.1718 + */
24.1719 + public int getRunningThreadCount() {
24.1720 + int r = parallelism + (int)(ctl >> AC_SHIFT);
24.1721 + return (r <= 0) ? 0 : r; // suppress momentarily negative values
24.1722 + }
24.1723 +
24.1724 + /**
24.1725 + * Returns an estimate of the number of threads that are currently
24.1726 + * stealing or executing tasks. This method may overestimate the
24.1727 + * number of active threads.
24.1728 + *
24.1729 + * @return the number of active threads
24.1730 + */
24.1731 + public int getActiveThreadCount() {
24.1732 + int r = parallelism + (int)(ctl >> AC_SHIFT) + blockedCount;
24.1733 + return (r <= 0) ? 0 : r; // suppress momentarily negative values
24.1734 + }
24.1735 +
24.1736 + /**
24.1737 + * Returns {@code true} if all worker threads are currently idle.
24.1738 + * An idle worker is one that cannot obtain a task to execute
24.1739 + * because none are available to steal from other threads, and
24.1740 + * there are no pending submissions to the pool. This method is
24.1741 + * conservative; it might not return {@code true} immediately upon
24.1742 + * idleness of all threads, but will eventually become true if
24.1743 + * threads remain inactive.
24.1744 + *
24.1745 + * @return {@code true} if all threads are currently idle
24.1746 + */
24.1747 + public boolean isQuiescent() {
24.1748 + return parallelism + (int)(ctl >> AC_SHIFT) + blockedCount == 0;
24.1749 + }
24.1750 +
24.1751 + /**
24.1752 + * Returns an estimate of the total number of tasks stolen from
24.1753 + * one thread's work queue by another. The reported value
24.1754 + * underestimates the actual total number of steals when the pool
24.1755 + * is not quiescent. This value may be useful for monitoring and
24.1756 + * tuning fork/join programs: in general, steal counts should be
24.1757 + * high enough to keep threads busy, but low enough to avoid
24.1758 + * overhead and contention across threads.
24.1759 + *
24.1760 + * @return the number of steals
24.1761 + */
24.1762 + public long getStealCount() {
24.1763 + return stealCount;
24.1764 + }
24.1765 +
24.1766 + /**
24.1767 + * Returns an estimate of the total number of tasks currently held
24.1768 + * in queues by worker threads (but not including tasks submitted
24.1769 + * to the pool that have not begun executing). This value is only
24.1770 + * an approximation, obtained by iterating across all threads in
24.1771 + * the pool. This method may be useful for tuning task
24.1772 + * granularities.
24.1773 + *
24.1774 + * @return the number of queued tasks
24.1775 + */
24.1776 + public long getQueuedTaskCount() {
24.1777 + long count = 0;
24.1778 + ForkJoinWorkerThread[] ws;
24.1779 + if ((short)(ctl >>> TC_SHIFT) > -parallelism &&
24.1780 + (ws = workers) != null) {
24.1781 + for (ForkJoinWorkerThread w : ws)
24.1782 + if (w != null)
24.1783 + count -= w.queueBase - w.queueTop; // must read base first
24.1784 + }
24.1785 + return count;
24.1786 + }
24.1787 +
24.1788 + /**
24.1789 + * Returns an estimate of the number of tasks submitted to this
24.1790 + * pool that have not yet begun executing. This method may take
24.1791 + * time proportional to the number of submissions.
24.1792 + *
24.1793 + * @return the number of queued submissions
24.1794 + */
24.1795 + public int getQueuedSubmissionCount() {
24.1796 + return -queueBase + queueTop;
24.1797 + }
24.1798 +
24.1799 + /**
24.1800 + * Returns {@code true} if there are any tasks submitted to this
24.1801 + * pool that have not yet begun executing.
24.1802 + *
24.1803 + * @return {@code true} if there are any queued submissions
24.1804 + */
24.1805 + public boolean hasQueuedSubmissions() {
24.1806 + return queueBase != queueTop;
24.1807 + }
24.1808 +
24.1809 + /**
24.1810 + * Removes and returns the next unexecuted submission if one is
24.1811 + * available. This method may be useful in extensions to this
24.1812 + * class that re-assign work in systems with multiple pools.
24.1813 + *
24.1814 + * @return the next submission, or {@code null} if none
24.1815 + */
24.1816 + protected ForkJoinTask<?> pollSubmission() {
24.1817 + ForkJoinTask<?> t; ForkJoinTask<?>[] q; int b, i;
24.1818 + while ((b = queueBase) != queueTop &&
24.1819 + (q = submissionQueue) != null &&
24.1820 + (i = (q.length - 1) & b) >= 0) {
24.1821 + long u = (i << ASHIFT) + ABASE;
24.1822 + if ((t = q[i]) != null &&
24.1823 + queueBase == b &&
24.1824 + UNSAFE.compareAndSwapObject(q, u, t, null)) {
24.1825 + queueBase = b + 1;
24.1826 + return t;
24.1827 + }
24.1828 + }
24.1829 + return null;
24.1830 + }
24.1831 +
24.1832 + /**
24.1833 + * Removes all available unexecuted submitted and forked tasks
24.1834 + * from scheduling queues and adds them to the given collection,
24.1835 + * without altering their execution status. These may include
24.1836 + * artificially generated or wrapped tasks. This method is
24.1837 + * designed to be invoked only when the pool is known to be
24.1838 + * quiescent. Invocations at other times may not remove all
24.1839 + * tasks. A failure encountered while attempting to add elements
24.1840 + * to collection {@code c} may result in elements being in
24.1841 + * neither, either or both collections when the associated
24.1842 + * exception is thrown. The behavior of this operation is
24.1843 + * undefined if the specified collection is modified while the
24.1844 + * operation is in progress.
24.1845 + *
24.1846 + * @param c the collection to transfer elements into
24.1847 + * @return the number of elements transferred
24.1848 + */
24.1849 + protected int drainTasksTo(Collection<? super ForkJoinTask<?>> c) {
24.1850 + int count = 0;
24.1851 + while (queueBase != queueTop) {
24.1852 + ForkJoinTask<?> t = pollSubmission();
24.1853 + if (t != null) {
24.1854 + c.add(t);
24.1855 + ++count;
24.1856 + }
24.1857 + }
24.1858 + ForkJoinWorkerThread[] ws;
24.1859 + if ((short)(ctl >>> TC_SHIFT) > -parallelism &&
24.1860 + (ws = workers) != null) {
24.1861 + for (ForkJoinWorkerThread w : ws)
24.1862 + if (w != null)
24.1863 + count += w.drainTasksTo(c);
24.1864 + }
24.1865 + return count;
24.1866 + }
24.1867 +
24.1868 + /**
24.1869 + * Returns a string identifying this pool, as well as its state,
24.1870 + * including indications of run state, parallelism level, and
24.1871 + * worker and task counts.
24.1872 + *
24.1873 + * @return a string identifying this pool, as well as its state
24.1874 + */
24.1875 + public String toString() {
24.1876 + long st = getStealCount();
24.1877 + long qt = getQueuedTaskCount();
24.1878 + long qs = getQueuedSubmissionCount();
24.1879 + int pc = parallelism;
24.1880 + long c = ctl;
24.1881 + int tc = pc + (short)(c >>> TC_SHIFT);
24.1882 + int rc = pc + (int)(c >> AC_SHIFT);
24.1883 + if (rc < 0) // ignore transient negative
24.1884 + rc = 0;
24.1885 + int ac = rc + blockedCount;
24.1886 + String level;
24.1887 + if ((c & STOP_BIT) != 0)
24.1888 + level = (tc == 0) ? "Terminated" : "Terminating";
24.1889 + else
24.1890 + level = shutdown ? "Shutting down" : "Running";
24.1891 + return super.toString() +
24.1892 + "[" + level +
24.1893 + ", parallelism = " + pc +
24.1894 + ", size = " + tc +
24.1895 + ", active = " + ac +
24.1896 + ", running = " + rc +
24.1897 + ", steals = " + st +
24.1898 + ", tasks = " + qt +
24.1899 + ", submissions = " + qs +
24.1900 + "]";
24.1901 + }
24.1902 +
24.1903 + /**
24.1904 + * Initiates an orderly shutdown in which previously submitted
24.1905 + * tasks are executed, but no new tasks will be accepted.
24.1906 + * Invocation has no additional effect if already shut down.
24.1907 + * Tasks that are in the process of being submitted concurrently
24.1908 + * during the course of this method may or may not be rejected.
24.1909 + *
24.1910 + * @throws SecurityException if a security manager exists and
24.1911 + * the caller is not permitted to modify threads
24.1912 + * because it does not hold {@link
24.1913 + * java.lang.RuntimePermission}{@code ("modifyThread")}
24.1914 + */
24.1915 + public void shutdown() {
24.1916 + checkPermission();
24.1917 + shutdown = true;
24.1918 + tryTerminate(false);
24.1919 + }
24.1920 +
24.1921 + /**
24.1922 + * Attempts to cancel and/or stop all tasks, and reject all
24.1923 + * subsequently submitted tasks. Tasks that are in the process of
24.1924 + * being submitted or executed concurrently during the course of
24.1925 + * this method may or may not be rejected. This method cancels
24.1926 + * both existing and unexecuted tasks, in order to permit
24.1927 + * termination in the presence of task dependencies. So the method
24.1928 + * always returns an empty list (unlike the case for some other
24.1929 + * Executors).
24.1930 + *
24.1931 + * @return an empty list
24.1932 + * @throws SecurityException if a security manager exists and
24.1933 + * the caller is not permitted to modify threads
24.1934 + * because it does not hold {@link
24.1935 + * java.lang.RuntimePermission}{@code ("modifyThread")}
24.1936 + */
24.1937 + public List<Runnable> shutdownNow() {
24.1938 + checkPermission();
24.1939 + shutdown = true;
24.1940 + tryTerminate(true);
24.1941 + return Collections.emptyList();
24.1942 + }
24.1943 +
24.1944 + /**
24.1945 + * Returns {@code true} if all tasks have completed following shut down.
24.1946 + *
24.1947 + * @return {@code true} if all tasks have completed following shut down
24.1948 + */
24.1949 + public boolean isTerminated() {
24.1950 + long c = ctl;
24.1951 + return ((c & STOP_BIT) != 0L &&
24.1952 + (short)(c >>> TC_SHIFT) == -parallelism);
24.1953 + }
24.1954 +
24.1955 + /**
24.1956 + * Returns {@code true} if the process of termination has
24.1957 + * commenced but not yet completed. This method may be useful for
24.1958 + * debugging. A return of {@code true} reported a sufficient
24.1959 + * period after shutdown may indicate that submitted tasks have
24.1960 + * ignored or suppressed interruption, or are waiting for IO,
24.1961 + * causing this executor not to properly terminate. (See the
24.1962 + * advisory notes for class {@link ForkJoinTask} stating that
24.1963 + * tasks should not normally entail blocking operations. But if
24.1964 + * they do, they must abort them on interrupt.)
24.1965 + *
24.1966 + * @return {@code true} if terminating but not yet terminated
24.1967 + */
24.1968 + public boolean isTerminating() {
24.1969 + long c = ctl;
24.1970 + return ((c & STOP_BIT) != 0L &&
24.1971 + (short)(c >>> TC_SHIFT) != -parallelism);
24.1972 + }
24.1973 +
24.1974 + /**
24.1975 + * Returns true if terminating or terminated. Used by ForkJoinWorkerThread.
24.1976 + */
24.1977 + final boolean isAtLeastTerminating() {
24.1978 + return (ctl & STOP_BIT) != 0L;
24.1979 + }
24.1980 +
24.1981 + /**
24.1982 + * Returns {@code true} if this pool has been shut down.
24.1983 + *
24.1984 + * @return {@code true} if this pool has been shut down
24.1985 + */
24.1986 + public boolean isShutdown() {
24.1987 + return shutdown;
24.1988 + }
24.1989 +
24.1990 + /**
24.1991 + * Blocks until all tasks have completed execution after a shutdown
24.1992 + * request, or the timeout occurs, or the current thread is
24.1993 + * interrupted, whichever happens first.
24.1994 + *
24.1995 + * @param timeout the maximum time to wait
24.1996 + * @param unit the time unit of the timeout argument
24.1997 + * @return {@code true} if this executor terminated and
24.1998 + * {@code false} if the timeout elapsed before termination
24.1999 + * @throws InterruptedException if interrupted while waiting
24.2000 + */
24.2001 + public boolean awaitTermination(long timeout, TimeUnit unit)
24.2002 + throws InterruptedException {
24.2003 + long nanos = unit.toNanos(timeout);
24.2004 + final ReentrantLock lock = this.submissionLock;
24.2005 + lock.lock();
24.2006 + try {
24.2007 + for (;;) {
24.2008 + if (isTerminated())
24.2009 + return true;
24.2010 + if (nanos <= 0)
24.2011 + return false;
24.2012 + nanos = termination.awaitNanos(nanos);
24.2013 + }
24.2014 + } finally {
24.2015 + lock.unlock();
24.2016 + }
24.2017 + }
24.2018 +
24.2019 + /**
24.2020 + * Interface for extending managed parallelism for tasks running
24.2021 + * in {@link ForkJoinPool}s.
24.2022 + *
24.2023 + * <p>A {@code ManagedBlocker} provides two methods. Method
24.2024 + * {@code isReleasable} must return {@code true} if blocking is
24.2025 + * not necessary. Method {@code block} blocks the current thread
24.2026 + * if necessary (perhaps internally invoking {@code isReleasable}
24.2027 + * before actually blocking). These actions are performed by any
24.2028 + * thread invoking {@link ForkJoinPool#managedBlock}. The
24.2029 + * unusual methods in this API accommodate synchronizers that may,
24.2030 + * but don't usually, block for long periods. Similarly, they
24.2031 + * allow more efficient internal handling of cases in which
24.2032 + * additional workers may be, but usually are not, needed to
24.2033 + * ensure sufficient parallelism. Toward this end,
24.2034 + * implementations of method {@code isReleasable} must be amenable
24.2035 + * to repeated invocation.
24.2036 + *
24.2037 + * <p>For example, here is a ManagedBlocker based on a
24.2038 + * ReentrantLock:
24.2039 + * <pre> {@code
24.2040 + * class ManagedLocker implements ManagedBlocker {
24.2041 + * final ReentrantLock lock;
24.2042 + * boolean hasLock = false;
24.2043 + * ManagedLocker(ReentrantLock lock) { this.lock = lock; }
24.2044 + * public boolean block() {
24.2045 + * if (!hasLock)
24.2046 + * lock.lock();
24.2047 + * return true;
24.2048 + * }
24.2049 + * public boolean isReleasable() {
24.2050 + * return hasLock || (hasLock = lock.tryLock());
24.2051 + * }
24.2052 + * }}</pre>
24.2053 + *
24.2054 + * <p>Here is a class that possibly blocks waiting for an
24.2055 + * item on a given queue:
24.2056 + * <pre> {@code
24.2057 + * class QueueTaker<E> implements ManagedBlocker {
24.2058 + * final BlockingQueue<E> queue;
24.2059 + * volatile E item = null;
24.2060 + * QueueTaker(BlockingQueue<E> q) { this.queue = q; }
24.2061 + * public boolean block() throws InterruptedException {
24.2062 + * if (item == null)
24.2063 + * item = queue.take();
24.2064 + * return true;
24.2065 + * }
24.2066 + * public boolean isReleasable() {
24.2067 + * return item != null || (item = queue.poll()) != null;
24.2068 + * }
24.2069 + * public E getItem() { // call after pool.managedBlock completes
24.2070 + * return item;
24.2071 + * }
24.2072 + * }}</pre>
24.2073 + */
24.2074 + public static interface ManagedBlocker {
24.2075 + /**
24.2076 + * Possibly blocks the current thread, for example waiting for
24.2077 + * a lock or condition.
24.2078 + *
24.2079 + * @return {@code true} if no additional blocking is necessary
24.2080 + * (i.e., if isReleasable would return true)
24.2081 + * @throws InterruptedException if interrupted while waiting
24.2082 + * (the method is not required to do so, but is allowed to)
24.2083 + */
24.2084 + boolean block() throws InterruptedException;
24.2085 +
24.2086 + /**
24.2087 + * Returns {@code true} if blocking is unnecessary.
24.2088 + */
24.2089 + boolean isReleasable();
24.2090 + }
24.2091 +
24.2092 + /**
24.2093 + * Blocks in accord with the given blocker. If the current thread
24.2094 + * is a {@link ForkJoinWorkerThread}, this method possibly
24.2095 + * arranges for a spare thread to be activated if necessary to
24.2096 + * ensure sufficient parallelism while the current thread is blocked.
24.2097 + *
24.2098 + * <p>If the caller is not a {@link ForkJoinTask}, this method is
24.2099 + * behaviorally equivalent to
24.2100 + * <pre> {@code
24.2101 + * while (!blocker.isReleasable())
24.2102 + * if (blocker.block())
24.2103 + * return;
24.2104 + * }</pre>
24.2105 + *
24.2106 + * If the caller is a {@code ForkJoinTask}, then the pool may
24.2107 + * first be expanded to ensure parallelism, and later adjusted.
24.2108 + *
24.2109 + * @param blocker the blocker
24.2110 + * @throws InterruptedException if blocker.block did so
24.2111 + */
24.2112 + public static void managedBlock(ManagedBlocker blocker)
24.2113 + throws InterruptedException {
24.2114 + Thread t = Thread.currentThread();
24.2115 + if (t instanceof ForkJoinWorkerThread) {
24.2116 + ForkJoinWorkerThread w = (ForkJoinWorkerThread) t;
24.2117 + w.pool.awaitBlocker(blocker);
24.2118 + }
24.2119 + else {
24.2120 + do {} while (!blocker.isReleasable() && !blocker.block());
24.2121 + }
24.2122 + }
24.2123 +
24.2124 + // AbstractExecutorService overrides. These rely on undocumented
24.2125 + // fact that ForkJoinTask.adapt returns ForkJoinTasks that also
24.2126 + // implement RunnableFuture.
24.2127 +
24.2128 + protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
24.2129 + return (RunnableFuture<T>) ForkJoinTask.adapt(runnable, value);
24.2130 + }
24.2131 +
24.2132 + protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
24.2133 + return (RunnableFuture<T>) ForkJoinTask.adapt(callable);
24.2134 + }
24.2135 +
24.2136 + // Unsafe mechanics
24.2137 + private static final sun.misc.Unsafe UNSAFE;
24.2138 + private static final long ctlOffset;
24.2139 + private static final long stealCountOffset;
24.2140 + private static final long blockedCountOffset;
24.2141 + private static final long quiescerCountOffset;
24.2142 + private static final long scanGuardOffset;
24.2143 + private static final long nextWorkerNumberOffset;
24.2144 + private static final long ABASE;
24.2145 + private static final int ASHIFT;
24.2146 +
24.2147 + static {
24.2148 + poolNumberGenerator = new AtomicInteger();
24.2149 + workerSeedGenerator = new Random();
24.2150 + modifyThreadPermission = new RuntimePermission("modifyThread");
24.2151 + defaultForkJoinWorkerThreadFactory =
24.2152 + new DefaultForkJoinWorkerThreadFactory();
24.2153 + int s;
24.2154 + try {
24.2155 + UNSAFE = sun.misc.Unsafe.getUnsafe();
24.2156 + Class k = ForkJoinPool.class;
24.2157 + ctlOffset = UNSAFE.objectFieldOffset
24.2158 + (k.getDeclaredField("ctl"));
24.2159 + stealCountOffset = UNSAFE.objectFieldOffset
24.2160 + (k.getDeclaredField("stealCount"));
24.2161 + blockedCountOffset = UNSAFE.objectFieldOffset
24.2162 + (k.getDeclaredField("blockedCount"));
24.2163 + quiescerCountOffset = UNSAFE.objectFieldOffset
24.2164 + (k.getDeclaredField("quiescerCount"));
24.2165 + scanGuardOffset = UNSAFE.objectFieldOffset
24.2166 + (k.getDeclaredField("scanGuard"));
24.2167 + nextWorkerNumberOffset = UNSAFE.objectFieldOffset
24.2168 + (k.getDeclaredField("nextWorkerNumber"));
24.2169 + Class a = ForkJoinTask[].class;
24.2170 + ABASE = UNSAFE.arrayBaseOffset(a);
24.2171 + s = UNSAFE.arrayIndexScale(a);
24.2172 + } catch (Exception e) {
24.2173 + throw new Error(e);
24.2174 + }
24.2175 + if ((s & (s-1)) != 0)
24.2176 + throw new Error("data type scale not a power of two");
24.2177 + ASHIFT = 31 - Integer.numberOfLeadingZeros(s);
24.2178 + }
24.2179 +
24.2180 +}
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
25.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ForkJoinTask.java Sat Mar 19 10:48:29 2016 +0100
25.3 @@ -0,0 +1,1386 @@
25.4 +/*
25.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
25.6 + *
25.7 + * This code is free software; you can redistribute it and/or modify it
25.8 + * under the terms of the GNU General Public License version 2 only, as
25.9 + * published by the Free Software Foundation. Oracle designates this
25.10 + * particular file as subject to the "Classpath" exception as provided
25.11 + * by Oracle in the LICENSE file that accompanied this code.
25.12 + *
25.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
25.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
25.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25.16 + * version 2 for more details (a copy is included in the LICENSE file that
25.17 + * accompanied this code).
25.18 + *
25.19 + * You should have received a copy of the GNU General Public License version
25.20 + * 2 along with this work; if not, write to the Free Software Foundation,
25.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
25.22 + *
25.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
25.24 + * or visit www.oracle.com if you need additional information or have any
25.25 + * questions.
25.26 + */
25.27 +
25.28 +/*
25.29 + * This file is available under and governed by the GNU General Public
25.30 + * License version 2 only, as published by the Free Software Foundation.
25.31 + * However, the following notice accompanied the original version of this
25.32 + * file:
25.33 + *
25.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
25.35 + * Expert Group and released to the public domain, as explained at
25.36 + * http://creativecommons.org/publicdomain/zero/1.0/
25.37 + */
25.38 +
25.39 +package java.util.concurrent;
25.40 +
25.41 +import java.io.Serializable;
25.42 +import java.util.Collection;
25.43 +import java.util.Collections;
25.44 +import java.util.List;
25.45 +import java.util.RandomAccess;
25.46 +import java.util.Map;
25.47 +import java.lang.ref.WeakReference;
25.48 +import java.lang.ref.ReferenceQueue;
25.49 +import java.util.concurrent.Callable;
25.50 +import java.util.concurrent.CancellationException;
25.51 +import java.util.concurrent.ExecutionException;
25.52 +import java.util.concurrent.Executor;
25.53 +import java.util.concurrent.ExecutorService;
25.54 +import java.util.concurrent.Future;
25.55 +import java.util.concurrent.RejectedExecutionException;
25.56 +import java.util.concurrent.RunnableFuture;
25.57 +import java.util.concurrent.TimeUnit;
25.58 +import java.util.concurrent.TimeoutException;
25.59 +import java.util.concurrent.locks.ReentrantLock;
25.60 +import java.lang.reflect.Constructor;
25.61 +
25.62 +/**
25.63 + * Abstract base class for tasks that run within a {@link ForkJoinPool}.
25.64 + * A {@code ForkJoinTask} is a thread-like entity that is much
25.65 + * lighter weight than a normal thread. Huge numbers of tasks and
25.66 + * subtasks may be hosted by a small number of actual threads in a
25.67 + * ForkJoinPool, at the price of some usage limitations.
25.68 + *
25.69 + * <p>A "main" {@code ForkJoinTask} begins execution when submitted
25.70 + * to a {@link ForkJoinPool}. Once started, it will usually in turn
25.71 + * start other subtasks. As indicated by the name of this class,
25.72 + * many programs using {@code ForkJoinTask} employ only methods
25.73 + * {@link #fork} and {@link #join}, or derivatives such as {@link
25.74 + * #invokeAll(ForkJoinTask...) invokeAll}. However, this class also
25.75 + * provides a number of other methods that can come into play in
25.76 + * advanced usages, as well as extension mechanics that allow
25.77 + * support of new forms of fork/join processing.
25.78 + *
25.79 + * <p>A {@code ForkJoinTask} is a lightweight form of {@link Future}.
25.80 + * The efficiency of {@code ForkJoinTask}s stems from a set of
25.81 + * restrictions (that are only partially statically enforceable)
25.82 + * reflecting their intended use as computational tasks calculating
25.83 + * pure functions or operating on purely isolated objects. The
25.84 + * primary coordination mechanisms are {@link #fork}, that arranges
25.85 + * asynchronous execution, and {@link #join}, that doesn't proceed
25.86 + * until the task's result has been computed. Computations should
25.87 + * avoid {@code synchronized} methods or blocks, and should minimize
25.88 + * other blocking synchronization apart from joining other tasks or
25.89 + * using synchronizers such as Phasers that are advertised to
25.90 + * cooperate with fork/join scheduling. Tasks should also not perform
25.91 + * blocking IO, and should ideally access variables that are
25.92 + * completely independent of those accessed by other running
25.93 + * tasks. Minor breaches of these restrictions, for example using
25.94 + * shared output streams, may be tolerable in practice, but frequent
25.95 + * use may result in poor performance, and the potential to
25.96 + * indefinitely stall if the number of threads not waiting for IO or
25.97 + * other external synchronization becomes exhausted. This usage
25.98 + * restriction is in part enforced by not permitting checked
25.99 + * exceptions such as {@code IOExceptions} to be thrown. However,
25.100 + * computations may still encounter unchecked exceptions, that are
25.101 + * rethrown to callers attempting to join them. These exceptions may
25.102 + * additionally include {@link RejectedExecutionException} stemming
25.103 + * from internal resource exhaustion, such as failure to allocate
25.104 + * internal task queues. Rethrown exceptions behave in the same way as
25.105 + * regular exceptions, but, when possible, contain stack traces (as
25.106 + * displayed for example using {@code ex.printStackTrace()}) of both
25.107 + * the thread that initiated the computation as well as the thread
25.108 + * actually encountering the exception; minimally only the latter.
25.109 + *
25.110 + * <p>The primary method for awaiting completion and extracting
25.111 + * results of a task is {@link #join}, but there are several variants:
25.112 + * The {@link Future#get} methods support interruptible and/or timed
25.113 + * waits for completion and report results using {@code Future}
25.114 + * conventions. Method {@link #invoke} is semantically
25.115 + * equivalent to {@code fork(); join()} but always attempts to begin
25.116 + * execution in the current thread. The "<em>quiet</em>" forms of
25.117 + * these methods do not extract results or report exceptions. These
25.118 + * may be useful when a set of tasks are being executed, and you need
25.119 + * to delay processing of results or exceptions until all complete.
25.120 + * Method {@code invokeAll} (available in multiple versions)
25.121 + * performs the most common form of parallel invocation: forking a set
25.122 + * of tasks and joining them all.
25.123 + *
25.124 + * <p>The execution status of tasks may be queried at several levels
25.125 + * of detail: {@link #isDone} is true if a task completed in any way
25.126 + * (including the case where a task was cancelled without executing);
25.127 + * {@link #isCompletedNormally} is true if a task completed without
25.128 + * cancellation or encountering an exception; {@link #isCancelled} is
25.129 + * true if the task was cancelled (in which case {@link #getException}
25.130 + * returns a {@link java.util.concurrent.CancellationException}); and
25.131 + * {@link #isCompletedAbnormally} is true if a task was either
25.132 + * cancelled or encountered an exception, in which case {@link
25.133 + * #getException} will return either the encountered exception or
25.134 + * {@link java.util.concurrent.CancellationException}.
25.135 + *
25.136 + * <p>The ForkJoinTask class is not usually directly subclassed.
25.137 + * Instead, you subclass one of the abstract classes that support a
25.138 + * particular style of fork/join processing, typically {@link
25.139 + * RecursiveAction} for computations that do not return results, or
25.140 + * {@link RecursiveTask} for those that do. Normally, a concrete
25.141 + * ForkJoinTask subclass declares fields comprising its parameters,
25.142 + * established in a constructor, and then defines a {@code compute}
25.143 + * method that somehow uses the control methods supplied by this base
25.144 + * class. While these methods have {@code public} access (to allow
25.145 + * instances of different task subclasses to call each other's
25.146 + * methods), some of them may only be called from within other
25.147 + * ForkJoinTasks (as may be determined using method {@link
25.148 + * #inForkJoinPool}). Attempts to invoke them in other contexts
25.149 + * result in exceptions or errors, possibly including
25.150 + * {@code ClassCastException}.
25.151 + *
25.152 + * <p>Method {@link #join} and its variants are appropriate for use
25.153 + * only when completion dependencies are acyclic; that is, the
25.154 + * parallel computation can be described as a directed acyclic graph
25.155 + * (DAG). Otherwise, executions may encounter a form of deadlock as
25.156 + * tasks cyclically wait for each other. However, this framework
25.157 + * supports other methods and techniques (for example the use of
25.158 + * {@link Phaser}, {@link #helpQuiesce}, and {@link #complete}) that
25.159 + * may be of use in constructing custom subclasses for problems that
25.160 + * are not statically structured as DAGs.
25.161 + *
25.162 + * <p>Most base support methods are {@code final}, to prevent
25.163 + * overriding of implementations that are intrinsically tied to the
25.164 + * underlying lightweight task scheduling framework. Developers
25.165 + * creating new basic styles of fork/join processing should minimally
25.166 + * implement {@code protected} methods {@link #exec}, {@link
25.167 + * #setRawResult}, and {@link #getRawResult}, while also introducing
25.168 + * an abstract computational method that can be implemented in its
25.169 + * subclasses, possibly relying on other {@code protected} methods
25.170 + * provided by this class.
25.171 + *
25.172 + * <p>ForkJoinTasks should perform relatively small amounts of
25.173 + * computation. Large tasks should be split into smaller subtasks,
25.174 + * usually via recursive decomposition. As a very rough rule of thumb,
25.175 + * a task should perform more than 100 and less than 10000 basic
25.176 + * computational steps, and should avoid indefinite looping. If tasks
25.177 + * are too big, then parallelism cannot improve throughput. If too
25.178 + * small, then memory and internal task maintenance overhead may
25.179 + * overwhelm processing.
25.180 + *
25.181 + * <p>This class provides {@code adapt} methods for {@link Runnable}
25.182 + * and {@link Callable}, that may be of use when mixing execution of
25.183 + * {@code ForkJoinTasks} with other kinds of tasks. When all tasks are
25.184 + * of this form, consider using a pool constructed in <em>asyncMode</em>.
25.185 + *
25.186 + * <p>ForkJoinTasks are {@code Serializable}, which enables them to be
25.187 + * used in extensions such as remote execution frameworks. It is
25.188 + * sensible to serialize tasks only before or after, but not during,
25.189 + * execution. Serialization is not relied on during execution itself.
25.190 + *
25.191 + * @since 1.7
25.192 + * @author Doug Lea
25.193 + */
25.194 +public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
25.195 +
25.196 + /*
25.197 + * See the internal documentation of class ForkJoinPool for a
25.198 + * general implementation overview. ForkJoinTasks are mainly
25.199 + * responsible for maintaining their "status" field amidst relays
25.200 + * to methods in ForkJoinWorkerThread and ForkJoinPool. The
25.201 + * methods of this class are more-or-less layered into (1) basic
25.202 + * status maintenance (2) execution and awaiting completion (3)
25.203 + * user-level methods that additionally report results. This is
25.204 + * sometimes hard to see because this file orders exported methods
25.205 + * in a way that flows well in javadocs.
25.206 + */
25.207 +
25.208 + /*
25.209 + * The status field holds run control status bits packed into a
25.210 + * single int to minimize footprint and to ensure atomicity (via
25.211 + * CAS). Status is initially zero, and takes on nonnegative
25.212 + * values until completed, upon which status holds value
25.213 + * NORMAL, CANCELLED, or EXCEPTIONAL. Tasks undergoing blocking
25.214 + * waits by other threads have the SIGNAL bit set. Completion of
25.215 + * a stolen task with SIGNAL set awakens any waiters via
25.216 + * notifyAll. Even though suboptimal for some purposes, we use
25.217 + * basic builtin wait/notify to take advantage of "monitor
25.218 + * inflation" in JVMs that we would otherwise need to emulate to
25.219 + * avoid adding further per-task bookkeeping overhead. We want
25.220 + * these monitors to be "fat", i.e., not use biasing or thin-lock
25.221 + * techniques, so use some odd coding idioms that tend to avoid
25.222 + * them.
25.223 + */
25.224 +
25.225 + /** The run status of this task */
25.226 + volatile int status; // accessed directly by pool and workers
25.227 + private static final int NORMAL = -1;
25.228 + private static final int CANCELLED = -2;
25.229 + private static final int EXCEPTIONAL = -3;
25.230 + private static final int SIGNAL = 1;
25.231 +
25.232 + /**
25.233 + * Marks completion and wakes up threads waiting to join this task,
25.234 + * also clearing signal request bits.
25.235 + *
25.236 + * @param completion one of NORMAL, CANCELLED, EXCEPTIONAL
25.237 + * @return completion status on exit
25.238 + */
25.239 + private int setCompletion(int completion) {
25.240 + for (int s;;) {
25.241 + if ((s = status) < 0)
25.242 + return s;
25.243 + if (UNSAFE.compareAndSwapInt(this, statusOffset, s, completion)) {
25.244 + if (s != 0)
25.245 + synchronized (this) { notifyAll(); }
25.246 + return completion;
25.247 + }
25.248 + }
25.249 + }
25.250 +
25.251 + /**
25.252 + * Tries to block a worker thread until completed or timed out.
25.253 + * Uses Object.wait time argument conventions.
25.254 + * May fail on contention or interrupt.
25.255 + *
25.256 + * @param millis if > 0, wait time.
25.257 + */
25.258 + final void tryAwaitDone(long millis) {
25.259 + int s;
25.260 + try {
25.261 + if (((s = status) > 0 ||
25.262 + (s == 0 &&
25.263 + UNSAFE.compareAndSwapInt(this, statusOffset, 0, SIGNAL))) &&
25.264 + status > 0) {
25.265 + synchronized (this) {
25.266 + if (status > 0)
25.267 + wait(millis);
25.268 + }
25.269 + }
25.270 + } catch (InterruptedException ie) {
25.271 + // caller must check termination
25.272 + }
25.273 + }
25.274 +
25.275 + /**
25.276 + * Blocks a non-worker-thread until completion.
25.277 + * @return status upon completion
25.278 + */
25.279 + private int externalAwaitDone() {
25.280 + int s;
25.281 + if ((s = status) >= 0) {
25.282 + boolean interrupted = false;
25.283 + synchronized (this) {
25.284 + while ((s = status) >= 0) {
25.285 + if (s == 0)
25.286 + UNSAFE.compareAndSwapInt(this, statusOffset,
25.287 + 0, SIGNAL);
25.288 + else {
25.289 + try {
25.290 + wait();
25.291 + } catch (InterruptedException ie) {
25.292 + interrupted = true;
25.293 + }
25.294 + }
25.295 + }
25.296 + }
25.297 + if (interrupted)
25.298 + Thread.currentThread().interrupt();
25.299 + }
25.300 + return s;
25.301 + }
25.302 +
25.303 + /**
25.304 + * Blocks a non-worker-thread until completion or interruption or timeout.
25.305 + */
25.306 + private int externalInterruptibleAwaitDone(long millis)
25.307 + throws InterruptedException {
25.308 + int s;
25.309 + if (Thread.interrupted())
25.310 + throw new InterruptedException();
25.311 + if ((s = status) >= 0) {
25.312 + synchronized (this) {
25.313 + while ((s = status) >= 0) {
25.314 + if (s == 0)
25.315 + UNSAFE.compareAndSwapInt(this, statusOffset,
25.316 + 0, SIGNAL);
25.317 + else {
25.318 + wait(millis);
25.319 + if (millis > 0L)
25.320 + break;
25.321 + }
25.322 + }
25.323 + }
25.324 + }
25.325 + return s;
25.326 + }
25.327 +
25.328 + /**
25.329 + * Primary execution method for stolen tasks. Unless done, calls
25.330 + * exec and records status if completed, but doesn't wait for
25.331 + * completion otherwise.
25.332 + */
25.333 + final void doExec() {
25.334 + if (status >= 0) {
25.335 + boolean completed;
25.336 + try {
25.337 + completed = exec();
25.338 + } catch (Throwable rex) {
25.339 + setExceptionalCompletion(rex);
25.340 + return;
25.341 + }
25.342 + if (completed)
25.343 + setCompletion(NORMAL); // must be outside try block
25.344 + }
25.345 + }
25.346 +
25.347 + /**
25.348 + * Primary mechanics for join, get, quietlyJoin.
25.349 + * @return status upon completion
25.350 + */
25.351 + private int doJoin() {
25.352 + Thread t; ForkJoinWorkerThread w; int s; boolean completed;
25.353 + if ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) {
25.354 + if ((s = status) < 0)
25.355 + return s;
25.356 + if ((w = (ForkJoinWorkerThread)t).unpushTask(this)) {
25.357 + try {
25.358 + completed = exec();
25.359 + } catch (Throwable rex) {
25.360 + return setExceptionalCompletion(rex);
25.361 + }
25.362 + if (completed)
25.363 + return setCompletion(NORMAL);
25.364 + }
25.365 + return w.joinTask(this);
25.366 + }
25.367 + else
25.368 + return externalAwaitDone();
25.369 + }
25.370 +
25.371 + /**
25.372 + * Primary mechanics for invoke, quietlyInvoke.
25.373 + * @return status upon completion
25.374 + */
25.375 + private int doInvoke() {
25.376 + int s; boolean completed;
25.377 + if ((s = status) < 0)
25.378 + return s;
25.379 + try {
25.380 + completed = exec();
25.381 + } catch (Throwable rex) {
25.382 + return setExceptionalCompletion(rex);
25.383 + }
25.384 + if (completed)
25.385 + return setCompletion(NORMAL);
25.386 + else
25.387 + return doJoin();
25.388 + }
25.389 +
25.390 + // Exception table support
25.391 +
25.392 + /**
25.393 + * Table of exceptions thrown by tasks, to enable reporting by
25.394 + * callers. Because exceptions are rare, we don't directly keep
25.395 + * them with task objects, but instead use a weak ref table. Note
25.396 + * that cancellation exceptions don't appear in the table, but are
25.397 + * instead recorded as status values.
25.398 + *
25.399 + * Note: These statics are initialized below in static block.
25.400 + */
25.401 + private static final ExceptionNode[] exceptionTable;
25.402 + private static final ReentrantLock exceptionTableLock;
25.403 + private static final ReferenceQueue<Object> exceptionTableRefQueue;
25.404 +
25.405 + /**
25.406 + * Fixed capacity for exceptionTable.
25.407 + */
25.408 + private static final int EXCEPTION_MAP_CAPACITY = 32;
25.409 +
25.410 + /**
25.411 + * Key-value nodes for exception table. The chained hash table
25.412 + * uses identity comparisons, full locking, and weak references
25.413 + * for keys. The table has a fixed capacity because it only
25.414 + * maintains task exceptions long enough for joiners to access
25.415 + * them, so should never become very large for sustained
25.416 + * periods. However, since we do not know when the last joiner
25.417 + * completes, we must use weak references and expunge them. We do
25.418 + * so on each operation (hence full locking). Also, some thread in
25.419 + * any ForkJoinPool will call helpExpungeStaleExceptions when its
25.420 + * pool becomes isQuiescent.
25.421 + */
25.422 + static final class ExceptionNode extends WeakReference<ForkJoinTask<?>>{
25.423 + final Throwable ex;
25.424 + ExceptionNode next;
25.425 + final long thrower; // use id not ref to avoid weak cycles
25.426 + ExceptionNode(ForkJoinTask<?> task, Throwable ex, ExceptionNode next) {
25.427 + super(task, exceptionTableRefQueue);
25.428 + this.ex = ex;
25.429 + this.next = next;
25.430 + this.thrower = Thread.currentThread().getId();
25.431 + }
25.432 + }
25.433 +
25.434 + /**
25.435 + * Records exception and sets exceptional completion.
25.436 + *
25.437 + * @return status on exit
25.438 + */
25.439 + private int setExceptionalCompletion(Throwable ex) {
25.440 + int h = System.identityHashCode(this);
25.441 + final ReentrantLock lock = exceptionTableLock;
25.442 + lock.lock();
25.443 + try {
25.444 + expungeStaleExceptions();
25.445 + ExceptionNode[] t = exceptionTable;
25.446 + int i = h & (t.length - 1);
25.447 + for (ExceptionNode e = t[i]; ; e = e.next) {
25.448 + if (e == null) {
25.449 + t[i] = new ExceptionNode(this, ex, t[i]);
25.450 + break;
25.451 + }
25.452 + if (e.get() == this) // already present
25.453 + break;
25.454 + }
25.455 + } finally {
25.456 + lock.unlock();
25.457 + }
25.458 + return setCompletion(EXCEPTIONAL);
25.459 + }
25.460 +
25.461 + /**
25.462 + * Removes exception node and clears status
25.463 + */
25.464 + private void clearExceptionalCompletion() {
25.465 + int h = System.identityHashCode(this);
25.466 + final ReentrantLock lock = exceptionTableLock;
25.467 + lock.lock();
25.468 + try {
25.469 + ExceptionNode[] t = exceptionTable;
25.470 + int i = h & (t.length - 1);
25.471 + ExceptionNode e = t[i];
25.472 + ExceptionNode pred = null;
25.473 + while (e != null) {
25.474 + ExceptionNode next = e.next;
25.475 + if (e.get() == this) {
25.476 + if (pred == null)
25.477 + t[i] = next;
25.478 + else
25.479 + pred.next = next;
25.480 + break;
25.481 + }
25.482 + pred = e;
25.483 + e = next;
25.484 + }
25.485 + expungeStaleExceptions();
25.486 + status = 0;
25.487 + } finally {
25.488 + lock.unlock();
25.489 + }
25.490 + }
25.491 +
25.492 + /**
25.493 + * Returns a rethrowable exception for the given task, if
25.494 + * available. To provide accurate stack traces, if the exception
25.495 + * was not thrown by the current thread, we try to create a new
25.496 + * exception of the same type as the one thrown, but with the
25.497 + * recorded exception as its cause. If there is no such
25.498 + * constructor, we instead try to use a no-arg constructor,
25.499 + * followed by initCause, to the same effect. If none of these
25.500 + * apply, or any fail due to other exceptions, we return the
25.501 + * recorded exception, which is still correct, although it may
25.502 + * contain a misleading stack trace.
25.503 + *
25.504 + * @return the exception, or null if none
25.505 + */
25.506 + private Throwable getThrowableException() {
25.507 + if (status != EXCEPTIONAL)
25.508 + return null;
25.509 + int h = System.identityHashCode(this);
25.510 + ExceptionNode e;
25.511 + final ReentrantLock lock = exceptionTableLock;
25.512 + lock.lock();
25.513 + try {
25.514 + expungeStaleExceptions();
25.515 + ExceptionNode[] t = exceptionTable;
25.516 + e = t[h & (t.length - 1)];
25.517 + while (e != null && e.get() != this)
25.518 + e = e.next;
25.519 + } finally {
25.520 + lock.unlock();
25.521 + }
25.522 + Throwable ex;
25.523 + if (e == null || (ex = e.ex) == null)
25.524 + return null;
25.525 + if (e.thrower != Thread.currentThread().getId()) {
25.526 + Class ec = ex.getClass();
25.527 + try {
25.528 + Constructor<?> noArgCtor = null;
25.529 + Constructor<?>[] cs = ec.getConstructors();// public ctors only
25.530 + for (int i = 0; i < cs.length; ++i) {
25.531 + Constructor<?> c = cs[i];
25.532 + Class<?>[] ps = c.getParameterTypes();
25.533 + if (ps.length == 0)
25.534 + noArgCtor = c;
25.535 + else if (ps.length == 1 && ps[0] == Throwable.class)
25.536 + return (Throwable)(c.newInstance(ex));
25.537 + }
25.538 + if (noArgCtor != null) {
25.539 + Throwable wx = (Throwable)(noArgCtor.newInstance());
25.540 + wx.initCause(ex);
25.541 + return wx;
25.542 + }
25.543 + } catch (Exception ignore) {
25.544 + }
25.545 + }
25.546 + return ex;
25.547 + }
25.548 +
25.549 + /**
25.550 + * Poll stale refs and remove them. Call only while holding lock.
25.551 + */
25.552 + private static void expungeStaleExceptions() {
25.553 + for (Object x; (x = exceptionTableRefQueue.poll()) != null;) {
25.554 + if (x instanceof ExceptionNode) {
25.555 + ForkJoinTask<?> key = ((ExceptionNode)x).get();
25.556 + ExceptionNode[] t = exceptionTable;
25.557 + int i = System.identityHashCode(key) & (t.length - 1);
25.558 + ExceptionNode e = t[i];
25.559 + ExceptionNode pred = null;
25.560 + while (e != null) {
25.561 + ExceptionNode next = e.next;
25.562 + if (e == x) {
25.563 + if (pred == null)
25.564 + t[i] = next;
25.565 + else
25.566 + pred.next = next;
25.567 + break;
25.568 + }
25.569 + pred = e;
25.570 + e = next;
25.571 + }
25.572 + }
25.573 + }
25.574 + }
25.575 +
25.576 + /**
25.577 + * If lock is available, poll stale refs and remove them.
25.578 + * Called from ForkJoinPool when pools become quiescent.
25.579 + */
25.580 + static final void helpExpungeStaleExceptions() {
25.581 + final ReentrantLock lock = exceptionTableLock;
25.582 + if (lock.tryLock()) {
25.583 + try {
25.584 + expungeStaleExceptions();
25.585 + } finally {
25.586 + lock.unlock();
25.587 + }
25.588 + }
25.589 + }
25.590 +
25.591 + /**
25.592 + * Report the result of invoke or join; called only upon
25.593 + * non-normal return of internal versions.
25.594 + */
25.595 + private V reportResult() {
25.596 + int s; Throwable ex;
25.597 + if ((s = status) == CANCELLED)
25.598 + throw new CancellationException();
25.599 + if (s == EXCEPTIONAL && (ex = getThrowableException()) != null)
25.600 + UNSAFE.throwException(ex);
25.601 + return getRawResult();
25.602 + }
25.603 +
25.604 + // public methods
25.605 +
25.606 + /**
25.607 + * Arranges to asynchronously execute this task. While it is not
25.608 + * necessarily enforced, it is a usage error to fork a task more
25.609 + * than once unless it has completed and been reinitialized.
25.610 + * Subsequent modifications to the state of this task or any data
25.611 + * it operates on are not necessarily consistently observable by
25.612 + * any thread other than the one executing it unless preceded by a
25.613 + * call to {@link #join} or related methods, or a call to {@link
25.614 + * #isDone} returning {@code true}.
25.615 + *
25.616 + * <p>This method may be invoked only from within {@code
25.617 + * ForkJoinPool} computations (as may be determined using method
25.618 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
25.619 + * result in exceptions or errors, possibly including {@code
25.620 + * ClassCastException}.
25.621 + *
25.622 + * @return {@code this}, to simplify usage
25.623 + */
25.624 + public final ForkJoinTask<V> fork() {
25.625 + ((ForkJoinWorkerThread) Thread.currentThread())
25.626 + .pushTask(this);
25.627 + return this;
25.628 + }
25.629 +
25.630 + /**
25.631 + * Returns the result of the computation when it {@link #isDone is
25.632 + * done}. This method differs from {@link #get()} in that
25.633 + * abnormal completion results in {@code RuntimeException} or
25.634 + * {@code Error}, not {@code ExecutionException}, and that
25.635 + * interrupts of the calling thread do <em>not</em> cause the
25.636 + * method to abruptly return by throwing {@code
25.637 + * InterruptedException}.
25.638 + *
25.639 + * @return the computed result
25.640 + */
25.641 + public final V join() {
25.642 + if (doJoin() != NORMAL)
25.643 + return reportResult();
25.644 + else
25.645 + return getRawResult();
25.646 + }
25.647 +
25.648 + /**
25.649 + * Commences performing this task, awaits its completion if
25.650 + * necessary, and returns its result, or throws an (unchecked)
25.651 + * {@code RuntimeException} or {@code Error} if the underlying
25.652 + * computation did so.
25.653 + *
25.654 + * @return the computed result
25.655 + */
25.656 + public final V invoke() {
25.657 + if (doInvoke() != NORMAL)
25.658 + return reportResult();
25.659 + else
25.660 + return getRawResult();
25.661 + }
25.662 +
25.663 + /**
25.664 + * Forks the given tasks, returning when {@code isDone} holds for
25.665 + * each task or an (unchecked) exception is encountered, in which
25.666 + * case the exception is rethrown. If more than one task
25.667 + * encounters an exception, then this method throws any one of
25.668 + * these exceptions. If any task encounters an exception, the
25.669 + * other may be cancelled. However, the execution status of
25.670 + * individual tasks is not guaranteed upon exceptional return. The
25.671 + * status of each task may be obtained using {@link
25.672 + * #getException()} and related methods to check if they have been
25.673 + * cancelled, completed normally or exceptionally, or left
25.674 + * unprocessed.
25.675 + *
25.676 + * <p>This method may be invoked only from within {@code
25.677 + * ForkJoinPool} computations (as may be determined using method
25.678 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
25.679 + * result in exceptions or errors, possibly including {@code
25.680 + * ClassCastException}.
25.681 + *
25.682 + * @param t1 the first task
25.683 + * @param t2 the second task
25.684 + * @throws NullPointerException if any task is null
25.685 + */
25.686 + public static void invokeAll(ForkJoinTask<?> t1, ForkJoinTask<?> t2) {
25.687 + t2.fork();
25.688 + t1.invoke();
25.689 + t2.join();
25.690 + }
25.691 +
25.692 + /**
25.693 + * Forks the given tasks, returning when {@code isDone} holds for
25.694 + * each task or an (unchecked) exception is encountered, in which
25.695 + * case the exception is rethrown. If more than one task
25.696 + * encounters an exception, then this method throws any one of
25.697 + * these exceptions. If any task encounters an exception, others
25.698 + * may be cancelled. However, the execution status of individual
25.699 + * tasks is not guaranteed upon exceptional return. The status of
25.700 + * each task may be obtained using {@link #getException()} and
25.701 + * related methods to check if they have been cancelled, completed
25.702 + * normally or exceptionally, or left unprocessed.
25.703 + *
25.704 + * <p>This method may be invoked only from within {@code
25.705 + * ForkJoinPool} computations (as may be determined using method
25.706 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
25.707 + * result in exceptions or errors, possibly including {@code
25.708 + * ClassCastException}.
25.709 + *
25.710 + * @param tasks the tasks
25.711 + * @throws NullPointerException if any task is null
25.712 + */
25.713 + public static void invokeAll(ForkJoinTask<?>... tasks) {
25.714 + Throwable ex = null;
25.715 + int last = tasks.length - 1;
25.716 + for (int i = last; i >= 0; --i) {
25.717 + ForkJoinTask<?> t = tasks[i];
25.718 + if (t == null) {
25.719 + if (ex == null)
25.720 + ex = new NullPointerException();
25.721 + }
25.722 + else if (i != 0)
25.723 + t.fork();
25.724 + else if (t.doInvoke() < NORMAL && ex == null)
25.725 + ex = t.getException();
25.726 + }
25.727 + for (int i = 1; i <= last; ++i) {
25.728 + ForkJoinTask<?> t = tasks[i];
25.729 + if (t != null) {
25.730 + if (ex != null)
25.731 + t.cancel(false);
25.732 + else if (t.doJoin() < NORMAL && ex == null)
25.733 + ex = t.getException();
25.734 + }
25.735 + }
25.736 + if (ex != null)
25.737 + UNSAFE.throwException(ex);
25.738 + }
25.739 +
25.740 + /**
25.741 + * Forks all tasks in the specified collection, returning when
25.742 + * {@code isDone} holds for each task or an (unchecked) exception
25.743 + * is encountered, in which case the exception is rethrown. If
25.744 + * more than one task encounters an exception, then this method
25.745 + * throws any one of these exceptions. If any task encounters an
25.746 + * exception, others may be cancelled. However, the execution
25.747 + * status of individual tasks is not guaranteed upon exceptional
25.748 + * return. The status of each task may be obtained using {@link
25.749 + * #getException()} and related methods to check if they have been
25.750 + * cancelled, completed normally or exceptionally, or left
25.751 + * unprocessed.
25.752 + *
25.753 + * <p>This method may be invoked only from within {@code
25.754 + * ForkJoinPool} computations (as may be determined using method
25.755 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
25.756 + * result in exceptions or errors, possibly including {@code
25.757 + * ClassCastException}.
25.758 + *
25.759 + * @param tasks the collection of tasks
25.760 + * @return the tasks argument, to simplify usage
25.761 + * @throws NullPointerException if tasks or any element are null
25.762 + */
25.763 + public static <T extends ForkJoinTask<?>> Collection<T> invokeAll(Collection<T> tasks) {
25.764 + if (!(tasks instanceof RandomAccess) || !(tasks instanceof List<?>)) {
25.765 + invokeAll(tasks.toArray(new ForkJoinTask<?>[tasks.size()]));
25.766 + return tasks;
25.767 + }
25.768 + @SuppressWarnings("unchecked")
25.769 + List<? extends ForkJoinTask<?>> ts =
25.770 + (List<? extends ForkJoinTask<?>>) tasks;
25.771 + Throwable ex = null;
25.772 + int last = ts.size() - 1;
25.773 + for (int i = last; i >= 0; --i) {
25.774 + ForkJoinTask<?> t = ts.get(i);
25.775 + if (t == null) {
25.776 + if (ex == null)
25.777 + ex = new NullPointerException();
25.778 + }
25.779 + else if (i != 0)
25.780 + t.fork();
25.781 + else if (t.doInvoke() < NORMAL && ex == null)
25.782 + ex = t.getException();
25.783 + }
25.784 + for (int i = 1; i <= last; ++i) {
25.785 + ForkJoinTask<?> t = ts.get(i);
25.786 + if (t != null) {
25.787 + if (ex != null)
25.788 + t.cancel(false);
25.789 + else if (t.doJoin() < NORMAL && ex == null)
25.790 + ex = t.getException();
25.791 + }
25.792 + }
25.793 + if (ex != null)
25.794 + UNSAFE.throwException(ex);
25.795 + return tasks;
25.796 + }
25.797 +
25.798 + /**
25.799 + * Attempts to cancel execution of this task. This attempt will
25.800 + * fail if the task has already completed or could not be
25.801 + * cancelled for some other reason. If successful, and this task
25.802 + * has not started when {@code cancel} is called, execution of
25.803 + * this task is suppressed. After this method returns
25.804 + * successfully, unless there is an intervening call to {@link
25.805 + * #reinitialize}, subsequent calls to {@link #isCancelled},
25.806 + * {@link #isDone}, and {@code cancel} will return {@code true}
25.807 + * and calls to {@link #join} and related methods will result in
25.808 + * {@code CancellationException}.
25.809 + *
25.810 + * <p>This method may be overridden in subclasses, but if so, must
25.811 + * still ensure that these properties hold. In particular, the
25.812 + * {@code cancel} method itself must not throw exceptions.
25.813 + *
25.814 + * <p>This method is designed to be invoked by <em>other</em>
25.815 + * tasks. To terminate the current task, you can just return or
25.816 + * throw an unchecked exception from its computation method, or
25.817 + * invoke {@link #completeExceptionally}.
25.818 + *
25.819 + * @param mayInterruptIfRunning this value has no effect in the
25.820 + * default implementation because interrupts are not used to
25.821 + * control cancellation.
25.822 + *
25.823 + * @return {@code true} if this task is now cancelled
25.824 + */
25.825 + public boolean cancel(boolean mayInterruptIfRunning) {
25.826 + return setCompletion(CANCELLED) == CANCELLED;
25.827 + }
25.828 +
25.829 + /**
25.830 + * Cancels, ignoring any exceptions thrown by cancel. Used during
25.831 + * worker and pool shutdown. Cancel is spec'ed not to throw any
25.832 + * exceptions, but if it does anyway, we have no recourse during
25.833 + * shutdown, so guard against this case.
25.834 + */
25.835 + final void cancelIgnoringExceptions() {
25.836 + try {
25.837 + cancel(false);
25.838 + } catch (Throwable ignore) {
25.839 + }
25.840 + }
25.841 +
25.842 + public final boolean isDone() {
25.843 + return status < 0;
25.844 + }
25.845 +
25.846 + public final boolean isCancelled() {
25.847 + return status == CANCELLED;
25.848 + }
25.849 +
25.850 + /**
25.851 + * Returns {@code true} if this task threw an exception or was cancelled.
25.852 + *
25.853 + * @return {@code true} if this task threw an exception or was cancelled
25.854 + */
25.855 + public final boolean isCompletedAbnormally() {
25.856 + return status < NORMAL;
25.857 + }
25.858 +
25.859 + /**
25.860 + * Returns {@code true} if this task completed without throwing an
25.861 + * exception and was not cancelled.
25.862 + *
25.863 + * @return {@code true} if this task completed without throwing an
25.864 + * exception and was not cancelled
25.865 + */
25.866 + public final boolean isCompletedNormally() {
25.867 + return status == NORMAL;
25.868 + }
25.869 +
25.870 + /**
25.871 + * Returns the exception thrown by the base computation, or a
25.872 + * {@code CancellationException} if cancelled, or {@code null} if
25.873 + * none or if the method has not yet completed.
25.874 + *
25.875 + * @return the exception, or {@code null} if none
25.876 + */
25.877 + public final Throwable getException() {
25.878 + int s = status;
25.879 + return ((s >= NORMAL) ? null :
25.880 + (s == CANCELLED) ? new CancellationException() :
25.881 + getThrowableException());
25.882 + }
25.883 +
25.884 + /**
25.885 + * Completes this task abnormally, and if not already aborted or
25.886 + * cancelled, causes it to throw the given exception upon
25.887 + * {@code join} and related operations. This method may be used
25.888 + * to induce exceptions in asynchronous tasks, or to force
25.889 + * completion of tasks that would not otherwise complete. Its use
25.890 + * in other situations is discouraged. This method is
25.891 + * overridable, but overridden versions must invoke {@code super}
25.892 + * implementation to maintain guarantees.
25.893 + *
25.894 + * @param ex the exception to throw. If this exception is not a
25.895 + * {@code RuntimeException} or {@code Error}, the actual exception
25.896 + * thrown will be a {@code RuntimeException} with cause {@code ex}.
25.897 + */
25.898 + public void completeExceptionally(Throwable ex) {
25.899 + setExceptionalCompletion((ex instanceof RuntimeException) ||
25.900 + (ex instanceof Error) ? ex :
25.901 + new RuntimeException(ex));
25.902 + }
25.903 +
25.904 + /**
25.905 + * Completes this task, and if not already aborted or cancelled,
25.906 + * returning the given value as the result of subsequent
25.907 + * invocations of {@code join} and related operations. This method
25.908 + * may be used to provide results for asynchronous tasks, or to
25.909 + * provide alternative handling for tasks that would not otherwise
25.910 + * complete normally. Its use in other situations is
25.911 + * discouraged. This method is overridable, but overridden
25.912 + * versions must invoke {@code super} implementation to maintain
25.913 + * guarantees.
25.914 + *
25.915 + * @param value the result value for this task
25.916 + */
25.917 + public void complete(V value) {
25.918 + try {
25.919 + setRawResult(value);
25.920 + } catch (Throwable rex) {
25.921 + setExceptionalCompletion(rex);
25.922 + return;
25.923 + }
25.924 + setCompletion(NORMAL);
25.925 + }
25.926 +
25.927 + /**
25.928 + * Waits if necessary for the computation to complete, and then
25.929 + * retrieves its result.
25.930 + *
25.931 + * @return the computed result
25.932 + * @throws CancellationException if the computation was cancelled
25.933 + * @throws ExecutionException if the computation threw an
25.934 + * exception
25.935 + * @throws InterruptedException if the current thread is not a
25.936 + * member of a ForkJoinPool and was interrupted while waiting
25.937 + */
25.938 + public final V get() throws InterruptedException, ExecutionException {
25.939 + int s = (Thread.currentThread() instanceof ForkJoinWorkerThread) ?
25.940 + doJoin() : externalInterruptibleAwaitDone(0L);
25.941 + Throwable ex;
25.942 + if (s == CANCELLED)
25.943 + throw new CancellationException();
25.944 + if (s == EXCEPTIONAL && (ex = getThrowableException()) != null)
25.945 + throw new ExecutionException(ex);
25.946 + return getRawResult();
25.947 + }
25.948 +
25.949 + /**
25.950 + * Waits if necessary for at most the given time for the computation
25.951 + * to complete, and then retrieves its result, if available.
25.952 + *
25.953 + * @param timeout the maximum time to wait
25.954 + * @param unit the time unit of the timeout argument
25.955 + * @return the computed result
25.956 + * @throws CancellationException if the computation was cancelled
25.957 + * @throws ExecutionException if the computation threw an
25.958 + * exception
25.959 + * @throws InterruptedException if the current thread is not a
25.960 + * member of a ForkJoinPool and was interrupted while waiting
25.961 + * @throws TimeoutException if the wait timed out
25.962 + */
25.963 + public final V get(long timeout, TimeUnit unit)
25.964 + throws InterruptedException, ExecutionException, TimeoutException {
25.965 + Thread t = Thread.currentThread();
25.966 + if (t instanceof ForkJoinWorkerThread) {
25.967 + ForkJoinWorkerThread w = (ForkJoinWorkerThread) t;
25.968 + long nanos = unit.toNanos(timeout);
25.969 + if (status >= 0) {
25.970 + boolean completed = false;
25.971 + if (w.unpushTask(this)) {
25.972 + try {
25.973 + completed = exec();
25.974 + } catch (Throwable rex) {
25.975 + setExceptionalCompletion(rex);
25.976 + }
25.977 + }
25.978 + if (completed)
25.979 + setCompletion(NORMAL);
25.980 + else if (status >= 0 && nanos > 0)
25.981 + w.pool.timedAwaitJoin(this, nanos);
25.982 + }
25.983 + }
25.984 + else {
25.985 + long millis = unit.toMillis(timeout);
25.986 + if (millis > 0)
25.987 + externalInterruptibleAwaitDone(millis);
25.988 + }
25.989 + int s = status;
25.990 + if (s != NORMAL) {
25.991 + Throwable ex;
25.992 + if (s == CANCELLED)
25.993 + throw new CancellationException();
25.994 + if (s != EXCEPTIONAL)
25.995 + throw new TimeoutException();
25.996 + if ((ex = getThrowableException()) != null)
25.997 + throw new ExecutionException(ex);
25.998 + }
25.999 + return getRawResult();
25.1000 + }
25.1001 +
25.1002 + /**
25.1003 + * Joins this task, without returning its result or throwing its
25.1004 + * exception. This method may be useful when processing
25.1005 + * collections of tasks when some have been cancelled or otherwise
25.1006 + * known to have aborted.
25.1007 + */
25.1008 + public final void quietlyJoin() {
25.1009 + doJoin();
25.1010 + }
25.1011 +
25.1012 + /**
25.1013 + * Commences performing this task and awaits its completion if
25.1014 + * necessary, without returning its result or throwing its
25.1015 + * exception.
25.1016 + */
25.1017 + public final void quietlyInvoke() {
25.1018 + doInvoke();
25.1019 + }
25.1020 +
25.1021 + /**
25.1022 + * Possibly executes tasks until the pool hosting the current task
25.1023 + * {@link ForkJoinPool#isQuiescent is quiescent}. This method may
25.1024 + * be of use in designs in which many tasks are forked, but none
25.1025 + * are explicitly joined, instead executing them until all are
25.1026 + * processed.
25.1027 + *
25.1028 + * <p>This method may be invoked only from within {@code
25.1029 + * ForkJoinPool} computations (as may be determined using method
25.1030 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
25.1031 + * result in exceptions or errors, possibly including {@code
25.1032 + * ClassCastException}.
25.1033 + */
25.1034 + public static void helpQuiesce() {
25.1035 + ((ForkJoinWorkerThread) Thread.currentThread())
25.1036 + .helpQuiescePool();
25.1037 + }
25.1038 +
25.1039 + /**
25.1040 + * Resets the internal bookkeeping state of this task, allowing a
25.1041 + * subsequent {@code fork}. This method allows repeated reuse of
25.1042 + * this task, but only if reuse occurs when this task has either
25.1043 + * never been forked, or has been forked, then completed and all
25.1044 + * outstanding joins of this task have also completed. Effects
25.1045 + * under any other usage conditions are not guaranteed.
25.1046 + * This method may be useful when executing
25.1047 + * pre-constructed trees of subtasks in loops.
25.1048 + *
25.1049 + * <p>Upon completion of this method, {@code isDone()} reports
25.1050 + * {@code false}, and {@code getException()} reports {@code
25.1051 + * null}. However, the value returned by {@code getRawResult} is
25.1052 + * unaffected. To clear this value, you can invoke {@code
25.1053 + * setRawResult(null)}.
25.1054 + */
25.1055 + public void reinitialize() {
25.1056 + if (status == EXCEPTIONAL)
25.1057 + clearExceptionalCompletion();
25.1058 + else
25.1059 + status = 0;
25.1060 + }
25.1061 +
25.1062 + /**
25.1063 + * Returns the pool hosting the current task execution, or null
25.1064 + * if this task is executing outside of any ForkJoinPool.
25.1065 + *
25.1066 + * @see #inForkJoinPool
25.1067 + * @return the pool, or {@code null} if none
25.1068 + */
25.1069 + public static ForkJoinPool getPool() {
25.1070 + Thread t = Thread.currentThread();
25.1071 + return (t instanceof ForkJoinWorkerThread) ?
25.1072 + ((ForkJoinWorkerThread) t).pool : null;
25.1073 + }
25.1074 +
25.1075 + /**
25.1076 + * Returns {@code true} if the current thread is a {@link
25.1077 + * ForkJoinWorkerThread} executing as a ForkJoinPool computation.
25.1078 + *
25.1079 + * @return {@code true} if the current thread is a {@link
25.1080 + * ForkJoinWorkerThread} executing as a ForkJoinPool computation,
25.1081 + * or {@code false} otherwise
25.1082 + */
25.1083 + public static boolean inForkJoinPool() {
25.1084 + return Thread.currentThread() instanceof ForkJoinWorkerThread;
25.1085 + }
25.1086 +
25.1087 + /**
25.1088 + * Tries to unschedule this task for execution. This method will
25.1089 + * typically succeed if this task is the most recently forked task
25.1090 + * by the current thread, and has not commenced executing in
25.1091 + * another thread. This method may be useful when arranging
25.1092 + * alternative local processing of tasks that could have been, but
25.1093 + * were not, stolen.
25.1094 + *
25.1095 + * <p>This method may be invoked only from within {@code
25.1096 + * ForkJoinPool} computations (as may be determined using method
25.1097 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
25.1098 + * result in exceptions or errors, possibly including {@code
25.1099 + * ClassCastException}.
25.1100 + *
25.1101 + * @return {@code true} if unforked
25.1102 + */
25.1103 + public boolean tryUnfork() {
25.1104 + return ((ForkJoinWorkerThread) Thread.currentThread())
25.1105 + .unpushTask(this);
25.1106 + }
25.1107 +
25.1108 + /**
25.1109 + * Returns an estimate of the number of tasks that have been
25.1110 + * forked by the current worker thread but not yet executed. This
25.1111 + * value may be useful for heuristic decisions about whether to
25.1112 + * fork other tasks.
25.1113 + *
25.1114 + * <p>This method may be invoked only from within {@code
25.1115 + * ForkJoinPool} computations (as may be determined using method
25.1116 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
25.1117 + * result in exceptions or errors, possibly including {@code
25.1118 + * ClassCastException}.
25.1119 + *
25.1120 + * @return the number of tasks
25.1121 + */
25.1122 + public static int getQueuedTaskCount() {
25.1123 + return ((ForkJoinWorkerThread) Thread.currentThread())
25.1124 + .getQueueSize();
25.1125 + }
25.1126 +
25.1127 + /**
25.1128 + * Returns an estimate of how many more locally queued tasks are
25.1129 + * held by the current worker thread than there are other worker
25.1130 + * threads that might steal them. This value may be useful for
25.1131 + * heuristic decisions about whether to fork other tasks. In many
25.1132 + * usages of ForkJoinTasks, at steady state, each worker should
25.1133 + * aim to maintain a small constant surplus (for example, 3) of
25.1134 + * tasks, and to process computations locally if this threshold is
25.1135 + * exceeded.
25.1136 + *
25.1137 + * <p>This method may be invoked only from within {@code
25.1138 + * ForkJoinPool} computations (as may be determined using method
25.1139 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
25.1140 + * result in exceptions or errors, possibly including {@code
25.1141 + * ClassCastException}.
25.1142 + *
25.1143 + * @return the surplus number of tasks, which may be negative
25.1144 + */
25.1145 + public static int getSurplusQueuedTaskCount() {
25.1146 + return ((ForkJoinWorkerThread) Thread.currentThread())
25.1147 + .getEstimatedSurplusTaskCount();
25.1148 + }
25.1149 +
25.1150 + // Extension methods
25.1151 +
25.1152 + /**
25.1153 + * Returns the result that would be returned by {@link #join}, even
25.1154 + * if this task completed abnormally, or {@code null} if this task
25.1155 + * is not known to have been completed. This method is designed
25.1156 + * to aid debugging, as well as to support extensions. Its use in
25.1157 + * any other context is discouraged.
25.1158 + *
25.1159 + * @return the result, or {@code null} if not completed
25.1160 + */
25.1161 + public abstract V getRawResult();
25.1162 +
25.1163 + /**
25.1164 + * Forces the given value to be returned as a result. This method
25.1165 + * is designed to support extensions, and should not in general be
25.1166 + * called otherwise.
25.1167 + *
25.1168 + * @param value the value
25.1169 + */
25.1170 + protected abstract void setRawResult(V value);
25.1171 +
25.1172 + /**
25.1173 + * Immediately performs the base action of this task. This method
25.1174 + * is designed to support extensions, and should not in general be
25.1175 + * called otherwise. The return value controls whether this task
25.1176 + * is considered to be done normally. It may return false in
25.1177 + * asynchronous actions that require explicit invocations of
25.1178 + * {@link #complete} to become joinable. It may also throw an
25.1179 + * (unchecked) exception to indicate abnormal exit.
25.1180 + *
25.1181 + * @return {@code true} if completed normally
25.1182 + */
25.1183 + protected abstract boolean exec();
25.1184 +
25.1185 + /**
25.1186 + * Returns, but does not unschedule or execute, a task queued by
25.1187 + * the current thread but not yet executed, if one is immediately
25.1188 + * available. There is no guarantee that this task will actually
25.1189 + * be polled or executed next. Conversely, this method may return
25.1190 + * null even if a task exists but cannot be accessed without
25.1191 + * contention with other threads. This method is designed
25.1192 + * primarily to support extensions, and is unlikely to be useful
25.1193 + * otherwise.
25.1194 + *
25.1195 + * <p>This method may be invoked only from within {@code
25.1196 + * ForkJoinPool} computations (as may be determined using method
25.1197 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
25.1198 + * result in exceptions or errors, possibly including {@code
25.1199 + * ClassCastException}.
25.1200 + *
25.1201 + * @return the next task, or {@code null} if none are available
25.1202 + */
25.1203 + protected static ForkJoinTask<?> peekNextLocalTask() {
25.1204 + return ((ForkJoinWorkerThread) Thread.currentThread())
25.1205 + .peekTask();
25.1206 + }
25.1207 +
25.1208 + /**
25.1209 + * Unschedules and returns, without executing, the next task
25.1210 + * queued by the current thread but not yet executed. This method
25.1211 + * is designed primarily to support extensions, and is unlikely to
25.1212 + * be useful otherwise.
25.1213 + *
25.1214 + * <p>This method may be invoked only from within {@code
25.1215 + * ForkJoinPool} computations (as may be determined using method
25.1216 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
25.1217 + * result in exceptions or errors, possibly including {@code
25.1218 + * ClassCastException}.
25.1219 + *
25.1220 + * @return the next task, or {@code null} if none are available
25.1221 + */
25.1222 + protected static ForkJoinTask<?> pollNextLocalTask() {
25.1223 + return ((ForkJoinWorkerThread) Thread.currentThread())
25.1224 + .pollLocalTask();
25.1225 + }
25.1226 +
25.1227 + /**
25.1228 + * Unschedules and returns, without executing, the next task
25.1229 + * queued by the current thread but not yet executed, if one is
25.1230 + * available, or if not available, a task that was forked by some
25.1231 + * other thread, if available. Availability may be transient, so a
25.1232 + * {@code null} result does not necessarily imply quiescence
25.1233 + * of the pool this task is operating in. This method is designed
25.1234 + * primarily to support extensions, and is unlikely to be useful
25.1235 + * otherwise.
25.1236 + *
25.1237 + * <p>This method may be invoked only from within {@code
25.1238 + * ForkJoinPool} computations (as may be determined using method
25.1239 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
25.1240 + * result in exceptions or errors, possibly including {@code
25.1241 + * ClassCastException}.
25.1242 + *
25.1243 + * @return a task, or {@code null} if none are available
25.1244 + */
25.1245 + protected static ForkJoinTask<?> pollTask() {
25.1246 + return ((ForkJoinWorkerThread) Thread.currentThread())
25.1247 + .pollTask();
25.1248 + }
25.1249 +
25.1250 + /**
25.1251 + * Adaptor for Runnables. This implements RunnableFuture
25.1252 + * to be compliant with AbstractExecutorService constraints
25.1253 + * when used in ForkJoinPool.
25.1254 + */
25.1255 + static final class AdaptedRunnable<T> extends ForkJoinTask<T>
25.1256 + implements RunnableFuture<T> {
25.1257 + final Runnable runnable;
25.1258 + final T resultOnCompletion;
25.1259 + T result;
25.1260 + AdaptedRunnable(Runnable runnable, T result) {
25.1261 + if (runnable == null) throw new NullPointerException();
25.1262 + this.runnable = runnable;
25.1263 + this.resultOnCompletion = result;
25.1264 + }
25.1265 + public T getRawResult() { return result; }
25.1266 + public void setRawResult(T v) { result = v; }
25.1267 + public boolean exec() {
25.1268 + runnable.run();
25.1269 + result = resultOnCompletion;
25.1270 + return true;
25.1271 + }
25.1272 + public void run() { invoke(); }
25.1273 + private static final long serialVersionUID = 5232453952276885070L;
25.1274 + }
25.1275 +
25.1276 + /**
25.1277 + * Adaptor for Callables
25.1278 + */
25.1279 + static final class AdaptedCallable<T> extends ForkJoinTask<T>
25.1280 + implements RunnableFuture<T> {
25.1281 + final Callable<? extends T> callable;
25.1282 + T result;
25.1283 + AdaptedCallable(Callable<? extends T> callable) {
25.1284 + if (callable == null) throw new NullPointerException();
25.1285 + this.callable = callable;
25.1286 + }
25.1287 + public T getRawResult() { return result; }
25.1288 + public void setRawResult(T v) { result = v; }
25.1289 + public boolean exec() {
25.1290 + try {
25.1291 + result = callable.call();
25.1292 + return true;
25.1293 + } catch (Error err) {
25.1294 + throw err;
25.1295 + } catch (RuntimeException rex) {
25.1296 + throw rex;
25.1297 + } catch (Exception ex) {
25.1298 + throw new RuntimeException(ex);
25.1299 + }
25.1300 + }
25.1301 + public void run() { invoke(); }
25.1302 + private static final long serialVersionUID = 2838392045355241008L;
25.1303 + }
25.1304 +
25.1305 + /**
25.1306 + * Returns a new {@code ForkJoinTask} that performs the {@code run}
25.1307 + * method of the given {@code Runnable} as its action, and returns
25.1308 + * a null result upon {@link #join}.
25.1309 + *
25.1310 + * @param runnable the runnable action
25.1311 + * @return the task
25.1312 + */
25.1313 + public static ForkJoinTask<?> adapt(Runnable runnable) {
25.1314 + return new AdaptedRunnable<Void>(runnable, null);
25.1315 + }
25.1316 +
25.1317 + /**
25.1318 + * Returns a new {@code ForkJoinTask} that performs the {@code run}
25.1319 + * method of the given {@code Runnable} as its action, and returns
25.1320 + * the given result upon {@link #join}.
25.1321 + *
25.1322 + * @param runnable the runnable action
25.1323 + * @param result the result upon completion
25.1324 + * @return the task
25.1325 + */
25.1326 + public static <T> ForkJoinTask<T> adapt(Runnable runnable, T result) {
25.1327 + return new AdaptedRunnable<T>(runnable, result);
25.1328 + }
25.1329 +
25.1330 + /**
25.1331 + * Returns a new {@code ForkJoinTask} that performs the {@code call}
25.1332 + * method of the given {@code Callable} as its action, and returns
25.1333 + * its result upon {@link #join}, translating any checked exceptions
25.1334 + * encountered into {@code RuntimeException}.
25.1335 + *
25.1336 + * @param callable the callable action
25.1337 + * @return the task
25.1338 + */
25.1339 + public static <T> ForkJoinTask<T> adapt(Callable<? extends T> callable) {
25.1340 + return new AdaptedCallable<T>(callable);
25.1341 + }
25.1342 +
25.1343 + // Serialization support
25.1344 +
25.1345 + private static final long serialVersionUID = -7721805057305804111L;
25.1346 +
25.1347 + /**
25.1348 + * Saves the state to a stream (that is, serializes it).
25.1349 + *
25.1350 + * @serialData the current run status and the exception thrown
25.1351 + * during execution, or {@code null} if none
25.1352 + * @param s the stream
25.1353 + */
25.1354 + private void writeObject(java.io.ObjectOutputStream s)
25.1355 + throws java.io.IOException {
25.1356 + s.defaultWriteObject();
25.1357 + s.writeObject(getException());
25.1358 + }
25.1359 +
25.1360 + /**
25.1361 + * Reconstitutes the instance from a stream (that is, deserializes it).
25.1362 + *
25.1363 + * @param s the stream
25.1364 + */
25.1365 + private void readObject(java.io.ObjectInputStream s)
25.1366 + throws java.io.IOException, ClassNotFoundException {
25.1367 + s.defaultReadObject();
25.1368 + Object ex = s.readObject();
25.1369 + if (ex != null)
25.1370 + setExceptionalCompletion((Throwable)ex);
25.1371 + }
25.1372 +
25.1373 + // Unsafe mechanics
25.1374 + private static final sun.misc.Unsafe UNSAFE;
25.1375 + private static final long statusOffset;
25.1376 + static {
25.1377 + exceptionTableLock = new ReentrantLock();
25.1378 + exceptionTableRefQueue = new ReferenceQueue<Object>();
25.1379 + exceptionTable = new ExceptionNode[EXCEPTION_MAP_CAPACITY];
25.1380 + try {
25.1381 + UNSAFE = sun.misc.Unsafe.getUnsafe();
25.1382 + statusOffset = UNSAFE.objectFieldOffset
25.1383 + (ForkJoinTask.class.getDeclaredField("status"));
25.1384 + } catch (Exception e) {
25.1385 + throw new Error(e);
25.1386 + }
25.1387 + }
25.1388 +
25.1389 +}
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
26.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ForkJoinWorkerThread.java Sat Mar 19 10:48:29 2016 +0100
26.3 @@ -0,0 +1,998 @@
26.4 +/*
26.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
26.6 + *
26.7 + * This code is free software; you can redistribute it and/or modify it
26.8 + * under the terms of the GNU General Public License version 2 only, as
26.9 + * published by the Free Software Foundation. Oracle designates this
26.10 + * particular file as subject to the "Classpath" exception as provided
26.11 + * by Oracle in the LICENSE file that accompanied this code.
26.12 + *
26.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
26.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
26.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26.16 + * version 2 for more details (a copy is included in the LICENSE file that
26.17 + * accompanied this code).
26.18 + *
26.19 + * You should have received a copy of the GNU General Public License version
26.20 + * 2 along with this work; if not, write to the Free Software Foundation,
26.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
26.22 + *
26.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
26.24 + * or visit www.oracle.com if you need additional information or have any
26.25 + * questions.
26.26 + */
26.27 +
26.28 +/*
26.29 + * This file is available under and governed by the GNU General Public
26.30 + * License version 2 only, as published by the Free Software Foundation.
26.31 + * However, the following notice accompanied the original version of this
26.32 + * file:
26.33 + *
26.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
26.35 + * Expert Group and released to the public domain, as explained at
26.36 + * http://creativecommons.org/publicdomain/zero/1.0/
26.37 + */
26.38 +
26.39 +package java.util.concurrent;
26.40 +
26.41 +import java.util.Collection;
26.42 +import java.util.concurrent.RejectedExecutionException;
26.43 +
26.44 +/**
26.45 + * A thread managed by a {@link ForkJoinPool}, which executes
26.46 + * {@link ForkJoinTask}s.
26.47 + * This class is subclassable solely for the sake of adding
26.48 + * functionality -- there are no overridable methods dealing with
26.49 + * scheduling or execution. However, you can override initialization
26.50 + * and termination methods surrounding the main task processing loop.
26.51 + * If you do create such a subclass, you will also need to supply a
26.52 + * custom {@link ForkJoinPool.ForkJoinWorkerThreadFactory} to use it
26.53 + * in a {@code ForkJoinPool}.
26.54 + *
26.55 + * @since 1.7
26.56 + * @author Doug Lea
26.57 + */
26.58 +public class ForkJoinWorkerThread extends Thread {
26.59 + /*
26.60 + * Overview:
26.61 + *
26.62 + * ForkJoinWorkerThreads are managed by ForkJoinPools and perform
26.63 + * ForkJoinTasks. This class includes bookkeeping in support of
26.64 + * worker activation, suspension, and lifecycle control described
26.65 + * in more detail in the internal documentation of class
26.66 + * ForkJoinPool. And as described further below, this class also
26.67 + * includes special-cased support for some ForkJoinTask
26.68 + * methods. But the main mechanics involve work-stealing:
26.69 + *
26.70 + * Work-stealing queues are special forms of Deques that support
26.71 + * only three of the four possible end-operations -- push, pop,
26.72 + * and deq (aka steal), under the further constraints that push
26.73 + * and pop are called only from the owning thread, while deq may
26.74 + * be called from other threads. (If you are unfamiliar with
26.75 + * them, you probably want to read Herlihy and Shavit's book "The
26.76 + * Art of Multiprocessor programming", chapter 16 describing these
26.77 + * in more detail before proceeding.) The main work-stealing
26.78 + * queue design is roughly similar to those in the papers "Dynamic
26.79 + * Circular Work-Stealing Deque" by Chase and Lev, SPAA 2005
26.80 + * (http://research.sun.com/scalable/pubs/index.html) and
26.81 + * "Idempotent work stealing" by Michael, Saraswat, and Vechev,
26.82 + * PPoPP 2009 (http://portal.acm.org/citation.cfm?id=1504186).
26.83 + * The main differences ultimately stem from gc requirements that
26.84 + * we null out taken slots as soon as we can, to maintain as small
26.85 + * a footprint as possible even in programs generating huge
26.86 + * numbers of tasks. To accomplish this, we shift the CAS
26.87 + * arbitrating pop vs deq (steal) from being on the indices
26.88 + * ("queueBase" and "queueTop") to the slots themselves (mainly
26.89 + * via method "casSlotNull()"). So, both a successful pop and deq
26.90 + * mainly entail a CAS of a slot from non-null to null. Because
26.91 + * we rely on CASes of references, we do not need tag bits on
26.92 + * queueBase or queueTop. They are simple ints as used in any
26.93 + * circular array-based queue (see for example ArrayDeque).
26.94 + * Updates to the indices must still be ordered in a way that
26.95 + * guarantees that queueTop == queueBase means the queue is empty,
26.96 + * but otherwise may err on the side of possibly making the queue
26.97 + * appear nonempty when a push, pop, or deq have not fully
26.98 + * committed. Note that this means that the deq operation,
26.99 + * considered individually, is not wait-free. One thief cannot
26.100 + * successfully continue until another in-progress one (or, if
26.101 + * previously empty, a push) completes. However, in the
26.102 + * aggregate, we ensure at least probabilistic non-blockingness.
26.103 + * If an attempted steal fails, a thief always chooses a different
26.104 + * random victim target to try next. So, in order for one thief to
26.105 + * progress, it suffices for any in-progress deq or new push on
26.106 + * any empty queue to complete.
26.107 + *
26.108 + * This approach also enables support for "async mode" where local
26.109 + * task processing is in FIFO, not LIFO order; simply by using a
26.110 + * version of deq rather than pop when locallyFifo is true (as set
26.111 + * by the ForkJoinPool). This allows use in message-passing
26.112 + * frameworks in which tasks are never joined. However neither
26.113 + * mode considers affinities, loads, cache localities, etc, so
26.114 + * rarely provide the best possible performance on a given
26.115 + * machine, but portably provide good throughput by averaging over
26.116 + * these factors. (Further, even if we did try to use such
26.117 + * information, we do not usually have a basis for exploiting
26.118 + * it. For example, some sets of tasks profit from cache
26.119 + * affinities, but others are harmed by cache pollution effects.)
26.120 + *
26.121 + * When a worker would otherwise be blocked waiting to join a
26.122 + * task, it first tries a form of linear helping: Each worker
26.123 + * records (in field currentSteal) the most recent task it stole
26.124 + * from some other worker. Plus, it records (in field currentJoin)
26.125 + * the task it is currently actively joining. Method joinTask uses
26.126 + * these markers to try to find a worker to help (i.e., steal back
26.127 + * a task from and execute it) that could hasten completion of the
26.128 + * actively joined task. In essence, the joiner executes a task
26.129 + * that would be on its own local deque had the to-be-joined task
26.130 + * not been stolen. This may be seen as a conservative variant of
26.131 + * the approach in Wagner & Calder "Leapfrogging: a portable
26.132 + * technique for implementing efficient futures" SIGPLAN Notices,
26.133 + * 1993 (http://portal.acm.org/citation.cfm?id=155354). It differs
26.134 + * in that: (1) We only maintain dependency links across workers
26.135 + * upon steals, rather than use per-task bookkeeping. This may
26.136 + * require a linear scan of workers array to locate stealers, but
26.137 + * usually doesn't because stealers leave hints (that may become
26.138 + * stale/wrong) of where to locate them. This isolates cost to
26.139 + * when it is needed, rather than adding to per-task overhead.
26.140 + * (2) It is "shallow", ignoring nesting and potentially cyclic
26.141 + * mutual steals. (3) It is intentionally racy: field currentJoin
26.142 + * is updated only while actively joining, which means that we
26.143 + * miss links in the chain during long-lived tasks, GC stalls etc
26.144 + * (which is OK since blocking in such cases is usually a good
26.145 + * idea). (4) We bound the number of attempts to find work (see
26.146 + * MAX_HELP) and fall back to suspending the worker and if
26.147 + * necessary replacing it with another.
26.148 + *
26.149 + * Efficient implementation of these algorithms currently relies
26.150 + * on an uncomfortable amount of "Unsafe" mechanics. To maintain
26.151 + * correct orderings, reads and writes of variable queueBase
26.152 + * require volatile ordering. Variable queueTop need not be
26.153 + * volatile because non-local reads always follow those of
26.154 + * queueBase. Similarly, because they are protected by volatile
26.155 + * queueBase reads, reads of the queue array and its slots by
26.156 + * other threads do not need volatile load semantics, but writes
26.157 + * (in push) require store order and CASes (in pop and deq)
26.158 + * require (volatile) CAS semantics. (Michael, Saraswat, and
26.159 + * Vechev's algorithm has similar properties, but without support
26.160 + * for nulling slots.) Since these combinations aren't supported
26.161 + * using ordinary volatiles, the only way to accomplish these
26.162 + * efficiently is to use direct Unsafe calls. (Using external
26.163 + * AtomicIntegers and AtomicReferenceArrays for the indices and
26.164 + * array is significantly slower because of memory locality and
26.165 + * indirection effects.)
26.166 + *
26.167 + * Further, performance on most platforms is very sensitive to
26.168 + * placement and sizing of the (resizable) queue array. Even
26.169 + * though these queues don't usually become all that big, the
26.170 + * initial size must be large enough to counteract cache
26.171 + * contention effects across multiple queues (especially in the
26.172 + * presence of GC cardmarking). Also, to improve thread-locality,
26.173 + * queues are initialized after starting.
26.174 + */
26.175 +
26.176 + /**
26.177 + * Mask for pool indices encoded as shorts
26.178 + */
26.179 + private static final int SMASK = 0xffff;
26.180 +
26.181 + /**
26.182 + * Capacity of work-stealing queue array upon initialization.
26.183 + * Must be a power of two. Initial size must be at least 4, but is
26.184 + * padded to minimize cache effects.
26.185 + */
26.186 + private static final int INITIAL_QUEUE_CAPACITY = 1 << 13;
26.187 +
26.188 + /**
26.189 + * Maximum size for queue array. Must be a power of two
26.190 + * less than or equal to 1 << (31 - width of array entry) to
26.191 + * ensure lack of index wraparound, but is capped at a lower
26.192 + * value to help users trap runaway computations.
26.193 + */
26.194 + private static final int MAXIMUM_QUEUE_CAPACITY = 1 << 24; // 16M
26.195 +
26.196 + /**
26.197 + * The work-stealing queue array. Size must be a power of two.
26.198 + * Initialized when started (as oposed to when constructed), to
26.199 + * improve memory locality.
26.200 + */
26.201 + ForkJoinTask<?>[] queue;
26.202 +
26.203 + /**
26.204 + * The pool this thread works in. Accessed directly by ForkJoinTask.
26.205 + */
26.206 + final ForkJoinPool pool;
26.207 +
26.208 + /**
26.209 + * Index (mod queue.length) of next queue slot to push to or pop
26.210 + * from. It is written only by owner thread, and accessed by other
26.211 + * threads only after reading (volatile) queueBase. Both queueTop
26.212 + * and queueBase are allowed to wrap around on overflow, but
26.213 + * (queueTop - queueBase) still estimates size.
26.214 + */
26.215 + int queueTop;
26.216 +
26.217 + /**
26.218 + * Index (mod queue.length) of least valid queue slot, which is
26.219 + * always the next position to steal from if nonempty.
26.220 + */
26.221 + volatile int queueBase;
26.222 +
26.223 + /**
26.224 + * The index of most recent stealer, used as a hint to avoid
26.225 + * traversal in method helpJoinTask. This is only a hint because a
26.226 + * worker might have had multiple steals and this only holds one
26.227 + * of them (usually the most current). Declared non-volatile,
26.228 + * relying on other prevailing sync to keep reasonably current.
26.229 + */
26.230 + int stealHint;
26.231 +
26.232 + /**
26.233 + * Index of this worker in pool array. Set once by pool before
26.234 + * running, and accessed directly by pool to locate this worker in
26.235 + * its workers array.
26.236 + */
26.237 + final int poolIndex;
26.238 +
26.239 + /**
26.240 + * Encoded record for pool task waits. Usages are always
26.241 + * surrounded by volatile reads/writes
26.242 + */
26.243 + int nextWait;
26.244 +
26.245 + /**
26.246 + * Complement of poolIndex, offset by count of entries of task
26.247 + * waits. Accessed by ForkJoinPool to manage event waiters.
26.248 + */
26.249 + volatile int eventCount;
26.250 +
26.251 + /**
26.252 + * Seed for random number generator for choosing steal victims.
26.253 + * Uses Marsaglia xorshift. Must be initialized as nonzero.
26.254 + */
26.255 + int seed;
26.256 +
26.257 + /**
26.258 + * Number of steals. Directly accessed (and reset) by pool when
26.259 + * idle.
26.260 + */
26.261 + int stealCount;
26.262 +
26.263 + /**
26.264 + * True if this worker should or did terminate
26.265 + */
26.266 + volatile boolean terminate;
26.267 +
26.268 + /**
26.269 + * Set to true before LockSupport.park; false on return
26.270 + */
26.271 + volatile boolean parked;
26.272 +
26.273 + /**
26.274 + * True if use local fifo, not default lifo, for local polling.
26.275 + * Shadows value from ForkJoinPool.
26.276 + */
26.277 + final boolean locallyFifo;
26.278 +
26.279 + /**
26.280 + * The task most recently stolen from another worker (or
26.281 + * submission queue). All uses are surrounded by enough volatile
26.282 + * reads/writes to maintain as non-volatile.
26.283 + */
26.284 + ForkJoinTask<?> currentSteal;
26.285 +
26.286 + /**
26.287 + * The task currently being joined, set only when actively trying
26.288 + * to help other stealers in helpJoinTask. All uses are surrounded
26.289 + * by enough volatile reads/writes to maintain as non-volatile.
26.290 + */
26.291 + ForkJoinTask<?> currentJoin;
26.292 +
26.293 + /**
26.294 + * Creates a ForkJoinWorkerThread operating in the given pool.
26.295 + *
26.296 + * @param pool the pool this thread works in
26.297 + * @throws NullPointerException if pool is null
26.298 + */
26.299 + protected ForkJoinWorkerThread(ForkJoinPool pool) {
26.300 + super(pool.nextWorkerName());
26.301 + this.pool = pool;
26.302 + int k = pool.registerWorker(this);
26.303 + poolIndex = k;
26.304 + eventCount = ~k & SMASK; // clear wait count
26.305 + locallyFifo = pool.locallyFifo;
26.306 + Thread.UncaughtExceptionHandler ueh = pool.ueh;
26.307 + if (ueh != null)
26.308 + setUncaughtExceptionHandler(ueh);
26.309 + setDaemon(true);
26.310 + }
26.311 +
26.312 + // Public methods
26.313 +
26.314 + /**
26.315 + * Returns the pool hosting this thread.
26.316 + *
26.317 + * @return the pool
26.318 + */
26.319 + public ForkJoinPool getPool() {
26.320 + return pool;
26.321 + }
26.322 +
26.323 + /**
26.324 + * Returns the index number of this thread in its pool. The
26.325 + * returned value ranges from zero to the maximum number of
26.326 + * threads (minus one) that have ever been created in the pool.
26.327 + * This method may be useful for applications that track status or
26.328 + * collect results per-worker rather than per-task.
26.329 + *
26.330 + * @return the index number
26.331 + */
26.332 + public int getPoolIndex() {
26.333 + return poolIndex;
26.334 + }
26.335 +
26.336 + // Randomization
26.337 +
26.338 + /**
26.339 + * Computes next value for random victim probes and backoffs.
26.340 + * Scans don't require a very high quality generator, but also not
26.341 + * a crummy one. Marsaglia xor-shift is cheap and works well
26.342 + * enough. Note: This is manually inlined in FJP.scan() to avoid
26.343 + * writes inside busy loops.
26.344 + */
26.345 + private int nextSeed() {
26.346 + int r = seed;
26.347 + r ^= r << 13;
26.348 + r ^= r >>> 17;
26.349 + r ^= r << 5;
26.350 + return seed = r;
26.351 + }
26.352 +
26.353 + // Run State management
26.354 +
26.355 + /**
26.356 + * Initializes internal state after construction but before
26.357 + * processing any tasks. If you override this method, you must
26.358 + * invoke {@code super.onStart()} at the beginning of the method.
26.359 + * Initialization requires care: Most fields must have legal
26.360 + * default values, to ensure that attempted accesses from other
26.361 + * threads work correctly even before this thread starts
26.362 + * processing tasks.
26.363 + */
26.364 + protected void onStart() {
26.365 + queue = new ForkJoinTask<?>[INITIAL_QUEUE_CAPACITY];
26.366 + int r = pool.workerSeedGenerator.nextInt();
26.367 + seed = (r == 0) ? 1 : r; // must be nonzero
26.368 + }
26.369 +
26.370 + /**
26.371 + * Performs cleanup associated with termination of this worker
26.372 + * thread. If you override this method, you must invoke
26.373 + * {@code super.onTermination} at the end of the overridden method.
26.374 + *
26.375 + * @param exception the exception causing this thread to abort due
26.376 + * to an unrecoverable error, or {@code null} if completed normally
26.377 + */
26.378 + protected void onTermination(Throwable exception) {
26.379 + try {
26.380 + terminate = true;
26.381 + cancelTasks();
26.382 + pool.deregisterWorker(this, exception);
26.383 + } catch (Throwable ex) { // Shouldn't ever happen
26.384 + if (exception == null) // but if so, at least rethrown
26.385 + exception = ex;
26.386 + } finally {
26.387 + if (exception != null)
26.388 + UNSAFE.throwException(exception);
26.389 + }
26.390 + }
26.391 +
26.392 + /**
26.393 + * This method is required to be public, but should never be
26.394 + * called explicitly. It performs the main run loop to execute
26.395 + * {@link ForkJoinTask}s.
26.396 + */
26.397 + public void run() {
26.398 + Throwable exception = null;
26.399 + try {
26.400 + onStart();
26.401 + pool.work(this);
26.402 + } catch (Throwable ex) {
26.403 + exception = ex;
26.404 + } finally {
26.405 + onTermination(exception);
26.406 + }
26.407 + }
26.408 +
26.409 + /*
26.410 + * Intrinsics-based atomic writes for queue slots. These are
26.411 + * basically the same as methods in AtomicReferenceArray, but
26.412 + * specialized for (1) ForkJoinTask elements (2) requirement that
26.413 + * nullness and bounds checks have already been performed by
26.414 + * callers and (3) effective offsets are known not to overflow
26.415 + * from int to long (because of MAXIMUM_QUEUE_CAPACITY). We don't
26.416 + * need corresponding version for reads: plain array reads are OK
26.417 + * because they are protected by other volatile reads and are
26.418 + * confirmed by CASes.
26.419 + *
26.420 + * Most uses don't actually call these methods, but instead
26.421 + * contain inlined forms that enable more predictable
26.422 + * optimization. We don't define the version of write used in
26.423 + * pushTask at all, but instead inline there a store-fenced array
26.424 + * slot write.
26.425 + *
26.426 + * Also in most methods, as a performance (not correctness) issue,
26.427 + * we'd like to encourage compilers not to arbitrarily postpone
26.428 + * setting queueTop after writing slot. Currently there is no
26.429 + * intrinsic for arranging this, but using Unsafe putOrderedInt
26.430 + * may be a preferable strategy on some compilers even though its
26.431 + * main effect is a pre-, not post- fence. To simplify possible
26.432 + * changes, the option is left in comments next to the associated
26.433 + * assignments.
26.434 + */
26.435 +
26.436 + /**
26.437 + * CASes slot i of array q from t to null. Caller must ensure q is
26.438 + * non-null and index is in range.
26.439 + */
26.440 + private static final boolean casSlotNull(ForkJoinTask<?>[] q, int i,
26.441 + ForkJoinTask<?> t) {
26.442 + return UNSAFE.compareAndSwapObject(q, (i << ASHIFT) + ABASE, t, null);
26.443 + }
26.444 +
26.445 + /**
26.446 + * Performs a volatile write of the given task at given slot of
26.447 + * array q. Caller must ensure q is non-null and index is in
26.448 + * range. This method is used only during resets and backouts.
26.449 + */
26.450 + private static final void writeSlot(ForkJoinTask<?>[] q, int i,
26.451 + ForkJoinTask<?> t) {
26.452 + UNSAFE.putObjectVolatile(q, (i << ASHIFT) + ABASE, t);
26.453 + }
26.454 +
26.455 + // queue methods
26.456 +
26.457 + /**
26.458 + * Pushes a task. Call only from this thread.
26.459 + *
26.460 + * @param t the task. Caller must ensure non-null.
26.461 + */
26.462 + final void pushTask(ForkJoinTask<?> t) {
26.463 + ForkJoinTask<?>[] q; int s, m;
26.464 + if ((q = queue) != null) { // ignore if queue removed
26.465 + long u = (((s = queueTop) & (m = q.length - 1)) << ASHIFT) + ABASE;
26.466 + UNSAFE.putOrderedObject(q, u, t);
26.467 + queueTop = s + 1; // or use putOrderedInt
26.468 + if ((s -= queueBase) <= 2)
26.469 + pool.signalWork();
26.470 + else if (s == m)
26.471 + growQueue();
26.472 + }
26.473 + }
26.474 +
26.475 + /**
26.476 + * Creates or doubles queue array. Transfers elements by
26.477 + * emulating steals (deqs) from old array and placing, oldest
26.478 + * first, into new array.
26.479 + */
26.480 + private void growQueue() {
26.481 + ForkJoinTask<?>[] oldQ = queue;
26.482 + int size = oldQ != null ? oldQ.length << 1 : INITIAL_QUEUE_CAPACITY;
26.483 + if (size > MAXIMUM_QUEUE_CAPACITY)
26.484 + throw new RejectedExecutionException("Queue capacity exceeded");
26.485 + if (size < INITIAL_QUEUE_CAPACITY)
26.486 + size = INITIAL_QUEUE_CAPACITY;
26.487 + ForkJoinTask<?>[] q = queue = new ForkJoinTask<?>[size];
26.488 + int mask = size - 1;
26.489 + int top = queueTop;
26.490 + int oldMask;
26.491 + if (oldQ != null && (oldMask = oldQ.length - 1) >= 0) {
26.492 + for (int b = queueBase; b != top; ++b) {
26.493 + long u = ((b & oldMask) << ASHIFT) + ABASE;
26.494 + Object x = UNSAFE.getObjectVolatile(oldQ, u);
26.495 + if (x != null && UNSAFE.compareAndSwapObject(oldQ, u, x, null))
26.496 + UNSAFE.putObjectVolatile
26.497 + (q, ((b & mask) << ASHIFT) + ABASE, x);
26.498 + }
26.499 + }
26.500 + }
26.501 +
26.502 + /**
26.503 + * Tries to take a task from the base of the queue, failing if
26.504 + * empty or contended. Note: Specializations of this code appear
26.505 + * in locallyDeqTask and elsewhere.
26.506 + *
26.507 + * @return a task, or null if none or contended
26.508 + */
26.509 + final ForkJoinTask<?> deqTask() {
26.510 + ForkJoinTask<?> t; ForkJoinTask<?>[] q; int b, i;
26.511 + if (queueTop != (b = queueBase) &&
26.512 + (q = queue) != null && // must read q after b
26.513 + (i = (q.length - 1) & b) >= 0 &&
26.514 + (t = q[i]) != null && queueBase == b &&
26.515 + UNSAFE.compareAndSwapObject(q, (i << ASHIFT) + ABASE, t, null)) {
26.516 + queueBase = b + 1;
26.517 + return t;
26.518 + }
26.519 + return null;
26.520 + }
26.521 +
26.522 + /**
26.523 + * Tries to take a task from the base of own queue. Called only
26.524 + * by this thread.
26.525 + *
26.526 + * @return a task, or null if none
26.527 + */
26.528 + final ForkJoinTask<?> locallyDeqTask() {
26.529 + ForkJoinTask<?> t; int m, b, i;
26.530 + ForkJoinTask<?>[] q = queue;
26.531 + if (q != null && (m = q.length - 1) >= 0) {
26.532 + while (queueTop != (b = queueBase)) {
26.533 + if ((t = q[i = m & b]) != null &&
26.534 + queueBase == b &&
26.535 + UNSAFE.compareAndSwapObject(q, (i << ASHIFT) + ABASE,
26.536 + t, null)) {
26.537 + queueBase = b + 1;
26.538 + return t;
26.539 + }
26.540 + }
26.541 + }
26.542 + return null;
26.543 + }
26.544 +
26.545 + /**
26.546 + * Returns a popped task, or null if empty.
26.547 + * Called only by this thread.
26.548 + */
26.549 + private ForkJoinTask<?> popTask() {
26.550 + int m;
26.551 + ForkJoinTask<?>[] q = queue;
26.552 + if (q != null && (m = q.length - 1) >= 0) {
26.553 + for (int s; (s = queueTop) != queueBase;) {
26.554 + int i = m & --s;
26.555 + long u = (i << ASHIFT) + ABASE; // raw offset
26.556 + ForkJoinTask<?> t = q[i];
26.557 + if (t == null) // lost to stealer
26.558 + break;
26.559 + if (UNSAFE.compareAndSwapObject(q, u, t, null)) {
26.560 + queueTop = s; // or putOrderedInt
26.561 + return t;
26.562 + }
26.563 + }
26.564 + }
26.565 + return null;
26.566 + }
26.567 +
26.568 + /**
26.569 + * Specialized version of popTask to pop only if topmost element
26.570 + * is the given task. Called only by this thread.
26.571 + *
26.572 + * @param t the task. Caller must ensure non-null.
26.573 + */
26.574 + final boolean unpushTask(ForkJoinTask<?> t) {
26.575 + ForkJoinTask<?>[] q;
26.576 + int s;
26.577 + if ((q = queue) != null && (s = queueTop) != queueBase &&
26.578 + UNSAFE.compareAndSwapObject
26.579 + (q, (((q.length - 1) & --s) << ASHIFT) + ABASE, t, null)) {
26.580 + queueTop = s; // or putOrderedInt
26.581 + return true;
26.582 + }
26.583 + return false;
26.584 + }
26.585 +
26.586 + /**
26.587 + * Returns next task, or null if empty or contended.
26.588 + */
26.589 + final ForkJoinTask<?> peekTask() {
26.590 + int m;
26.591 + ForkJoinTask<?>[] q = queue;
26.592 + if (q == null || (m = q.length - 1) < 0)
26.593 + return null;
26.594 + int i = locallyFifo ? queueBase : (queueTop - 1);
26.595 + return q[i & m];
26.596 + }
26.597 +
26.598 + // Support methods for ForkJoinPool
26.599 +
26.600 + /**
26.601 + * Runs the given task, plus any local tasks until queue is empty
26.602 + */
26.603 + final void execTask(ForkJoinTask<?> t) {
26.604 + currentSteal = t;
26.605 + for (;;) {
26.606 + if (t != null)
26.607 + t.doExec();
26.608 + if (queueTop == queueBase)
26.609 + break;
26.610 + t = locallyFifo ? locallyDeqTask() : popTask();
26.611 + }
26.612 + ++stealCount;
26.613 + currentSteal = null;
26.614 + }
26.615 +
26.616 + /**
26.617 + * Removes and cancels all tasks in queue. Can be called from any
26.618 + * thread.
26.619 + */
26.620 + final void cancelTasks() {
26.621 + ForkJoinTask<?> cj = currentJoin; // try to cancel ongoing tasks
26.622 + if (cj != null && cj.status >= 0)
26.623 + cj.cancelIgnoringExceptions();
26.624 + ForkJoinTask<?> cs = currentSteal;
26.625 + if (cs != null && cs.status >= 0)
26.626 + cs.cancelIgnoringExceptions();
26.627 + while (queueBase != queueTop) {
26.628 + ForkJoinTask<?> t = deqTask();
26.629 + if (t != null)
26.630 + t.cancelIgnoringExceptions();
26.631 + }
26.632 + }
26.633 +
26.634 + /**
26.635 + * Drains tasks to given collection c.
26.636 + *
26.637 + * @return the number of tasks drained
26.638 + */
26.639 + final int drainTasksTo(Collection<? super ForkJoinTask<?>> c) {
26.640 + int n = 0;
26.641 + while (queueBase != queueTop) {
26.642 + ForkJoinTask<?> t = deqTask();
26.643 + if (t != null) {
26.644 + c.add(t);
26.645 + ++n;
26.646 + }
26.647 + }
26.648 + return n;
26.649 + }
26.650 +
26.651 + // Support methods for ForkJoinTask
26.652 +
26.653 + /**
26.654 + * Returns an estimate of the number of tasks in the queue.
26.655 + */
26.656 + final int getQueueSize() {
26.657 + return queueTop - queueBase;
26.658 + }
26.659 +
26.660 + /**
26.661 + * Gets and removes a local task.
26.662 + *
26.663 + * @return a task, if available
26.664 + */
26.665 + final ForkJoinTask<?> pollLocalTask() {
26.666 + return locallyFifo ? locallyDeqTask() : popTask();
26.667 + }
26.668 +
26.669 + /**
26.670 + * Gets and removes a local or stolen task.
26.671 + *
26.672 + * @return a task, if available
26.673 + */
26.674 + final ForkJoinTask<?> pollTask() {
26.675 + ForkJoinWorkerThread[] ws;
26.676 + ForkJoinTask<?> t = pollLocalTask();
26.677 + if (t != null || (ws = pool.workers) == null)
26.678 + return t;
26.679 + int n = ws.length; // cheap version of FJP.scan
26.680 + int steps = n << 1;
26.681 + int r = nextSeed();
26.682 + int i = 0;
26.683 + while (i < steps) {
26.684 + ForkJoinWorkerThread w = ws[(i++ + r) & (n - 1)];
26.685 + if (w != null && w.queueBase != w.queueTop && w.queue != null) {
26.686 + if ((t = w.deqTask()) != null)
26.687 + return t;
26.688 + i = 0;
26.689 + }
26.690 + }
26.691 + return null;
26.692 + }
26.693 +
26.694 + /**
26.695 + * The maximum stolen->joining link depth allowed in helpJoinTask,
26.696 + * as well as the maximum number of retries (allowing on average
26.697 + * one staleness retry per level) per attempt to instead try
26.698 + * compensation. Depths for legitimate chains are unbounded, but
26.699 + * we use a fixed constant to avoid (otherwise unchecked) cycles
26.700 + * and bound staleness of traversal parameters at the expense of
26.701 + * sometimes blocking when we could be helping.
26.702 + */
26.703 + private static final int MAX_HELP = 16;
26.704 +
26.705 + /**
26.706 + * Possibly runs some tasks and/or blocks, until joinMe is done.
26.707 + *
26.708 + * @param joinMe the task to join
26.709 + * @return completion status on exit
26.710 + */
26.711 + final int joinTask(ForkJoinTask<?> joinMe) {
26.712 + ForkJoinTask<?> prevJoin = currentJoin;
26.713 + currentJoin = joinMe;
26.714 + for (int s, retries = MAX_HELP;;) {
26.715 + if ((s = joinMe.status) < 0) {
26.716 + currentJoin = prevJoin;
26.717 + return s;
26.718 + }
26.719 + if (retries > 0) {
26.720 + if (queueTop != queueBase) {
26.721 + if (!localHelpJoinTask(joinMe))
26.722 + retries = 0; // cannot help
26.723 + }
26.724 + else if (retries == MAX_HELP >>> 1) {
26.725 + --retries; // check uncommon case
26.726 + if (tryDeqAndExec(joinMe) >= 0)
26.727 + Thread.yield(); // for politeness
26.728 + }
26.729 + else
26.730 + retries = helpJoinTask(joinMe) ? MAX_HELP : retries - 1;
26.731 + }
26.732 + else {
26.733 + retries = MAX_HELP; // restart if not done
26.734 + pool.tryAwaitJoin(joinMe);
26.735 + }
26.736 + }
26.737 + }
26.738 +
26.739 + /**
26.740 + * If present, pops and executes the given task, or any other
26.741 + * cancelled task
26.742 + *
26.743 + * @return false if any other non-cancelled task exists in local queue
26.744 + */
26.745 + private boolean localHelpJoinTask(ForkJoinTask<?> joinMe) {
26.746 + int s, i; ForkJoinTask<?>[] q; ForkJoinTask<?> t;
26.747 + if ((s = queueTop) != queueBase && (q = queue) != null &&
26.748 + (i = (q.length - 1) & --s) >= 0 &&
26.749 + (t = q[i]) != null) {
26.750 + if (t != joinMe && t.status >= 0)
26.751 + return false;
26.752 + if (UNSAFE.compareAndSwapObject
26.753 + (q, (i << ASHIFT) + ABASE, t, null)) {
26.754 + queueTop = s; // or putOrderedInt
26.755 + t.doExec();
26.756 + }
26.757 + }
26.758 + return true;
26.759 + }
26.760 +
26.761 + /**
26.762 + * Tries to locate and execute tasks for a stealer of the given
26.763 + * task, or in turn one of its stealers, Traces
26.764 + * currentSteal->currentJoin links looking for a thread working on
26.765 + * a descendant of the given task and with a non-empty queue to
26.766 + * steal back and execute tasks from. The implementation is very
26.767 + * branchy to cope with potential inconsistencies or loops
26.768 + * encountering chains that are stale, unknown, or of length
26.769 + * greater than MAX_HELP links. All of these cases are dealt with
26.770 + * by just retrying by caller.
26.771 + *
26.772 + * @param joinMe the task to join
26.773 + * @param canSteal true if local queue is empty
26.774 + * @return true if ran a task
26.775 + */
26.776 + private boolean helpJoinTask(ForkJoinTask<?> joinMe) {
26.777 + boolean helped = false;
26.778 + int m = pool.scanGuard & SMASK;
26.779 + ForkJoinWorkerThread[] ws = pool.workers;
26.780 + if (ws != null && ws.length > m && joinMe.status >= 0) {
26.781 + int levels = MAX_HELP; // remaining chain length
26.782 + ForkJoinTask<?> task = joinMe; // base of chain
26.783 + outer:for (ForkJoinWorkerThread thread = this;;) {
26.784 + // Try to find v, the stealer of task, by first using hint
26.785 + ForkJoinWorkerThread v = ws[thread.stealHint & m];
26.786 + if (v == null || v.currentSteal != task) {
26.787 + for (int j = 0; ;) { // search array
26.788 + if ((v = ws[j]) != null && v.currentSteal == task) {
26.789 + thread.stealHint = j;
26.790 + break; // save hint for next time
26.791 + }
26.792 + if (++j > m)
26.793 + break outer; // can't find stealer
26.794 + }
26.795 + }
26.796 + // Try to help v, using specialized form of deqTask
26.797 + for (;;) {
26.798 + ForkJoinTask<?>[] q; int b, i;
26.799 + if (joinMe.status < 0)
26.800 + break outer;
26.801 + if ((b = v.queueBase) == v.queueTop ||
26.802 + (q = v.queue) == null ||
26.803 + (i = (q.length-1) & b) < 0)
26.804 + break; // empty
26.805 + long u = (i << ASHIFT) + ABASE;
26.806 + ForkJoinTask<?> t = q[i];
26.807 + if (task.status < 0)
26.808 + break outer; // stale
26.809 + if (t != null && v.queueBase == b &&
26.810 + UNSAFE.compareAndSwapObject(q, u, t, null)) {
26.811 + v.queueBase = b + 1;
26.812 + v.stealHint = poolIndex;
26.813 + ForkJoinTask<?> ps = currentSteal;
26.814 + currentSteal = t;
26.815 + t.doExec();
26.816 + currentSteal = ps;
26.817 + helped = true;
26.818 + }
26.819 + }
26.820 + // Try to descend to find v's stealer
26.821 + ForkJoinTask<?> next = v.currentJoin;
26.822 + if (--levels > 0 && task.status >= 0 &&
26.823 + next != null && next != task) {
26.824 + task = next;
26.825 + thread = v;
26.826 + }
26.827 + else
26.828 + break; // max levels, stale, dead-end, or cyclic
26.829 + }
26.830 + }
26.831 + return helped;
26.832 + }
26.833 +
26.834 + /**
26.835 + * Performs an uncommon case for joinTask: If task t is at base of
26.836 + * some workers queue, steals and executes it.
26.837 + *
26.838 + * @param t the task
26.839 + * @return t's status
26.840 + */
26.841 + private int tryDeqAndExec(ForkJoinTask<?> t) {
26.842 + int m = pool.scanGuard & SMASK;
26.843 + ForkJoinWorkerThread[] ws = pool.workers;
26.844 + if (ws != null && ws.length > m && t.status >= 0) {
26.845 + for (int j = 0; j <= m; ++j) {
26.846 + ForkJoinTask<?>[] q; int b, i;
26.847 + ForkJoinWorkerThread v = ws[j];
26.848 + if (v != null &&
26.849 + (b = v.queueBase) != v.queueTop &&
26.850 + (q = v.queue) != null &&
26.851 + (i = (q.length - 1) & b) >= 0 &&
26.852 + q[i] == t) {
26.853 + long u = (i << ASHIFT) + ABASE;
26.854 + if (v.queueBase == b &&
26.855 + UNSAFE.compareAndSwapObject(q, u, t, null)) {
26.856 + v.queueBase = b + 1;
26.857 + v.stealHint = poolIndex;
26.858 + ForkJoinTask<?> ps = currentSteal;
26.859 + currentSteal = t;
26.860 + t.doExec();
26.861 + currentSteal = ps;
26.862 + }
26.863 + break;
26.864 + }
26.865 + }
26.866 + }
26.867 + return t.status;
26.868 + }
26.869 +
26.870 + /**
26.871 + * Implements ForkJoinTask.getSurplusQueuedTaskCount(). Returns
26.872 + * an estimate of the number of tasks, offset by a function of
26.873 + * number of idle workers.
26.874 + *
26.875 + * This method provides a cheap heuristic guide for task
26.876 + * partitioning when programmers, frameworks, tools, or languages
26.877 + * have little or no idea about task granularity. In essence by
26.878 + * offering this method, we ask users only about tradeoffs in
26.879 + * overhead vs expected throughput and its variance, rather than
26.880 + * how finely to partition tasks.
26.881 + *
26.882 + * In a steady state strict (tree-structured) computation, each
26.883 + * thread makes available for stealing enough tasks for other
26.884 + * threads to remain active. Inductively, if all threads play by
26.885 + * the same rules, each thread should make available only a
26.886 + * constant number of tasks.
26.887 + *
26.888 + * The minimum useful constant is just 1. But using a value of 1
26.889 + * would require immediate replenishment upon each steal to
26.890 + * maintain enough tasks, which is infeasible. Further,
26.891 + * partitionings/granularities of offered tasks should minimize
26.892 + * steal rates, which in general means that threads nearer the top
26.893 + * of computation tree should generate more than those nearer the
26.894 + * bottom. In perfect steady state, each thread is at
26.895 + * approximately the same level of computation tree. However,
26.896 + * producing extra tasks amortizes the uncertainty of progress and
26.897 + * diffusion assumptions.
26.898 + *
26.899 + * So, users will want to use values larger, but not much larger
26.900 + * than 1 to both smooth over transient shortages and hedge
26.901 + * against uneven progress; as traded off against the cost of
26.902 + * extra task overhead. We leave the user to pick a threshold
26.903 + * value to compare with the results of this call to guide
26.904 + * decisions, but recommend values such as 3.
26.905 + *
26.906 + * When all threads are active, it is on average OK to estimate
26.907 + * surplus strictly locally. In steady-state, if one thread is
26.908 + * maintaining say 2 surplus tasks, then so are others. So we can
26.909 + * just use estimated queue length (although note that (queueTop -
26.910 + * queueBase) can be an overestimate because of stealers lagging
26.911 + * increments of queueBase). However, this strategy alone leads
26.912 + * to serious mis-estimates in some non-steady-state conditions
26.913 + * (ramp-up, ramp-down, other stalls). We can detect many of these
26.914 + * by further considering the number of "idle" threads, that are
26.915 + * known to have zero queued tasks, so compensate by a factor of
26.916 + * (#idle/#active) threads.
26.917 + */
26.918 + final int getEstimatedSurplusTaskCount() {
26.919 + return queueTop - queueBase - pool.idlePerActive();
26.920 + }
26.921 +
26.922 + /**
26.923 + * Runs tasks until {@code pool.isQuiescent()}. We piggyback on
26.924 + * pool's active count ctl maintenance, but rather than blocking
26.925 + * when tasks cannot be found, we rescan until all others cannot
26.926 + * find tasks either. The bracketing by pool quiescerCounts
26.927 + * updates suppresses pool auto-shutdown mechanics that could
26.928 + * otherwise prematurely terminate the pool because all threads
26.929 + * appear to be inactive.
26.930 + */
26.931 + final void helpQuiescePool() {
26.932 + boolean active = true;
26.933 + ForkJoinTask<?> ps = currentSteal; // to restore below
26.934 + ForkJoinPool p = pool;
26.935 + p.addQuiescerCount(1);
26.936 + for (;;) {
26.937 + ForkJoinWorkerThread[] ws = p.workers;
26.938 + ForkJoinWorkerThread v = null;
26.939 + int n;
26.940 + if (queueTop != queueBase)
26.941 + v = this;
26.942 + else if (ws != null && (n = ws.length) > 1) {
26.943 + ForkJoinWorkerThread w;
26.944 + int r = nextSeed(); // cheap version of FJP.scan
26.945 + int steps = n << 1;
26.946 + for (int i = 0; i < steps; ++i) {
26.947 + if ((w = ws[(i + r) & (n - 1)]) != null &&
26.948 + w.queueBase != w.queueTop) {
26.949 + v = w;
26.950 + break;
26.951 + }
26.952 + }
26.953 + }
26.954 + if (v != null) {
26.955 + ForkJoinTask<?> t;
26.956 + if (!active) {
26.957 + active = true;
26.958 + p.addActiveCount(1);
26.959 + }
26.960 + if ((t = (v != this) ? v.deqTask() :
26.961 + locallyFifo ? locallyDeqTask() : popTask()) != null) {
26.962 + currentSteal = t;
26.963 + t.doExec();
26.964 + currentSteal = ps;
26.965 + }
26.966 + }
26.967 + else {
26.968 + if (active) {
26.969 + active = false;
26.970 + p.addActiveCount(-1);
26.971 + }
26.972 + if (p.isQuiescent()) {
26.973 + p.addActiveCount(1);
26.974 + p.addQuiescerCount(-1);
26.975 + break;
26.976 + }
26.977 + }
26.978 + }
26.979 + }
26.980 +
26.981 + // Unsafe mechanics
26.982 + private static final sun.misc.Unsafe UNSAFE;
26.983 + private static final long ABASE;
26.984 + private static final int ASHIFT;
26.985 +
26.986 + static {
26.987 + int s;
26.988 + try {
26.989 + UNSAFE = sun.misc.Unsafe.getUnsafe();
26.990 + Class a = ForkJoinTask[].class;
26.991 + ABASE = UNSAFE.arrayBaseOffset(a);
26.992 + s = UNSAFE.arrayIndexScale(a);
26.993 + } catch (Exception e) {
26.994 + throw new Error(e);
26.995 + }
26.996 + if ((s & (s-1)) != 0)
26.997 + throw new Error("data type scale not a power of two");
26.998 + ASHIFT = 31 - Integer.numberOfLeadingZeros(s);
26.999 + }
26.1000 +
26.1001 +}
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
27.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/Future.java Sat Mar 19 10:48:29 2016 +0100
27.3 @@ -0,0 +1,169 @@
27.4 +/*
27.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
27.6 + *
27.7 + * This code is free software; you can redistribute it and/or modify it
27.8 + * under the terms of the GNU General Public License version 2 only, as
27.9 + * published by the Free Software Foundation. Oracle designates this
27.10 + * particular file as subject to the "Classpath" exception as provided
27.11 + * by Oracle in the LICENSE file that accompanied this code.
27.12 + *
27.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
27.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
27.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27.16 + * version 2 for more details (a copy is included in the LICENSE file that
27.17 + * accompanied this code).
27.18 + *
27.19 + * You should have received a copy of the GNU General Public License version
27.20 + * 2 along with this work; if not, write to the Free Software Foundation,
27.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
27.22 + *
27.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
27.24 + * or visit www.oracle.com if you need additional information or have any
27.25 + * questions.
27.26 + */
27.27 +
27.28 +/*
27.29 + * This file is available under and governed by the GNU General Public
27.30 + * License version 2 only, as published by the Free Software Foundation.
27.31 + * However, the following notice accompanied the original version of this
27.32 + * file:
27.33 + *
27.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
27.35 + * Expert Group and released to the public domain, as explained at
27.36 + * http://creativecommons.org/publicdomain/zero/1.0/
27.37 + */
27.38 +
27.39 +package java.util.concurrent;
27.40 +
27.41 +/**
27.42 + * A <tt>Future</tt> represents the result of an asynchronous
27.43 + * computation. Methods are provided to check if the computation is
27.44 + * complete, to wait for its completion, and to retrieve the result of
27.45 + * the computation. The result can only be retrieved using method
27.46 + * <tt>get</tt> when the computation has completed, blocking if
27.47 + * necessary until it is ready. Cancellation is performed by the
27.48 + * <tt>cancel</tt> method. Additional methods are provided to
27.49 + * determine if the task completed normally or was cancelled. Once a
27.50 + * computation has completed, the computation cannot be cancelled.
27.51 + * If you would like to use a <tt>Future</tt> for the sake
27.52 + * of cancellability but not provide a usable result, you can
27.53 + * declare types of the form {@code Future<?>} and
27.54 + * return <tt>null</tt> as a result of the underlying task.
27.55 + *
27.56 + * <p>
27.57 + * <b>Sample Usage</b> (Note that the following classes are all
27.58 + * made-up.) <p>
27.59 + * <pre> {@code
27.60 + * interface ArchiveSearcher { String search(String target); }
27.61 + * class App {
27.62 + * ExecutorService executor = ...
27.63 + * ArchiveSearcher searcher = ...
27.64 + * void showSearch(final String target)
27.65 + * throws InterruptedException {
27.66 + * Future<String> future
27.67 + * = executor.submit(new Callable<String>() {
27.68 + * public String call() {
27.69 + * return searcher.search(target);
27.70 + * }});
27.71 + * displayOtherThings(); // do other things while searching
27.72 + * try {
27.73 + * displayText(future.get()); // use future
27.74 + * } catch (ExecutionException ex) { cleanup(); return; }
27.75 + * }
27.76 + * }}</pre>
27.77 + *
27.78 + * The {@link FutureTask} class is an implementation of <tt>Future</tt> that
27.79 + * implements <tt>Runnable</tt>, and so may be executed by an <tt>Executor</tt>.
27.80 + * For example, the above construction with <tt>submit</tt> could be replaced by:
27.81 + * <pre> {@code
27.82 + * FutureTask<String> future =
27.83 + * new FutureTask<String>(new Callable<String>() {
27.84 + * public String call() {
27.85 + * return searcher.search(target);
27.86 + * }});
27.87 + * executor.execute(future);}</pre>
27.88 + *
27.89 + * <p>Memory consistency effects: Actions taken by the asynchronous computation
27.90 + * <a href="package-summary.html#MemoryVisibility"> <i>happen-before</i></a>
27.91 + * actions following the corresponding {@code Future.get()} in another thread.
27.92 + *
27.93 + * @see FutureTask
27.94 + * @see Executor
27.95 + * @since 1.5
27.96 + * @author Doug Lea
27.97 + * @param <V> The result type returned by this Future's <tt>get</tt> method
27.98 + */
27.99 +public interface Future<V> {
27.100 +
27.101 + /**
27.102 + * Attempts to cancel execution of this task. This attempt will
27.103 + * fail if the task has already completed, has already been cancelled,
27.104 + * or could not be cancelled for some other reason. If successful,
27.105 + * and this task has not started when <tt>cancel</tt> is called,
27.106 + * this task should never run. If the task has already started,
27.107 + * then the <tt>mayInterruptIfRunning</tt> parameter determines
27.108 + * whether the thread executing this task should be interrupted in
27.109 + * an attempt to stop the task.
27.110 + *
27.111 + * <p>After this method returns, subsequent calls to {@link #isDone} will
27.112 + * always return <tt>true</tt>. Subsequent calls to {@link #isCancelled}
27.113 + * will always return <tt>true</tt> if this method returned <tt>true</tt>.
27.114 + *
27.115 + * @param mayInterruptIfRunning <tt>true</tt> if the thread executing this
27.116 + * task should be interrupted; otherwise, in-progress tasks are allowed
27.117 + * to complete
27.118 + * @return <tt>false</tt> if the task could not be cancelled,
27.119 + * typically because it has already completed normally;
27.120 + * <tt>true</tt> otherwise
27.121 + */
27.122 + boolean cancel(boolean mayInterruptIfRunning);
27.123 +
27.124 + /**
27.125 + * Returns <tt>true</tt> if this task was cancelled before it completed
27.126 + * normally.
27.127 + *
27.128 + * @return <tt>true</tt> if this task was cancelled before it completed
27.129 + */
27.130 + boolean isCancelled();
27.131 +
27.132 + /**
27.133 + * Returns <tt>true</tt> if this task completed.
27.134 + *
27.135 + * Completion may be due to normal termination, an exception, or
27.136 + * cancellation -- in all of these cases, this method will return
27.137 + * <tt>true</tt>.
27.138 + *
27.139 + * @return <tt>true</tt> if this task completed
27.140 + */
27.141 + boolean isDone();
27.142 +
27.143 + /**
27.144 + * Waits if necessary for the computation to complete, and then
27.145 + * retrieves its result.
27.146 + *
27.147 + * @return the computed result
27.148 + * @throws CancellationException if the computation was cancelled
27.149 + * @throws ExecutionException if the computation threw an
27.150 + * exception
27.151 + * @throws InterruptedException if the current thread was interrupted
27.152 + * while waiting
27.153 + */
27.154 + V get() throws InterruptedException, ExecutionException;
27.155 +
27.156 + /**
27.157 + * Waits if necessary for at most the given time for the computation
27.158 + * to complete, and then retrieves its result, if available.
27.159 + *
27.160 + * @param timeout the maximum time to wait
27.161 + * @param unit the time unit of the timeout argument
27.162 + * @return the computed result
27.163 + * @throws CancellationException if the computation was cancelled
27.164 + * @throws ExecutionException if the computation threw an
27.165 + * exception
27.166 + * @throws InterruptedException if the current thread was interrupted
27.167 + * while waiting
27.168 + * @throws TimeoutException if the wait timed out
27.169 + */
27.170 + V get(long timeout, TimeUnit unit)
27.171 + throws InterruptedException, ExecutionException, TimeoutException;
27.172 +}
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
28.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/FutureTask.java Sat Mar 19 10:48:29 2016 +0100
28.3 @@ -0,0 +1,360 @@
28.4 +/*
28.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
28.6 + *
28.7 + * This code is free software; you can redistribute it and/or modify it
28.8 + * under the terms of the GNU General Public License version 2 only, as
28.9 + * published by the Free Software Foundation. Oracle designates this
28.10 + * particular file as subject to the "Classpath" exception as provided
28.11 + * by Oracle in the LICENSE file that accompanied this code.
28.12 + *
28.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
28.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
28.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
28.16 + * version 2 for more details (a copy is included in the LICENSE file that
28.17 + * accompanied this code).
28.18 + *
28.19 + * You should have received a copy of the GNU General Public License version
28.20 + * 2 along with this work; if not, write to the Free Software Foundation,
28.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
28.22 + *
28.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
28.24 + * or visit www.oracle.com if you need additional information or have any
28.25 + * questions.
28.26 + */
28.27 +
28.28 +/*
28.29 + * This file is available under and governed by the GNU General Public
28.30 + * License version 2 only, as published by the Free Software Foundation.
28.31 + * However, the following notice accompanied the original version of this
28.32 + * file:
28.33 + *
28.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
28.35 + * Expert Group and released to the public domain, as explained at
28.36 + * http://creativecommons.org/publicdomain/zero/1.0/
28.37 + */
28.38 +
28.39 +package java.util.concurrent;
28.40 +import java.util.concurrent.locks.*;
28.41 +
28.42 +/**
28.43 + * A cancellable asynchronous computation. This class provides a base
28.44 + * implementation of {@link Future}, with methods to start and cancel
28.45 + * a computation, query to see if the computation is complete, and
28.46 + * retrieve the result of the computation. The result can only be
28.47 + * retrieved when the computation has completed; the <tt>get</tt>
28.48 + * method will block if the computation has not yet completed. Once
28.49 + * the computation has completed, the computation cannot be restarted
28.50 + * or cancelled.
28.51 + *
28.52 + * <p>A <tt>FutureTask</tt> can be used to wrap a {@link Callable} or
28.53 + * {@link java.lang.Runnable} object. Because <tt>FutureTask</tt>
28.54 + * implements <tt>Runnable</tt>, a <tt>FutureTask</tt> can be
28.55 + * submitted to an {@link Executor} for execution.
28.56 + *
28.57 + * <p>In addition to serving as a standalone class, this class provides
28.58 + * <tt>protected</tt> functionality that may be useful when creating
28.59 + * customized task classes.
28.60 + *
28.61 + * @since 1.5
28.62 + * @author Doug Lea
28.63 + * @param <V> The result type returned by this FutureTask's <tt>get</tt> method
28.64 + */
28.65 +public class FutureTask<V> implements RunnableFuture<V> {
28.66 + /** Synchronization control for FutureTask */
28.67 + private final Sync sync;
28.68 +
28.69 + /**
28.70 + * Creates a <tt>FutureTask</tt> that will, upon running, execute the
28.71 + * given <tt>Callable</tt>.
28.72 + *
28.73 + * @param callable the callable task
28.74 + * @throws NullPointerException if callable is null
28.75 + */
28.76 + public FutureTask(Callable<V> callable) {
28.77 + if (callable == null)
28.78 + throw new NullPointerException();
28.79 + sync = new Sync(callable);
28.80 + }
28.81 +
28.82 + /**
28.83 + * Creates a <tt>FutureTask</tt> that will, upon running, execute the
28.84 + * given <tt>Runnable</tt>, and arrange that <tt>get</tt> will return the
28.85 + * given result on successful completion.
28.86 + *
28.87 + * @param runnable the runnable task
28.88 + * @param result the result to return on successful completion. If
28.89 + * you don't need a particular result, consider using
28.90 + * constructions of the form:
28.91 + * {@code Future<?> f = new FutureTask<Void>(runnable, null)}
28.92 + * @throws NullPointerException if runnable is null
28.93 + */
28.94 + public FutureTask(Runnable runnable, V result) {
28.95 + sync = new Sync(Executors.callable(runnable, result));
28.96 + }
28.97 +
28.98 + public boolean isCancelled() {
28.99 + return sync.innerIsCancelled();
28.100 + }
28.101 +
28.102 + public boolean isDone() {
28.103 + return sync.innerIsDone();
28.104 + }
28.105 +
28.106 + public boolean cancel(boolean mayInterruptIfRunning) {
28.107 + return sync.innerCancel(mayInterruptIfRunning);
28.108 + }
28.109 +
28.110 + /**
28.111 + * @throws CancellationException {@inheritDoc}
28.112 + */
28.113 + public V get() throws InterruptedException, ExecutionException {
28.114 + return sync.innerGet();
28.115 + }
28.116 +
28.117 + /**
28.118 + * @throws CancellationException {@inheritDoc}
28.119 + */
28.120 + public V get(long timeout, TimeUnit unit)
28.121 + throws InterruptedException, ExecutionException, TimeoutException {
28.122 + return sync.innerGet(unit.toNanos(timeout));
28.123 + }
28.124 +
28.125 + /**
28.126 + * Protected method invoked when this task transitions to state
28.127 + * <tt>isDone</tt> (whether normally or via cancellation). The
28.128 + * default implementation does nothing. Subclasses may override
28.129 + * this method to invoke completion callbacks or perform
28.130 + * bookkeeping. Note that you can query status inside the
28.131 + * implementation of this method to determine whether this task
28.132 + * has been cancelled.
28.133 + */
28.134 + protected void done() { }
28.135 +
28.136 + /**
28.137 + * Sets the result of this Future to the given value unless
28.138 + * this future has already been set or has been cancelled.
28.139 + * This method is invoked internally by the <tt>run</tt> method
28.140 + * upon successful completion of the computation.
28.141 + * @param v the value
28.142 + */
28.143 + protected void set(V v) {
28.144 + sync.innerSet(v);
28.145 + }
28.146 +
28.147 + /**
28.148 + * Causes this future to report an <tt>ExecutionException</tt>
28.149 + * with the given throwable as its cause, unless this Future has
28.150 + * already been set or has been cancelled.
28.151 + * This method is invoked internally by the <tt>run</tt> method
28.152 + * upon failure of the computation.
28.153 + * @param t the cause of failure
28.154 + */
28.155 + protected void setException(Throwable t) {
28.156 + sync.innerSetException(t);
28.157 + }
28.158 +
28.159 + // The following (duplicated) doc comment can be removed once
28.160 + //
28.161 + // 6270645: Javadoc comments should be inherited from most derived
28.162 + // superinterface or superclass
28.163 + // is fixed.
28.164 + /**
28.165 + * Sets this Future to the result of its computation
28.166 + * unless it has been cancelled.
28.167 + */
28.168 + public void run() {
28.169 + sync.innerRun();
28.170 + }
28.171 +
28.172 + /**
28.173 + * Executes the computation without setting its result, and then
28.174 + * resets this Future to initial state, failing to do so if the
28.175 + * computation encounters an exception or is cancelled. This is
28.176 + * designed for use with tasks that intrinsically execute more
28.177 + * than once.
28.178 + * @return true if successfully run and reset
28.179 + */
28.180 + protected boolean runAndReset() {
28.181 + return sync.innerRunAndReset();
28.182 + }
28.183 +
28.184 + /**
28.185 + * Synchronization control for FutureTask. Note that this must be
28.186 + * a non-static inner class in order to invoke the protected
28.187 + * <tt>done</tt> method. For clarity, all inner class support
28.188 + * methods are same as outer, prefixed with "inner".
28.189 + *
28.190 + * Uses AQS sync state to represent run status
28.191 + */
28.192 + private final class Sync extends AbstractQueuedSynchronizer {
28.193 + private static final long serialVersionUID = -7828117401763700385L;
28.194 +
28.195 + /** State value representing that task is ready to run */
28.196 + private static final int READY = 0;
28.197 + /** State value representing that task is running */
28.198 + private static final int RUNNING = 1;
28.199 + /** State value representing that task ran */
28.200 + private static final int RAN = 2;
28.201 + /** State value representing that task was cancelled */
28.202 + private static final int CANCELLED = 4;
28.203 +
28.204 + /** The underlying callable */
28.205 + private final Callable<V> callable;
28.206 + /** The result to return from get() */
28.207 + private V result;
28.208 + /** The exception to throw from get() */
28.209 + private Throwable exception;
28.210 +
28.211 + /**
28.212 + * The thread running task. When nulled after set/cancel, this
28.213 + * indicates that the results are accessible. Must be
28.214 + * volatile, to ensure visibility upon completion.
28.215 + */
28.216 + private volatile Thread runner;
28.217 +
28.218 + Sync(Callable<V> callable) {
28.219 + this.callable = callable;
28.220 + }
28.221 +
28.222 + private boolean ranOrCancelled(int state) {
28.223 + return (state & (RAN | CANCELLED)) != 0;
28.224 + }
28.225 +
28.226 + /**
28.227 + * Implements AQS base acquire to succeed if ran or cancelled
28.228 + */
28.229 + protected int tryAcquireShared(int ignore) {
28.230 + return innerIsDone() ? 1 : -1;
28.231 + }
28.232 +
28.233 + /**
28.234 + * Implements AQS base release to always signal after setting
28.235 + * final done status by nulling runner thread.
28.236 + */
28.237 + protected boolean tryReleaseShared(int ignore) {
28.238 + runner = null;
28.239 + return true;
28.240 + }
28.241 +
28.242 + boolean innerIsCancelled() {
28.243 + return getState() == CANCELLED;
28.244 + }
28.245 +
28.246 + boolean innerIsDone() {
28.247 + return ranOrCancelled(getState()) && runner == null;
28.248 + }
28.249 +
28.250 + V innerGet() throws InterruptedException, ExecutionException {
28.251 + acquireSharedInterruptibly(0);
28.252 + if (getState() == CANCELLED)
28.253 + throw new CancellationException();
28.254 + if (exception != null)
28.255 + throw new ExecutionException(exception);
28.256 + return result;
28.257 + }
28.258 +
28.259 + V innerGet(long nanosTimeout) throws InterruptedException, ExecutionException, TimeoutException {
28.260 + if (!tryAcquireSharedNanos(0, nanosTimeout))
28.261 + throw new TimeoutException();
28.262 + if (getState() == CANCELLED)
28.263 + throw new CancellationException();
28.264 + if (exception != null)
28.265 + throw new ExecutionException(exception);
28.266 + return result;
28.267 + }
28.268 +
28.269 + void innerSet(V v) {
28.270 + for (;;) {
28.271 + int s = getState();
28.272 + if (s == RAN)
28.273 + return;
28.274 + if (s == CANCELLED) {
28.275 + // aggressively release to set runner to null,
28.276 + // in case we are racing with a cancel request
28.277 + // that will try to interrupt runner
28.278 + releaseShared(0);
28.279 + return;
28.280 + }
28.281 + if (compareAndSetState(s, RAN)) {
28.282 + result = v;
28.283 + releaseShared(0);
28.284 + done();
28.285 + return;
28.286 + }
28.287 + }
28.288 + }
28.289 +
28.290 + void innerSetException(Throwable t) {
28.291 + for (;;) {
28.292 + int s = getState();
28.293 + if (s == RAN)
28.294 + return;
28.295 + if (s == CANCELLED) {
28.296 + // aggressively release to set runner to null,
28.297 + // in case we are racing with a cancel request
28.298 + // that will try to interrupt runner
28.299 + releaseShared(0);
28.300 + return;
28.301 + }
28.302 + if (compareAndSetState(s, RAN)) {
28.303 + exception = t;
28.304 + releaseShared(0);
28.305 + done();
28.306 + return;
28.307 + }
28.308 + }
28.309 + }
28.310 +
28.311 + boolean innerCancel(boolean mayInterruptIfRunning) {
28.312 + for (;;) {
28.313 + int s = getState();
28.314 + if (ranOrCancelled(s))
28.315 + return false;
28.316 + if (compareAndSetState(s, CANCELLED))
28.317 + break;
28.318 + }
28.319 + if (mayInterruptIfRunning) {
28.320 + Thread r = runner;
28.321 + if (r != null)
28.322 + r.interrupt();
28.323 + }
28.324 + releaseShared(0);
28.325 + done();
28.326 + return true;
28.327 + }
28.328 +
28.329 + void innerRun() {
28.330 + if (!compareAndSetState(READY, RUNNING))
28.331 + return;
28.332 +
28.333 + runner = Thread.currentThread();
28.334 + if (getState() == RUNNING) { // recheck after setting thread
28.335 + V result;
28.336 + try {
28.337 + result = callable.call();
28.338 + } catch (Throwable ex) {
28.339 + setException(ex);
28.340 + return;
28.341 + }
28.342 + set(result);
28.343 + } else {
28.344 + releaseShared(0); // cancel
28.345 + }
28.346 + }
28.347 +
28.348 + boolean innerRunAndReset() {
28.349 + if (!compareAndSetState(READY, RUNNING))
28.350 + return false;
28.351 + try {
28.352 + runner = Thread.currentThread();
28.353 + if (getState() == RUNNING)
28.354 + callable.call(); // don't set result
28.355 + runner = null;
28.356 + return compareAndSetState(RUNNING, READY);
28.357 + } catch (Throwable ex) {
28.358 + setException(ex);
28.359 + return false;
28.360 + }
28.361 + }
28.362 + }
28.363 +}
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
29.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/LinkedBlockingDeque.java Sat Mar 19 10:48:29 2016 +0100
29.3 @@ -0,0 +1,1198 @@
29.4 +/*
29.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
29.6 + *
29.7 + * This code is free software; you can redistribute it and/or modify it
29.8 + * under the terms of the GNU General Public License version 2 only, as
29.9 + * published by the Free Software Foundation. Oracle designates this
29.10 + * particular file as subject to the "Classpath" exception as provided
29.11 + * by Oracle in the LICENSE file that accompanied this code.
29.12 + *
29.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
29.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
29.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
29.16 + * version 2 for more details (a copy is included in the LICENSE file that
29.17 + * accompanied this code).
29.18 + *
29.19 + * You should have received a copy of the GNU General Public License version
29.20 + * 2 along with this work; if not, write to the Free Software Foundation,
29.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
29.22 + *
29.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
29.24 + * or visit www.oracle.com if you need additional information or have any
29.25 + * questions.
29.26 + */
29.27 +
29.28 +/*
29.29 + * This file is available under and governed by the GNU General Public
29.30 + * License version 2 only, as published by the Free Software Foundation.
29.31 + * However, the following notice accompanied the original version of this
29.32 + * file:
29.33 + *
29.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
29.35 + * Expert Group and released to the public domain, as explained at
29.36 + * http://creativecommons.org/publicdomain/zero/1.0/
29.37 + */
29.38 +
29.39 +package java.util.concurrent;
29.40 +
29.41 +import java.util.AbstractQueue;
29.42 +import java.util.Collection;
29.43 +import java.util.Iterator;
29.44 +import java.util.NoSuchElementException;
29.45 +import java.util.concurrent.locks.Condition;
29.46 +import java.util.concurrent.locks.ReentrantLock;
29.47 +
29.48 +/**
29.49 + * An optionally-bounded {@linkplain BlockingDeque blocking deque} based on
29.50 + * linked nodes.
29.51 + *
29.52 + * <p> The optional capacity bound constructor argument serves as a
29.53 + * way to prevent excessive expansion. The capacity, if unspecified,
29.54 + * is equal to {@link Integer#MAX_VALUE}. Linked nodes are
29.55 + * dynamically created upon each insertion unless this would bring the
29.56 + * deque above capacity.
29.57 + *
29.58 + * <p>Most operations run in constant time (ignoring time spent
29.59 + * blocking). Exceptions include {@link #remove(Object) remove},
29.60 + * {@link #removeFirstOccurrence removeFirstOccurrence}, {@link
29.61 + * #removeLastOccurrence removeLastOccurrence}, {@link #contains
29.62 + * contains}, {@link #iterator iterator.remove()}, and the bulk
29.63 + * operations, all of which run in linear time.
29.64 + *
29.65 + * <p>This class and its iterator implement all of the
29.66 + * <em>optional</em> methods of the {@link Collection} and {@link
29.67 + * Iterator} interfaces.
29.68 + *
29.69 + * <p>This class is a member of the
29.70 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
29.71 + * Java Collections Framework</a>.
29.72 + *
29.73 + * @since 1.6
29.74 + * @author Doug Lea
29.75 + * @param <E> the type of elements held in this collection
29.76 + */
29.77 +public class LinkedBlockingDeque<E>
29.78 + extends AbstractQueue<E>
29.79 + implements BlockingDeque<E>, java.io.Serializable {
29.80 +
29.81 + /*
29.82 + * Implemented as a simple doubly-linked list protected by a
29.83 + * single lock and using conditions to manage blocking.
29.84 + *
29.85 + * To implement weakly consistent iterators, it appears we need to
29.86 + * keep all Nodes GC-reachable from a predecessor dequeued Node.
29.87 + * That would cause two problems:
29.88 + * - allow a rogue Iterator to cause unbounded memory retention
29.89 + * - cause cross-generational linking of old Nodes to new Nodes if
29.90 + * a Node was tenured while live, which generational GCs have a
29.91 + * hard time dealing with, causing repeated major collections.
29.92 + * However, only non-deleted Nodes need to be reachable from
29.93 + * dequeued Nodes, and reachability does not necessarily have to
29.94 + * be of the kind understood by the GC. We use the trick of
29.95 + * linking a Node that has just been dequeued to itself. Such a
29.96 + * self-link implicitly means to jump to "first" (for next links)
29.97 + * or "last" (for prev links).
29.98 + */
29.99 +
29.100 + /*
29.101 + * We have "diamond" multiple interface/abstract class inheritance
29.102 + * here, and that introduces ambiguities. Often we want the
29.103 + * BlockingDeque javadoc combined with the AbstractQueue
29.104 + * implementation, so a lot of method specs are duplicated here.
29.105 + */
29.106 +
29.107 + private static final long serialVersionUID = -387911632671998426L;
29.108 +
29.109 + /** Doubly-linked list node class */
29.110 + static final class Node<E> {
29.111 + /**
29.112 + * The item, or null if this node has been removed.
29.113 + */
29.114 + E item;
29.115 +
29.116 + /**
29.117 + * One of:
29.118 + * - the real predecessor Node
29.119 + * - this Node, meaning the predecessor is tail
29.120 + * - null, meaning there is no predecessor
29.121 + */
29.122 + Node<E> prev;
29.123 +
29.124 + /**
29.125 + * One of:
29.126 + * - the real successor Node
29.127 + * - this Node, meaning the successor is head
29.128 + * - null, meaning there is no successor
29.129 + */
29.130 + Node<E> next;
29.131 +
29.132 + Node(E x) {
29.133 + item = x;
29.134 + }
29.135 + }
29.136 +
29.137 + /**
29.138 + * Pointer to first node.
29.139 + * Invariant: (first == null && last == null) ||
29.140 + * (first.prev == null && first.item != null)
29.141 + */
29.142 + transient Node<E> first;
29.143 +
29.144 + /**
29.145 + * Pointer to last node.
29.146 + * Invariant: (first == null && last == null) ||
29.147 + * (last.next == null && last.item != null)
29.148 + */
29.149 + transient Node<E> last;
29.150 +
29.151 + /** Number of items in the deque */
29.152 + private transient int count;
29.153 +
29.154 + /** Maximum number of items in the deque */
29.155 + private final int capacity;
29.156 +
29.157 + /** Main lock guarding all access */
29.158 + final ReentrantLock lock = new ReentrantLock();
29.159 +
29.160 + /** Condition for waiting takes */
29.161 + private final Condition notEmpty = lock.newCondition();
29.162 +
29.163 + /** Condition for waiting puts */
29.164 + private final Condition notFull = lock.newCondition();
29.165 +
29.166 + /**
29.167 + * Creates a {@code LinkedBlockingDeque} with a capacity of
29.168 + * {@link Integer#MAX_VALUE}.
29.169 + */
29.170 + public LinkedBlockingDeque() {
29.171 + this(Integer.MAX_VALUE);
29.172 + }
29.173 +
29.174 + /**
29.175 + * Creates a {@code LinkedBlockingDeque} with the given (fixed) capacity.
29.176 + *
29.177 + * @param capacity the capacity of this deque
29.178 + * @throws IllegalArgumentException if {@code capacity} is less than 1
29.179 + */
29.180 + public LinkedBlockingDeque(int capacity) {
29.181 + if (capacity <= 0) throw new IllegalArgumentException();
29.182 + this.capacity = capacity;
29.183 + }
29.184 +
29.185 + /**
29.186 + * Creates a {@code LinkedBlockingDeque} with a capacity of
29.187 + * {@link Integer#MAX_VALUE}, initially containing the elements of
29.188 + * the given collection, added in traversal order of the
29.189 + * collection's iterator.
29.190 + *
29.191 + * @param c the collection of elements to initially contain
29.192 + * @throws NullPointerException if the specified collection or any
29.193 + * of its elements are null
29.194 + */
29.195 + public LinkedBlockingDeque(Collection<? extends E> c) {
29.196 + this(Integer.MAX_VALUE);
29.197 + final ReentrantLock lock = this.lock;
29.198 + lock.lock(); // Never contended, but necessary for visibility
29.199 + try {
29.200 + for (E e : c) {
29.201 + if (e == null)
29.202 + throw new NullPointerException();
29.203 + if (!linkLast(new Node<E>(e)))
29.204 + throw new IllegalStateException("Deque full");
29.205 + }
29.206 + } finally {
29.207 + lock.unlock();
29.208 + }
29.209 + }
29.210 +
29.211 +
29.212 + // Basic linking and unlinking operations, called only while holding lock
29.213 +
29.214 + /**
29.215 + * Links node as first element, or returns false if full.
29.216 + */
29.217 + private boolean linkFirst(Node<E> node) {
29.218 + // assert lock.isHeldByCurrentThread();
29.219 + if (count >= capacity)
29.220 + return false;
29.221 + Node<E> f = first;
29.222 + node.next = f;
29.223 + first = node;
29.224 + if (last == null)
29.225 + last = node;
29.226 + else
29.227 + f.prev = node;
29.228 + ++count;
29.229 + notEmpty.signal();
29.230 + return true;
29.231 + }
29.232 +
29.233 + /**
29.234 + * Links node as last element, or returns false if full.
29.235 + */
29.236 + private boolean linkLast(Node<E> node) {
29.237 + // assert lock.isHeldByCurrentThread();
29.238 + if (count >= capacity)
29.239 + return false;
29.240 + Node<E> l = last;
29.241 + node.prev = l;
29.242 + last = node;
29.243 + if (first == null)
29.244 + first = node;
29.245 + else
29.246 + l.next = node;
29.247 + ++count;
29.248 + notEmpty.signal();
29.249 + return true;
29.250 + }
29.251 +
29.252 + /**
29.253 + * Removes and returns first element, or null if empty.
29.254 + */
29.255 + private E unlinkFirst() {
29.256 + // assert lock.isHeldByCurrentThread();
29.257 + Node<E> f = first;
29.258 + if (f == null)
29.259 + return null;
29.260 + Node<E> n = f.next;
29.261 + E item = f.item;
29.262 + f.item = null;
29.263 + f.next = f; // help GC
29.264 + first = n;
29.265 + if (n == null)
29.266 + last = null;
29.267 + else
29.268 + n.prev = null;
29.269 + --count;
29.270 + notFull.signal();
29.271 + return item;
29.272 + }
29.273 +
29.274 + /**
29.275 + * Removes and returns last element, or null if empty.
29.276 + */
29.277 + private E unlinkLast() {
29.278 + // assert lock.isHeldByCurrentThread();
29.279 + Node<E> l = last;
29.280 + if (l == null)
29.281 + return null;
29.282 + Node<E> p = l.prev;
29.283 + E item = l.item;
29.284 + l.item = null;
29.285 + l.prev = l; // help GC
29.286 + last = p;
29.287 + if (p == null)
29.288 + first = null;
29.289 + else
29.290 + p.next = null;
29.291 + --count;
29.292 + notFull.signal();
29.293 + return item;
29.294 + }
29.295 +
29.296 + /**
29.297 + * Unlinks x.
29.298 + */
29.299 + void unlink(Node<E> x) {
29.300 + // assert lock.isHeldByCurrentThread();
29.301 + Node<E> p = x.prev;
29.302 + Node<E> n = x.next;
29.303 + if (p == null) {
29.304 + unlinkFirst();
29.305 + } else if (n == null) {
29.306 + unlinkLast();
29.307 + } else {
29.308 + p.next = n;
29.309 + n.prev = p;
29.310 + x.item = null;
29.311 + // Don't mess with x's links. They may still be in use by
29.312 + // an iterator.
29.313 + --count;
29.314 + notFull.signal();
29.315 + }
29.316 + }
29.317 +
29.318 + // BlockingDeque methods
29.319 +
29.320 + /**
29.321 + * @throws IllegalStateException {@inheritDoc}
29.322 + * @throws NullPointerException {@inheritDoc}
29.323 + */
29.324 + public void addFirst(E e) {
29.325 + if (!offerFirst(e))
29.326 + throw new IllegalStateException("Deque full");
29.327 + }
29.328 +
29.329 + /**
29.330 + * @throws IllegalStateException {@inheritDoc}
29.331 + * @throws NullPointerException {@inheritDoc}
29.332 + */
29.333 + public void addLast(E e) {
29.334 + if (!offerLast(e))
29.335 + throw new IllegalStateException("Deque full");
29.336 + }
29.337 +
29.338 + /**
29.339 + * @throws NullPointerException {@inheritDoc}
29.340 + */
29.341 + public boolean offerFirst(E e) {
29.342 + if (e == null) throw new NullPointerException();
29.343 + Node<E> node = new Node<E>(e);
29.344 + final ReentrantLock lock = this.lock;
29.345 + lock.lock();
29.346 + try {
29.347 + return linkFirst(node);
29.348 + } finally {
29.349 + lock.unlock();
29.350 + }
29.351 + }
29.352 +
29.353 + /**
29.354 + * @throws NullPointerException {@inheritDoc}
29.355 + */
29.356 + public boolean offerLast(E e) {
29.357 + if (e == null) throw new NullPointerException();
29.358 + Node<E> node = new Node<E>(e);
29.359 + final ReentrantLock lock = this.lock;
29.360 + lock.lock();
29.361 + try {
29.362 + return linkLast(node);
29.363 + } finally {
29.364 + lock.unlock();
29.365 + }
29.366 + }
29.367 +
29.368 + /**
29.369 + * @throws NullPointerException {@inheritDoc}
29.370 + * @throws InterruptedException {@inheritDoc}
29.371 + */
29.372 + public void putFirst(E e) throws InterruptedException {
29.373 + if (e == null) throw new NullPointerException();
29.374 + Node<E> node = new Node<E>(e);
29.375 + final ReentrantLock lock = this.lock;
29.376 + lock.lock();
29.377 + try {
29.378 + while (!linkFirst(node))
29.379 + notFull.await();
29.380 + } finally {
29.381 + lock.unlock();
29.382 + }
29.383 + }
29.384 +
29.385 + /**
29.386 + * @throws NullPointerException {@inheritDoc}
29.387 + * @throws InterruptedException {@inheritDoc}
29.388 + */
29.389 + public void putLast(E e) throws InterruptedException {
29.390 + if (e == null) throw new NullPointerException();
29.391 + Node<E> node = new Node<E>(e);
29.392 + final ReentrantLock lock = this.lock;
29.393 + lock.lock();
29.394 + try {
29.395 + while (!linkLast(node))
29.396 + notFull.await();
29.397 + } finally {
29.398 + lock.unlock();
29.399 + }
29.400 + }
29.401 +
29.402 + /**
29.403 + * @throws NullPointerException {@inheritDoc}
29.404 + * @throws InterruptedException {@inheritDoc}
29.405 + */
29.406 + public boolean offerFirst(E e, long timeout, TimeUnit unit)
29.407 + throws InterruptedException {
29.408 + if (e == null) throw new NullPointerException();
29.409 + Node<E> node = new Node<E>(e);
29.410 + long nanos = unit.toNanos(timeout);
29.411 + final ReentrantLock lock = this.lock;
29.412 + lock.lockInterruptibly();
29.413 + try {
29.414 + while (!linkFirst(node)) {
29.415 + if (nanos <= 0)
29.416 + return false;
29.417 + nanos = notFull.awaitNanos(nanos);
29.418 + }
29.419 + return true;
29.420 + } finally {
29.421 + lock.unlock();
29.422 + }
29.423 + }
29.424 +
29.425 + /**
29.426 + * @throws NullPointerException {@inheritDoc}
29.427 + * @throws InterruptedException {@inheritDoc}
29.428 + */
29.429 + public boolean offerLast(E e, long timeout, TimeUnit unit)
29.430 + throws InterruptedException {
29.431 + if (e == null) throw new NullPointerException();
29.432 + Node<E> node = new Node<E>(e);
29.433 + long nanos = unit.toNanos(timeout);
29.434 + final ReentrantLock lock = this.lock;
29.435 + lock.lockInterruptibly();
29.436 + try {
29.437 + while (!linkLast(node)) {
29.438 + if (nanos <= 0)
29.439 + return false;
29.440 + nanos = notFull.awaitNanos(nanos);
29.441 + }
29.442 + return true;
29.443 + } finally {
29.444 + lock.unlock();
29.445 + }
29.446 + }
29.447 +
29.448 + /**
29.449 + * @throws NoSuchElementException {@inheritDoc}
29.450 + */
29.451 + public E removeFirst() {
29.452 + E x = pollFirst();
29.453 + if (x == null) throw new NoSuchElementException();
29.454 + return x;
29.455 + }
29.456 +
29.457 + /**
29.458 + * @throws NoSuchElementException {@inheritDoc}
29.459 + */
29.460 + public E removeLast() {
29.461 + E x = pollLast();
29.462 + if (x == null) throw new NoSuchElementException();
29.463 + return x;
29.464 + }
29.465 +
29.466 + public E pollFirst() {
29.467 + final ReentrantLock lock = this.lock;
29.468 + lock.lock();
29.469 + try {
29.470 + return unlinkFirst();
29.471 + } finally {
29.472 + lock.unlock();
29.473 + }
29.474 + }
29.475 +
29.476 + public E pollLast() {
29.477 + final ReentrantLock lock = this.lock;
29.478 + lock.lock();
29.479 + try {
29.480 + return unlinkLast();
29.481 + } finally {
29.482 + lock.unlock();
29.483 + }
29.484 + }
29.485 +
29.486 + public E takeFirst() throws InterruptedException {
29.487 + final ReentrantLock lock = this.lock;
29.488 + lock.lock();
29.489 + try {
29.490 + E x;
29.491 + while ( (x = unlinkFirst()) == null)
29.492 + notEmpty.await();
29.493 + return x;
29.494 + } finally {
29.495 + lock.unlock();
29.496 + }
29.497 + }
29.498 +
29.499 + public E takeLast() throws InterruptedException {
29.500 + final ReentrantLock lock = this.lock;
29.501 + lock.lock();
29.502 + try {
29.503 + E x;
29.504 + while ( (x = unlinkLast()) == null)
29.505 + notEmpty.await();
29.506 + return x;
29.507 + } finally {
29.508 + lock.unlock();
29.509 + }
29.510 + }
29.511 +
29.512 + public E pollFirst(long timeout, TimeUnit unit)
29.513 + throws InterruptedException {
29.514 + long nanos = unit.toNanos(timeout);
29.515 + final ReentrantLock lock = this.lock;
29.516 + lock.lockInterruptibly();
29.517 + try {
29.518 + E x;
29.519 + while ( (x = unlinkFirst()) == null) {
29.520 + if (nanos <= 0)
29.521 + return null;
29.522 + nanos = notEmpty.awaitNanos(nanos);
29.523 + }
29.524 + return x;
29.525 + } finally {
29.526 + lock.unlock();
29.527 + }
29.528 + }
29.529 +
29.530 + public E pollLast(long timeout, TimeUnit unit)
29.531 + throws InterruptedException {
29.532 + long nanos = unit.toNanos(timeout);
29.533 + final ReentrantLock lock = this.lock;
29.534 + lock.lockInterruptibly();
29.535 + try {
29.536 + E x;
29.537 + while ( (x = unlinkLast()) == null) {
29.538 + if (nanos <= 0)
29.539 + return null;
29.540 + nanos = notEmpty.awaitNanos(nanos);
29.541 + }
29.542 + return x;
29.543 + } finally {
29.544 + lock.unlock();
29.545 + }
29.546 + }
29.547 +
29.548 + /**
29.549 + * @throws NoSuchElementException {@inheritDoc}
29.550 + */
29.551 + public E getFirst() {
29.552 + E x = peekFirst();
29.553 + if (x == null) throw new NoSuchElementException();
29.554 + return x;
29.555 + }
29.556 +
29.557 + /**
29.558 + * @throws NoSuchElementException {@inheritDoc}
29.559 + */
29.560 + public E getLast() {
29.561 + E x = peekLast();
29.562 + if (x == null) throw new NoSuchElementException();
29.563 + return x;
29.564 + }
29.565 +
29.566 + public E peekFirst() {
29.567 + final ReentrantLock lock = this.lock;
29.568 + lock.lock();
29.569 + try {
29.570 + return (first == null) ? null : first.item;
29.571 + } finally {
29.572 + lock.unlock();
29.573 + }
29.574 + }
29.575 +
29.576 + public E peekLast() {
29.577 + final ReentrantLock lock = this.lock;
29.578 + lock.lock();
29.579 + try {
29.580 + return (last == null) ? null : last.item;
29.581 + } finally {
29.582 + lock.unlock();
29.583 + }
29.584 + }
29.585 +
29.586 + public boolean removeFirstOccurrence(Object o) {
29.587 + if (o == null) return false;
29.588 + final ReentrantLock lock = this.lock;
29.589 + lock.lock();
29.590 + try {
29.591 + for (Node<E> p = first; p != null; p = p.next) {
29.592 + if (o.equals(p.item)) {
29.593 + unlink(p);
29.594 + return true;
29.595 + }
29.596 + }
29.597 + return false;
29.598 + } finally {
29.599 + lock.unlock();
29.600 + }
29.601 + }
29.602 +
29.603 + public boolean removeLastOccurrence(Object o) {
29.604 + if (o == null) return false;
29.605 + final ReentrantLock lock = this.lock;
29.606 + lock.lock();
29.607 + try {
29.608 + for (Node<E> p = last; p != null; p = p.prev) {
29.609 + if (o.equals(p.item)) {
29.610 + unlink(p);
29.611 + return true;
29.612 + }
29.613 + }
29.614 + return false;
29.615 + } finally {
29.616 + lock.unlock();
29.617 + }
29.618 + }
29.619 +
29.620 + // BlockingQueue methods
29.621 +
29.622 + /**
29.623 + * Inserts the specified element at the end of this deque unless it would
29.624 + * violate capacity restrictions. When using a capacity-restricted deque,
29.625 + * it is generally preferable to use method {@link #offer(Object) offer}.
29.626 + *
29.627 + * <p>This method is equivalent to {@link #addLast}.
29.628 + *
29.629 + * @throws IllegalStateException if the element cannot be added at this
29.630 + * time due to capacity restrictions
29.631 + * @throws NullPointerException if the specified element is null
29.632 + */
29.633 + public boolean add(E e) {
29.634 + addLast(e);
29.635 + return true;
29.636 + }
29.637 +
29.638 + /**
29.639 + * @throws NullPointerException if the specified element is null
29.640 + */
29.641 + public boolean offer(E e) {
29.642 + return offerLast(e);
29.643 + }
29.644 +
29.645 + /**
29.646 + * @throws NullPointerException {@inheritDoc}
29.647 + * @throws InterruptedException {@inheritDoc}
29.648 + */
29.649 + public void put(E e) throws InterruptedException {
29.650 + putLast(e);
29.651 + }
29.652 +
29.653 + /**
29.654 + * @throws NullPointerException {@inheritDoc}
29.655 + * @throws InterruptedException {@inheritDoc}
29.656 + */
29.657 + public boolean offer(E e, long timeout, TimeUnit unit)
29.658 + throws InterruptedException {
29.659 + return offerLast(e, timeout, unit);
29.660 + }
29.661 +
29.662 + /**
29.663 + * Retrieves and removes the head of the queue represented by this deque.
29.664 + * This method differs from {@link #poll poll} only in that it throws an
29.665 + * exception if this deque is empty.
29.666 + *
29.667 + * <p>This method is equivalent to {@link #removeFirst() removeFirst}.
29.668 + *
29.669 + * @return the head of the queue represented by this deque
29.670 + * @throws NoSuchElementException if this deque is empty
29.671 + */
29.672 + public E remove() {
29.673 + return removeFirst();
29.674 + }
29.675 +
29.676 + public E poll() {
29.677 + return pollFirst();
29.678 + }
29.679 +
29.680 + public E take() throws InterruptedException {
29.681 + return takeFirst();
29.682 + }
29.683 +
29.684 + public E poll(long timeout, TimeUnit unit) throws InterruptedException {
29.685 + return pollFirst(timeout, unit);
29.686 + }
29.687 +
29.688 + /**
29.689 + * Retrieves, but does not remove, the head of the queue represented by
29.690 + * this deque. This method differs from {@link #peek peek} only in that
29.691 + * it throws an exception if this deque is empty.
29.692 + *
29.693 + * <p>This method is equivalent to {@link #getFirst() getFirst}.
29.694 + *
29.695 + * @return the head of the queue represented by this deque
29.696 + * @throws NoSuchElementException if this deque is empty
29.697 + */
29.698 + public E element() {
29.699 + return getFirst();
29.700 + }
29.701 +
29.702 + public E peek() {
29.703 + return peekFirst();
29.704 + }
29.705 +
29.706 + /**
29.707 + * Returns the number of additional elements that this deque can ideally
29.708 + * (in the absence of memory or resource constraints) accept without
29.709 + * blocking. This is always equal to the initial capacity of this deque
29.710 + * less the current {@code size} of this deque.
29.711 + *
29.712 + * <p>Note that you <em>cannot</em> always tell if an attempt to insert
29.713 + * an element will succeed by inspecting {@code remainingCapacity}
29.714 + * because it may be the case that another thread is about to
29.715 + * insert or remove an element.
29.716 + */
29.717 + public int remainingCapacity() {
29.718 + final ReentrantLock lock = this.lock;
29.719 + lock.lock();
29.720 + try {
29.721 + return capacity - count;
29.722 + } finally {
29.723 + lock.unlock();
29.724 + }
29.725 + }
29.726 +
29.727 + /**
29.728 + * @throws UnsupportedOperationException {@inheritDoc}
29.729 + * @throws ClassCastException {@inheritDoc}
29.730 + * @throws NullPointerException {@inheritDoc}
29.731 + * @throws IllegalArgumentException {@inheritDoc}
29.732 + */
29.733 + public int drainTo(Collection<? super E> c) {
29.734 + return drainTo(c, Integer.MAX_VALUE);
29.735 + }
29.736 +
29.737 + /**
29.738 + * @throws UnsupportedOperationException {@inheritDoc}
29.739 + * @throws ClassCastException {@inheritDoc}
29.740 + * @throws NullPointerException {@inheritDoc}
29.741 + * @throws IllegalArgumentException {@inheritDoc}
29.742 + */
29.743 + public int drainTo(Collection<? super E> c, int maxElements) {
29.744 + if (c == null)
29.745 + throw new NullPointerException();
29.746 + if (c == this)
29.747 + throw new IllegalArgumentException();
29.748 + final ReentrantLock lock = this.lock;
29.749 + lock.lock();
29.750 + try {
29.751 + int n = Math.min(maxElements, count);
29.752 + for (int i = 0; i < n; i++) {
29.753 + c.add(first.item); // In this order, in case add() throws.
29.754 + unlinkFirst();
29.755 + }
29.756 + return n;
29.757 + } finally {
29.758 + lock.unlock();
29.759 + }
29.760 + }
29.761 +
29.762 + // Stack methods
29.763 +
29.764 + /**
29.765 + * @throws IllegalStateException {@inheritDoc}
29.766 + * @throws NullPointerException {@inheritDoc}
29.767 + */
29.768 + public void push(E e) {
29.769 + addFirst(e);
29.770 + }
29.771 +
29.772 + /**
29.773 + * @throws NoSuchElementException {@inheritDoc}
29.774 + */
29.775 + public E pop() {
29.776 + return removeFirst();
29.777 + }
29.778 +
29.779 + // Collection methods
29.780 +
29.781 + /**
29.782 + * Removes the first occurrence of the specified element from this deque.
29.783 + * If the deque does not contain the element, it is unchanged.
29.784 + * More formally, removes the first element {@code e} such that
29.785 + * {@code o.equals(e)} (if such an element exists).
29.786 + * Returns {@code true} if this deque contained the specified element
29.787 + * (or equivalently, if this deque changed as a result of the call).
29.788 + *
29.789 + * <p>This method is equivalent to
29.790 + * {@link #removeFirstOccurrence(Object) removeFirstOccurrence}.
29.791 + *
29.792 + * @param o element to be removed from this deque, if present
29.793 + * @return {@code true} if this deque changed as a result of the call
29.794 + */
29.795 + public boolean remove(Object o) {
29.796 + return removeFirstOccurrence(o);
29.797 + }
29.798 +
29.799 + /**
29.800 + * Returns the number of elements in this deque.
29.801 + *
29.802 + * @return the number of elements in this deque
29.803 + */
29.804 + public int size() {
29.805 + final ReentrantLock lock = this.lock;
29.806 + lock.lock();
29.807 + try {
29.808 + return count;
29.809 + } finally {
29.810 + lock.unlock();
29.811 + }
29.812 + }
29.813 +
29.814 + /**
29.815 + * Returns {@code true} if this deque contains the specified element.
29.816 + * More formally, returns {@code true} if and only if this deque contains
29.817 + * at least one element {@code e} such that {@code o.equals(e)}.
29.818 + *
29.819 + * @param o object to be checked for containment in this deque
29.820 + * @return {@code true} if this deque contains the specified element
29.821 + */
29.822 + public boolean contains(Object o) {
29.823 + if (o == null) return false;
29.824 + final ReentrantLock lock = this.lock;
29.825 + lock.lock();
29.826 + try {
29.827 + for (Node<E> p = first; p != null; p = p.next)
29.828 + if (o.equals(p.item))
29.829 + return true;
29.830 + return false;
29.831 + } finally {
29.832 + lock.unlock();
29.833 + }
29.834 + }
29.835 +
29.836 + /*
29.837 + * TODO: Add support for more efficient bulk operations.
29.838 + *
29.839 + * We don't want to acquire the lock for every iteration, but we
29.840 + * also want other threads a chance to interact with the
29.841 + * collection, especially when count is close to capacity.
29.842 + */
29.843 +
29.844 +// /**
29.845 +// * Adds all of the elements in the specified collection to this
29.846 +// * queue. Attempts to addAll of a queue to itself result in
29.847 +// * {@code IllegalArgumentException}. Further, the behavior of
29.848 +// * this operation is undefined if the specified collection is
29.849 +// * modified while the operation is in progress.
29.850 +// *
29.851 +// * @param c collection containing elements to be added to this queue
29.852 +// * @return {@code true} if this queue changed as a result of the call
29.853 +// * @throws ClassCastException {@inheritDoc}
29.854 +// * @throws NullPointerException {@inheritDoc}
29.855 +// * @throws IllegalArgumentException {@inheritDoc}
29.856 +// * @throws IllegalStateException {@inheritDoc}
29.857 +// * @see #add(Object)
29.858 +// */
29.859 +// public boolean addAll(Collection<? extends E> c) {
29.860 +// if (c == null)
29.861 +// throw new NullPointerException();
29.862 +// if (c == this)
29.863 +// throw new IllegalArgumentException();
29.864 +// final ReentrantLock lock = this.lock;
29.865 +// lock.lock();
29.866 +// try {
29.867 +// boolean modified = false;
29.868 +// for (E e : c)
29.869 +// if (linkLast(e))
29.870 +// modified = true;
29.871 +// return modified;
29.872 +// } finally {
29.873 +// lock.unlock();
29.874 +// }
29.875 +// }
29.876 +
29.877 + /**
29.878 + * Returns an array containing all of the elements in this deque, in
29.879 + * proper sequence (from first to last element).
29.880 + *
29.881 + * <p>The returned array will be "safe" in that no references to it are
29.882 + * maintained by this deque. (In other words, this method must allocate
29.883 + * a new array). The caller is thus free to modify the returned array.
29.884 + *
29.885 + * <p>This method acts as bridge between array-based and collection-based
29.886 + * APIs.
29.887 + *
29.888 + * @return an array containing all of the elements in this deque
29.889 + */
29.890 + @SuppressWarnings("unchecked")
29.891 + public Object[] toArray() {
29.892 + final ReentrantLock lock = this.lock;
29.893 + lock.lock();
29.894 + try {
29.895 + Object[] a = new Object[count];
29.896 + int k = 0;
29.897 + for (Node<E> p = first; p != null; p = p.next)
29.898 + a[k++] = p.item;
29.899 + return a;
29.900 + } finally {
29.901 + lock.unlock();
29.902 + }
29.903 + }
29.904 +
29.905 + /**
29.906 + * Returns an array containing all of the elements in this deque, in
29.907 + * proper sequence; the runtime type of the returned array is that of
29.908 + * the specified array. If the deque fits in the specified array, it
29.909 + * is returned therein. Otherwise, a new array is allocated with the
29.910 + * runtime type of the specified array and the size of this deque.
29.911 + *
29.912 + * <p>If this deque fits in the specified array with room to spare
29.913 + * (i.e., the array has more elements than this deque), the element in
29.914 + * the array immediately following the end of the deque is set to
29.915 + * {@code null}.
29.916 + *
29.917 + * <p>Like the {@link #toArray()} method, this method acts as bridge between
29.918 + * array-based and collection-based APIs. Further, this method allows
29.919 + * precise control over the runtime type of the output array, and may,
29.920 + * under certain circumstances, be used to save allocation costs.
29.921 + *
29.922 + * <p>Suppose {@code x} is a deque known to contain only strings.
29.923 + * The following code can be used to dump the deque into a newly
29.924 + * allocated array of {@code String}:
29.925 + *
29.926 + * <pre>
29.927 + * String[] y = x.toArray(new String[0]);</pre>
29.928 + *
29.929 + * Note that {@code toArray(new Object[0])} is identical in function to
29.930 + * {@code toArray()}.
29.931 + *
29.932 + * @param a the array into which the elements of the deque are to
29.933 + * be stored, if it is big enough; otherwise, a new array of the
29.934 + * same runtime type is allocated for this purpose
29.935 + * @return an array containing all of the elements in this deque
29.936 + * @throws ArrayStoreException if the runtime type of the specified array
29.937 + * is not a supertype of the runtime type of every element in
29.938 + * this deque
29.939 + * @throws NullPointerException if the specified array is null
29.940 + */
29.941 + @SuppressWarnings("unchecked")
29.942 + public <T> T[] toArray(T[] a) {
29.943 + final ReentrantLock lock = this.lock;
29.944 + lock.lock();
29.945 + try {
29.946 + if (a.length < count)
29.947 + a = (T[])java.lang.reflect.Array.newInstance
29.948 + (a.getClass().getComponentType(), count);
29.949 +
29.950 + int k = 0;
29.951 + for (Node<E> p = first; p != null; p = p.next)
29.952 + a[k++] = (T)p.item;
29.953 + if (a.length > k)
29.954 + a[k] = null;
29.955 + return a;
29.956 + } finally {
29.957 + lock.unlock();
29.958 + }
29.959 + }
29.960 +
29.961 + public String toString() {
29.962 + final ReentrantLock lock = this.lock;
29.963 + lock.lock();
29.964 + try {
29.965 + Node<E> p = first;
29.966 + if (p == null)
29.967 + return "[]";
29.968 +
29.969 + StringBuilder sb = new StringBuilder();
29.970 + sb.append('[');
29.971 + for (;;) {
29.972 + E e = p.item;
29.973 + sb.append(e == this ? "(this Collection)" : e);
29.974 + p = p.next;
29.975 + if (p == null)
29.976 + return sb.append(']').toString();
29.977 + sb.append(',').append(' ');
29.978 + }
29.979 + } finally {
29.980 + lock.unlock();
29.981 + }
29.982 + }
29.983 +
29.984 + /**
29.985 + * Atomically removes all of the elements from this deque.
29.986 + * The deque will be empty after this call returns.
29.987 + */
29.988 + public void clear() {
29.989 + final ReentrantLock lock = this.lock;
29.990 + lock.lock();
29.991 + try {
29.992 + for (Node<E> f = first; f != null; ) {
29.993 + f.item = null;
29.994 + Node<E> n = f.next;
29.995 + f.prev = null;
29.996 + f.next = null;
29.997 + f = n;
29.998 + }
29.999 + first = last = null;
29.1000 + count = 0;
29.1001 + notFull.signalAll();
29.1002 + } finally {
29.1003 + lock.unlock();
29.1004 + }
29.1005 + }
29.1006 +
29.1007 + /**
29.1008 + * Returns an iterator over the elements in this deque in proper sequence.
29.1009 + * The elements will be returned in order from first (head) to last (tail).
29.1010 + *
29.1011 + * <p>The returned iterator is a "weakly consistent" iterator that
29.1012 + * will never throw {@link java.util.ConcurrentModificationException
29.1013 + * ConcurrentModificationException}, and guarantees to traverse
29.1014 + * elements as they existed upon construction of the iterator, and
29.1015 + * may (but is not guaranteed to) reflect any modifications
29.1016 + * subsequent to construction.
29.1017 + *
29.1018 + * @return an iterator over the elements in this deque in proper sequence
29.1019 + */
29.1020 + public Iterator<E> iterator() {
29.1021 + return new Itr();
29.1022 + }
29.1023 +
29.1024 + /**
29.1025 + * Returns an iterator over the elements in this deque in reverse
29.1026 + * sequential order. The elements will be returned in order from
29.1027 + * last (tail) to first (head).
29.1028 + *
29.1029 + * <p>The returned iterator is a "weakly consistent" iterator that
29.1030 + * will never throw {@link java.util.ConcurrentModificationException
29.1031 + * ConcurrentModificationException}, and guarantees to traverse
29.1032 + * elements as they existed upon construction of the iterator, and
29.1033 + * may (but is not guaranteed to) reflect any modifications
29.1034 + * subsequent to construction.
29.1035 + *
29.1036 + * @return an iterator over the elements in this deque in reverse order
29.1037 + */
29.1038 + public Iterator<E> descendingIterator() {
29.1039 + return new DescendingItr();
29.1040 + }
29.1041 +
29.1042 + /**
29.1043 + * Base class for Iterators for LinkedBlockingDeque
29.1044 + */
29.1045 + private abstract class AbstractItr implements Iterator<E> {
29.1046 + /**
29.1047 + * The next node to return in next()
29.1048 + */
29.1049 + Node<E> next;
29.1050 +
29.1051 + /**
29.1052 + * nextItem holds on to item fields because once we claim that
29.1053 + * an element exists in hasNext(), we must return item read
29.1054 + * under lock (in advance()) even if it was in the process of
29.1055 + * being removed when hasNext() was called.
29.1056 + */
29.1057 + E nextItem;
29.1058 +
29.1059 + /**
29.1060 + * Node returned by most recent call to next. Needed by remove.
29.1061 + * Reset to null if this element is deleted by a call to remove.
29.1062 + */
29.1063 + private Node<E> lastRet;
29.1064 +
29.1065 + abstract Node<E> firstNode();
29.1066 + abstract Node<E> nextNode(Node<E> n);
29.1067 +
29.1068 + AbstractItr() {
29.1069 + // set to initial position
29.1070 + final ReentrantLock lock = LinkedBlockingDeque.this.lock;
29.1071 + lock.lock();
29.1072 + try {
29.1073 + next = firstNode();
29.1074 + nextItem = (next == null) ? null : next.item;
29.1075 + } finally {
29.1076 + lock.unlock();
29.1077 + }
29.1078 + }
29.1079 +
29.1080 + /**
29.1081 + * Returns the successor node of the given non-null, but
29.1082 + * possibly previously deleted, node.
29.1083 + */
29.1084 + private Node<E> succ(Node<E> n) {
29.1085 + // Chains of deleted nodes ending in null or self-links
29.1086 + // are possible if multiple interior nodes are removed.
29.1087 + for (;;) {
29.1088 + Node<E> s = nextNode(n);
29.1089 + if (s == null)
29.1090 + return null;
29.1091 + else if (s.item != null)
29.1092 + return s;
29.1093 + else if (s == n)
29.1094 + return firstNode();
29.1095 + else
29.1096 + n = s;
29.1097 + }
29.1098 + }
29.1099 +
29.1100 + /**
29.1101 + * Advances next.
29.1102 + */
29.1103 + void advance() {
29.1104 + final ReentrantLock lock = LinkedBlockingDeque.this.lock;
29.1105 + lock.lock();
29.1106 + try {
29.1107 + // assert next != null;
29.1108 + next = succ(next);
29.1109 + nextItem = (next == null) ? null : next.item;
29.1110 + } finally {
29.1111 + lock.unlock();
29.1112 + }
29.1113 + }
29.1114 +
29.1115 + public boolean hasNext() {
29.1116 + return next != null;
29.1117 + }
29.1118 +
29.1119 + public E next() {
29.1120 + if (next == null)
29.1121 + throw new NoSuchElementException();
29.1122 + lastRet = next;
29.1123 + E x = nextItem;
29.1124 + advance();
29.1125 + return x;
29.1126 + }
29.1127 +
29.1128 + public void remove() {
29.1129 + Node<E> n = lastRet;
29.1130 + if (n == null)
29.1131 + throw new IllegalStateException();
29.1132 + lastRet = null;
29.1133 + final ReentrantLock lock = LinkedBlockingDeque.this.lock;
29.1134 + lock.lock();
29.1135 + try {
29.1136 + if (n.item != null)
29.1137 + unlink(n);
29.1138 + } finally {
29.1139 + lock.unlock();
29.1140 + }
29.1141 + }
29.1142 + }
29.1143 +
29.1144 + /** Forward iterator */
29.1145 + private class Itr extends AbstractItr {
29.1146 + Node<E> firstNode() { return first; }
29.1147 + Node<E> nextNode(Node<E> n) { return n.next; }
29.1148 + }
29.1149 +
29.1150 + /** Descending iterator */
29.1151 + private class DescendingItr extends AbstractItr {
29.1152 + Node<E> firstNode() { return last; }
29.1153 + Node<E> nextNode(Node<E> n) { return n.prev; }
29.1154 + }
29.1155 +
29.1156 + /**
29.1157 + * Save the state of this deque to a stream (that is, serialize it).
29.1158 + *
29.1159 + * @serialData The capacity (int), followed by elements (each an
29.1160 + * {@code Object}) in the proper order, followed by a null
29.1161 + * @param s the stream
29.1162 + */
29.1163 + private void writeObject(java.io.ObjectOutputStream s)
29.1164 + throws java.io.IOException {
29.1165 + final ReentrantLock lock = this.lock;
29.1166 + lock.lock();
29.1167 + try {
29.1168 + // Write out capacity and any hidden stuff
29.1169 + s.defaultWriteObject();
29.1170 + // Write out all elements in the proper order.
29.1171 + for (Node<E> p = first; p != null; p = p.next)
29.1172 + s.writeObject(p.item);
29.1173 + // Use trailing null as sentinel
29.1174 + s.writeObject(null);
29.1175 + } finally {
29.1176 + lock.unlock();
29.1177 + }
29.1178 + }
29.1179 +
29.1180 + /**
29.1181 + * Reconstitute this deque from a stream (that is,
29.1182 + * deserialize it).
29.1183 + * @param s the stream
29.1184 + */
29.1185 + private void readObject(java.io.ObjectInputStream s)
29.1186 + throws java.io.IOException, ClassNotFoundException {
29.1187 + s.defaultReadObject();
29.1188 + count = 0;
29.1189 + first = null;
29.1190 + last = null;
29.1191 + // Read in all elements and place in queue
29.1192 + for (;;) {
29.1193 + @SuppressWarnings("unchecked")
29.1194 + E item = (E)s.readObject();
29.1195 + if (item == null)
29.1196 + break;
29.1197 + add(item);
29.1198 + }
29.1199 + }
29.1200 +
29.1201 +}
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
30.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/LinkedBlockingQueue.java Sat Mar 19 10:48:29 2016 +0100
30.3 @@ -0,0 +1,910 @@
30.4 +/*
30.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
30.6 + *
30.7 + * This code is free software; you can redistribute it and/or modify it
30.8 + * under the terms of the GNU General Public License version 2 only, as
30.9 + * published by the Free Software Foundation. Oracle designates this
30.10 + * particular file as subject to the "Classpath" exception as provided
30.11 + * by Oracle in the LICENSE file that accompanied this code.
30.12 + *
30.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
30.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
30.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
30.16 + * version 2 for more details (a copy is included in the LICENSE file that
30.17 + * accompanied this code).
30.18 + *
30.19 + * You should have received a copy of the GNU General Public License version
30.20 + * 2 along with this work; if not, write to the Free Software Foundation,
30.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
30.22 + *
30.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
30.24 + * or visit www.oracle.com if you need additional information or have any
30.25 + * questions.
30.26 + */
30.27 +
30.28 +/*
30.29 + * This file is available under and governed by the GNU General Public
30.30 + * License version 2 only, as published by the Free Software Foundation.
30.31 + * However, the following notice accompanied the original version of this
30.32 + * file:
30.33 + *
30.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
30.35 + * Expert Group and released to the public domain, as explained at
30.36 + * http://creativecommons.org/publicdomain/zero/1.0/
30.37 + */
30.38 +
30.39 +package java.util.concurrent;
30.40 +
30.41 +import java.util.concurrent.atomic.AtomicInteger;
30.42 +import java.util.concurrent.locks.Condition;
30.43 +import java.util.concurrent.locks.ReentrantLock;
30.44 +import java.util.AbstractQueue;
30.45 +import java.util.Collection;
30.46 +import java.util.Iterator;
30.47 +import java.util.NoSuchElementException;
30.48 +
30.49 +/**
30.50 + * An optionally-bounded {@linkplain BlockingQueue blocking queue} based on
30.51 + * linked nodes.
30.52 + * This queue orders elements FIFO (first-in-first-out).
30.53 + * The <em>head</em> of the queue is that element that has been on the
30.54 + * queue the longest time.
30.55 + * The <em>tail</em> of the queue is that element that has been on the
30.56 + * queue the shortest time. New elements
30.57 + * are inserted at the tail of the queue, and the queue retrieval
30.58 + * operations obtain elements at the head of the queue.
30.59 + * Linked queues typically have higher throughput than array-based queues but
30.60 + * less predictable performance in most concurrent applications.
30.61 + *
30.62 + * <p> The optional capacity bound constructor argument serves as a
30.63 + * way to prevent excessive queue expansion. The capacity, if unspecified,
30.64 + * is equal to {@link Integer#MAX_VALUE}. Linked nodes are
30.65 + * dynamically created upon each insertion unless this would bring the
30.66 + * queue above capacity.
30.67 + *
30.68 + * <p>This class and its iterator implement all of the
30.69 + * <em>optional</em> methods of the {@link Collection} and {@link
30.70 + * Iterator} interfaces.
30.71 + *
30.72 + * <p>This class is a member of the
30.73 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
30.74 + * Java Collections Framework</a>.
30.75 + *
30.76 + * @since 1.5
30.77 + * @author Doug Lea
30.78 + * @param <E> the type of elements held in this collection
30.79 + *
30.80 + */
30.81 +public class LinkedBlockingQueue<E> extends AbstractQueue<E>
30.82 + implements BlockingQueue<E>, java.io.Serializable {
30.83 + private static final long serialVersionUID = -6903933977591709194L;
30.84 +
30.85 + /*
30.86 + * A variant of the "two lock queue" algorithm. The putLock gates
30.87 + * entry to put (and offer), and has an associated condition for
30.88 + * waiting puts. Similarly for the takeLock. The "count" field
30.89 + * that they both rely on is maintained as an atomic to avoid
30.90 + * needing to get both locks in most cases. Also, to minimize need
30.91 + * for puts to get takeLock and vice-versa, cascading notifies are
30.92 + * used. When a put notices that it has enabled at least one take,
30.93 + * it signals taker. That taker in turn signals others if more
30.94 + * items have been entered since the signal. And symmetrically for
30.95 + * takes signalling puts. Operations such as remove(Object) and
30.96 + * iterators acquire both locks.
30.97 + *
30.98 + * Visibility between writers and readers is provided as follows:
30.99 + *
30.100 + * Whenever an element is enqueued, the putLock is acquired and
30.101 + * count updated. A subsequent reader guarantees visibility to the
30.102 + * enqueued Node by either acquiring the putLock (via fullyLock)
30.103 + * or by acquiring the takeLock, and then reading n = count.get();
30.104 + * this gives visibility to the first n items.
30.105 + *
30.106 + * To implement weakly consistent iterators, it appears we need to
30.107 + * keep all Nodes GC-reachable from a predecessor dequeued Node.
30.108 + * That would cause two problems:
30.109 + * - allow a rogue Iterator to cause unbounded memory retention
30.110 + * - cause cross-generational linking of old Nodes to new Nodes if
30.111 + * a Node was tenured while live, which generational GCs have a
30.112 + * hard time dealing with, causing repeated major collections.
30.113 + * However, only non-deleted Nodes need to be reachable from
30.114 + * dequeued Nodes, and reachability does not necessarily have to
30.115 + * be of the kind understood by the GC. We use the trick of
30.116 + * linking a Node that has just been dequeued to itself. Such a
30.117 + * self-link implicitly means to advance to head.next.
30.118 + */
30.119 +
30.120 + /**
30.121 + * Linked list node class
30.122 + */
30.123 + static class Node<E> {
30.124 + E item;
30.125 +
30.126 + /**
30.127 + * One of:
30.128 + * - the real successor Node
30.129 + * - this Node, meaning the successor is head.next
30.130 + * - null, meaning there is no successor (this is the last node)
30.131 + */
30.132 + Node<E> next;
30.133 +
30.134 + Node(E x) { item = x; }
30.135 + }
30.136 +
30.137 + /** The capacity bound, or Integer.MAX_VALUE if none */
30.138 + private final int capacity;
30.139 +
30.140 + /** Current number of elements */
30.141 + private final AtomicInteger count = new AtomicInteger(0);
30.142 +
30.143 + /**
30.144 + * Head of linked list.
30.145 + * Invariant: head.item == null
30.146 + */
30.147 + private transient Node<E> head;
30.148 +
30.149 + /**
30.150 + * Tail of linked list.
30.151 + * Invariant: last.next == null
30.152 + */
30.153 + private transient Node<E> last;
30.154 +
30.155 + /** Lock held by take, poll, etc */
30.156 + private final ReentrantLock takeLock = new ReentrantLock();
30.157 +
30.158 + /** Wait queue for waiting takes */
30.159 + private final Condition notEmpty = takeLock.newCondition();
30.160 +
30.161 + /** Lock held by put, offer, etc */
30.162 + private final ReentrantLock putLock = new ReentrantLock();
30.163 +
30.164 + /** Wait queue for waiting puts */
30.165 + private final Condition notFull = putLock.newCondition();
30.166 +
30.167 + /**
30.168 + * Signals a waiting take. Called only from put/offer (which do not
30.169 + * otherwise ordinarily lock takeLock.)
30.170 + */
30.171 + private void signalNotEmpty() {
30.172 + final ReentrantLock takeLock = this.takeLock;
30.173 + takeLock.lock();
30.174 + try {
30.175 + notEmpty.signal();
30.176 + } finally {
30.177 + takeLock.unlock();
30.178 + }
30.179 + }
30.180 +
30.181 + /**
30.182 + * Signals a waiting put. Called only from take/poll.
30.183 + */
30.184 + private void signalNotFull() {
30.185 + final ReentrantLock putLock = this.putLock;
30.186 + putLock.lock();
30.187 + try {
30.188 + notFull.signal();
30.189 + } finally {
30.190 + putLock.unlock();
30.191 + }
30.192 + }
30.193 +
30.194 + /**
30.195 + * Links node at end of queue.
30.196 + *
30.197 + * @param node the node
30.198 + */
30.199 + private void enqueue(Node<E> node) {
30.200 + // assert putLock.isHeldByCurrentThread();
30.201 + // assert last.next == null;
30.202 + last = last.next = node;
30.203 + }
30.204 +
30.205 + /**
30.206 + * Removes a node from head of queue.
30.207 + *
30.208 + * @return the node
30.209 + */
30.210 + private E dequeue() {
30.211 + // assert takeLock.isHeldByCurrentThread();
30.212 + // assert head.item == null;
30.213 + Node<E> h = head;
30.214 + Node<E> first = h.next;
30.215 + h.next = h; // help GC
30.216 + head = first;
30.217 + E x = first.item;
30.218 + first.item = null;
30.219 + return x;
30.220 + }
30.221 +
30.222 + /**
30.223 + * Lock to prevent both puts and takes.
30.224 + */
30.225 + void fullyLock() {
30.226 + putLock.lock();
30.227 + takeLock.lock();
30.228 + }
30.229 +
30.230 + /**
30.231 + * Unlock to allow both puts and takes.
30.232 + */
30.233 + void fullyUnlock() {
30.234 + takeLock.unlock();
30.235 + putLock.unlock();
30.236 + }
30.237 +
30.238 +// /**
30.239 +// * Tells whether both locks are held by current thread.
30.240 +// */
30.241 +// boolean isFullyLocked() {
30.242 +// return (putLock.isHeldByCurrentThread() &&
30.243 +// takeLock.isHeldByCurrentThread());
30.244 +// }
30.245 +
30.246 + /**
30.247 + * Creates a {@code LinkedBlockingQueue} with a capacity of
30.248 + * {@link Integer#MAX_VALUE}.
30.249 + */
30.250 + public LinkedBlockingQueue() {
30.251 + this(Integer.MAX_VALUE);
30.252 + }
30.253 +
30.254 + /**
30.255 + * Creates a {@code LinkedBlockingQueue} with the given (fixed) capacity.
30.256 + *
30.257 + * @param capacity the capacity of this queue
30.258 + * @throws IllegalArgumentException if {@code capacity} is not greater
30.259 + * than zero
30.260 + */
30.261 + public LinkedBlockingQueue(int capacity) {
30.262 + if (capacity <= 0) throw new IllegalArgumentException();
30.263 + this.capacity = capacity;
30.264 + last = head = new Node<E>(null);
30.265 + }
30.266 +
30.267 + /**
30.268 + * Creates a {@code LinkedBlockingQueue} with a capacity of
30.269 + * {@link Integer#MAX_VALUE}, initially containing the elements of the
30.270 + * given collection,
30.271 + * added in traversal order of the collection's iterator.
30.272 + *
30.273 + * @param c the collection of elements to initially contain
30.274 + * @throws NullPointerException if the specified collection or any
30.275 + * of its elements are null
30.276 + */
30.277 + public LinkedBlockingQueue(Collection<? extends E> c) {
30.278 + this(Integer.MAX_VALUE);
30.279 + final ReentrantLock putLock = this.putLock;
30.280 + putLock.lock(); // Never contended, but necessary for visibility
30.281 + try {
30.282 + int n = 0;
30.283 + for (E e : c) {
30.284 + if (e == null)
30.285 + throw new NullPointerException();
30.286 + if (n == capacity)
30.287 + throw new IllegalStateException("Queue full");
30.288 + enqueue(new Node<E>(e));
30.289 + ++n;
30.290 + }
30.291 + count.set(n);
30.292 + } finally {
30.293 + putLock.unlock();
30.294 + }
30.295 + }
30.296 +
30.297 +
30.298 + // this doc comment is overridden to remove the reference to collections
30.299 + // greater in size than Integer.MAX_VALUE
30.300 + /**
30.301 + * Returns the number of elements in this queue.
30.302 + *
30.303 + * @return the number of elements in this queue
30.304 + */
30.305 + public int size() {
30.306 + return count.get();
30.307 + }
30.308 +
30.309 + // this doc comment is a modified copy of the inherited doc comment,
30.310 + // without the reference to unlimited queues.
30.311 + /**
30.312 + * Returns the number of additional elements that this queue can ideally
30.313 + * (in the absence of memory or resource constraints) accept without
30.314 + * blocking. This is always equal to the initial capacity of this queue
30.315 + * less the current {@code size} of this queue.
30.316 + *
30.317 + * <p>Note that you <em>cannot</em> always tell if an attempt to insert
30.318 + * an element will succeed by inspecting {@code remainingCapacity}
30.319 + * because it may be the case that another thread is about to
30.320 + * insert or remove an element.
30.321 + */
30.322 + public int remainingCapacity() {
30.323 + return capacity - count.get();
30.324 + }
30.325 +
30.326 + /**
30.327 + * Inserts the specified element at the tail of this queue, waiting if
30.328 + * necessary for space to become available.
30.329 + *
30.330 + * @throws InterruptedException {@inheritDoc}
30.331 + * @throws NullPointerException {@inheritDoc}
30.332 + */
30.333 + public void put(E e) throws InterruptedException {
30.334 + if (e == null) throw new NullPointerException();
30.335 + // Note: convention in all put/take/etc is to preset local var
30.336 + // holding count negative to indicate failure unless set.
30.337 + int c = -1;
30.338 + Node<E> node = new Node(e);
30.339 + final ReentrantLock putLock = this.putLock;
30.340 + final AtomicInteger count = this.count;
30.341 + putLock.lockInterruptibly();
30.342 + try {
30.343 + /*
30.344 + * Note that count is used in wait guard even though it is
30.345 + * not protected by lock. This works because count can
30.346 + * only decrease at this point (all other puts are shut
30.347 + * out by lock), and we (or some other waiting put) are
30.348 + * signalled if it ever changes from capacity. Similarly
30.349 + * for all other uses of count in other wait guards.
30.350 + */
30.351 + while (count.get() == capacity) {
30.352 + notFull.await();
30.353 + }
30.354 + enqueue(node);
30.355 + c = count.getAndIncrement();
30.356 + if (c + 1 < capacity)
30.357 + notFull.signal();
30.358 + } finally {
30.359 + putLock.unlock();
30.360 + }
30.361 + if (c == 0)
30.362 + signalNotEmpty();
30.363 + }
30.364 +
30.365 + /**
30.366 + * Inserts the specified element at the tail of this queue, waiting if
30.367 + * necessary up to the specified wait time for space to become available.
30.368 + *
30.369 + * @return {@code true} if successful, or {@code false} if
30.370 + * the specified waiting time elapses before space is available.
30.371 + * @throws InterruptedException {@inheritDoc}
30.372 + * @throws NullPointerException {@inheritDoc}
30.373 + */
30.374 + public boolean offer(E e, long timeout, TimeUnit unit)
30.375 + throws InterruptedException {
30.376 +
30.377 + if (e == null) throw new NullPointerException();
30.378 + long nanos = unit.toNanos(timeout);
30.379 + int c = -1;
30.380 + final ReentrantLock putLock = this.putLock;
30.381 + final AtomicInteger count = this.count;
30.382 + putLock.lockInterruptibly();
30.383 + try {
30.384 + while (count.get() == capacity) {
30.385 + if (nanos <= 0)
30.386 + return false;
30.387 + nanos = notFull.awaitNanos(nanos);
30.388 + }
30.389 + enqueue(new Node<E>(e));
30.390 + c = count.getAndIncrement();
30.391 + if (c + 1 < capacity)
30.392 + notFull.signal();
30.393 + } finally {
30.394 + putLock.unlock();
30.395 + }
30.396 + if (c == 0)
30.397 + signalNotEmpty();
30.398 + return true;
30.399 + }
30.400 +
30.401 + /**
30.402 + * Inserts the specified element at the tail of this queue if it is
30.403 + * possible to do so immediately without exceeding the queue's capacity,
30.404 + * returning {@code true} upon success and {@code false} if this queue
30.405 + * is full.
30.406 + * When using a capacity-restricted queue, this method is generally
30.407 + * preferable to method {@link BlockingQueue#add add}, which can fail to
30.408 + * insert an element only by throwing an exception.
30.409 + *
30.410 + * @throws NullPointerException if the specified element is null
30.411 + */
30.412 + public boolean offer(E e) {
30.413 + if (e == null) throw new NullPointerException();
30.414 + final AtomicInteger count = this.count;
30.415 + if (count.get() == capacity)
30.416 + return false;
30.417 + int c = -1;
30.418 + Node<E> node = new Node(e);
30.419 + final ReentrantLock putLock = this.putLock;
30.420 + putLock.lock();
30.421 + try {
30.422 + if (count.get() < capacity) {
30.423 + enqueue(node);
30.424 + c = count.getAndIncrement();
30.425 + if (c + 1 < capacity)
30.426 + notFull.signal();
30.427 + }
30.428 + } finally {
30.429 + putLock.unlock();
30.430 + }
30.431 + if (c == 0)
30.432 + signalNotEmpty();
30.433 + return c >= 0;
30.434 + }
30.435 +
30.436 +
30.437 + public E take() throws InterruptedException {
30.438 + E x;
30.439 + int c = -1;
30.440 + final AtomicInteger count = this.count;
30.441 + final ReentrantLock takeLock = this.takeLock;
30.442 + takeLock.lockInterruptibly();
30.443 + try {
30.444 + while (count.get() == 0) {
30.445 + notEmpty.await();
30.446 + }
30.447 + x = dequeue();
30.448 + c = count.getAndDecrement();
30.449 + if (c > 1)
30.450 + notEmpty.signal();
30.451 + } finally {
30.452 + takeLock.unlock();
30.453 + }
30.454 + if (c == capacity)
30.455 + signalNotFull();
30.456 + return x;
30.457 + }
30.458 +
30.459 + public E poll(long timeout, TimeUnit unit) throws InterruptedException {
30.460 + E x = null;
30.461 + int c = -1;
30.462 + long nanos = unit.toNanos(timeout);
30.463 + final AtomicInteger count = this.count;
30.464 + final ReentrantLock takeLock = this.takeLock;
30.465 + takeLock.lockInterruptibly();
30.466 + try {
30.467 + while (count.get() == 0) {
30.468 + if (nanos <= 0)
30.469 + return null;
30.470 + nanos = notEmpty.awaitNanos(nanos);
30.471 + }
30.472 + x = dequeue();
30.473 + c = count.getAndDecrement();
30.474 + if (c > 1)
30.475 + notEmpty.signal();
30.476 + } finally {
30.477 + takeLock.unlock();
30.478 + }
30.479 + if (c == capacity)
30.480 + signalNotFull();
30.481 + return x;
30.482 + }
30.483 +
30.484 + public E poll() {
30.485 + final AtomicInteger count = this.count;
30.486 + if (count.get() == 0)
30.487 + return null;
30.488 + E x = null;
30.489 + int c = -1;
30.490 + final ReentrantLock takeLock = this.takeLock;
30.491 + takeLock.lock();
30.492 + try {
30.493 + if (count.get() > 0) {
30.494 + x = dequeue();
30.495 + c = count.getAndDecrement();
30.496 + if (c > 1)
30.497 + notEmpty.signal();
30.498 + }
30.499 + } finally {
30.500 + takeLock.unlock();
30.501 + }
30.502 + if (c == capacity)
30.503 + signalNotFull();
30.504 + return x;
30.505 + }
30.506 +
30.507 + public E peek() {
30.508 + if (count.get() == 0)
30.509 + return null;
30.510 + final ReentrantLock takeLock = this.takeLock;
30.511 + takeLock.lock();
30.512 + try {
30.513 + Node<E> first = head.next;
30.514 + if (first == null)
30.515 + return null;
30.516 + else
30.517 + return first.item;
30.518 + } finally {
30.519 + takeLock.unlock();
30.520 + }
30.521 + }
30.522 +
30.523 + /**
30.524 + * Unlinks interior Node p with predecessor trail.
30.525 + */
30.526 + void unlink(Node<E> p, Node<E> trail) {
30.527 + // assert isFullyLocked();
30.528 + // p.next is not changed, to allow iterators that are
30.529 + // traversing p to maintain their weak-consistency guarantee.
30.530 + p.item = null;
30.531 + trail.next = p.next;
30.532 + if (last == p)
30.533 + last = trail;
30.534 + if (count.getAndDecrement() == capacity)
30.535 + notFull.signal();
30.536 + }
30.537 +
30.538 + /**
30.539 + * Removes a single instance of the specified element from this queue,
30.540 + * if it is present. More formally, removes an element {@code e} such
30.541 + * that {@code o.equals(e)}, if this queue contains one or more such
30.542 + * elements.
30.543 + * Returns {@code true} if this queue contained the specified element
30.544 + * (or equivalently, if this queue changed as a result of the call).
30.545 + *
30.546 + * @param o element to be removed from this queue, if present
30.547 + * @return {@code true} if this queue changed as a result of the call
30.548 + */
30.549 + public boolean remove(Object o) {
30.550 + if (o == null) return false;
30.551 + fullyLock();
30.552 + try {
30.553 + for (Node<E> trail = head, p = trail.next;
30.554 + p != null;
30.555 + trail = p, p = p.next) {
30.556 + if (o.equals(p.item)) {
30.557 + unlink(p, trail);
30.558 + return true;
30.559 + }
30.560 + }
30.561 + return false;
30.562 + } finally {
30.563 + fullyUnlock();
30.564 + }
30.565 + }
30.566 +
30.567 + /**
30.568 + * Returns {@code true} if this queue contains the specified element.
30.569 + * More formally, returns {@code true} if and only if this queue contains
30.570 + * at least one element {@code e} such that {@code o.equals(e)}.
30.571 + *
30.572 + * @param o object to be checked for containment in this queue
30.573 + * @return {@code true} if this queue contains the specified element
30.574 + */
30.575 + public boolean contains(Object o) {
30.576 + if (o == null) return false;
30.577 + fullyLock();
30.578 + try {
30.579 + for (Node<E> p = head.next; p != null; p = p.next)
30.580 + if (o.equals(p.item))
30.581 + return true;
30.582 + return false;
30.583 + } finally {
30.584 + fullyUnlock();
30.585 + }
30.586 + }
30.587 +
30.588 + /**
30.589 + * Returns an array containing all of the elements in this queue, in
30.590 + * proper sequence.
30.591 + *
30.592 + * <p>The returned array will be "safe" in that no references to it are
30.593 + * maintained by this queue. (In other words, this method must allocate
30.594 + * a new array). The caller is thus free to modify the returned array.
30.595 + *
30.596 + * <p>This method acts as bridge between array-based and collection-based
30.597 + * APIs.
30.598 + *
30.599 + * @return an array containing all of the elements in this queue
30.600 + */
30.601 + public Object[] toArray() {
30.602 + fullyLock();
30.603 + try {
30.604 + int size = count.get();
30.605 + Object[] a = new Object[size];
30.606 + int k = 0;
30.607 + for (Node<E> p = head.next; p != null; p = p.next)
30.608 + a[k++] = p.item;
30.609 + return a;
30.610 + } finally {
30.611 + fullyUnlock();
30.612 + }
30.613 + }
30.614 +
30.615 + /**
30.616 + * Returns an array containing all of the elements in this queue, in
30.617 + * proper sequence; the runtime type of the returned array is that of
30.618 + * the specified array. If the queue fits in the specified array, it
30.619 + * is returned therein. Otherwise, a new array is allocated with the
30.620 + * runtime type of the specified array and the size of this queue.
30.621 + *
30.622 + * <p>If this queue fits in the specified array with room to spare
30.623 + * (i.e., the array has more elements than this queue), the element in
30.624 + * the array immediately following the end of the queue is set to
30.625 + * {@code null}.
30.626 + *
30.627 + * <p>Like the {@link #toArray()} method, this method acts as bridge between
30.628 + * array-based and collection-based APIs. Further, this method allows
30.629 + * precise control over the runtime type of the output array, and may,
30.630 + * under certain circumstances, be used to save allocation costs.
30.631 + *
30.632 + * <p>Suppose {@code x} is a queue known to contain only strings.
30.633 + * The following code can be used to dump the queue into a newly
30.634 + * allocated array of {@code String}:
30.635 + *
30.636 + * <pre>
30.637 + * String[] y = x.toArray(new String[0]);</pre>
30.638 + *
30.639 + * Note that {@code toArray(new Object[0])} is identical in function to
30.640 + * {@code toArray()}.
30.641 + *
30.642 + * @param a the array into which the elements of the queue are to
30.643 + * be stored, if it is big enough; otherwise, a new array of the
30.644 + * same runtime type is allocated for this purpose
30.645 + * @return an array containing all of the elements in this queue
30.646 + * @throws ArrayStoreException if the runtime type of the specified array
30.647 + * is not a supertype of the runtime type of every element in
30.648 + * this queue
30.649 + * @throws NullPointerException if the specified array is null
30.650 + */
30.651 + @SuppressWarnings("unchecked")
30.652 + public <T> T[] toArray(T[] a) {
30.653 + fullyLock();
30.654 + try {
30.655 + int size = count.get();
30.656 + if (a.length < size)
30.657 + a = (T[])java.lang.reflect.Array.newInstance
30.658 + (a.getClass().getComponentType(), size);
30.659 +
30.660 + int k = 0;
30.661 + for (Node<E> p = head.next; p != null; p = p.next)
30.662 + a[k++] = (T)p.item;
30.663 + if (a.length > k)
30.664 + a[k] = null;
30.665 + return a;
30.666 + } finally {
30.667 + fullyUnlock();
30.668 + }
30.669 + }
30.670 +
30.671 + public String toString() {
30.672 + fullyLock();
30.673 + try {
30.674 + Node<E> p = head.next;
30.675 + if (p == null)
30.676 + return "[]";
30.677 +
30.678 + StringBuilder sb = new StringBuilder();
30.679 + sb.append('[');
30.680 + for (;;) {
30.681 + E e = p.item;
30.682 + sb.append(e == this ? "(this Collection)" : e);
30.683 + p = p.next;
30.684 + if (p == null)
30.685 + return sb.append(']').toString();
30.686 + sb.append(',').append(' ');
30.687 + }
30.688 + } finally {
30.689 + fullyUnlock();
30.690 + }
30.691 + }
30.692 +
30.693 + /**
30.694 + * Atomically removes all of the elements from this queue.
30.695 + * The queue will be empty after this call returns.
30.696 + */
30.697 + public void clear() {
30.698 + fullyLock();
30.699 + try {
30.700 + for (Node<E> p, h = head; (p = h.next) != null; h = p) {
30.701 + h.next = h;
30.702 + p.item = null;
30.703 + }
30.704 + head = last;
30.705 + // assert head.item == null && head.next == null;
30.706 + if (count.getAndSet(0) == capacity)
30.707 + notFull.signal();
30.708 + } finally {
30.709 + fullyUnlock();
30.710 + }
30.711 + }
30.712 +
30.713 + /**
30.714 + * @throws UnsupportedOperationException {@inheritDoc}
30.715 + * @throws ClassCastException {@inheritDoc}
30.716 + * @throws NullPointerException {@inheritDoc}
30.717 + * @throws IllegalArgumentException {@inheritDoc}
30.718 + */
30.719 + public int drainTo(Collection<? super E> c) {
30.720 + return drainTo(c, Integer.MAX_VALUE);
30.721 + }
30.722 +
30.723 + /**
30.724 + * @throws UnsupportedOperationException {@inheritDoc}
30.725 + * @throws ClassCastException {@inheritDoc}
30.726 + * @throws NullPointerException {@inheritDoc}
30.727 + * @throws IllegalArgumentException {@inheritDoc}
30.728 + */
30.729 + public int drainTo(Collection<? super E> c, int maxElements) {
30.730 + if (c == null)
30.731 + throw new NullPointerException();
30.732 + if (c == this)
30.733 + throw new IllegalArgumentException();
30.734 + boolean signalNotFull = false;
30.735 + final ReentrantLock takeLock = this.takeLock;
30.736 + takeLock.lock();
30.737 + try {
30.738 + int n = Math.min(maxElements, count.get());
30.739 + // count.get provides visibility to first n Nodes
30.740 + Node<E> h = head;
30.741 + int i = 0;
30.742 + try {
30.743 + while (i < n) {
30.744 + Node<E> p = h.next;
30.745 + c.add(p.item);
30.746 + p.item = null;
30.747 + h.next = h;
30.748 + h = p;
30.749 + ++i;
30.750 + }
30.751 + return n;
30.752 + } finally {
30.753 + // Restore invariants even if c.add() threw
30.754 + if (i > 0) {
30.755 + // assert h.item == null;
30.756 + head = h;
30.757 + signalNotFull = (count.getAndAdd(-i) == capacity);
30.758 + }
30.759 + }
30.760 + } finally {
30.761 + takeLock.unlock();
30.762 + if (signalNotFull)
30.763 + signalNotFull();
30.764 + }
30.765 + }
30.766 +
30.767 + /**
30.768 + * Returns an iterator over the elements in this queue in proper sequence.
30.769 + * The elements will be returned in order from first (head) to last (tail).
30.770 + *
30.771 + * <p>The returned iterator is a "weakly consistent" iterator that
30.772 + * will never throw {@link java.util.ConcurrentModificationException
30.773 + * ConcurrentModificationException}, and guarantees to traverse
30.774 + * elements as they existed upon construction of the iterator, and
30.775 + * may (but is not guaranteed to) reflect any modifications
30.776 + * subsequent to construction.
30.777 + *
30.778 + * @return an iterator over the elements in this queue in proper sequence
30.779 + */
30.780 + public Iterator<E> iterator() {
30.781 + return new Itr();
30.782 + }
30.783 +
30.784 + private class Itr implements Iterator<E> {
30.785 + /*
30.786 + * Basic weakly-consistent iterator. At all times hold the next
30.787 + * item to hand out so that if hasNext() reports true, we will
30.788 + * still have it to return even if lost race with a take etc.
30.789 + */
30.790 + private Node<E> current;
30.791 + private Node<E> lastRet;
30.792 + private E currentElement;
30.793 +
30.794 + Itr() {
30.795 + fullyLock();
30.796 + try {
30.797 + current = head.next;
30.798 + if (current != null)
30.799 + currentElement = current.item;
30.800 + } finally {
30.801 + fullyUnlock();
30.802 + }
30.803 + }
30.804 +
30.805 + public boolean hasNext() {
30.806 + return current != null;
30.807 + }
30.808 +
30.809 + /**
30.810 + * Returns the next live successor of p, or null if no such.
30.811 + *
30.812 + * Unlike other traversal methods, iterators need to handle both:
30.813 + * - dequeued nodes (p.next == p)
30.814 + * - (possibly multiple) interior removed nodes (p.item == null)
30.815 + */
30.816 + private Node<E> nextNode(Node<E> p) {
30.817 + for (;;) {
30.818 + Node<E> s = p.next;
30.819 + if (s == p)
30.820 + return head.next;
30.821 + if (s == null || s.item != null)
30.822 + return s;
30.823 + p = s;
30.824 + }
30.825 + }
30.826 +
30.827 + public E next() {
30.828 + fullyLock();
30.829 + try {
30.830 + if (current == null)
30.831 + throw new NoSuchElementException();
30.832 + E x = currentElement;
30.833 + lastRet = current;
30.834 + current = nextNode(current);
30.835 + currentElement = (current == null) ? null : current.item;
30.836 + return x;
30.837 + } finally {
30.838 + fullyUnlock();
30.839 + }
30.840 + }
30.841 +
30.842 + public void remove() {
30.843 + if (lastRet == null)
30.844 + throw new IllegalStateException();
30.845 + fullyLock();
30.846 + try {
30.847 + Node<E> node = lastRet;
30.848 + lastRet = null;
30.849 + for (Node<E> trail = head, p = trail.next;
30.850 + p != null;
30.851 + trail = p, p = p.next) {
30.852 + if (p == node) {
30.853 + unlink(p, trail);
30.854 + break;
30.855 + }
30.856 + }
30.857 + } finally {
30.858 + fullyUnlock();
30.859 + }
30.860 + }
30.861 + }
30.862 +
30.863 + /**
30.864 + * Save the state to a stream (that is, serialize it).
30.865 + *
30.866 + * @serialData The capacity is emitted (int), followed by all of
30.867 + * its elements (each an {@code Object}) in the proper order,
30.868 + * followed by a null
30.869 + * @param s the stream
30.870 + */
30.871 + private void writeObject(java.io.ObjectOutputStream s)
30.872 + throws java.io.IOException {
30.873 +
30.874 + fullyLock();
30.875 + try {
30.876 + // Write out any hidden stuff, plus capacity
30.877 + s.defaultWriteObject();
30.878 +
30.879 + // Write out all elements in the proper order.
30.880 + for (Node<E> p = head.next; p != null; p = p.next)
30.881 + s.writeObject(p.item);
30.882 +
30.883 + // Use trailing null as sentinel
30.884 + s.writeObject(null);
30.885 + } finally {
30.886 + fullyUnlock();
30.887 + }
30.888 + }
30.889 +
30.890 + /**
30.891 + * Reconstitute this queue instance from a stream (that is,
30.892 + * deserialize it).
30.893 + *
30.894 + * @param s the stream
30.895 + */
30.896 + private void readObject(java.io.ObjectInputStream s)
30.897 + throws java.io.IOException, ClassNotFoundException {
30.898 + // Read in capacity, and any hidden stuff
30.899 + s.defaultReadObject();
30.900 +
30.901 + count.set(0);
30.902 + last = head = new Node<E>(null);
30.903 +
30.904 + // Read in all elements and place in queue
30.905 + for (;;) {
30.906 + @SuppressWarnings("unchecked")
30.907 + E item = (E)s.readObject();
30.908 + if (item == null)
30.909 + break;
30.910 + add(item);
30.911 + }
30.912 + }
30.913 +}
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
31.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/LinkedTransferQueue.java Sat Mar 19 10:48:29 2016 +0100
31.3 @@ -0,0 +1,1351 @@
31.4 +/*
31.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
31.6 + *
31.7 + * This code is free software; you can redistribute it and/or modify it
31.8 + * under the terms of the GNU General Public License version 2 only, as
31.9 + * published by the Free Software Foundation. Oracle designates this
31.10 + * particular file as subject to the "Classpath" exception as provided
31.11 + * by Oracle in the LICENSE file that accompanied this code.
31.12 + *
31.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
31.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
31.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
31.16 + * version 2 for more details (a copy is included in the LICENSE file that
31.17 + * accompanied this code).
31.18 + *
31.19 + * You should have received a copy of the GNU General Public License version
31.20 + * 2 along with this work; if not, write to the Free Software Foundation,
31.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
31.22 + *
31.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
31.24 + * or visit www.oracle.com if you need additional information or have any
31.25 + * questions.
31.26 + */
31.27 +
31.28 +/*
31.29 + * This file is available under and governed by the GNU General Public
31.30 + * License version 2 only, as published by the Free Software Foundation.
31.31 + * However, the following notice accompanied the original version of this
31.32 + * file:
31.33 + *
31.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
31.35 + * Expert Group and released to the public domain, as explained at
31.36 + * http://creativecommons.org/publicdomain/zero/1.0/
31.37 + */
31.38 +
31.39 +package java.util.concurrent;
31.40 +
31.41 +import java.util.AbstractQueue;
31.42 +import java.util.Collection;
31.43 +import java.util.Iterator;
31.44 +import java.util.NoSuchElementException;
31.45 +import java.util.Queue;
31.46 +import java.util.concurrent.TimeUnit;
31.47 +import java.util.concurrent.locks.LockSupport;
31.48 +
31.49 +/**
31.50 + * An unbounded {@link TransferQueue} based on linked nodes.
31.51 + * This queue orders elements FIFO (first-in-first-out) with respect
31.52 + * to any given producer. The <em>head</em> of the queue is that
31.53 + * element that has been on the queue the longest time for some
31.54 + * producer. The <em>tail</em> of the queue is that element that has
31.55 + * been on the queue the shortest time for some producer.
31.56 + *
31.57 + * <p>Beware that, unlike in most collections, the {@code size} method
31.58 + * is <em>NOT</em> a constant-time operation. Because of the
31.59 + * asynchronous nature of these queues, determining the current number
31.60 + * of elements requires a traversal of the elements, and so may report
31.61 + * inaccurate results if this collection is modified during traversal.
31.62 + * Additionally, the bulk operations {@code addAll},
31.63 + * {@code removeAll}, {@code retainAll}, {@code containsAll},
31.64 + * {@code equals}, and {@code toArray} are <em>not</em> guaranteed
31.65 + * to be performed atomically. For example, an iterator operating
31.66 + * concurrently with an {@code addAll} operation might view only some
31.67 + * of the added elements.
31.68 + *
31.69 + * <p>This class and its iterator implement all of the
31.70 + * <em>optional</em> methods of the {@link Collection} and {@link
31.71 + * Iterator} interfaces.
31.72 + *
31.73 + * <p>Memory consistency effects: As with other concurrent
31.74 + * collections, actions in a thread prior to placing an object into a
31.75 + * {@code LinkedTransferQueue}
31.76 + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
31.77 + * actions subsequent to the access or removal of that element from
31.78 + * the {@code LinkedTransferQueue} in another thread.
31.79 + *
31.80 + * <p>This class is a member of the
31.81 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
31.82 + * Java Collections Framework</a>.
31.83 + *
31.84 + * @since 1.7
31.85 + * @author Doug Lea
31.86 + * @param <E> the type of elements held in this collection
31.87 + */
31.88 +public class LinkedTransferQueue<E> extends AbstractQueue<E>
31.89 + implements TransferQueue<E>, java.io.Serializable {
31.90 + private static final long serialVersionUID = -3223113410248163686L;
31.91 +
31.92 + /*
31.93 + * *** Overview of Dual Queues with Slack ***
31.94 + *
31.95 + * Dual Queues, introduced by Scherer and Scott
31.96 + * (http://www.cs.rice.edu/~wns1/papers/2004-DISC-DDS.pdf) are
31.97 + * (linked) queues in which nodes may represent either data or
31.98 + * requests. When a thread tries to enqueue a data node, but
31.99 + * encounters a request node, it instead "matches" and removes it;
31.100 + * and vice versa for enqueuing requests. Blocking Dual Queues
31.101 + * arrange that threads enqueuing unmatched requests block until
31.102 + * other threads provide the match. Dual Synchronous Queues (see
31.103 + * Scherer, Lea, & Scott
31.104 + * http://www.cs.rochester.edu/u/scott/papers/2009_Scherer_CACM_SSQ.pdf)
31.105 + * additionally arrange that threads enqueuing unmatched data also
31.106 + * block. Dual Transfer Queues support all of these modes, as
31.107 + * dictated by callers.
31.108 + *
31.109 + * A FIFO dual queue may be implemented using a variation of the
31.110 + * Michael & Scott (M&S) lock-free queue algorithm
31.111 + * (http://www.cs.rochester.edu/u/scott/papers/1996_PODC_queues.pdf).
31.112 + * It maintains two pointer fields, "head", pointing to a
31.113 + * (matched) node that in turn points to the first actual
31.114 + * (unmatched) queue node (or null if empty); and "tail" that
31.115 + * points to the last node on the queue (or again null if
31.116 + * empty). For example, here is a possible queue with four data
31.117 + * elements:
31.118 + *
31.119 + * head tail
31.120 + * | |
31.121 + * v v
31.122 + * M -> U -> U -> U -> U
31.123 + *
31.124 + * The M&S queue algorithm is known to be prone to scalability and
31.125 + * overhead limitations when maintaining (via CAS) these head and
31.126 + * tail pointers. This has led to the development of
31.127 + * contention-reducing variants such as elimination arrays (see
31.128 + * Moir et al http://portal.acm.org/citation.cfm?id=1074013) and
31.129 + * optimistic back pointers (see Ladan-Mozes & Shavit
31.130 + * http://people.csail.mit.edu/edya/publications/OptimisticFIFOQueue-journal.pdf).
31.131 + * However, the nature of dual queues enables a simpler tactic for
31.132 + * improving M&S-style implementations when dual-ness is needed.
31.133 + *
31.134 + * In a dual queue, each node must atomically maintain its match
31.135 + * status. While there are other possible variants, we implement
31.136 + * this here as: for a data-mode node, matching entails CASing an
31.137 + * "item" field from a non-null data value to null upon match, and
31.138 + * vice-versa for request nodes, CASing from null to a data
31.139 + * value. (Note that the linearization properties of this style of
31.140 + * queue are easy to verify -- elements are made available by
31.141 + * linking, and unavailable by matching.) Compared to plain M&S
31.142 + * queues, this property of dual queues requires one additional
31.143 + * successful atomic operation per enq/deq pair. But it also
31.144 + * enables lower cost variants of queue maintenance mechanics. (A
31.145 + * variation of this idea applies even for non-dual queues that
31.146 + * support deletion of interior elements, such as
31.147 + * j.u.c.ConcurrentLinkedQueue.)
31.148 + *
31.149 + * Once a node is matched, its match status can never again
31.150 + * change. We may thus arrange that the linked list of them
31.151 + * contain a prefix of zero or more matched nodes, followed by a
31.152 + * suffix of zero or more unmatched nodes. (Note that we allow
31.153 + * both the prefix and suffix to be zero length, which in turn
31.154 + * means that we do not use a dummy header.) If we were not
31.155 + * concerned with either time or space efficiency, we could
31.156 + * correctly perform enqueue and dequeue operations by traversing
31.157 + * from a pointer to the initial node; CASing the item of the
31.158 + * first unmatched node on match and CASing the next field of the
31.159 + * trailing node on appends. (Plus some special-casing when
31.160 + * initially empty). While this would be a terrible idea in
31.161 + * itself, it does have the benefit of not requiring ANY atomic
31.162 + * updates on head/tail fields.
31.163 + *
31.164 + * We introduce here an approach that lies between the extremes of
31.165 + * never versus always updating queue (head and tail) pointers.
31.166 + * This offers a tradeoff between sometimes requiring extra
31.167 + * traversal steps to locate the first and/or last unmatched
31.168 + * nodes, versus the reduced overhead and contention of fewer
31.169 + * updates to queue pointers. For example, a possible snapshot of
31.170 + * a queue is:
31.171 + *
31.172 + * head tail
31.173 + * | |
31.174 + * v v
31.175 + * M -> M -> U -> U -> U -> U
31.176 + *
31.177 + * The best value for this "slack" (the targeted maximum distance
31.178 + * between the value of "head" and the first unmatched node, and
31.179 + * similarly for "tail") is an empirical matter. We have found
31.180 + * that using very small constants in the range of 1-3 work best
31.181 + * over a range of platforms. Larger values introduce increasing
31.182 + * costs of cache misses and risks of long traversal chains, while
31.183 + * smaller values increase CAS contention and overhead.
31.184 + *
31.185 + * Dual queues with slack differ from plain M&S dual queues by
31.186 + * virtue of only sometimes updating head or tail pointers when
31.187 + * matching, appending, or even traversing nodes; in order to
31.188 + * maintain a targeted slack. The idea of "sometimes" may be
31.189 + * operationalized in several ways. The simplest is to use a
31.190 + * per-operation counter incremented on each traversal step, and
31.191 + * to try (via CAS) to update the associated queue pointer
31.192 + * whenever the count exceeds a threshold. Another, that requires
31.193 + * more overhead, is to use random number generators to update
31.194 + * with a given probability per traversal step.
31.195 + *
31.196 + * In any strategy along these lines, because CASes updating
31.197 + * fields may fail, the actual slack may exceed targeted
31.198 + * slack. However, they may be retried at any time to maintain
31.199 + * targets. Even when using very small slack values, this
31.200 + * approach works well for dual queues because it allows all
31.201 + * operations up to the point of matching or appending an item
31.202 + * (hence potentially allowing progress by another thread) to be
31.203 + * read-only, thus not introducing any further contention. As
31.204 + * described below, we implement this by performing slack
31.205 + * maintenance retries only after these points.
31.206 + *
31.207 + * As an accompaniment to such techniques, traversal overhead can
31.208 + * be further reduced without increasing contention of head
31.209 + * pointer updates: Threads may sometimes shortcut the "next" link
31.210 + * path from the current "head" node to be closer to the currently
31.211 + * known first unmatched node, and similarly for tail. Again, this
31.212 + * may be triggered with using thresholds or randomization.
31.213 + *
31.214 + * These ideas must be further extended to avoid unbounded amounts
31.215 + * of costly-to-reclaim garbage caused by the sequential "next"
31.216 + * links of nodes starting at old forgotten head nodes: As first
31.217 + * described in detail by Boehm
31.218 + * (http://portal.acm.org/citation.cfm?doid=503272.503282) if a GC
31.219 + * delays noticing that any arbitrarily old node has become
31.220 + * garbage, all newer dead nodes will also be unreclaimed.
31.221 + * (Similar issues arise in non-GC environments.) To cope with
31.222 + * this in our implementation, upon CASing to advance the head
31.223 + * pointer, we set the "next" link of the previous head to point
31.224 + * only to itself; thus limiting the length of connected dead lists.
31.225 + * (We also take similar care to wipe out possibly garbage
31.226 + * retaining values held in other Node fields.) However, doing so
31.227 + * adds some further complexity to traversal: If any "next"
31.228 + * pointer links to itself, it indicates that the current thread
31.229 + * has lagged behind a head-update, and so the traversal must
31.230 + * continue from the "head". Traversals trying to find the
31.231 + * current tail starting from "tail" may also encounter
31.232 + * self-links, in which case they also continue at "head".
31.233 + *
31.234 + * It is tempting in slack-based scheme to not even use CAS for
31.235 + * updates (similarly to Ladan-Mozes & Shavit). However, this
31.236 + * cannot be done for head updates under the above link-forgetting
31.237 + * mechanics because an update may leave head at a detached node.
31.238 + * And while direct writes are possible for tail updates, they
31.239 + * increase the risk of long retraversals, and hence long garbage
31.240 + * chains, which can be much more costly than is worthwhile
31.241 + * considering that the cost difference of performing a CAS vs
31.242 + * write is smaller when they are not triggered on each operation
31.243 + * (especially considering that writes and CASes equally require
31.244 + * additional GC bookkeeping ("write barriers") that are sometimes
31.245 + * more costly than the writes themselves because of contention).
31.246 + *
31.247 + * *** Overview of implementation ***
31.248 + *
31.249 + * We use a threshold-based approach to updates, with a slack
31.250 + * threshold of two -- that is, we update head/tail when the
31.251 + * current pointer appears to be two or more steps away from the
31.252 + * first/last node. The slack value is hard-wired: a path greater
31.253 + * than one is naturally implemented by checking equality of
31.254 + * traversal pointers except when the list has only one element,
31.255 + * in which case we keep slack threshold at one. Avoiding tracking
31.256 + * explicit counts across method calls slightly simplifies an
31.257 + * already-messy implementation. Using randomization would
31.258 + * probably work better if there were a low-quality dirt-cheap
31.259 + * per-thread one available, but even ThreadLocalRandom is too
31.260 + * heavy for these purposes.
31.261 + *
31.262 + * With such a small slack threshold value, it is not worthwhile
31.263 + * to augment this with path short-circuiting (i.e., unsplicing
31.264 + * interior nodes) except in the case of cancellation/removal (see
31.265 + * below).
31.266 + *
31.267 + * We allow both the head and tail fields to be null before any
31.268 + * nodes are enqueued; initializing upon first append. This
31.269 + * simplifies some other logic, as well as providing more
31.270 + * efficient explicit control paths instead of letting JVMs insert
31.271 + * implicit NullPointerExceptions when they are null. While not
31.272 + * currently fully implemented, we also leave open the possibility
31.273 + * of re-nulling these fields when empty (which is complicated to
31.274 + * arrange, for little benefit.)
31.275 + *
31.276 + * All enqueue/dequeue operations are handled by the single method
31.277 + * "xfer" with parameters indicating whether to act as some form
31.278 + * of offer, put, poll, take, or transfer (each possibly with
31.279 + * timeout). The relative complexity of using one monolithic
31.280 + * method outweighs the code bulk and maintenance problems of
31.281 + * using separate methods for each case.
31.282 + *
31.283 + * Operation consists of up to three phases. The first is
31.284 + * implemented within method xfer, the second in tryAppend, and
31.285 + * the third in method awaitMatch.
31.286 + *
31.287 + * 1. Try to match an existing node
31.288 + *
31.289 + * Starting at head, skip already-matched nodes until finding
31.290 + * an unmatched node of opposite mode, if one exists, in which
31.291 + * case matching it and returning, also if necessary updating
31.292 + * head to one past the matched node (or the node itself if the
31.293 + * list has no other unmatched nodes). If the CAS misses, then
31.294 + * a loop retries advancing head by two steps until either
31.295 + * success or the slack is at most two. By requiring that each
31.296 + * attempt advances head by two (if applicable), we ensure that
31.297 + * the slack does not grow without bound. Traversals also check
31.298 + * if the initial head is now off-list, in which case they
31.299 + * start at the new head.
31.300 + *
31.301 + * If no candidates are found and the call was untimed
31.302 + * poll/offer, (argument "how" is NOW) return.
31.303 + *
31.304 + * 2. Try to append a new node (method tryAppend)
31.305 + *
31.306 + * Starting at current tail pointer, find the actual last node
31.307 + * and try to append a new node (or if head was null, establish
31.308 + * the first node). Nodes can be appended only if their
31.309 + * predecessors are either already matched or are of the same
31.310 + * mode. If we detect otherwise, then a new node with opposite
31.311 + * mode must have been appended during traversal, so we must
31.312 + * restart at phase 1. The traversal and update steps are
31.313 + * otherwise similar to phase 1: Retrying upon CAS misses and
31.314 + * checking for staleness. In particular, if a self-link is
31.315 + * encountered, then we can safely jump to a node on the list
31.316 + * by continuing the traversal at current head.
31.317 + *
31.318 + * On successful append, if the call was ASYNC, return.
31.319 + *
31.320 + * 3. Await match or cancellation (method awaitMatch)
31.321 + *
31.322 + * Wait for another thread to match node; instead cancelling if
31.323 + * the current thread was interrupted or the wait timed out. On
31.324 + * multiprocessors, we use front-of-queue spinning: If a node
31.325 + * appears to be the first unmatched node in the queue, it
31.326 + * spins a bit before blocking. In either case, before blocking
31.327 + * it tries to unsplice any nodes between the current "head"
31.328 + * and the first unmatched node.
31.329 + *
31.330 + * Front-of-queue spinning vastly improves performance of
31.331 + * heavily contended queues. And so long as it is relatively
31.332 + * brief and "quiet", spinning does not much impact performance
31.333 + * of less-contended queues. During spins threads check their
31.334 + * interrupt status and generate a thread-local random number
31.335 + * to decide to occasionally perform a Thread.yield. While
31.336 + * yield has underdefined specs, we assume that might it help,
31.337 + * and will not hurt in limiting impact of spinning on busy
31.338 + * systems. We also use smaller (1/2) spins for nodes that are
31.339 + * not known to be front but whose predecessors have not
31.340 + * blocked -- these "chained" spins avoid artifacts of
31.341 + * front-of-queue rules which otherwise lead to alternating
31.342 + * nodes spinning vs blocking. Further, front threads that
31.343 + * represent phase changes (from data to request node or vice
31.344 + * versa) compared to their predecessors receive additional
31.345 + * chained spins, reflecting longer paths typically required to
31.346 + * unblock threads during phase changes.
31.347 + *
31.348 + *
31.349 + * ** Unlinking removed interior nodes **
31.350 + *
31.351 + * In addition to minimizing garbage retention via self-linking
31.352 + * described above, we also unlink removed interior nodes. These
31.353 + * may arise due to timed out or interrupted waits, or calls to
31.354 + * remove(x) or Iterator.remove. Normally, given a node that was
31.355 + * at one time known to be the predecessor of some node s that is
31.356 + * to be removed, we can unsplice s by CASing the next field of
31.357 + * its predecessor if it still points to s (otherwise s must
31.358 + * already have been removed or is now offlist). But there are two
31.359 + * situations in which we cannot guarantee to make node s
31.360 + * unreachable in this way: (1) If s is the trailing node of list
31.361 + * (i.e., with null next), then it is pinned as the target node
31.362 + * for appends, so can only be removed later after other nodes are
31.363 + * appended. (2) We cannot necessarily unlink s given a
31.364 + * predecessor node that is matched (including the case of being
31.365 + * cancelled): the predecessor may already be unspliced, in which
31.366 + * case some previous reachable node may still point to s.
31.367 + * (For further explanation see Herlihy & Shavit "The Art of
31.368 + * Multiprocessor Programming" chapter 9). Although, in both
31.369 + * cases, we can rule out the need for further action if either s
31.370 + * or its predecessor are (or can be made to be) at, or fall off
31.371 + * from, the head of list.
31.372 + *
31.373 + * Without taking these into account, it would be possible for an
31.374 + * unbounded number of supposedly removed nodes to remain
31.375 + * reachable. Situations leading to such buildup are uncommon but
31.376 + * can occur in practice; for example when a series of short timed
31.377 + * calls to poll repeatedly time out but never otherwise fall off
31.378 + * the list because of an untimed call to take at the front of the
31.379 + * queue.
31.380 + *
31.381 + * When these cases arise, rather than always retraversing the
31.382 + * entire list to find an actual predecessor to unlink (which
31.383 + * won't help for case (1) anyway), we record a conservative
31.384 + * estimate of possible unsplice failures (in "sweepVotes").
31.385 + * We trigger a full sweep when the estimate exceeds a threshold
31.386 + * ("SWEEP_THRESHOLD") indicating the maximum number of estimated
31.387 + * removal failures to tolerate before sweeping through, unlinking
31.388 + * cancelled nodes that were not unlinked upon initial removal.
31.389 + * We perform sweeps by the thread hitting threshold (rather than
31.390 + * background threads or by spreading work to other threads)
31.391 + * because in the main contexts in which removal occurs, the
31.392 + * caller is already timed-out, cancelled, or performing a
31.393 + * potentially O(n) operation (e.g. remove(x)), none of which are
31.394 + * time-critical enough to warrant the overhead that alternatives
31.395 + * would impose on other threads.
31.396 + *
31.397 + * Because the sweepVotes estimate is conservative, and because
31.398 + * nodes become unlinked "naturally" as they fall off the head of
31.399 + * the queue, and because we allow votes to accumulate even while
31.400 + * sweeps are in progress, there are typically significantly fewer
31.401 + * such nodes than estimated. Choice of a threshold value
31.402 + * balances the likelihood of wasted effort and contention, versus
31.403 + * providing a worst-case bound on retention of interior nodes in
31.404 + * quiescent queues. The value defined below was chosen
31.405 + * empirically to balance these under various timeout scenarios.
31.406 + *
31.407 + * Note that we cannot self-link unlinked interior nodes during
31.408 + * sweeps. However, the associated garbage chains terminate when
31.409 + * some successor ultimately falls off the head of the list and is
31.410 + * self-linked.
31.411 + */
31.412 +
31.413 + /** True if on multiprocessor */
31.414 + private static final boolean MP =
31.415 + Runtime.getRuntime().availableProcessors() > 1;
31.416 +
31.417 + /**
31.418 + * The number of times to spin (with randomly interspersed calls
31.419 + * to Thread.yield) on multiprocessor before blocking when a node
31.420 + * is apparently the first waiter in the queue. See above for
31.421 + * explanation. Must be a power of two. The value is empirically
31.422 + * derived -- it works pretty well across a variety of processors,
31.423 + * numbers of CPUs, and OSes.
31.424 + */
31.425 + private static final int FRONT_SPINS = 1 << 7;
31.426 +
31.427 + /**
31.428 + * The number of times to spin before blocking when a node is
31.429 + * preceded by another node that is apparently spinning. Also
31.430 + * serves as an increment to FRONT_SPINS on phase changes, and as
31.431 + * base average frequency for yielding during spins. Must be a
31.432 + * power of two.
31.433 + */
31.434 + private static final int CHAINED_SPINS = FRONT_SPINS >>> 1;
31.435 +
31.436 + /**
31.437 + * The maximum number of estimated removal failures (sweepVotes)
31.438 + * to tolerate before sweeping through the queue unlinking
31.439 + * cancelled nodes that were not unlinked upon initial
31.440 + * removal. See above for explanation. The value must be at least
31.441 + * two to avoid useless sweeps when removing trailing nodes.
31.442 + */
31.443 + static final int SWEEP_THRESHOLD = 32;
31.444 +
31.445 + /**
31.446 + * Queue nodes. Uses Object, not E, for items to allow forgetting
31.447 + * them after use. Relies heavily on Unsafe mechanics to minimize
31.448 + * unnecessary ordering constraints: Writes that are intrinsically
31.449 + * ordered wrt other accesses or CASes use simple relaxed forms.
31.450 + */
31.451 + static final class Node {
31.452 + final boolean isData; // false if this is a request node
31.453 + volatile Object item; // initially non-null if isData; CASed to match
31.454 + volatile Node next;
31.455 + volatile Thread waiter; // null until waiting
31.456 +
31.457 + // CAS methods for fields
31.458 + final boolean casNext(Node cmp, Node val) {
31.459 + return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
31.460 + }
31.461 +
31.462 + final boolean casItem(Object cmp, Object val) {
31.463 + // assert cmp == null || cmp.getClass() != Node.class;
31.464 + return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);
31.465 + }
31.466 +
31.467 + /**
31.468 + * Constructs a new node. Uses relaxed write because item can
31.469 + * only be seen after publication via casNext.
31.470 + */
31.471 + Node(Object item, boolean isData) {
31.472 + UNSAFE.putObject(this, itemOffset, item); // relaxed write
31.473 + this.isData = isData;
31.474 + }
31.475 +
31.476 + /**
31.477 + * Links node to itself to avoid garbage retention. Called
31.478 + * only after CASing head field, so uses relaxed write.
31.479 + */
31.480 + final void forgetNext() {
31.481 + UNSAFE.putObject(this, nextOffset, this);
31.482 + }
31.483 +
31.484 + /**
31.485 + * Sets item to self and waiter to null, to avoid garbage
31.486 + * retention after matching or cancelling. Uses relaxed writes
31.487 + * because order is already constrained in the only calling
31.488 + * contexts: item is forgotten only after volatile/atomic
31.489 + * mechanics that extract items. Similarly, clearing waiter
31.490 + * follows either CAS or return from park (if ever parked;
31.491 + * else we don't care).
31.492 + */
31.493 + final void forgetContents() {
31.494 + UNSAFE.putObject(this, itemOffset, this);
31.495 + UNSAFE.putObject(this, waiterOffset, null);
31.496 + }
31.497 +
31.498 + /**
31.499 + * Returns true if this node has been matched, including the
31.500 + * case of artificial matches due to cancellation.
31.501 + */
31.502 + final boolean isMatched() {
31.503 + Object x = item;
31.504 + return (x == this) || ((x == null) == isData);
31.505 + }
31.506 +
31.507 + /**
31.508 + * Returns true if this is an unmatched request node.
31.509 + */
31.510 + final boolean isUnmatchedRequest() {
31.511 + return !isData && item == null;
31.512 + }
31.513 +
31.514 + /**
31.515 + * Returns true if a node with the given mode cannot be
31.516 + * appended to this node because this node is unmatched and
31.517 + * has opposite data mode.
31.518 + */
31.519 + final boolean cannotPrecede(boolean haveData) {
31.520 + boolean d = isData;
31.521 + Object x;
31.522 + return d != haveData && (x = item) != this && (x != null) == d;
31.523 + }
31.524 +
31.525 + /**
31.526 + * Tries to artificially match a data node -- used by remove.
31.527 + */
31.528 + final boolean tryMatchData() {
31.529 + // assert isData;
31.530 + Object x = item;
31.531 + if (x != null && x != this && casItem(x, null)) {
31.532 + LockSupport.unpark(waiter);
31.533 + return true;
31.534 + }
31.535 + return false;
31.536 + }
31.537 +
31.538 + private static final long serialVersionUID = -3375979862319811754L;
31.539 +
31.540 + // Unsafe mechanics
31.541 + private static final sun.misc.Unsafe UNSAFE;
31.542 + private static final long itemOffset;
31.543 + private static final long nextOffset;
31.544 + private static final long waiterOffset;
31.545 + static {
31.546 + try {
31.547 + UNSAFE = sun.misc.Unsafe.getUnsafe();
31.548 + Class k = Node.class;
31.549 + itemOffset = UNSAFE.objectFieldOffset
31.550 + (k.getDeclaredField("item"));
31.551 + nextOffset = UNSAFE.objectFieldOffset
31.552 + (k.getDeclaredField("next"));
31.553 + waiterOffset = UNSAFE.objectFieldOffset
31.554 + (k.getDeclaredField("waiter"));
31.555 + } catch (Exception e) {
31.556 + throw new Error(e);
31.557 + }
31.558 + }
31.559 + }
31.560 +
31.561 + /** head of the queue; null until first enqueue */
31.562 + transient volatile Node head;
31.563 +
31.564 + /** tail of the queue; null until first append */
31.565 + private transient volatile Node tail;
31.566 +
31.567 + /** The number of apparent failures to unsplice removed nodes */
31.568 + private transient volatile int sweepVotes;
31.569 +
31.570 + // CAS methods for fields
31.571 + private boolean casTail(Node cmp, Node val) {
31.572 + return UNSAFE.compareAndSwapObject(this, tailOffset, cmp, val);
31.573 + }
31.574 +
31.575 + private boolean casHead(Node cmp, Node val) {
31.576 + return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
31.577 + }
31.578 +
31.579 + private boolean casSweepVotes(int cmp, int val) {
31.580 + return UNSAFE.compareAndSwapInt(this, sweepVotesOffset, cmp, val);
31.581 + }
31.582 +
31.583 + /*
31.584 + * Possible values for "how" argument in xfer method.
31.585 + */
31.586 + private static final int NOW = 0; // for untimed poll, tryTransfer
31.587 + private static final int ASYNC = 1; // for offer, put, add
31.588 + private static final int SYNC = 2; // for transfer, take
31.589 + private static final int TIMED = 3; // for timed poll, tryTransfer
31.590 +
31.591 + @SuppressWarnings("unchecked")
31.592 + static <E> E cast(Object item) {
31.593 + // assert item == null || item.getClass() != Node.class;
31.594 + return (E) item;
31.595 + }
31.596 +
31.597 + /**
31.598 + * Implements all queuing methods. See above for explanation.
31.599 + *
31.600 + * @param e the item or null for take
31.601 + * @param haveData true if this is a put, else a take
31.602 + * @param how NOW, ASYNC, SYNC, or TIMED
31.603 + * @param nanos timeout in nanosecs, used only if mode is TIMED
31.604 + * @return an item if matched, else e
31.605 + * @throws NullPointerException if haveData mode but e is null
31.606 + */
31.607 + private E xfer(E e, boolean haveData, int how, long nanos) {
31.608 + if (haveData && (e == null))
31.609 + throw new NullPointerException();
31.610 + Node s = null; // the node to append, if needed
31.611 +
31.612 + retry:
31.613 + for (;;) { // restart on append race
31.614 +
31.615 + for (Node h = head, p = h; p != null;) { // find & match first node
31.616 + boolean isData = p.isData;
31.617 + Object item = p.item;
31.618 + if (item != p && (item != null) == isData) { // unmatched
31.619 + if (isData == haveData) // can't match
31.620 + break;
31.621 + if (p.casItem(item, e)) { // match
31.622 + for (Node q = p; q != h;) {
31.623 + Node n = q.next; // update by 2 unless singleton
31.624 + if (head == h && casHead(h, n == null ? q : n)) {
31.625 + h.forgetNext();
31.626 + break;
31.627 + } // advance and retry
31.628 + if ((h = head) == null ||
31.629 + (q = h.next) == null || !q.isMatched())
31.630 + break; // unless slack < 2
31.631 + }
31.632 + LockSupport.unpark(p.waiter);
31.633 + return this.<E>cast(item);
31.634 + }
31.635 + }
31.636 + Node n = p.next;
31.637 + p = (p != n) ? n : (h = head); // Use head if p offlist
31.638 + }
31.639 +
31.640 + if (how != NOW) { // No matches available
31.641 + if (s == null)
31.642 + s = new Node(e, haveData);
31.643 + Node pred = tryAppend(s, haveData);
31.644 + if (pred == null)
31.645 + continue retry; // lost race vs opposite mode
31.646 + if (how != ASYNC)
31.647 + return awaitMatch(s, pred, e, (how == TIMED), nanos);
31.648 + }
31.649 + return e; // not waiting
31.650 + }
31.651 + }
31.652 +
31.653 + /**
31.654 + * Tries to append node s as tail.
31.655 + *
31.656 + * @param s the node to append
31.657 + * @param haveData true if appending in data mode
31.658 + * @return null on failure due to losing race with append in
31.659 + * different mode, else s's predecessor, or s itself if no
31.660 + * predecessor
31.661 + */
31.662 + private Node tryAppend(Node s, boolean haveData) {
31.663 + for (Node t = tail, p = t;;) { // move p to last node and append
31.664 + Node n, u; // temps for reads of next & tail
31.665 + if (p == null && (p = head) == null) {
31.666 + if (casHead(null, s))
31.667 + return s; // initialize
31.668 + }
31.669 + else if (p.cannotPrecede(haveData))
31.670 + return null; // lost race vs opposite mode
31.671 + else if ((n = p.next) != null) // not last; keep traversing
31.672 + p = p != t && t != (u = tail) ? (t = u) : // stale tail
31.673 + (p != n) ? n : null; // restart if off list
31.674 + else if (!p.casNext(null, s))
31.675 + p = p.next; // re-read on CAS failure
31.676 + else {
31.677 + if (p != t) { // update if slack now >= 2
31.678 + while ((tail != t || !casTail(t, s)) &&
31.679 + (t = tail) != null &&
31.680 + (s = t.next) != null && // advance and retry
31.681 + (s = s.next) != null && s != t);
31.682 + }
31.683 + return p;
31.684 + }
31.685 + }
31.686 + }
31.687 +
31.688 + /**
31.689 + * Spins/yields/blocks until node s is matched or caller gives up.
31.690 + *
31.691 + * @param s the waiting node
31.692 + * @param pred the predecessor of s, or s itself if it has no
31.693 + * predecessor, or null if unknown (the null case does not occur
31.694 + * in any current calls but may in possible future extensions)
31.695 + * @param e the comparison value for checking match
31.696 + * @param timed if true, wait only until timeout elapses
31.697 + * @param nanos timeout in nanosecs, used only if timed is true
31.698 + * @return matched item, or e if unmatched on interrupt or timeout
31.699 + */
31.700 + private E awaitMatch(Node s, Node pred, E e, boolean timed, long nanos) {
31.701 + long lastTime = timed ? System.nanoTime() : 0L;
31.702 + Thread w = Thread.currentThread();
31.703 + int spins = -1; // initialized after first item and cancel checks
31.704 + ThreadLocalRandom randomYields = null; // bound if needed
31.705 +
31.706 + for (;;) {
31.707 + Object item = s.item;
31.708 + if (item != e) { // matched
31.709 + // assert item != s;
31.710 + s.forgetContents(); // avoid garbage
31.711 + return this.<E>cast(item);
31.712 + }
31.713 + if ((w.isInterrupted() || (timed && nanos <= 0)) &&
31.714 + s.casItem(e, s)) { // cancel
31.715 + unsplice(pred, s);
31.716 + return e;
31.717 + }
31.718 +
31.719 + if (spins < 0) { // establish spins at/near front
31.720 + if ((spins = spinsFor(pred, s.isData)) > 0)
31.721 + randomYields = ThreadLocalRandom.current();
31.722 + }
31.723 + else if (spins > 0) { // spin
31.724 + --spins;
31.725 + if (randomYields.nextInt(CHAINED_SPINS) == 0)
31.726 + Thread.yield(); // occasionally yield
31.727 + }
31.728 + else if (s.waiter == null) {
31.729 + s.waiter = w; // request unpark then recheck
31.730 + }
31.731 + else if (timed) {
31.732 + long now = System.nanoTime();
31.733 + if ((nanos -= now - lastTime) > 0)
31.734 + LockSupport.parkNanos(this, nanos);
31.735 + lastTime = now;
31.736 + }
31.737 + else {
31.738 + LockSupport.park(this);
31.739 + }
31.740 + }
31.741 + }
31.742 +
31.743 + /**
31.744 + * Returns spin/yield value for a node with given predecessor and
31.745 + * data mode. See above for explanation.
31.746 + */
31.747 + private static int spinsFor(Node pred, boolean haveData) {
31.748 + if (MP && pred != null) {
31.749 + if (pred.isData != haveData) // phase change
31.750 + return FRONT_SPINS + CHAINED_SPINS;
31.751 + if (pred.isMatched()) // probably at front
31.752 + return FRONT_SPINS;
31.753 + if (pred.waiter == null) // pred apparently spinning
31.754 + return CHAINED_SPINS;
31.755 + }
31.756 + return 0;
31.757 + }
31.758 +
31.759 + /* -------------- Traversal methods -------------- */
31.760 +
31.761 + /**
31.762 + * Returns the successor of p, or the head node if p.next has been
31.763 + * linked to self, which will only be true if traversing with a
31.764 + * stale pointer that is now off the list.
31.765 + */
31.766 + final Node succ(Node p) {
31.767 + Node next = p.next;
31.768 + return (p == next) ? head : next;
31.769 + }
31.770 +
31.771 + /**
31.772 + * Returns the first unmatched node of the given mode, or null if
31.773 + * none. Used by methods isEmpty, hasWaitingConsumer.
31.774 + */
31.775 + private Node firstOfMode(boolean isData) {
31.776 + for (Node p = head; p != null; p = succ(p)) {
31.777 + if (!p.isMatched())
31.778 + return (p.isData == isData) ? p : null;
31.779 + }
31.780 + return null;
31.781 + }
31.782 +
31.783 + /**
31.784 + * Returns the item in the first unmatched node with isData; or
31.785 + * null if none. Used by peek.
31.786 + */
31.787 + private E firstDataItem() {
31.788 + for (Node p = head; p != null; p = succ(p)) {
31.789 + Object item = p.item;
31.790 + if (p.isData) {
31.791 + if (item != null && item != p)
31.792 + return this.<E>cast(item);
31.793 + }
31.794 + else if (item == null)
31.795 + return null;
31.796 + }
31.797 + return null;
31.798 + }
31.799 +
31.800 + /**
31.801 + * Traverses and counts unmatched nodes of the given mode.
31.802 + * Used by methods size and getWaitingConsumerCount.
31.803 + */
31.804 + private int countOfMode(boolean data) {
31.805 + int count = 0;
31.806 + for (Node p = head; p != null; ) {
31.807 + if (!p.isMatched()) {
31.808 + if (p.isData != data)
31.809 + return 0;
31.810 + if (++count == Integer.MAX_VALUE) // saturated
31.811 + break;
31.812 + }
31.813 + Node n = p.next;
31.814 + if (n != p)
31.815 + p = n;
31.816 + else {
31.817 + count = 0;
31.818 + p = head;
31.819 + }
31.820 + }
31.821 + return count;
31.822 + }
31.823 +
31.824 + final class Itr implements Iterator<E> {
31.825 + private Node nextNode; // next node to return item for
31.826 + private E nextItem; // the corresponding item
31.827 + private Node lastRet; // last returned node, to support remove
31.828 + private Node lastPred; // predecessor to unlink lastRet
31.829 +
31.830 + /**
31.831 + * Moves to next node after prev, or first node if prev null.
31.832 + */
31.833 + private void advance(Node prev) {
31.834 + /*
31.835 + * To track and avoid buildup of deleted nodes in the face
31.836 + * of calls to both Queue.remove and Itr.remove, we must
31.837 + * include variants of unsplice and sweep upon each
31.838 + * advance: Upon Itr.remove, we may need to catch up links
31.839 + * from lastPred, and upon other removes, we might need to
31.840 + * skip ahead from stale nodes and unsplice deleted ones
31.841 + * found while advancing.
31.842 + */
31.843 +
31.844 + Node r, b; // reset lastPred upon possible deletion of lastRet
31.845 + if ((r = lastRet) != null && !r.isMatched())
31.846 + lastPred = r; // next lastPred is old lastRet
31.847 + else if ((b = lastPred) == null || b.isMatched())
31.848 + lastPred = null; // at start of list
31.849 + else {
31.850 + Node s, n; // help with removal of lastPred.next
31.851 + while ((s = b.next) != null &&
31.852 + s != b && s.isMatched() &&
31.853 + (n = s.next) != null && n != s)
31.854 + b.casNext(s, n);
31.855 + }
31.856 +
31.857 + this.lastRet = prev;
31.858 +
31.859 + for (Node p = prev, s, n;;) {
31.860 + s = (p == null) ? head : p.next;
31.861 + if (s == null)
31.862 + break;
31.863 + else if (s == p) {
31.864 + p = null;
31.865 + continue;
31.866 + }
31.867 + Object item = s.item;
31.868 + if (s.isData) {
31.869 + if (item != null && item != s) {
31.870 + nextItem = LinkedTransferQueue.<E>cast(item);
31.871 + nextNode = s;
31.872 + return;
31.873 + }
31.874 + }
31.875 + else if (item == null)
31.876 + break;
31.877 + // assert s.isMatched();
31.878 + if (p == null)
31.879 + p = s;
31.880 + else if ((n = s.next) == null)
31.881 + break;
31.882 + else if (s == n)
31.883 + p = null;
31.884 + else
31.885 + p.casNext(s, n);
31.886 + }
31.887 + nextNode = null;
31.888 + nextItem = null;
31.889 + }
31.890 +
31.891 + Itr() {
31.892 + advance(null);
31.893 + }
31.894 +
31.895 + public final boolean hasNext() {
31.896 + return nextNode != null;
31.897 + }
31.898 +
31.899 + public final E next() {
31.900 + Node p = nextNode;
31.901 + if (p == null) throw new NoSuchElementException();
31.902 + E e = nextItem;
31.903 + advance(p);
31.904 + return e;
31.905 + }
31.906 +
31.907 + public final void remove() {
31.908 + final Node lastRet = this.lastRet;
31.909 + if (lastRet == null)
31.910 + throw new IllegalStateException();
31.911 + this.lastRet = null;
31.912 + if (lastRet.tryMatchData())
31.913 + unsplice(lastPred, lastRet);
31.914 + }
31.915 + }
31.916 +
31.917 + /* -------------- Removal methods -------------- */
31.918 +
31.919 + /**
31.920 + * Unsplices (now or later) the given deleted/cancelled node with
31.921 + * the given predecessor.
31.922 + *
31.923 + * @param pred a node that was at one time known to be the
31.924 + * predecessor of s, or null or s itself if s is/was at head
31.925 + * @param s the node to be unspliced
31.926 + */
31.927 + final void unsplice(Node pred, Node s) {
31.928 + s.forgetContents(); // forget unneeded fields
31.929 + /*
31.930 + * See above for rationale. Briefly: if pred still points to
31.931 + * s, try to unlink s. If s cannot be unlinked, because it is
31.932 + * trailing node or pred might be unlinked, and neither pred
31.933 + * nor s are head or offlist, add to sweepVotes, and if enough
31.934 + * votes have accumulated, sweep.
31.935 + */
31.936 + if (pred != null && pred != s && pred.next == s) {
31.937 + Node n = s.next;
31.938 + if (n == null ||
31.939 + (n != s && pred.casNext(s, n) && pred.isMatched())) {
31.940 + for (;;) { // check if at, or could be, head
31.941 + Node h = head;
31.942 + if (h == pred || h == s || h == null)
31.943 + return; // at head or list empty
31.944 + if (!h.isMatched())
31.945 + break;
31.946 + Node hn = h.next;
31.947 + if (hn == null)
31.948 + return; // now empty
31.949 + if (hn != h && casHead(h, hn))
31.950 + h.forgetNext(); // advance head
31.951 + }
31.952 + if (pred.next != pred && s.next != s) { // recheck if offlist
31.953 + for (;;) { // sweep now if enough votes
31.954 + int v = sweepVotes;
31.955 + if (v < SWEEP_THRESHOLD) {
31.956 + if (casSweepVotes(v, v + 1))
31.957 + break;
31.958 + }
31.959 + else if (casSweepVotes(v, 0)) {
31.960 + sweep();
31.961 + break;
31.962 + }
31.963 + }
31.964 + }
31.965 + }
31.966 + }
31.967 + }
31.968 +
31.969 + /**
31.970 + * Unlinks matched (typically cancelled) nodes encountered in a
31.971 + * traversal from head.
31.972 + */
31.973 + private void sweep() {
31.974 + for (Node p = head, s, n; p != null && (s = p.next) != null; ) {
31.975 + if (!s.isMatched())
31.976 + // Unmatched nodes are never self-linked
31.977 + p = s;
31.978 + else if ((n = s.next) == null) // trailing node is pinned
31.979 + break;
31.980 + else if (s == n) // stale
31.981 + // No need to also check for p == s, since that implies s == n
31.982 + p = head;
31.983 + else
31.984 + p.casNext(s, n);
31.985 + }
31.986 + }
31.987 +
31.988 + /**
31.989 + * Main implementation of remove(Object)
31.990 + */
31.991 + private boolean findAndRemove(Object e) {
31.992 + if (e != null) {
31.993 + for (Node pred = null, p = head; p != null; ) {
31.994 + Object item = p.item;
31.995 + if (p.isData) {
31.996 + if (item != null && item != p && e.equals(item) &&
31.997 + p.tryMatchData()) {
31.998 + unsplice(pred, p);
31.999 + return true;
31.1000 + }
31.1001 + }
31.1002 + else if (item == null)
31.1003 + break;
31.1004 + pred = p;
31.1005 + if ((p = p.next) == pred) { // stale
31.1006 + pred = null;
31.1007 + p = head;
31.1008 + }
31.1009 + }
31.1010 + }
31.1011 + return false;
31.1012 + }
31.1013 +
31.1014 +
31.1015 + /**
31.1016 + * Creates an initially empty {@code LinkedTransferQueue}.
31.1017 + */
31.1018 + public LinkedTransferQueue() {
31.1019 + }
31.1020 +
31.1021 + /**
31.1022 + * Creates a {@code LinkedTransferQueue}
31.1023 + * initially containing the elements of the given collection,
31.1024 + * added in traversal order of the collection's iterator.
31.1025 + *
31.1026 + * @param c the collection of elements to initially contain
31.1027 + * @throws NullPointerException if the specified collection or any
31.1028 + * of its elements are null
31.1029 + */
31.1030 + public LinkedTransferQueue(Collection<? extends E> c) {
31.1031 + this();
31.1032 + addAll(c);
31.1033 + }
31.1034 +
31.1035 + /**
31.1036 + * Inserts the specified element at the tail of this queue.
31.1037 + * As the queue is unbounded, this method will never block.
31.1038 + *
31.1039 + * @throws NullPointerException if the specified element is null
31.1040 + */
31.1041 + public void put(E e) {
31.1042 + xfer(e, true, ASYNC, 0);
31.1043 + }
31.1044 +
31.1045 + /**
31.1046 + * Inserts the specified element at the tail of this queue.
31.1047 + * As the queue is unbounded, this method will never block or
31.1048 + * return {@code false}.
31.1049 + *
31.1050 + * @return {@code true} (as specified by
31.1051 + * {@link BlockingQueue#offer(Object,long,TimeUnit) BlockingQueue.offer})
31.1052 + * @throws NullPointerException if the specified element is null
31.1053 + */
31.1054 + public boolean offer(E e, long timeout, TimeUnit unit) {
31.1055 + xfer(e, true, ASYNC, 0);
31.1056 + return true;
31.1057 + }
31.1058 +
31.1059 + /**
31.1060 + * Inserts the specified element at the tail of this queue.
31.1061 + * As the queue is unbounded, this method will never return {@code false}.
31.1062 + *
31.1063 + * @return {@code true} (as specified by {@link Queue#offer})
31.1064 + * @throws NullPointerException if the specified element is null
31.1065 + */
31.1066 + public boolean offer(E e) {
31.1067 + xfer(e, true, ASYNC, 0);
31.1068 + return true;
31.1069 + }
31.1070 +
31.1071 + /**
31.1072 + * Inserts the specified element at the tail of this queue.
31.1073 + * As the queue is unbounded, this method will never throw
31.1074 + * {@link IllegalStateException} or return {@code false}.
31.1075 + *
31.1076 + * @return {@code true} (as specified by {@link Collection#add})
31.1077 + * @throws NullPointerException if the specified element is null
31.1078 + */
31.1079 + public boolean add(E e) {
31.1080 + xfer(e, true, ASYNC, 0);
31.1081 + return true;
31.1082 + }
31.1083 +
31.1084 + /**
31.1085 + * Transfers the element to a waiting consumer immediately, if possible.
31.1086 + *
31.1087 + * <p>More precisely, transfers the specified element immediately
31.1088 + * if there exists a consumer already waiting to receive it (in
31.1089 + * {@link #take} or timed {@link #poll(long,TimeUnit) poll}),
31.1090 + * otherwise returning {@code false} without enqueuing the element.
31.1091 + *
31.1092 + * @throws NullPointerException if the specified element is null
31.1093 + */
31.1094 + public boolean tryTransfer(E e) {
31.1095 + return xfer(e, true, NOW, 0) == null;
31.1096 + }
31.1097 +
31.1098 + /**
31.1099 + * Transfers the element to a consumer, waiting if necessary to do so.
31.1100 + *
31.1101 + * <p>More precisely, transfers the specified element immediately
31.1102 + * if there exists a consumer already waiting to receive it (in
31.1103 + * {@link #take} or timed {@link #poll(long,TimeUnit) poll}),
31.1104 + * else inserts the specified element at the tail of this queue
31.1105 + * and waits until the element is received by a consumer.
31.1106 + *
31.1107 + * @throws NullPointerException if the specified element is null
31.1108 + */
31.1109 + public void transfer(E e) throws InterruptedException {
31.1110 + if (xfer(e, true, SYNC, 0) != null) {
31.1111 + Thread.interrupted(); // failure possible only due to interrupt
31.1112 + throw new InterruptedException();
31.1113 + }
31.1114 + }
31.1115 +
31.1116 + /**
31.1117 + * Transfers the element to a consumer if it is possible to do so
31.1118 + * before the timeout elapses.
31.1119 + *
31.1120 + * <p>More precisely, transfers the specified element immediately
31.1121 + * if there exists a consumer already waiting to receive it (in
31.1122 + * {@link #take} or timed {@link #poll(long,TimeUnit) poll}),
31.1123 + * else inserts the specified element at the tail of this queue
31.1124 + * and waits until the element is received by a consumer,
31.1125 + * returning {@code false} if the specified wait time elapses
31.1126 + * before the element can be transferred.
31.1127 + *
31.1128 + * @throws NullPointerException if the specified element is null
31.1129 + */
31.1130 + public boolean tryTransfer(E e, long timeout, TimeUnit unit)
31.1131 + throws InterruptedException {
31.1132 + if (xfer(e, true, TIMED, unit.toNanos(timeout)) == null)
31.1133 + return true;
31.1134 + if (!Thread.interrupted())
31.1135 + return false;
31.1136 + throw new InterruptedException();
31.1137 + }
31.1138 +
31.1139 + public E take() throws InterruptedException {
31.1140 + E e = xfer(null, false, SYNC, 0);
31.1141 + if (e != null)
31.1142 + return e;
31.1143 + Thread.interrupted();
31.1144 + throw new InterruptedException();
31.1145 + }
31.1146 +
31.1147 + public E poll(long timeout, TimeUnit unit) throws InterruptedException {
31.1148 + E e = xfer(null, false, TIMED, unit.toNanos(timeout));
31.1149 + if (e != null || !Thread.interrupted())
31.1150 + return e;
31.1151 + throw new InterruptedException();
31.1152 + }
31.1153 +
31.1154 + public E poll() {
31.1155 + return xfer(null, false, NOW, 0);
31.1156 + }
31.1157 +
31.1158 + /**
31.1159 + * @throws NullPointerException {@inheritDoc}
31.1160 + * @throws IllegalArgumentException {@inheritDoc}
31.1161 + */
31.1162 + public int drainTo(Collection<? super E> c) {
31.1163 + if (c == null)
31.1164 + throw new NullPointerException();
31.1165 + if (c == this)
31.1166 + throw new IllegalArgumentException();
31.1167 + int n = 0;
31.1168 + E e;
31.1169 + while ( (e = poll()) != null) {
31.1170 + c.add(e);
31.1171 + ++n;
31.1172 + }
31.1173 + return n;
31.1174 + }
31.1175 +
31.1176 + /**
31.1177 + * @throws NullPointerException {@inheritDoc}
31.1178 + * @throws IllegalArgumentException {@inheritDoc}
31.1179 + */
31.1180 + public int drainTo(Collection<? super E> c, int maxElements) {
31.1181 + if (c == null)
31.1182 + throw new NullPointerException();
31.1183 + if (c == this)
31.1184 + throw new IllegalArgumentException();
31.1185 + int n = 0;
31.1186 + E e;
31.1187 + while (n < maxElements && (e = poll()) != null) {
31.1188 + c.add(e);
31.1189 + ++n;
31.1190 + }
31.1191 + return n;
31.1192 + }
31.1193 +
31.1194 + /**
31.1195 + * Returns an iterator over the elements in this queue in proper sequence.
31.1196 + * The elements will be returned in order from first (head) to last (tail).
31.1197 + *
31.1198 + * <p>The returned iterator is a "weakly consistent" iterator that
31.1199 + * will never throw {@link java.util.ConcurrentModificationException
31.1200 + * ConcurrentModificationException}, and guarantees to traverse
31.1201 + * elements as they existed upon construction of the iterator, and
31.1202 + * may (but is not guaranteed to) reflect any modifications
31.1203 + * subsequent to construction.
31.1204 + *
31.1205 + * @return an iterator over the elements in this queue in proper sequence
31.1206 + */
31.1207 + public Iterator<E> iterator() {
31.1208 + return new Itr();
31.1209 + }
31.1210 +
31.1211 + public E peek() {
31.1212 + return firstDataItem();
31.1213 + }
31.1214 +
31.1215 + /**
31.1216 + * Returns {@code true} if this queue contains no elements.
31.1217 + *
31.1218 + * @return {@code true} if this queue contains no elements
31.1219 + */
31.1220 + public boolean isEmpty() {
31.1221 + for (Node p = head; p != null; p = succ(p)) {
31.1222 + if (!p.isMatched())
31.1223 + return !p.isData;
31.1224 + }
31.1225 + return true;
31.1226 + }
31.1227 +
31.1228 + public boolean hasWaitingConsumer() {
31.1229 + return firstOfMode(false) != null;
31.1230 + }
31.1231 +
31.1232 + /**
31.1233 + * Returns the number of elements in this queue. If this queue
31.1234 + * contains more than {@code Integer.MAX_VALUE} elements, returns
31.1235 + * {@code Integer.MAX_VALUE}.
31.1236 + *
31.1237 + * <p>Beware that, unlike in most collections, this method is
31.1238 + * <em>NOT</em> a constant-time operation. Because of the
31.1239 + * asynchronous nature of these queues, determining the current
31.1240 + * number of elements requires an O(n) traversal.
31.1241 + *
31.1242 + * @return the number of elements in this queue
31.1243 + */
31.1244 + public int size() {
31.1245 + return countOfMode(true);
31.1246 + }
31.1247 +
31.1248 + public int getWaitingConsumerCount() {
31.1249 + return countOfMode(false);
31.1250 + }
31.1251 +
31.1252 + /**
31.1253 + * Removes a single instance of the specified element from this queue,
31.1254 + * if it is present. More formally, removes an element {@code e} such
31.1255 + * that {@code o.equals(e)}, if this queue contains one or more such
31.1256 + * elements.
31.1257 + * Returns {@code true} if this queue contained the specified element
31.1258 + * (or equivalently, if this queue changed as a result of the call).
31.1259 + *
31.1260 + * @param o element to be removed from this queue, if present
31.1261 + * @return {@code true} if this queue changed as a result of the call
31.1262 + */
31.1263 + public boolean remove(Object o) {
31.1264 + return findAndRemove(o);
31.1265 + }
31.1266 +
31.1267 + /**
31.1268 + * Returns {@code true} if this queue contains the specified element.
31.1269 + * More formally, returns {@code true} if and only if this queue contains
31.1270 + * at least one element {@code e} such that {@code o.equals(e)}.
31.1271 + *
31.1272 + * @param o object to be checked for containment in this queue
31.1273 + * @return {@code true} if this queue contains the specified element
31.1274 + */
31.1275 + public boolean contains(Object o) {
31.1276 + if (o == null) return false;
31.1277 + for (Node p = head; p != null; p = succ(p)) {
31.1278 + Object item = p.item;
31.1279 + if (p.isData) {
31.1280 + if (item != null && item != p && o.equals(item))
31.1281 + return true;
31.1282 + }
31.1283 + else if (item == null)
31.1284 + break;
31.1285 + }
31.1286 + return false;
31.1287 + }
31.1288 +
31.1289 + /**
31.1290 + * Always returns {@code Integer.MAX_VALUE} because a
31.1291 + * {@code LinkedTransferQueue} is not capacity constrained.
31.1292 + *
31.1293 + * @return {@code Integer.MAX_VALUE} (as specified by
31.1294 + * {@link BlockingQueue#remainingCapacity()})
31.1295 + */
31.1296 + public int remainingCapacity() {
31.1297 + return Integer.MAX_VALUE;
31.1298 + }
31.1299 +
31.1300 + /**
31.1301 + * Saves the state to a stream (that is, serializes it).
31.1302 + *
31.1303 + * @serialData All of the elements (each an {@code E}) in
31.1304 + * the proper order, followed by a null
31.1305 + * @param s the stream
31.1306 + */
31.1307 + private void writeObject(java.io.ObjectOutputStream s)
31.1308 + throws java.io.IOException {
31.1309 + s.defaultWriteObject();
31.1310 + for (E e : this)
31.1311 + s.writeObject(e);
31.1312 + // Use trailing null as sentinel
31.1313 + s.writeObject(null);
31.1314 + }
31.1315 +
31.1316 + /**
31.1317 + * Reconstitutes the Queue instance from a stream (that is,
31.1318 + * deserializes it).
31.1319 + *
31.1320 + * @param s the stream
31.1321 + */
31.1322 + private void readObject(java.io.ObjectInputStream s)
31.1323 + throws java.io.IOException, ClassNotFoundException {
31.1324 + s.defaultReadObject();
31.1325 + for (;;) {
31.1326 + @SuppressWarnings("unchecked") E item = (E) s.readObject();
31.1327 + if (item == null)
31.1328 + break;
31.1329 + else
31.1330 + offer(item);
31.1331 + }
31.1332 + }
31.1333 +
31.1334 + // Unsafe mechanics
31.1335 +
31.1336 + private static final sun.misc.Unsafe UNSAFE;
31.1337 + private static final long headOffset;
31.1338 + private static final long tailOffset;
31.1339 + private static final long sweepVotesOffset;
31.1340 + static {
31.1341 + try {
31.1342 + UNSAFE = sun.misc.Unsafe.getUnsafe();
31.1343 + Class k = LinkedTransferQueue.class;
31.1344 + headOffset = UNSAFE.objectFieldOffset
31.1345 + (k.getDeclaredField("head"));
31.1346 + tailOffset = UNSAFE.objectFieldOffset
31.1347 + (k.getDeclaredField("tail"));
31.1348 + sweepVotesOffset = UNSAFE.objectFieldOffset
31.1349 + (k.getDeclaredField("sweepVotes"));
31.1350 + } catch (Exception e) {
31.1351 + throw new Error(e);
31.1352 + }
31.1353 + }
31.1354 +}
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
32.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/Phaser.java Sat Mar 19 10:48:29 2016 +0100
32.3 @@ -0,0 +1,1152 @@
32.4 +/*
32.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
32.6 + *
32.7 + * This code is free software; you can redistribute it and/or modify it
32.8 + * under the terms of the GNU General Public License version 2 only, as
32.9 + * published by the Free Software Foundation. Oracle designates this
32.10 + * particular file as subject to the "Classpath" exception as provided
32.11 + * by Oracle in the LICENSE file that accompanied this code.
32.12 + *
32.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
32.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
32.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
32.16 + * version 2 for more details (a copy is included in the LICENSE file that
32.17 + * accompanied this code).
32.18 + *
32.19 + * You should have received a copy of the GNU General Public License version
32.20 + * 2 along with this work; if not, write to the Free Software Foundation,
32.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
32.22 + *
32.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
32.24 + * or visit www.oracle.com if you need additional information or have any
32.25 + * questions.
32.26 + */
32.27 +
32.28 +/*
32.29 + * This file is available under and governed by the GNU General Public
32.30 + * License version 2 only, as published by the Free Software Foundation.
32.31 + * However, the following notice accompanied the original version of this
32.32 + * file:
32.33 + *
32.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
32.35 + * Expert Group and released to the public domain, as explained at
32.36 + * http://creativecommons.org/publicdomain/zero/1.0/
32.37 + */
32.38 +
32.39 +package java.util.concurrent;
32.40 +
32.41 +import java.util.concurrent.TimeUnit;
32.42 +import java.util.concurrent.TimeoutException;
32.43 +import java.util.concurrent.atomic.AtomicReference;
32.44 +import java.util.concurrent.locks.LockSupport;
32.45 +
32.46 +/**
32.47 + * A reusable synchronization barrier, similar in functionality to
32.48 + * {@link java.util.concurrent.CyclicBarrier CyclicBarrier} and
32.49 + * {@link java.util.concurrent.CountDownLatch CountDownLatch}
32.50 + * but supporting more flexible usage.
32.51 + *
32.52 + * <p> <b>Registration.</b> Unlike the case for other barriers, the
32.53 + * number of parties <em>registered</em> to synchronize on a phaser
32.54 + * may vary over time. Tasks may be registered at any time (using
32.55 + * methods {@link #register}, {@link #bulkRegister}, or forms of
32.56 + * constructors establishing initial numbers of parties), and
32.57 + * optionally deregistered upon any arrival (using {@link
32.58 + * #arriveAndDeregister}). As is the case with most basic
32.59 + * synchronization constructs, registration and deregistration affect
32.60 + * only internal counts; they do not establish any further internal
32.61 + * bookkeeping, so tasks cannot query whether they are registered.
32.62 + * (However, you can introduce such bookkeeping by subclassing this
32.63 + * class.)
32.64 + *
32.65 + * <p> <b>Synchronization.</b> Like a {@code CyclicBarrier}, a {@code
32.66 + * Phaser} may be repeatedly awaited. Method {@link
32.67 + * #arriveAndAwaitAdvance} has effect analogous to {@link
32.68 + * java.util.concurrent.CyclicBarrier#await CyclicBarrier.await}. Each
32.69 + * generation of a phaser has an associated phase number. The phase
32.70 + * number starts at zero, and advances when all parties arrive at the
32.71 + * phaser, wrapping around to zero after reaching {@code
32.72 + * Integer.MAX_VALUE}. The use of phase numbers enables independent
32.73 + * control of actions upon arrival at a phaser and upon awaiting
32.74 + * others, via two kinds of methods that may be invoked by any
32.75 + * registered party:
32.76 + *
32.77 + * <ul>
32.78 + *
32.79 + * <li> <b>Arrival.</b> Methods {@link #arrive} and
32.80 + * {@link #arriveAndDeregister} record arrival. These methods
32.81 + * do not block, but return an associated <em>arrival phase
32.82 + * number</em>; that is, the phase number of the phaser to which
32.83 + * the arrival applied. When the final party for a given phase
32.84 + * arrives, an optional action is performed and the phase
32.85 + * advances. These actions are performed by the party
32.86 + * triggering a phase advance, and are arranged by overriding
32.87 + * method {@link #onAdvance(int, int)}, which also controls
32.88 + * termination. Overriding this method is similar to, but more
32.89 + * flexible than, providing a barrier action to a {@code
32.90 + * CyclicBarrier}.
32.91 + *
32.92 + * <li> <b>Waiting.</b> Method {@link #awaitAdvance} requires an
32.93 + * argument indicating an arrival phase number, and returns when
32.94 + * the phaser advances to (or is already at) a different phase.
32.95 + * Unlike similar constructions using {@code CyclicBarrier},
32.96 + * method {@code awaitAdvance} continues to wait even if the
32.97 + * waiting thread is interrupted. Interruptible and timeout
32.98 + * versions are also available, but exceptions encountered while
32.99 + * tasks wait interruptibly or with timeout do not change the
32.100 + * state of the phaser. If necessary, you can perform any
32.101 + * associated recovery within handlers of those exceptions,
32.102 + * often after invoking {@code forceTermination}. Phasers may
32.103 + * also be used by tasks executing in a {@link ForkJoinPool},
32.104 + * which will ensure sufficient parallelism to execute tasks
32.105 + * when others are blocked waiting for a phase to advance.
32.106 + *
32.107 + * </ul>
32.108 + *
32.109 + * <p> <b>Termination.</b> A phaser may enter a <em>termination</em>
32.110 + * state, that may be checked using method {@link #isTerminated}. Upon
32.111 + * termination, all synchronization methods immediately return without
32.112 + * waiting for advance, as indicated by a negative return value.
32.113 + * Similarly, attempts to register upon termination have no effect.
32.114 + * Termination is triggered when an invocation of {@code onAdvance}
32.115 + * returns {@code true}. The default implementation returns {@code
32.116 + * true} if a deregistration has caused the number of registered
32.117 + * parties to become zero. As illustrated below, when phasers control
32.118 + * actions with a fixed number of iterations, it is often convenient
32.119 + * to override this method to cause termination when the current phase
32.120 + * number reaches a threshold. Method {@link #forceTermination} is
32.121 + * also available to abruptly release waiting threads and allow them
32.122 + * to terminate.
32.123 + *
32.124 + * <p> <b>Tiering.</b> Phasers may be <em>tiered</em> (i.e.,
32.125 + * constructed in tree structures) to reduce contention. Phasers with
32.126 + * large numbers of parties that would otherwise experience heavy
32.127 + * synchronization contention costs may instead be set up so that
32.128 + * groups of sub-phasers share a common parent. This may greatly
32.129 + * increase throughput even though it incurs greater per-operation
32.130 + * overhead.
32.131 + *
32.132 + * <p>In a tree of tiered phasers, registration and deregistration of
32.133 + * child phasers with their parent are managed automatically.
32.134 + * Whenever the number of registered parties of a child phaser becomes
32.135 + * non-zero (as established in the {@link #Phaser(Phaser,int)}
32.136 + * constructor, {@link #register}, or {@link #bulkRegister}), the
32.137 + * child phaser is registered with its parent. Whenever the number of
32.138 + * registered parties becomes zero as the result of an invocation of
32.139 + * {@link #arriveAndDeregister}, the child phaser is deregistered
32.140 + * from its parent.
32.141 + *
32.142 + * <p><b>Monitoring.</b> While synchronization methods may be invoked
32.143 + * only by registered parties, the current state of a phaser may be
32.144 + * monitored by any caller. At any given moment there are {@link
32.145 + * #getRegisteredParties} parties in total, of which {@link
32.146 + * #getArrivedParties} have arrived at the current phase ({@link
32.147 + * #getPhase}). When the remaining ({@link #getUnarrivedParties})
32.148 + * parties arrive, the phase advances. The values returned by these
32.149 + * methods may reflect transient states and so are not in general
32.150 + * useful for synchronization control. Method {@link #toString}
32.151 + * returns snapshots of these state queries in a form convenient for
32.152 + * informal monitoring.
32.153 + *
32.154 + * <p><b>Sample usages:</b>
32.155 + *
32.156 + * <p>A {@code Phaser} may be used instead of a {@code CountDownLatch}
32.157 + * to control a one-shot action serving a variable number of parties.
32.158 + * The typical idiom is for the method setting this up to first
32.159 + * register, then start the actions, then deregister, as in:
32.160 + *
32.161 + * <pre> {@code
32.162 + * void runTasks(List<Runnable> tasks) {
32.163 + * final Phaser phaser = new Phaser(1); // "1" to register self
32.164 + * // create and start threads
32.165 + * for (final Runnable task : tasks) {
32.166 + * phaser.register();
32.167 + * new Thread() {
32.168 + * public void run() {
32.169 + * phaser.arriveAndAwaitAdvance(); // await all creation
32.170 + * task.run();
32.171 + * }
32.172 + * }.start();
32.173 + * }
32.174 + *
32.175 + * // allow threads to start and deregister self
32.176 + * phaser.arriveAndDeregister();
32.177 + * }}</pre>
32.178 + *
32.179 + * <p>One way to cause a set of threads to repeatedly perform actions
32.180 + * for a given number of iterations is to override {@code onAdvance}:
32.181 + *
32.182 + * <pre> {@code
32.183 + * void startTasks(List<Runnable> tasks, final int iterations) {
32.184 + * final Phaser phaser = new Phaser() {
32.185 + * protected boolean onAdvance(int phase, int registeredParties) {
32.186 + * return phase >= iterations || registeredParties == 0;
32.187 + * }
32.188 + * };
32.189 + * phaser.register();
32.190 + * for (final Runnable task : tasks) {
32.191 + * phaser.register();
32.192 + * new Thread() {
32.193 + * public void run() {
32.194 + * do {
32.195 + * task.run();
32.196 + * phaser.arriveAndAwaitAdvance();
32.197 + * } while (!phaser.isTerminated());
32.198 + * }
32.199 + * }.start();
32.200 + * }
32.201 + * phaser.arriveAndDeregister(); // deregister self, don't wait
32.202 + * }}</pre>
32.203 + *
32.204 + * If the main task must later await termination, it
32.205 + * may re-register and then execute a similar loop:
32.206 + * <pre> {@code
32.207 + * // ...
32.208 + * phaser.register();
32.209 + * while (!phaser.isTerminated())
32.210 + * phaser.arriveAndAwaitAdvance();}</pre>
32.211 + *
32.212 + * <p>Related constructions may be used to await particular phase numbers
32.213 + * in contexts where you are sure that the phase will never wrap around
32.214 + * {@code Integer.MAX_VALUE}. For example:
32.215 + *
32.216 + * <pre> {@code
32.217 + * void awaitPhase(Phaser phaser, int phase) {
32.218 + * int p = phaser.register(); // assumes caller not already registered
32.219 + * while (p < phase) {
32.220 + * if (phaser.isTerminated())
32.221 + * // ... deal with unexpected termination
32.222 + * else
32.223 + * p = phaser.arriveAndAwaitAdvance();
32.224 + * }
32.225 + * phaser.arriveAndDeregister();
32.226 + * }}</pre>
32.227 + *
32.228 + *
32.229 + * <p>To create a set of {@code n} tasks using a tree of phasers, you
32.230 + * could use code of the following form, assuming a Task class with a
32.231 + * constructor accepting a {@code Phaser} that it registers with upon
32.232 + * construction. After invocation of {@code build(new Task[n], 0, n,
32.233 + * new Phaser())}, these tasks could then be started, for example by
32.234 + * submitting to a pool:
32.235 + *
32.236 + * <pre> {@code
32.237 + * void build(Task[] tasks, int lo, int hi, Phaser ph) {
32.238 + * if (hi - lo > TASKS_PER_PHASER) {
32.239 + * for (int i = lo; i < hi; i += TASKS_PER_PHASER) {
32.240 + * int j = Math.min(i + TASKS_PER_PHASER, hi);
32.241 + * build(tasks, i, j, new Phaser(ph));
32.242 + * }
32.243 + * } else {
32.244 + * for (int i = lo; i < hi; ++i)
32.245 + * tasks[i] = new Task(ph);
32.246 + * // assumes new Task(ph) performs ph.register()
32.247 + * }
32.248 + * }}</pre>
32.249 + *
32.250 + * The best value of {@code TASKS_PER_PHASER} depends mainly on
32.251 + * expected synchronization rates. A value as low as four may
32.252 + * be appropriate for extremely small per-phase task bodies (thus
32.253 + * high rates), or up to hundreds for extremely large ones.
32.254 + *
32.255 + * <p><b>Implementation notes</b>: This implementation restricts the
32.256 + * maximum number of parties to 65535. Attempts to register additional
32.257 + * parties result in {@code IllegalStateException}. However, you can and
32.258 + * should create tiered phasers to accommodate arbitrarily large sets
32.259 + * of participants.
32.260 + *
32.261 + * @since 1.7
32.262 + * @author Doug Lea
32.263 + */
32.264 +public class Phaser {
32.265 + /*
32.266 + * This class implements an extension of X10 "clocks". Thanks to
32.267 + * Vijay Saraswat for the idea, and to Vivek Sarkar for
32.268 + * enhancements to extend functionality.
32.269 + */
32.270 +
32.271 + /**
32.272 + * Primary state representation, holding four bit-fields:
32.273 + *
32.274 + * unarrived -- the number of parties yet to hit barrier (bits 0-15)
32.275 + * parties -- the number of parties to wait (bits 16-31)
32.276 + * phase -- the generation of the barrier (bits 32-62)
32.277 + * terminated -- set if barrier is terminated (bit 63 / sign)
32.278 + *
32.279 + * Except that a phaser with no registered parties is
32.280 + * distinguished by the otherwise illegal state of having zero
32.281 + * parties and one unarrived parties (encoded as EMPTY below).
32.282 + *
32.283 + * To efficiently maintain atomicity, these values are packed into
32.284 + * a single (atomic) long. Good performance relies on keeping
32.285 + * state decoding and encoding simple, and keeping race windows
32.286 + * short.
32.287 + *
32.288 + * All state updates are performed via CAS except initial
32.289 + * registration of a sub-phaser (i.e., one with a non-null
32.290 + * parent). In this (relatively rare) case, we use built-in
32.291 + * synchronization to lock while first registering with its
32.292 + * parent.
32.293 + *
32.294 + * The phase of a subphaser is allowed to lag that of its
32.295 + * ancestors until it is actually accessed -- see method
32.296 + * reconcileState.
32.297 + */
32.298 + private volatile long state;
32.299 +
32.300 + private static final int MAX_PARTIES = 0xffff;
32.301 + private static final int MAX_PHASE = Integer.MAX_VALUE;
32.302 + private static final int PARTIES_SHIFT = 16;
32.303 + private static final int PHASE_SHIFT = 32;
32.304 + private static final int UNARRIVED_MASK = 0xffff; // to mask ints
32.305 + private static final long PARTIES_MASK = 0xffff0000L; // to mask longs
32.306 + private static final long TERMINATION_BIT = 1L << 63;
32.307 +
32.308 + // some special values
32.309 + private static final int ONE_ARRIVAL = 1;
32.310 + private static final int ONE_PARTY = 1 << PARTIES_SHIFT;
32.311 + private static final int EMPTY = 1;
32.312 +
32.313 + // The following unpacking methods are usually manually inlined
32.314 +
32.315 + private static int unarrivedOf(long s) {
32.316 + int counts = (int)s;
32.317 + return (counts == EMPTY) ? 0 : counts & UNARRIVED_MASK;
32.318 + }
32.319 +
32.320 + private static int partiesOf(long s) {
32.321 + return (int)s >>> PARTIES_SHIFT;
32.322 + }
32.323 +
32.324 + private static int phaseOf(long s) {
32.325 + return (int)(s >>> PHASE_SHIFT);
32.326 + }
32.327 +
32.328 + private static int arrivedOf(long s) {
32.329 + int counts = (int)s;
32.330 + return (counts == EMPTY) ? 0 :
32.331 + (counts >>> PARTIES_SHIFT) - (counts & UNARRIVED_MASK);
32.332 + }
32.333 +
32.334 + /**
32.335 + * The parent of this phaser, or null if none
32.336 + */
32.337 + private final Phaser parent;
32.338 +
32.339 + /**
32.340 + * The root of phaser tree. Equals this if not in a tree.
32.341 + */
32.342 + private final Phaser root;
32.343 +
32.344 + /**
32.345 + * Heads of Treiber stacks for waiting threads. To eliminate
32.346 + * contention when releasing some threads while adding others, we
32.347 + * use two of them, alternating across even and odd phases.
32.348 + * Subphasers share queues with root to speed up releases.
32.349 + */
32.350 + private final AtomicReference<QNode> evenQ;
32.351 + private final AtomicReference<QNode> oddQ;
32.352 +
32.353 + private AtomicReference<QNode> queueFor(int phase) {
32.354 + return ((phase & 1) == 0) ? evenQ : oddQ;
32.355 + }
32.356 +
32.357 + /**
32.358 + * Returns message string for bounds exceptions on arrival.
32.359 + */
32.360 + private String badArrive(long s) {
32.361 + return "Attempted arrival of unregistered party for " +
32.362 + stateToString(s);
32.363 + }
32.364 +
32.365 + /**
32.366 + * Returns message string for bounds exceptions on registration.
32.367 + */
32.368 + private String badRegister(long s) {
32.369 + return "Attempt to register more than " +
32.370 + MAX_PARTIES + " parties for " + stateToString(s);
32.371 + }
32.372 +
32.373 + /**
32.374 + * Main implementation for methods arrive and arriveAndDeregister.
32.375 + * Manually tuned to speed up and minimize race windows for the
32.376 + * common case of just decrementing unarrived field.
32.377 + *
32.378 + * @param deregister false for arrive, true for arriveAndDeregister
32.379 + */
32.380 + private int doArrive(boolean deregister) {
32.381 + int adj = deregister ? ONE_ARRIVAL|ONE_PARTY : ONE_ARRIVAL;
32.382 + final Phaser root = this.root;
32.383 + for (;;) {
32.384 + long s = (root == this) ? state : reconcileState();
32.385 + int phase = (int)(s >>> PHASE_SHIFT);
32.386 + int counts = (int)s;
32.387 + int unarrived = (counts & UNARRIVED_MASK) - 1;
32.388 + if (phase < 0)
32.389 + return phase;
32.390 + else if (counts == EMPTY || unarrived < 0) {
32.391 + if (root == this || reconcileState() == s)
32.392 + throw new IllegalStateException(badArrive(s));
32.393 + }
32.394 + else if (UNSAFE.compareAndSwapLong(this, stateOffset, s, s-=adj)) {
32.395 + if (unarrived == 0) {
32.396 + long n = s & PARTIES_MASK; // base of next state
32.397 + int nextUnarrived = (int)n >>> PARTIES_SHIFT;
32.398 + if (root != this)
32.399 + return parent.doArrive(nextUnarrived == 0);
32.400 + if (onAdvance(phase, nextUnarrived))
32.401 + n |= TERMINATION_BIT;
32.402 + else if (nextUnarrived == 0)
32.403 + n |= EMPTY;
32.404 + else
32.405 + n |= nextUnarrived;
32.406 + n |= (long)((phase + 1) & MAX_PHASE) << PHASE_SHIFT;
32.407 + UNSAFE.compareAndSwapLong(this, stateOffset, s, n);
32.408 + releaseWaiters(phase);
32.409 + }
32.410 + return phase;
32.411 + }
32.412 + }
32.413 + }
32.414 +
32.415 + /**
32.416 + * Implementation of register, bulkRegister
32.417 + *
32.418 + * @param registrations number to add to both parties and
32.419 + * unarrived fields. Must be greater than zero.
32.420 + */
32.421 + private int doRegister(int registrations) {
32.422 + // adjustment to state
32.423 + long adj = ((long)registrations << PARTIES_SHIFT) | registrations;
32.424 + final Phaser parent = this.parent;
32.425 + int phase;
32.426 + for (;;) {
32.427 + long s = state;
32.428 + int counts = (int)s;
32.429 + int parties = counts >>> PARTIES_SHIFT;
32.430 + int unarrived = counts & UNARRIVED_MASK;
32.431 + if (registrations > MAX_PARTIES - parties)
32.432 + throw new IllegalStateException(badRegister(s));
32.433 + else if ((phase = (int)(s >>> PHASE_SHIFT)) < 0)
32.434 + break;
32.435 + else if (counts != EMPTY) { // not 1st registration
32.436 + if (parent == null || reconcileState() == s) {
32.437 + if (unarrived == 0) // wait out advance
32.438 + root.internalAwaitAdvance(phase, null);
32.439 + else if (UNSAFE.compareAndSwapLong(this, stateOffset,
32.440 + s, s + adj))
32.441 + break;
32.442 + }
32.443 + }
32.444 + else if (parent == null) { // 1st root registration
32.445 + long next = ((long)phase << PHASE_SHIFT) | adj;
32.446 + if (UNSAFE.compareAndSwapLong(this, stateOffset, s, next))
32.447 + break;
32.448 + }
32.449 + else {
32.450 + synchronized (this) { // 1st sub registration
32.451 + if (state == s) { // recheck under lock
32.452 + parent.doRegister(1);
32.453 + do { // force current phase
32.454 + phase = (int)(root.state >>> PHASE_SHIFT);
32.455 + // assert phase < 0 || (int)state == EMPTY;
32.456 + } while (!UNSAFE.compareAndSwapLong
32.457 + (this, stateOffset, state,
32.458 + ((long)phase << PHASE_SHIFT) | adj));
32.459 + break;
32.460 + }
32.461 + }
32.462 + }
32.463 + }
32.464 + return phase;
32.465 + }
32.466 +
32.467 + /**
32.468 + * Resolves lagged phase propagation from root if necessary.
32.469 + * Reconciliation normally occurs when root has advanced but
32.470 + * subphasers have not yet done so, in which case they must finish
32.471 + * their own advance by setting unarrived to parties (or if
32.472 + * parties is zero, resetting to unregistered EMPTY state).
32.473 + * However, this method may also be called when "floating"
32.474 + * subphasers with possibly some unarrived parties are merely
32.475 + * catching up to current phase, in which case counts are
32.476 + * unaffected.
32.477 + *
32.478 + * @return reconciled state
32.479 + */
32.480 + private long reconcileState() {
32.481 + final Phaser root = this.root;
32.482 + long s = state;
32.483 + if (root != this) {
32.484 + int phase, u, p;
32.485 + // CAS root phase with current parties; possibly trip unarrived
32.486 + while ((phase = (int)(root.state >>> PHASE_SHIFT)) !=
32.487 + (int)(s >>> PHASE_SHIFT) &&
32.488 + !UNSAFE.compareAndSwapLong
32.489 + (this, stateOffset, s,
32.490 + s = (((long)phase << PHASE_SHIFT) |
32.491 + (s & PARTIES_MASK) |
32.492 + ((p = (int)s >>> PARTIES_SHIFT) == 0 ? EMPTY :
32.493 + (u = (int)s & UNARRIVED_MASK) == 0 ? p : u))))
32.494 + s = state;
32.495 + }
32.496 + return s;
32.497 + }
32.498 +
32.499 + /**
32.500 + * Creates a new phaser with no initially registered parties, no
32.501 + * parent, and initial phase number 0. Any thread using this
32.502 + * phaser will need to first register for it.
32.503 + */
32.504 + public Phaser() {
32.505 + this(null, 0);
32.506 + }
32.507 +
32.508 + /**
32.509 + * Creates a new phaser with the given number of registered
32.510 + * unarrived parties, no parent, and initial phase number 0.
32.511 + *
32.512 + * @param parties the number of parties required to advance to the
32.513 + * next phase
32.514 + * @throws IllegalArgumentException if parties less than zero
32.515 + * or greater than the maximum number of parties supported
32.516 + */
32.517 + public Phaser(int parties) {
32.518 + this(null, parties);
32.519 + }
32.520 +
32.521 + /**
32.522 + * Equivalent to {@link #Phaser(Phaser, int) Phaser(parent, 0)}.
32.523 + *
32.524 + * @param parent the parent phaser
32.525 + */
32.526 + public Phaser(Phaser parent) {
32.527 + this(parent, 0);
32.528 + }
32.529 +
32.530 + /**
32.531 + * Creates a new phaser with the given parent and number of
32.532 + * registered unarrived parties. When the given parent is non-null
32.533 + * and the given number of parties is greater than zero, this
32.534 + * child phaser is registered with its parent.
32.535 + *
32.536 + * @param parent the parent phaser
32.537 + * @param parties the number of parties required to advance to the
32.538 + * next phase
32.539 + * @throws IllegalArgumentException if parties less than zero
32.540 + * or greater than the maximum number of parties supported
32.541 + */
32.542 + public Phaser(Phaser parent, int parties) {
32.543 + if (parties >>> PARTIES_SHIFT != 0)
32.544 + throw new IllegalArgumentException("Illegal number of parties");
32.545 + int phase = 0;
32.546 + this.parent = parent;
32.547 + if (parent != null) {
32.548 + final Phaser root = parent.root;
32.549 + this.root = root;
32.550 + this.evenQ = root.evenQ;
32.551 + this.oddQ = root.oddQ;
32.552 + if (parties != 0)
32.553 + phase = parent.doRegister(1);
32.554 + }
32.555 + else {
32.556 + this.root = this;
32.557 + this.evenQ = new AtomicReference<QNode>();
32.558 + this.oddQ = new AtomicReference<QNode>();
32.559 + }
32.560 + this.state = (parties == 0) ? (long)EMPTY :
32.561 + ((long)phase << PHASE_SHIFT) |
32.562 + ((long)parties << PARTIES_SHIFT) |
32.563 + ((long)parties);
32.564 + }
32.565 +
32.566 + /**
32.567 + * Adds a new unarrived party to this phaser. If an ongoing
32.568 + * invocation of {@link #onAdvance} is in progress, this method
32.569 + * may await its completion before returning. If this phaser has
32.570 + * a parent, and this phaser previously had no registered parties,
32.571 + * this child phaser is also registered with its parent. If
32.572 + * this phaser is terminated, the attempt to register has
32.573 + * no effect, and a negative value is returned.
32.574 + *
32.575 + * @return the arrival phase number to which this registration
32.576 + * applied. If this value is negative, then this phaser has
32.577 + * terminated, in which case registration has no effect.
32.578 + * @throws IllegalStateException if attempting to register more
32.579 + * than the maximum supported number of parties
32.580 + */
32.581 + public int register() {
32.582 + return doRegister(1);
32.583 + }
32.584 +
32.585 + /**
32.586 + * Adds the given number of new unarrived parties to this phaser.
32.587 + * If an ongoing invocation of {@link #onAdvance} is in progress,
32.588 + * this method may await its completion before returning. If this
32.589 + * phaser has a parent, and the given number of parties is greater
32.590 + * than zero, and this phaser previously had no registered
32.591 + * parties, this child phaser is also registered with its parent.
32.592 + * If this phaser is terminated, the attempt to register has no
32.593 + * effect, and a negative value is returned.
32.594 + *
32.595 + * @param parties the number of additional parties required to
32.596 + * advance to the next phase
32.597 + * @return the arrival phase number to which this registration
32.598 + * applied. If this value is negative, then this phaser has
32.599 + * terminated, in which case registration has no effect.
32.600 + * @throws IllegalStateException if attempting to register more
32.601 + * than the maximum supported number of parties
32.602 + * @throws IllegalArgumentException if {@code parties < 0}
32.603 + */
32.604 + public int bulkRegister(int parties) {
32.605 + if (parties < 0)
32.606 + throw new IllegalArgumentException();
32.607 + if (parties == 0)
32.608 + return getPhase();
32.609 + return doRegister(parties);
32.610 + }
32.611 +
32.612 + /**
32.613 + * Arrives at this phaser, without waiting for others to arrive.
32.614 + *
32.615 + * <p>It is a usage error for an unregistered party to invoke this
32.616 + * method. However, this error may result in an {@code
32.617 + * IllegalStateException} only upon some subsequent operation on
32.618 + * this phaser, if ever.
32.619 + *
32.620 + * @return the arrival phase number, or a negative value if terminated
32.621 + * @throws IllegalStateException if not terminated and the number
32.622 + * of unarrived parties would become negative
32.623 + */
32.624 + public int arrive() {
32.625 + return doArrive(false);
32.626 + }
32.627 +
32.628 + /**
32.629 + * Arrives at this phaser and deregisters from it without waiting
32.630 + * for others to arrive. Deregistration reduces the number of
32.631 + * parties required to advance in future phases. If this phaser
32.632 + * has a parent, and deregistration causes this phaser to have
32.633 + * zero parties, this phaser is also deregistered from its parent.
32.634 + *
32.635 + * <p>It is a usage error for an unregistered party to invoke this
32.636 + * method. However, this error may result in an {@code
32.637 + * IllegalStateException} only upon some subsequent operation on
32.638 + * this phaser, if ever.
32.639 + *
32.640 + * @return the arrival phase number, or a negative value if terminated
32.641 + * @throws IllegalStateException if not terminated and the number
32.642 + * of registered or unarrived parties would become negative
32.643 + */
32.644 + public int arriveAndDeregister() {
32.645 + return doArrive(true);
32.646 + }
32.647 +
32.648 + /**
32.649 + * Arrives at this phaser and awaits others. Equivalent in effect
32.650 + * to {@code awaitAdvance(arrive())}. If you need to await with
32.651 + * interruption or timeout, you can arrange this with an analogous
32.652 + * construction using one of the other forms of the {@code
32.653 + * awaitAdvance} method. If instead you need to deregister upon
32.654 + * arrival, use {@code awaitAdvance(arriveAndDeregister())}.
32.655 + *
32.656 + * <p>It is a usage error for an unregistered party to invoke this
32.657 + * method. However, this error may result in an {@code
32.658 + * IllegalStateException} only upon some subsequent operation on
32.659 + * this phaser, if ever.
32.660 + *
32.661 + * @return the arrival phase number, or the (negative)
32.662 + * {@linkplain #getPhase() current phase} if terminated
32.663 + * @throws IllegalStateException if not terminated and the number
32.664 + * of unarrived parties would become negative
32.665 + */
32.666 + public int arriveAndAwaitAdvance() {
32.667 + // Specialization of doArrive+awaitAdvance eliminating some reads/paths
32.668 + final Phaser root = this.root;
32.669 + for (;;) {
32.670 + long s = (root == this) ? state : reconcileState();
32.671 + int phase = (int)(s >>> PHASE_SHIFT);
32.672 + int counts = (int)s;
32.673 + int unarrived = (counts & UNARRIVED_MASK) - 1;
32.674 + if (phase < 0)
32.675 + return phase;
32.676 + else if (counts == EMPTY || unarrived < 0) {
32.677 + if (reconcileState() == s)
32.678 + throw new IllegalStateException(badArrive(s));
32.679 + }
32.680 + else if (UNSAFE.compareAndSwapLong(this, stateOffset, s,
32.681 + s -= ONE_ARRIVAL)) {
32.682 + if (unarrived != 0)
32.683 + return root.internalAwaitAdvance(phase, null);
32.684 + if (root != this)
32.685 + return parent.arriveAndAwaitAdvance();
32.686 + long n = s & PARTIES_MASK; // base of next state
32.687 + int nextUnarrived = (int)n >>> PARTIES_SHIFT;
32.688 + if (onAdvance(phase, nextUnarrived))
32.689 + n |= TERMINATION_BIT;
32.690 + else if (nextUnarrived == 0)
32.691 + n |= EMPTY;
32.692 + else
32.693 + n |= nextUnarrived;
32.694 + int nextPhase = (phase + 1) & MAX_PHASE;
32.695 + n |= (long)nextPhase << PHASE_SHIFT;
32.696 + if (!UNSAFE.compareAndSwapLong(this, stateOffset, s, n))
32.697 + return (int)(state >>> PHASE_SHIFT); // terminated
32.698 + releaseWaiters(phase);
32.699 + return nextPhase;
32.700 + }
32.701 + }
32.702 + }
32.703 +
32.704 + /**
32.705 + * Awaits the phase of this phaser to advance from the given phase
32.706 + * value, returning immediately if the current phase is not equal
32.707 + * to the given phase value or this phaser is terminated.
32.708 + *
32.709 + * @param phase an arrival phase number, or negative value if
32.710 + * terminated; this argument is normally the value returned by a
32.711 + * previous call to {@code arrive} or {@code arriveAndDeregister}.
32.712 + * @return the next arrival phase number, or the argument if it is
32.713 + * negative, or the (negative) {@linkplain #getPhase() current phase}
32.714 + * if terminated
32.715 + */
32.716 + public int awaitAdvance(int phase) {
32.717 + final Phaser root = this.root;
32.718 + long s = (root == this) ? state : reconcileState();
32.719 + int p = (int)(s >>> PHASE_SHIFT);
32.720 + if (phase < 0)
32.721 + return phase;
32.722 + if (p == phase)
32.723 + return root.internalAwaitAdvance(phase, null);
32.724 + return p;
32.725 + }
32.726 +
32.727 + /**
32.728 + * Awaits the phase of this phaser to advance from the given phase
32.729 + * value, throwing {@code InterruptedException} if interrupted
32.730 + * while waiting, or returning immediately if the current phase is
32.731 + * not equal to the given phase value or this phaser is
32.732 + * terminated.
32.733 + *
32.734 + * @param phase an arrival phase number, or negative value if
32.735 + * terminated; this argument is normally the value returned by a
32.736 + * previous call to {@code arrive} or {@code arriveAndDeregister}.
32.737 + * @return the next arrival phase number, or the argument if it is
32.738 + * negative, or the (negative) {@linkplain #getPhase() current phase}
32.739 + * if terminated
32.740 + * @throws InterruptedException if thread interrupted while waiting
32.741 + */
32.742 + public int awaitAdvanceInterruptibly(int phase)
32.743 + throws InterruptedException {
32.744 + final Phaser root = this.root;
32.745 + long s = (root == this) ? state : reconcileState();
32.746 + int p = (int)(s >>> PHASE_SHIFT);
32.747 + if (phase < 0)
32.748 + return phase;
32.749 + if (p == phase) {
32.750 + QNode node = new QNode(this, phase, true, false, 0L);
32.751 + p = root.internalAwaitAdvance(phase, node);
32.752 + if (node.wasInterrupted)
32.753 + throw new InterruptedException();
32.754 + }
32.755 + return p;
32.756 + }
32.757 +
32.758 + /**
32.759 + * Awaits the phase of this phaser to advance from the given phase
32.760 + * value or the given timeout to elapse, throwing {@code
32.761 + * InterruptedException} if interrupted while waiting, or
32.762 + * returning immediately if the current phase is not equal to the
32.763 + * given phase value or this phaser is terminated.
32.764 + *
32.765 + * @param phase an arrival phase number, or negative value if
32.766 + * terminated; this argument is normally the value returned by a
32.767 + * previous call to {@code arrive} or {@code arriveAndDeregister}.
32.768 + * @param timeout how long to wait before giving up, in units of
32.769 + * {@code unit}
32.770 + * @param unit a {@code TimeUnit} determining how to interpret the
32.771 + * {@code timeout} parameter
32.772 + * @return the next arrival phase number, or the argument if it is
32.773 + * negative, or the (negative) {@linkplain #getPhase() current phase}
32.774 + * if terminated
32.775 + * @throws InterruptedException if thread interrupted while waiting
32.776 + * @throws TimeoutException if timed out while waiting
32.777 + */
32.778 + public int awaitAdvanceInterruptibly(int phase,
32.779 + long timeout, TimeUnit unit)
32.780 + throws InterruptedException, TimeoutException {
32.781 + long nanos = unit.toNanos(timeout);
32.782 + final Phaser root = this.root;
32.783 + long s = (root == this) ? state : reconcileState();
32.784 + int p = (int)(s >>> PHASE_SHIFT);
32.785 + if (phase < 0)
32.786 + return phase;
32.787 + if (p == phase) {
32.788 + QNode node = new QNode(this, phase, true, true, nanos);
32.789 + p = root.internalAwaitAdvance(phase, node);
32.790 + if (node.wasInterrupted)
32.791 + throw new InterruptedException();
32.792 + else if (p == phase)
32.793 + throw new TimeoutException();
32.794 + }
32.795 + return p;
32.796 + }
32.797 +
32.798 + /**
32.799 + * Forces this phaser to enter termination state. Counts of
32.800 + * registered parties are unaffected. If this phaser is a member
32.801 + * of a tiered set of phasers, then all of the phasers in the set
32.802 + * are terminated. If this phaser is already terminated, this
32.803 + * method has no effect. This method may be useful for
32.804 + * coordinating recovery after one or more tasks encounter
32.805 + * unexpected exceptions.
32.806 + */
32.807 + public void forceTermination() {
32.808 + // Only need to change root state
32.809 + final Phaser root = this.root;
32.810 + long s;
32.811 + while ((s = root.state) >= 0) {
32.812 + if (UNSAFE.compareAndSwapLong(root, stateOffset,
32.813 + s, s | TERMINATION_BIT)) {
32.814 + // signal all threads
32.815 + releaseWaiters(0);
32.816 + releaseWaiters(1);
32.817 + return;
32.818 + }
32.819 + }
32.820 + }
32.821 +
32.822 + /**
32.823 + * Returns the current phase number. The maximum phase number is
32.824 + * {@code Integer.MAX_VALUE}, after which it restarts at
32.825 + * zero. Upon termination, the phase number is negative,
32.826 + * in which case the prevailing phase prior to termination
32.827 + * may be obtained via {@code getPhase() + Integer.MIN_VALUE}.
32.828 + *
32.829 + * @return the phase number, or a negative value if terminated
32.830 + */
32.831 + public final int getPhase() {
32.832 + return (int)(root.state >>> PHASE_SHIFT);
32.833 + }
32.834 +
32.835 + /**
32.836 + * Returns the number of parties registered at this phaser.
32.837 + *
32.838 + * @return the number of parties
32.839 + */
32.840 + public int getRegisteredParties() {
32.841 + return partiesOf(state);
32.842 + }
32.843 +
32.844 + /**
32.845 + * Returns the number of registered parties that have arrived at
32.846 + * the current phase of this phaser. If this phaser has terminated,
32.847 + * the returned value is meaningless and arbitrary.
32.848 + *
32.849 + * @return the number of arrived parties
32.850 + */
32.851 + public int getArrivedParties() {
32.852 + return arrivedOf(reconcileState());
32.853 + }
32.854 +
32.855 + /**
32.856 + * Returns the number of registered parties that have not yet
32.857 + * arrived at the current phase of this phaser. If this phaser has
32.858 + * terminated, the returned value is meaningless and arbitrary.
32.859 + *
32.860 + * @return the number of unarrived parties
32.861 + */
32.862 + public int getUnarrivedParties() {
32.863 + return unarrivedOf(reconcileState());
32.864 + }
32.865 +
32.866 + /**
32.867 + * Returns the parent of this phaser, or {@code null} if none.
32.868 + *
32.869 + * @return the parent of this phaser, or {@code null} if none
32.870 + */
32.871 + public Phaser getParent() {
32.872 + return parent;
32.873 + }
32.874 +
32.875 + /**
32.876 + * Returns the root ancestor of this phaser, which is the same as
32.877 + * this phaser if it has no parent.
32.878 + *
32.879 + * @return the root ancestor of this phaser
32.880 + */
32.881 + public Phaser getRoot() {
32.882 + return root;
32.883 + }
32.884 +
32.885 + /**
32.886 + * Returns {@code true} if this phaser has been terminated.
32.887 + *
32.888 + * @return {@code true} if this phaser has been terminated
32.889 + */
32.890 + public boolean isTerminated() {
32.891 + return root.state < 0L;
32.892 + }
32.893 +
32.894 + /**
32.895 + * Overridable method to perform an action upon impending phase
32.896 + * advance, and to control termination. This method is invoked
32.897 + * upon arrival of the party advancing this phaser (when all other
32.898 + * waiting parties are dormant). If this method returns {@code
32.899 + * true}, this phaser will be set to a final termination state
32.900 + * upon advance, and subsequent calls to {@link #isTerminated}
32.901 + * will return true. Any (unchecked) Exception or Error thrown by
32.902 + * an invocation of this method is propagated to the party
32.903 + * attempting to advance this phaser, in which case no advance
32.904 + * occurs.
32.905 + *
32.906 + * <p>The arguments to this method provide the state of the phaser
32.907 + * prevailing for the current transition. The effects of invoking
32.908 + * arrival, registration, and waiting methods on this phaser from
32.909 + * within {@code onAdvance} are unspecified and should not be
32.910 + * relied on.
32.911 + *
32.912 + * <p>If this phaser is a member of a tiered set of phasers, then
32.913 + * {@code onAdvance} is invoked only for its root phaser on each
32.914 + * advance.
32.915 + *
32.916 + * <p>To support the most common use cases, the default
32.917 + * implementation of this method returns {@code true} when the
32.918 + * number of registered parties has become zero as the result of a
32.919 + * party invoking {@code arriveAndDeregister}. You can disable
32.920 + * this behavior, thus enabling continuation upon future
32.921 + * registrations, by overriding this method to always return
32.922 + * {@code false}:
32.923 + *
32.924 + * <pre> {@code
32.925 + * Phaser phaser = new Phaser() {
32.926 + * protected boolean onAdvance(int phase, int parties) { return false; }
32.927 + * }}</pre>
32.928 + *
32.929 + * @param phase the current phase number on entry to this method,
32.930 + * before this phaser is advanced
32.931 + * @param registeredParties the current number of registered parties
32.932 + * @return {@code true} if this phaser should terminate
32.933 + */
32.934 + protected boolean onAdvance(int phase, int registeredParties) {
32.935 + return registeredParties == 0;
32.936 + }
32.937 +
32.938 + /**
32.939 + * Returns a string identifying this phaser, as well as its
32.940 + * state. The state, in brackets, includes the String {@code
32.941 + * "phase = "} followed by the phase number, {@code "parties = "}
32.942 + * followed by the number of registered parties, and {@code
32.943 + * "arrived = "} followed by the number of arrived parties.
32.944 + *
32.945 + * @return a string identifying this phaser, as well as its state
32.946 + */
32.947 + public String toString() {
32.948 + return stateToString(reconcileState());
32.949 + }
32.950 +
32.951 + /**
32.952 + * Implementation of toString and string-based error messages
32.953 + */
32.954 + private String stateToString(long s) {
32.955 + return super.toString() +
32.956 + "[phase = " + phaseOf(s) +
32.957 + " parties = " + partiesOf(s) +
32.958 + " arrived = " + arrivedOf(s) + "]";
32.959 + }
32.960 +
32.961 + // Waiting mechanics
32.962 +
32.963 + /**
32.964 + * Removes and signals threads from queue for phase.
32.965 + */
32.966 + private void releaseWaiters(int phase) {
32.967 + QNode q; // first element of queue
32.968 + Thread t; // its thread
32.969 + AtomicReference<QNode> head = (phase & 1) == 0 ? evenQ : oddQ;
32.970 + while ((q = head.get()) != null &&
32.971 + q.phase != (int)(root.state >>> PHASE_SHIFT)) {
32.972 + if (head.compareAndSet(q, q.next) &&
32.973 + (t = q.thread) != null) {
32.974 + q.thread = null;
32.975 + LockSupport.unpark(t);
32.976 + }
32.977 + }
32.978 + }
32.979 +
32.980 + /**
32.981 + * Variant of releaseWaiters that additionally tries to remove any
32.982 + * nodes no longer waiting for advance due to timeout or
32.983 + * interrupt. Currently, nodes are removed only if they are at
32.984 + * head of queue, which suffices to reduce memory footprint in
32.985 + * most usages.
32.986 + *
32.987 + * @return current phase on exit
32.988 + */
32.989 + private int abortWait(int phase) {
32.990 + AtomicReference<QNode> head = (phase & 1) == 0 ? evenQ : oddQ;
32.991 + for (;;) {
32.992 + Thread t;
32.993 + QNode q = head.get();
32.994 + int p = (int)(root.state >>> PHASE_SHIFT);
32.995 + if (q == null || ((t = q.thread) != null && q.phase == p))
32.996 + return p;
32.997 + if (head.compareAndSet(q, q.next) && t != null) {
32.998 + q.thread = null;
32.999 + LockSupport.unpark(t);
32.1000 + }
32.1001 + }
32.1002 + }
32.1003 +
32.1004 + /** The number of CPUs, for spin control */
32.1005 + private static final int NCPU = Runtime.getRuntime().availableProcessors();
32.1006 +
32.1007 + /**
32.1008 + * The number of times to spin before blocking while waiting for
32.1009 + * advance, per arrival while waiting. On multiprocessors, fully
32.1010 + * blocking and waking up a large number of threads all at once is
32.1011 + * usually a very slow process, so we use rechargeable spins to
32.1012 + * avoid it when threads regularly arrive: When a thread in
32.1013 + * internalAwaitAdvance notices another arrival before blocking,
32.1014 + * and there appear to be enough CPUs available, it spins
32.1015 + * SPINS_PER_ARRIVAL more times before blocking. The value trades
32.1016 + * off good-citizenship vs big unnecessary slowdowns.
32.1017 + */
32.1018 + static final int SPINS_PER_ARRIVAL = (NCPU < 2) ? 1 : 1 << 8;
32.1019 +
32.1020 + /**
32.1021 + * Possibly blocks and waits for phase to advance unless aborted.
32.1022 + * Call only from root node.
32.1023 + *
32.1024 + * @param phase current phase
32.1025 + * @param node if non-null, the wait node to track interrupt and timeout;
32.1026 + * if null, denotes noninterruptible wait
32.1027 + * @return current phase
32.1028 + */
32.1029 + private int internalAwaitAdvance(int phase, QNode node) {
32.1030 + releaseWaiters(phase-1); // ensure old queue clean
32.1031 + boolean queued = false; // true when node is enqueued
32.1032 + int lastUnarrived = 0; // to increase spins upon change
32.1033 + int spins = SPINS_PER_ARRIVAL;
32.1034 + long s;
32.1035 + int p;
32.1036 + while ((p = (int)((s = state) >>> PHASE_SHIFT)) == phase) {
32.1037 + if (node == null) { // spinning in noninterruptible mode
32.1038 + int unarrived = (int)s & UNARRIVED_MASK;
32.1039 + if (unarrived != lastUnarrived &&
32.1040 + (lastUnarrived = unarrived) < NCPU)
32.1041 + spins += SPINS_PER_ARRIVAL;
32.1042 + boolean interrupted = Thread.interrupted();
32.1043 + if (interrupted || --spins < 0) { // need node to record intr
32.1044 + node = new QNode(this, phase, false, false, 0L);
32.1045 + node.wasInterrupted = interrupted;
32.1046 + }
32.1047 + }
32.1048 + else if (node.isReleasable()) // done or aborted
32.1049 + break;
32.1050 + else if (!queued) { // push onto queue
32.1051 + AtomicReference<QNode> head = (phase & 1) == 0 ? evenQ : oddQ;
32.1052 + QNode q = node.next = head.get();
32.1053 + if ((q == null || q.phase == phase) &&
32.1054 + (int)(state >>> PHASE_SHIFT) == phase) // avoid stale enq
32.1055 + queued = head.compareAndSet(q, node);
32.1056 + }
32.1057 + else {
32.1058 + try {
32.1059 + ForkJoinPool.managedBlock(node);
32.1060 + } catch (InterruptedException ie) {
32.1061 + node.wasInterrupted = true;
32.1062 + }
32.1063 + }
32.1064 + }
32.1065 +
32.1066 + if (node != null) {
32.1067 + if (node.thread != null)
32.1068 + node.thread = null; // avoid need for unpark()
32.1069 + if (node.wasInterrupted && !node.interruptible)
32.1070 + Thread.currentThread().interrupt();
32.1071 + if (p == phase && (p = (int)(state >>> PHASE_SHIFT)) == phase)
32.1072 + return abortWait(phase); // possibly clean up on abort
32.1073 + }
32.1074 + releaseWaiters(phase);
32.1075 + return p;
32.1076 + }
32.1077 +
32.1078 + /**
32.1079 + * Wait nodes for Treiber stack representing wait queue
32.1080 + */
32.1081 + static final class QNode implements ForkJoinPool.ManagedBlocker {
32.1082 + final Phaser phaser;
32.1083 + final int phase;
32.1084 + final boolean interruptible;
32.1085 + final boolean timed;
32.1086 + boolean wasInterrupted;
32.1087 + long nanos;
32.1088 + long lastTime;
32.1089 + volatile Thread thread; // nulled to cancel wait
32.1090 + QNode next;
32.1091 +
32.1092 + QNode(Phaser phaser, int phase, boolean interruptible,
32.1093 + boolean timed, long nanos) {
32.1094 + this.phaser = phaser;
32.1095 + this.phase = phase;
32.1096 + this.interruptible = interruptible;
32.1097 + this.nanos = nanos;
32.1098 + this.timed = timed;
32.1099 + this.lastTime = timed ? System.nanoTime() : 0L;
32.1100 + thread = Thread.currentThread();
32.1101 + }
32.1102 +
32.1103 + public boolean isReleasable() {
32.1104 + if (thread == null)
32.1105 + return true;
32.1106 + if (phaser.getPhase() != phase) {
32.1107 + thread = null;
32.1108 + return true;
32.1109 + }
32.1110 + if (Thread.interrupted())
32.1111 + wasInterrupted = true;
32.1112 + if (wasInterrupted && interruptible) {
32.1113 + thread = null;
32.1114 + return true;
32.1115 + }
32.1116 + if (timed) {
32.1117 + if (nanos > 0L) {
32.1118 + long now = System.nanoTime();
32.1119 + nanos -= now - lastTime;
32.1120 + lastTime = now;
32.1121 + }
32.1122 + if (nanos <= 0L) {
32.1123 + thread = null;
32.1124 + return true;
32.1125 + }
32.1126 + }
32.1127 + return false;
32.1128 + }
32.1129 +
32.1130 + public boolean block() {
32.1131 + if (isReleasable())
32.1132 + return true;
32.1133 + else if (!timed)
32.1134 + LockSupport.park(this);
32.1135 + else if (nanos > 0)
32.1136 + LockSupport.parkNanos(this, nanos);
32.1137 + return isReleasable();
32.1138 + }
32.1139 + }
32.1140 +
32.1141 + // Unsafe mechanics
32.1142 +
32.1143 + private static final sun.misc.Unsafe UNSAFE;
32.1144 + private static final long stateOffset;
32.1145 + static {
32.1146 + try {
32.1147 + UNSAFE = sun.misc.Unsafe.getUnsafe();
32.1148 + Class k = Phaser.class;
32.1149 + stateOffset = UNSAFE.objectFieldOffset
32.1150 + (k.getDeclaredField("state"));
32.1151 + } catch (Exception e) {
32.1152 + throw new Error(e);
32.1153 + }
32.1154 + }
32.1155 +}
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
33.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/PriorityBlockingQueue.java Sat Mar 19 10:48:29 2016 +0100
33.3 @@ -0,0 +1,978 @@
33.4 +/*
33.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
33.6 + *
33.7 + * This code is free software; you can redistribute it and/or modify it
33.8 + * under the terms of the GNU General Public License version 2 only, as
33.9 + * published by the Free Software Foundation. Oracle designates this
33.10 + * particular file as subject to the "Classpath" exception as provided
33.11 + * by Oracle in the LICENSE file that accompanied this code.
33.12 + *
33.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
33.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
33.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
33.16 + * version 2 for more details (a copy is included in the LICENSE file that
33.17 + * accompanied this code).
33.18 + *
33.19 + * You should have received a copy of the GNU General Public License version
33.20 + * 2 along with this work; if not, write to the Free Software Foundation,
33.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
33.22 + *
33.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
33.24 + * or visit www.oracle.com if you need additional information or have any
33.25 + * questions.
33.26 + */
33.27 +
33.28 +/*
33.29 + * This file is available under and governed by the GNU General Public
33.30 + * License version 2 only, as published by the Free Software Foundation.
33.31 + * However, the following notice accompanied the original version of this
33.32 + * file:
33.33 + *
33.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
33.35 + * Expert Group and released to the public domain, as explained at
33.36 + * http://creativecommons.org/publicdomain/zero/1.0/
33.37 + */
33.38 +
33.39 +package java.util.concurrent;
33.40 +
33.41 +import java.util.concurrent.locks.*;
33.42 +import java.util.*;
33.43 +
33.44 +/**
33.45 + * An unbounded {@linkplain BlockingQueue blocking queue} that uses
33.46 + * the same ordering rules as class {@link PriorityQueue} and supplies
33.47 + * blocking retrieval operations. While this queue is logically
33.48 + * unbounded, attempted additions may fail due to resource exhaustion
33.49 + * (causing {@code OutOfMemoryError}). This class does not permit
33.50 + * {@code null} elements. A priority queue relying on {@linkplain
33.51 + * Comparable natural ordering} also does not permit insertion of
33.52 + * non-comparable objects (doing so results in
33.53 + * {@code ClassCastException}).
33.54 + *
33.55 + * <p>This class and its iterator implement all of the
33.56 + * <em>optional</em> methods of the {@link Collection} and {@link
33.57 + * Iterator} interfaces. The Iterator provided in method {@link
33.58 + * #iterator()} is <em>not</em> guaranteed to traverse the elements of
33.59 + * the PriorityBlockingQueue in any particular order. If you need
33.60 + * ordered traversal, consider using
33.61 + * {@code Arrays.sort(pq.toArray())}. Also, method {@code drainTo}
33.62 + * can be used to <em>remove</em> some or all elements in priority
33.63 + * order and place them in another collection.
33.64 + *
33.65 + * <p>Operations on this class make no guarantees about the ordering
33.66 + * of elements with equal priority. If you need to enforce an
33.67 + * ordering, you can define custom classes or comparators that use a
33.68 + * secondary key to break ties in primary priority values. For
33.69 + * example, here is a class that applies first-in-first-out
33.70 + * tie-breaking to comparable elements. To use it, you would insert a
33.71 + * {@code new FIFOEntry(anEntry)} instead of a plain entry object.
33.72 + *
33.73 + * <pre> {@code
33.74 + * class FIFOEntry<E extends Comparable<? super E>>
33.75 + * implements Comparable<FIFOEntry<E>> {
33.76 + * static final AtomicLong seq = new AtomicLong(0);
33.77 + * final long seqNum;
33.78 + * final E entry;
33.79 + * public FIFOEntry(E entry) {
33.80 + * seqNum = seq.getAndIncrement();
33.81 + * this.entry = entry;
33.82 + * }
33.83 + * public E getEntry() { return entry; }
33.84 + * public int compareTo(FIFOEntry<E> other) {
33.85 + * int res = entry.compareTo(other.entry);
33.86 + * if (res == 0 && other.entry != this.entry)
33.87 + * res = (seqNum < other.seqNum ? -1 : 1);
33.88 + * return res;
33.89 + * }
33.90 + * }}</pre>
33.91 + *
33.92 + * <p>This class is a member of the
33.93 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
33.94 + * Java Collections Framework</a>.
33.95 + *
33.96 + * @since 1.5
33.97 + * @author Doug Lea
33.98 + * @param <E> the type of elements held in this collection
33.99 + */
33.100 +public class PriorityBlockingQueue<E> extends AbstractQueue<E>
33.101 + implements BlockingQueue<E>, java.io.Serializable {
33.102 + private static final long serialVersionUID = 5595510919245408276L;
33.103 +
33.104 + /*
33.105 + * The implementation uses an array-based binary heap, with public
33.106 + * operations protected with a single lock. However, allocation
33.107 + * during resizing uses a simple spinlock (used only while not
33.108 + * holding main lock) in order to allow takes to operate
33.109 + * concurrently with allocation. This avoids repeated
33.110 + * postponement of waiting consumers and consequent element
33.111 + * build-up. The need to back away from lock during allocation
33.112 + * makes it impossible to simply wrap delegated
33.113 + * java.util.PriorityQueue operations within a lock, as was done
33.114 + * in a previous version of this class. To maintain
33.115 + * interoperability, a plain PriorityQueue is still used during
33.116 + * serialization, which maintains compatibility at the espense of
33.117 + * transiently doubling overhead.
33.118 + */
33.119 +
33.120 + /**
33.121 + * Default array capacity.
33.122 + */
33.123 + private static final int DEFAULT_INITIAL_CAPACITY = 11;
33.124 +
33.125 + /**
33.126 + * The maximum size of array to allocate.
33.127 + * Some VMs reserve some header words in an array.
33.128 + * Attempts to allocate larger arrays may result in
33.129 + * OutOfMemoryError: Requested array size exceeds VM limit
33.130 + */
33.131 + private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
33.132 +
33.133 + /**
33.134 + * Priority queue represented as a balanced binary heap: the two
33.135 + * children of queue[n] are queue[2*n+1] and queue[2*(n+1)]. The
33.136 + * priority queue is ordered by comparator, or by the elements'
33.137 + * natural ordering, if comparator is null: For each node n in the
33.138 + * heap and each descendant d of n, n <= d. The element with the
33.139 + * lowest value is in queue[0], assuming the queue is nonempty.
33.140 + */
33.141 + private transient Object[] queue;
33.142 +
33.143 + /**
33.144 + * The number of elements in the priority queue.
33.145 + */
33.146 + private transient int size;
33.147 +
33.148 + /**
33.149 + * The comparator, or null if priority queue uses elements'
33.150 + * natural ordering.
33.151 + */
33.152 + private transient Comparator<? super E> comparator;
33.153 +
33.154 + /**
33.155 + * Lock used for all public operations
33.156 + */
33.157 + private final ReentrantLock lock;
33.158 +
33.159 + /**
33.160 + * Condition for blocking when empty
33.161 + */
33.162 + private final Condition notEmpty;
33.163 +
33.164 + /**
33.165 + * Spinlock for allocation, acquired via CAS.
33.166 + */
33.167 + private transient volatile int allocationSpinLock;
33.168 +
33.169 + /**
33.170 + * A plain PriorityQueue used only for serialization,
33.171 + * to maintain compatibility with previous versions
33.172 + * of this class. Non-null only during serialization/deserialization.
33.173 + */
33.174 + private PriorityQueue q;
33.175 +
33.176 + /**
33.177 + * Creates a {@code PriorityBlockingQueue} with the default
33.178 + * initial capacity (11) that orders its elements according to
33.179 + * their {@linkplain Comparable natural ordering}.
33.180 + */
33.181 + public PriorityBlockingQueue() {
33.182 + this(DEFAULT_INITIAL_CAPACITY, null);
33.183 + }
33.184 +
33.185 + /**
33.186 + * Creates a {@code PriorityBlockingQueue} with the specified
33.187 + * initial capacity that orders its elements according to their
33.188 + * {@linkplain Comparable natural ordering}.
33.189 + *
33.190 + * @param initialCapacity the initial capacity for this priority queue
33.191 + * @throws IllegalArgumentException if {@code initialCapacity} is less
33.192 + * than 1
33.193 + */
33.194 + public PriorityBlockingQueue(int initialCapacity) {
33.195 + this(initialCapacity, null);
33.196 + }
33.197 +
33.198 + /**
33.199 + * Creates a {@code PriorityBlockingQueue} with the specified initial
33.200 + * capacity that orders its elements according to the specified
33.201 + * comparator.
33.202 + *
33.203 + * @param initialCapacity the initial capacity for this priority queue
33.204 + * @param comparator the comparator that will be used to order this
33.205 + * priority queue. If {@code null}, the {@linkplain Comparable
33.206 + * natural ordering} of the elements will be used.
33.207 + * @throws IllegalArgumentException if {@code initialCapacity} is less
33.208 + * than 1
33.209 + */
33.210 + public PriorityBlockingQueue(int initialCapacity,
33.211 + Comparator<? super E> comparator) {
33.212 + if (initialCapacity < 1)
33.213 + throw new IllegalArgumentException();
33.214 + this.lock = new ReentrantLock();
33.215 + this.notEmpty = lock.newCondition();
33.216 + this.comparator = comparator;
33.217 + this.queue = new Object[initialCapacity];
33.218 + }
33.219 +
33.220 + /**
33.221 + * Creates a {@code PriorityBlockingQueue} containing the elements
33.222 + * in the specified collection. If the specified collection is a
33.223 + * {@link SortedSet} or a {@link PriorityQueue}, this
33.224 + * priority queue will be ordered according to the same ordering.
33.225 + * Otherwise, this priority queue will be ordered according to the
33.226 + * {@linkplain Comparable natural ordering} of its elements.
33.227 + *
33.228 + * @param c the collection whose elements are to be placed
33.229 + * into this priority queue
33.230 + * @throws ClassCastException if elements of the specified collection
33.231 + * cannot be compared to one another according to the priority
33.232 + * queue's ordering
33.233 + * @throws NullPointerException if the specified collection or any
33.234 + * of its elements are null
33.235 + */
33.236 + public PriorityBlockingQueue(Collection<? extends E> c) {
33.237 + this.lock = new ReentrantLock();
33.238 + this.notEmpty = lock.newCondition();
33.239 + boolean heapify = true; // true if not known to be in heap order
33.240 + boolean screen = true; // true if must screen for nulls
33.241 + if (c instanceof SortedSet<?>) {
33.242 + SortedSet<? extends E> ss = (SortedSet<? extends E>) c;
33.243 + this.comparator = (Comparator<? super E>) ss.comparator();
33.244 + heapify = false;
33.245 + }
33.246 + else if (c instanceof PriorityBlockingQueue<?>) {
33.247 + PriorityBlockingQueue<? extends E> pq =
33.248 + (PriorityBlockingQueue<? extends E>) c;
33.249 + this.comparator = (Comparator<? super E>) pq.comparator();
33.250 + screen = false;
33.251 + if (pq.getClass() == PriorityBlockingQueue.class) // exact match
33.252 + heapify = false;
33.253 + }
33.254 + Object[] a = c.toArray();
33.255 + int n = a.length;
33.256 + // If c.toArray incorrectly doesn't return Object[], copy it.
33.257 + if (a.getClass() != Object[].class)
33.258 + a = Arrays.copyOf(a, n, Object[].class);
33.259 + if (screen && (n == 1 || this.comparator != null)) {
33.260 + for (int i = 0; i < n; ++i)
33.261 + if (a[i] == null)
33.262 + throw new NullPointerException();
33.263 + }
33.264 + this.queue = a;
33.265 + this.size = n;
33.266 + if (heapify)
33.267 + heapify();
33.268 + }
33.269 +
33.270 + /**
33.271 + * Tries to grow array to accommodate at least one more element
33.272 + * (but normally expand by about 50%), giving up (allowing retry)
33.273 + * on contention (which we expect to be rare). Call only while
33.274 + * holding lock.
33.275 + *
33.276 + * @param array the heap array
33.277 + * @param oldCap the length of the array
33.278 + */
33.279 + private void tryGrow(Object[] array, int oldCap) {
33.280 + lock.unlock(); // must release and then re-acquire main lock
33.281 + Object[] newArray = null;
33.282 + if (allocationSpinLock == 0 &&
33.283 + UNSAFE.compareAndSwapInt(this, allocationSpinLockOffset,
33.284 + 0, 1)) {
33.285 + try {
33.286 + int newCap = oldCap + ((oldCap < 64) ?
33.287 + (oldCap + 2) : // grow faster if small
33.288 + (oldCap >> 1));
33.289 + if (newCap - MAX_ARRAY_SIZE > 0) { // possible overflow
33.290 + int minCap = oldCap + 1;
33.291 + if (minCap < 0 || minCap > MAX_ARRAY_SIZE)
33.292 + throw new OutOfMemoryError();
33.293 + newCap = MAX_ARRAY_SIZE;
33.294 + }
33.295 + if (newCap > oldCap && queue == array)
33.296 + newArray = new Object[newCap];
33.297 + } finally {
33.298 + allocationSpinLock = 0;
33.299 + }
33.300 + }
33.301 + if (newArray == null) // back off if another thread is allocating
33.302 + Thread.yield();
33.303 + lock.lock();
33.304 + if (newArray != null && queue == array) {
33.305 + queue = newArray;
33.306 + System.arraycopy(array, 0, newArray, 0, oldCap);
33.307 + }
33.308 + }
33.309 +
33.310 + /**
33.311 + * Mechanics for poll(). Call only while holding lock.
33.312 + */
33.313 + private E extract() {
33.314 + E result;
33.315 + int n = size - 1;
33.316 + if (n < 0)
33.317 + result = null;
33.318 + else {
33.319 + Object[] array = queue;
33.320 + result = (E) array[0];
33.321 + E x = (E) array[n];
33.322 + array[n] = null;
33.323 + Comparator<? super E> cmp = comparator;
33.324 + if (cmp == null)
33.325 + siftDownComparable(0, x, array, n);
33.326 + else
33.327 + siftDownUsingComparator(0, x, array, n, cmp);
33.328 + size = n;
33.329 + }
33.330 + return result;
33.331 + }
33.332 +
33.333 + /**
33.334 + * Inserts item x at position k, maintaining heap invariant by
33.335 + * promoting x up the tree until it is greater than or equal to
33.336 + * its parent, or is the root.
33.337 + *
33.338 + * To simplify and speed up coercions and comparisons. the
33.339 + * Comparable and Comparator versions are separated into different
33.340 + * methods that are otherwise identical. (Similarly for siftDown.)
33.341 + * These methods are static, with heap state as arguments, to
33.342 + * simplify use in light of possible comparator exceptions.
33.343 + *
33.344 + * @param k the position to fill
33.345 + * @param x the item to insert
33.346 + * @param array the heap array
33.347 + * @param n heap size
33.348 + */
33.349 + private static <T> void siftUpComparable(int k, T x, Object[] array) {
33.350 + Comparable<? super T> key = (Comparable<? super T>) x;
33.351 + while (k > 0) {
33.352 + int parent = (k - 1) >>> 1;
33.353 + Object e = array[parent];
33.354 + if (key.compareTo((T) e) >= 0)
33.355 + break;
33.356 + array[k] = e;
33.357 + k = parent;
33.358 + }
33.359 + array[k] = key;
33.360 + }
33.361 +
33.362 + private static <T> void siftUpUsingComparator(int k, T x, Object[] array,
33.363 + Comparator<? super T> cmp) {
33.364 + while (k > 0) {
33.365 + int parent = (k - 1) >>> 1;
33.366 + Object e = array[parent];
33.367 + if (cmp.compare(x, (T) e) >= 0)
33.368 + break;
33.369 + array[k] = e;
33.370 + k = parent;
33.371 + }
33.372 + array[k] = x;
33.373 + }
33.374 +
33.375 + /**
33.376 + * Inserts item x at position k, maintaining heap invariant by
33.377 + * demoting x down the tree repeatedly until it is less than or
33.378 + * equal to its children or is a leaf.
33.379 + *
33.380 + * @param k the position to fill
33.381 + * @param x the item to insert
33.382 + * @param array the heap array
33.383 + * @param n heap size
33.384 + */
33.385 + private static <T> void siftDownComparable(int k, T x, Object[] array,
33.386 + int n) {
33.387 + Comparable<? super T> key = (Comparable<? super T>)x;
33.388 + int half = n >>> 1; // loop while a non-leaf
33.389 + while (k < half) {
33.390 + int child = (k << 1) + 1; // assume left child is least
33.391 + Object c = array[child];
33.392 + int right = child + 1;
33.393 + if (right < n &&
33.394 + ((Comparable<? super T>) c).compareTo((T) array[right]) > 0)
33.395 + c = array[child = right];
33.396 + if (key.compareTo((T) c) <= 0)
33.397 + break;
33.398 + array[k] = c;
33.399 + k = child;
33.400 + }
33.401 + array[k] = key;
33.402 + }
33.403 +
33.404 + private static <T> void siftDownUsingComparator(int k, T x, Object[] array,
33.405 + int n,
33.406 + Comparator<? super T> cmp) {
33.407 + int half = n >>> 1;
33.408 + while (k < half) {
33.409 + int child = (k << 1) + 1;
33.410 + Object c = array[child];
33.411 + int right = child + 1;
33.412 + if (right < n && cmp.compare((T) c, (T) array[right]) > 0)
33.413 + c = array[child = right];
33.414 + if (cmp.compare(x, (T) c) <= 0)
33.415 + break;
33.416 + array[k] = c;
33.417 + k = child;
33.418 + }
33.419 + array[k] = x;
33.420 + }
33.421 +
33.422 + /**
33.423 + * Establishes the heap invariant (described above) in the entire tree,
33.424 + * assuming nothing about the order of the elements prior to the call.
33.425 + */
33.426 + private void heapify() {
33.427 + Object[] array = queue;
33.428 + int n = size;
33.429 + int half = (n >>> 1) - 1;
33.430 + Comparator<? super E> cmp = comparator;
33.431 + if (cmp == null) {
33.432 + for (int i = half; i >= 0; i--)
33.433 + siftDownComparable(i, (E) array[i], array, n);
33.434 + }
33.435 + else {
33.436 + for (int i = half; i >= 0; i--)
33.437 + siftDownUsingComparator(i, (E) array[i], array, n, cmp);
33.438 + }
33.439 + }
33.440 +
33.441 + /**
33.442 + * Inserts the specified element into this priority queue.
33.443 + *
33.444 + * @param e the element to add
33.445 + * @return {@code true} (as specified by {@link Collection#add})
33.446 + * @throws ClassCastException if the specified element cannot be compared
33.447 + * with elements currently in the priority queue according to the
33.448 + * priority queue's ordering
33.449 + * @throws NullPointerException if the specified element is null
33.450 + */
33.451 + public boolean add(E e) {
33.452 + return offer(e);
33.453 + }
33.454 +
33.455 + /**
33.456 + * Inserts the specified element into this priority queue.
33.457 + * As the queue is unbounded, this method will never return {@code false}.
33.458 + *
33.459 + * @param e the element to add
33.460 + * @return {@code true} (as specified by {@link Queue#offer})
33.461 + * @throws ClassCastException if the specified element cannot be compared
33.462 + * with elements currently in the priority queue according to the
33.463 + * priority queue's ordering
33.464 + * @throws NullPointerException if the specified element is null
33.465 + */
33.466 + public boolean offer(E e) {
33.467 + if (e == null)
33.468 + throw new NullPointerException();
33.469 + final ReentrantLock lock = this.lock;
33.470 + lock.lock();
33.471 + int n, cap;
33.472 + Object[] array;
33.473 + while ((n = size) >= (cap = (array = queue).length))
33.474 + tryGrow(array, cap);
33.475 + try {
33.476 + Comparator<? super E> cmp = comparator;
33.477 + if (cmp == null)
33.478 + siftUpComparable(n, e, array);
33.479 + else
33.480 + siftUpUsingComparator(n, e, array, cmp);
33.481 + size = n + 1;
33.482 + notEmpty.signal();
33.483 + } finally {
33.484 + lock.unlock();
33.485 + }
33.486 + return true;
33.487 + }
33.488 +
33.489 + /**
33.490 + * Inserts the specified element into this priority queue.
33.491 + * As the queue is unbounded, this method will never block.
33.492 + *
33.493 + * @param e the element to add
33.494 + * @throws ClassCastException if the specified element cannot be compared
33.495 + * with elements currently in the priority queue according to the
33.496 + * priority queue's ordering
33.497 + * @throws NullPointerException if the specified element is null
33.498 + */
33.499 + public void put(E e) {
33.500 + offer(e); // never need to block
33.501 + }
33.502 +
33.503 + /**
33.504 + * Inserts the specified element into this priority queue.
33.505 + * As the queue is unbounded, this method will never block or
33.506 + * return {@code false}.
33.507 + *
33.508 + * @param e the element to add
33.509 + * @param timeout This parameter is ignored as the method never blocks
33.510 + * @param unit This parameter is ignored as the method never blocks
33.511 + * @return {@code true} (as specified by
33.512 + * {@link BlockingQueue#offer(Object,long,TimeUnit) BlockingQueue.offer})
33.513 + * @throws ClassCastException if the specified element cannot be compared
33.514 + * with elements currently in the priority queue according to the
33.515 + * priority queue's ordering
33.516 + * @throws NullPointerException if the specified element is null
33.517 + */
33.518 + public boolean offer(E e, long timeout, TimeUnit unit) {
33.519 + return offer(e); // never need to block
33.520 + }
33.521 +
33.522 + public E poll() {
33.523 + final ReentrantLock lock = this.lock;
33.524 + lock.lock();
33.525 + E result;
33.526 + try {
33.527 + result = extract();
33.528 + } finally {
33.529 + lock.unlock();
33.530 + }
33.531 + return result;
33.532 + }
33.533 +
33.534 + public E take() throws InterruptedException {
33.535 + final ReentrantLock lock = this.lock;
33.536 + lock.lockInterruptibly();
33.537 + E result;
33.538 + try {
33.539 + while ( (result = extract()) == null)
33.540 + notEmpty.await();
33.541 + } finally {
33.542 + lock.unlock();
33.543 + }
33.544 + return result;
33.545 + }
33.546 +
33.547 + public E poll(long timeout, TimeUnit unit) throws InterruptedException {
33.548 + long nanos = unit.toNanos(timeout);
33.549 + final ReentrantLock lock = this.lock;
33.550 + lock.lockInterruptibly();
33.551 + E result;
33.552 + try {
33.553 + while ( (result = extract()) == null && nanos > 0)
33.554 + nanos = notEmpty.awaitNanos(nanos);
33.555 + } finally {
33.556 + lock.unlock();
33.557 + }
33.558 + return result;
33.559 + }
33.560 +
33.561 + public E peek() {
33.562 + final ReentrantLock lock = this.lock;
33.563 + lock.lock();
33.564 + E result;
33.565 + try {
33.566 + result = size > 0 ? (E) queue[0] : null;
33.567 + } finally {
33.568 + lock.unlock();
33.569 + }
33.570 + return result;
33.571 + }
33.572 +
33.573 + /**
33.574 + * Returns the comparator used to order the elements in this queue,
33.575 + * or {@code null} if this queue uses the {@linkplain Comparable
33.576 + * natural ordering} of its elements.
33.577 + *
33.578 + * @return the comparator used to order the elements in this queue,
33.579 + * or {@code null} if this queue uses the natural
33.580 + * ordering of its elements
33.581 + */
33.582 + public Comparator<? super E> comparator() {
33.583 + return comparator;
33.584 + }
33.585 +
33.586 + public int size() {
33.587 + final ReentrantLock lock = this.lock;
33.588 + lock.lock();
33.589 + try {
33.590 + return size;
33.591 + } finally {
33.592 + lock.unlock();
33.593 + }
33.594 + }
33.595 +
33.596 + /**
33.597 + * Always returns {@code Integer.MAX_VALUE} because
33.598 + * a {@code PriorityBlockingQueue} is not capacity constrained.
33.599 + * @return {@code Integer.MAX_VALUE} always
33.600 + */
33.601 + public int remainingCapacity() {
33.602 + return Integer.MAX_VALUE;
33.603 + }
33.604 +
33.605 + private int indexOf(Object o) {
33.606 + if (o != null) {
33.607 + Object[] array = queue;
33.608 + int n = size;
33.609 + for (int i = 0; i < n; i++)
33.610 + if (o.equals(array[i]))
33.611 + return i;
33.612 + }
33.613 + return -1;
33.614 + }
33.615 +
33.616 + /**
33.617 + * Removes the ith element from queue.
33.618 + */
33.619 + private void removeAt(int i) {
33.620 + Object[] array = queue;
33.621 + int n = size - 1;
33.622 + if (n == i) // removed last element
33.623 + array[i] = null;
33.624 + else {
33.625 + E moved = (E) array[n];
33.626 + array[n] = null;
33.627 + Comparator<? super E> cmp = comparator;
33.628 + if (cmp == null)
33.629 + siftDownComparable(i, moved, array, n);
33.630 + else
33.631 + siftDownUsingComparator(i, moved, array, n, cmp);
33.632 + if (array[i] == moved) {
33.633 + if (cmp == null)
33.634 + siftUpComparable(i, moved, array);
33.635 + else
33.636 + siftUpUsingComparator(i, moved, array, cmp);
33.637 + }
33.638 + }
33.639 + size = n;
33.640 + }
33.641 +
33.642 + /**
33.643 + * Removes a single instance of the specified element from this queue,
33.644 + * if it is present. More formally, removes an element {@code e} such
33.645 + * that {@code o.equals(e)}, if this queue contains one or more such
33.646 + * elements. Returns {@code true} if and only if this queue contained
33.647 + * the specified element (or equivalently, if this queue changed as a
33.648 + * result of the call).
33.649 + *
33.650 + * @param o element to be removed from this queue, if present
33.651 + * @return {@code true} if this queue changed as a result of the call
33.652 + */
33.653 + public boolean remove(Object o) {
33.654 + boolean removed = false;
33.655 + final ReentrantLock lock = this.lock;
33.656 + lock.lock();
33.657 + try {
33.658 + int i = indexOf(o);
33.659 + if (i != -1) {
33.660 + removeAt(i);
33.661 + removed = true;
33.662 + }
33.663 + } finally {
33.664 + lock.unlock();
33.665 + }
33.666 + return removed;
33.667 + }
33.668 +
33.669 +
33.670 + /**
33.671 + * Identity-based version for use in Itr.remove
33.672 + */
33.673 + private void removeEQ(Object o) {
33.674 + final ReentrantLock lock = this.lock;
33.675 + lock.lock();
33.676 + try {
33.677 + Object[] array = queue;
33.678 + int n = size;
33.679 + for (int i = 0; i < n; i++) {
33.680 + if (o == array[i]) {
33.681 + removeAt(i);
33.682 + break;
33.683 + }
33.684 + }
33.685 + } finally {
33.686 + lock.unlock();
33.687 + }
33.688 + }
33.689 +
33.690 + /**
33.691 + * Returns {@code true} if this queue contains the specified element.
33.692 + * More formally, returns {@code true} if and only if this queue contains
33.693 + * at least one element {@code e} such that {@code o.equals(e)}.
33.694 + *
33.695 + * @param o object to be checked for containment in this queue
33.696 + * @return {@code true} if this queue contains the specified element
33.697 + */
33.698 + public boolean contains(Object o) {
33.699 + int index;
33.700 + final ReentrantLock lock = this.lock;
33.701 + lock.lock();
33.702 + try {
33.703 + index = indexOf(o);
33.704 + } finally {
33.705 + lock.unlock();
33.706 + }
33.707 + return index != -1;
33.708 + }
33.709 +
33.710 + /**
33.711 + * Returns an array containing all of the elements in this queue.
33.712 + * The returned array elements are in no particular order.
33.713 + *
33.714 + * <p>The returned array will be "safe" in that no references to it are
33.715 + * maintained by this queue. (In other words, this method must allocate
33.716 + * a new array). The caller is thus free to modify the returned array.
33.717 + *
33.718 + * <p>This method acts as bridge between array-based and collection-based
33.719 + * APIs.
33.720 + *
33.721 + * @return an array containing all of the elements in this queue
33.722 + */
33.723 + public Object[] toArray() {
33.724 + final ReentrantLock lock = this.lock;
33.725 + lock.lock();
33.726 + try {
33.727 + return Arrays.copyOf(queue, size);
33.728 + } finally {
33.729 + lock.unlock();
33.730 + }
33.731 + }
33.732 +
33.733 +
33.734 + public String toString() {
33.735 + final ReentrantLock lock = this.lock;
33.736 + lock.lock();
33.737 + try {
33.738 + int n = size;
33.739 + if (n == 0)
33.740 + return "[]";
33.741 + StringBuilder sb = new StringBuilder();
33.742 + sb.append('[');
33.743 + for (int i = 0; i < n; ++i) {
33.744 + E e = (E)queue[i];
33.745 + sb.append(e == this ? "(this Collection)" : e);
33.746 + if (i != n - 1)
33.747 + sb.append(',').append(' ');
33.748 + }
33.749 + return sb.append(']').toString();
33.750 + } finally {
33.751 + lock.unlock();
33.752 + }
33.753 + }
33.754 +
33.755 + /**
33.756 + * @throws UnsupportedOperationException {@inheritDoc}
33.757 + * @throws ClassCastException {@inheritDoc}
33.758 + * @throws NullPointerException {@inheritDoc}
33.759 + * @throws IllegalArgumentException {@inheritDoc}
33.760 + */
33.761 + public int drainTo(Collection<? super E> c) {
33.762 + if (c == null)
33.763 + throw new NullPointerException();
33.764 + if (c == this)
33.765 + throw new IllegalArgumentException();
33.766 + final ReentrantLock lock = this.lock;
33.767 + lock.lock();
33.768 + try {
33.769 + int n = 0;
33.770 + E e;
33.771 + while ( (e = extract()) != null) {
33.772 + c.add(e);
33.773 + ++n;
33.774 + }
33.775 + return n;
33.776 + } finally {
33.777 + lock.unlock();
33.778 + }
33.779 + }
33.780 +
33.781 + /**
33.782 + * @throws UnsupportedOperationException {@inheritDoc}
33.783 + * @throws ClassCastException {@inheritDoc}
33.784 + * @throws NullPointerException {@inheritDoc}
33.785 + * @throws IllegalArgumentException {@inheritDoc}
33.786 + */
33.787 + public int drainTo(Collection<? super E> c, int maxElements) {
33.788 + if (c == null)
33.789 + throw new NullPointerException();
33.790 + if (c == this)
33.791 + throw new IllegalArgumentException();
33.792 + if (maxElements <= 0)
33.793 + return 0;
33.794 + final ReentrantLock lock = this.lock;
33.795 + lock.lock();
33.796 + try {
33.797 + int n = 0;
33.798 + E e;
33.799 + while (n < maxElements && (e = extract()) != null) {
33.800 + c.add(e);
33.801 + ++n;
33.802 + }
33.803 + return n;
33.804 + } finally {
33.805 + lock.unlock();
33.806 + }
33.807 + }
33.808 +
33.809 + /**
33.810 + * Atomically removes all of the elements from this queue.
33.811 + * The queue will be empty after this call returns.
33.812 + */
33.813 + public void clear() {
33.814 + final ReentrantLock lock = this.lock;
33.815 + lock.lock();
33.816 + try {
33.817 + Object[] array = queue;
33.818 + int n = size;
33.819 + size = 0;
33.820 + for (int i = 0; i < n; i++)
33.821 + array[i] = null;
33.822 + } finally {
33.823 + lock.unlock();
33.824 + }
33.825 + }
33.826 +
33.827 + /**
33.828 + * Returns an array containing all of the elements in this queue; the
33.829 + * runtime type of the returned array is that of the specified array.
33.830 + * The returned array elements are in no particular order.
33.831 + * If the queue fits in the specified array, it is returned therein.
33.832 + * Otherwise, a new array is allocated with the runtime type of the
33.833 + * specified array and the size of this queue.
33.834 + *
33.835 + * <p>If this queue fits in the specified array with room to spare
33.836 + * (i.e., the array has more elements than this queue), the element in
33.837 + * the array immediately following the end of the queue is set to
33.838 + * {@code null}.
33.839 + *
33.840 + * <p>Like the {@link #toArray()} method, this method acts as bridge between
33.841 + * array-based and collection-based APIs. Further, this method allows
33.842 + * precise control over the runtime type of the output array, and may,
33.843 + * under certain circumstances, be used to save allocation costs.
33.844 + *
33.845 + * <p>Suppose {@code x} is a queue known to contain only strings.
33.846 + * The following code can be used to dump the queue into a newly
33.847 + * allocated array of {@code String}:
33.848 + *
33.849 + * <pre>
33.850 + * String[] y = x.toArray(new String[0]);</pre>
33.851 + *
33.852 + * Note that {@code toArray(new Object[0])} is identical in function to
33.853 + * {@code toArray()}.
33.854 + *
33.855 + * @param a the array into which the elements of the queue are to
33.856 + * be stored, if it is big enough; otherwise, a new array of the
33.857 + * same runtime type is allocated for this purpose
33.858 + * @return an array containing all of the elements in this queue
33.859 + * @throws ArrayStoreException if the runtime type of the specified array
33.860 + * is not a supertype of the runtime type of every element in
33.861 + * this queue
33.862 + * @throws NullPointerException if the specified array is null
33.863 + */
33.864 + public <T> T[] toArray(T[] a) {
33.865 + final ReentrantLock lock = this.lock;
33.866 + lock.lock();
33.867 + try {
33.868 + int n = size;
33.869 + if (a.length < n)
33.870 + // Make a new array of a's runtime type, but my contents:
33.871 + return (T[]) Arrays.copyOf(queue, size, a.getClass());
33.872 + System.arraycopy(queue, 0, a, 0, n);
33.873 + if (a.length > n)
33.874 + a[n] = null;
33.875 + return a;
33.876 + } finally {
33.877 + lock.unlock();
33.878 + }
33.879 + }
33.880 +
33.881 + /**
33.882 + * Returns an iterator over the elements in this queue. The
33.883 + * iterator does not return the elements in any particular order.
33.884 + *
33.885 + * <p>The returned iterator is a "weakly consistent" iterator that
33.886 + * will never throw {@link java.util.ConcurrentModificationException
33.887 + * ConcurrentModificationException}, and guarantees to traverse
33.888 + * elements as they existed upon construction of the iterator, and
33.889 + * may (but is not guaranteed to) reflect any modifications
33.890 + * subsequent to construction.
33.891 + *
33.892 + * @return an iterator over the elements in this queue
33.893 + */
33.894 + public Iterator<E> iterator() {
33.895 + return new Itr(toArray());
33.896 + }
33.897 +
33.898 + /**
33.899 + * Snapshot iterator that works off copy of underlying q array.
33.900 + */
33.901 + final class Itr implements Iterator<E> {
33.902 + final Object[] array; // Array of all elements
33.903 + int cursor; // index of next element to return;
33.904 + int lastRet; // index of last element, or -1 if no such
33.905 +
33.906 + Itr(Object[] array) {
33.907 + lastRet = -1;
33.908 + this.array = array;
33.909 + }
33.910 +
33.911 + public boolean hasNext() {
33.912 + return cursor < array.length;
33.913 + }
33.914 +
33.915 + public E next() {
33.916 + if (cursor >= array.length)
33.917 + throw new NoSuchElementException();
33.918 + lastRet = cursor;
33.919 + return (E)array[cursor++];
33.920 + }
33.921 +
33.922 + public void remove() {
33.923 + if (lastRet < 0)
33.924 + throw new IllegalStateException();
33.925 + removeEQ(array[lastRet]);
33.926 + lastRet = -1;
33.927 + }
33.928 + }
33.929 +
33.930 + /**
33.931 + * Saves the state to a stream (that is, serializes it). For
33.932 + * compatibility with previous version of this class,
33.933 + * elements are first copied to a java.util.PriorityQueue,
33.934 + * which is then serialized.
33.935 + */
33.936 + private void writeObject(java.io.ObjectOutputStream s)
33.937 + throws java.io.IOException {
33.938 + lock.lock();
33.939 + try {
33.940 + int n = size; // avoid zero capacity argument
33.941 + q = new PriorityQueue<E>(n == 0 ? 1 : n, comparator);
33.942 + q.addAll(this);
33.943 + s.defaultWriteObject();
33.944 + } finally {
33.945 + q = null;
33.946 + lock.unlock();
33.947 + }
33.948 + }
33.949 +
33.950 + /**
33.951 + * Reconstitutes the {@code PriorityBlockingQueue} instance from a stream
33.952 + * (that is, deserializes it).
33.953 + *
33.954 + * @param s the stream
33.955 + */
33.956 + private void readObject(java.io.ObjectInputStream s)
33.957 + throws java.io.IOException, ClassNotFoundException {
33.958 + try {
33.959 + s.defaultReadObject();
33.960 + this.queue = new Object[q.size()];
33.961 + comparator = q.comparator();
33.962 + addAll(q);
33.963 + } finally {
33.964 + q = null;
33.965 + }
33.966 + }
33.967 +
33.968 + // Unsafe mechanics
33.969 + private static final sun.misc.Unsafe UNSAFE;
33.970 + private static final long allocationSpinLockOffset;
33.971 + static {
33.972 + try {
33.973 + UNSAFE = sun.misc.Unsafe.getUnsafe();
33.974 + Class k = PriorityBlockingQueue.class;
33.975 + allocationSpinLockOffset = UNSAFE.objectFieldOffset
33.976 + (k.getDeclaredField("allocationSpinLock"));
33.977 + } catch (Exception e) {
33.978 + throw new Error(e);
33.979 + }
33.980 + }
33.981 +}
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
34.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/RecursiveAction.java Sat Mar 19 10:48:29 2016 +0100
34.3 @@ -0,0 +1,181 @@
34.4 +/*
34.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
34.6 + *
34.7 + * This code is free software; you can redistribute it and/or modify it
34.8 + * under the terms of the GNU General Public License version 2 only, as
34.9 + * published by the Free Software Foundation. Oracle designates this
34.10 + * particular file as subject to the "Classpath" exception as provided
34.11 + * by Oracle in the LICENSE file that accompanied this code.
34.12 + *
34.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
34.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
34.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
34.16 + * version 2 for more details (a copy is included in the LICENSE file that
34.17 + * accompanied this code).
34.18 + *
34.19 + * You should have received a copy of the GNU General Public License version
34.20 + * 2 along with this work; if not, write to the Free Software Foundation,
34.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
34.22 + *
34.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
34.24 + * or visit www.oracle.com if you need additional information or have any
34.25 + * questions.
34.26 + */
34.27 +
34.28 +/*
34.29 + * This file is available under and governed by the GNU General Public
34.30 + * License version 2 only, as published by the Free Software Foundation.
34.31 + * However, the following notice accompanied the original version of this
34.32 + * file:
34.33 + *
34.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
34.35 + * Expert Group and released to the public domain, as explained at
34.36 + * http://creativecommons.org/publicdomain/zero/1.0/
34.37 + */
34.38 +
34.39 +package java.util.concurrent;
34.40 +
34.41 +/**
34.42 + * A recursive resultless {@link ForkJoinTask}. This class
34.43 + * establishes conventions to parameterize resultless actions as
34.44 + * {@code Void} {@code ForkJoinTask}s. Because {@code null} is the
34.45 + * only valid value of type {@code Void}, methods such as join always
34.46 + * return {@code null} upon completion.
34.47 + *
34.48 + * <p><b>Sample Usages.</b> Here is a sketch of a ForkJoin sort that
34.49 + * sorts a given {@code long[]} array:
34.50 + *
34.51 + * <pre> {@code
34.52 + * class SortTask extends RecursiveAction {
34.53 + * final long[] array; final int lo; final int hi;
34.54 + * SortTask(long[] array, int lo, int hi) {
34.55 + * this.array = array; this.lo = lo; this.hi = hi;
34.56 + * }
34.57 + * protected void compute() {
34.58 + * if (hi - lo < THRESHOLD)
34.59 + * sequentiallySort(array, lo, hi);
34.60 + * else {
34.61 + * int mid = (lo + hi) >>> 1;
34.62 + * invokeAll(new SortTask(array, lo, mid),
34.63 + * new SortTask(array, mid, hi));
34.64 + * merge(array, lo, hi);
34.65 + * }
34.66 + * }
34.67 + * }}</pre>
34.68 + *
34.69 + * You could then sort {@code anArray} by creating {@code new
34.70 + * SortTask(anArray, 0, anArray.length-1) } and invoking it in a
34.71 + * ForkJoinPool. As a more concrete simple example, the following
34.72 + * task increments each element of an array:
34.73 + * <pre> {@code
34.74 + * class IncrementTask extends RecursiveAction {
34.75 + * final long[] array; final int lo; final int hi;
34.76 + * IncrementTask(long[] array, int lo, int hi) {
34.77 + * this.array = array; this.lo = lo; this.hi = hi;
34.78 + * }
34.79 + * protected void compute() {
34.80 + * if (hi - lo < THRESHOLD) {
34.81 + * for (int i = lo; i < hi; ++i)
34.82 + * array[i]++;
34.83 + * }
34.84 + * else {
34.85 + * int mid = (lo + hi) >>> 1;
34.86 + * invokeAll(new IncrementTask(array, lo, mid),
34.87 + * new IncrementTask(array, mid, hi));
34.88 + * }
34.89 + * }
34.90 + * }}</pre>
34.91 + *
34.92 + * <p>The following example illustrates some refinements and idioms
34.93 + * that may lead to better performance: RecursiveActions need not be
34.94 + * fully recursive, so long as they maintain the basic
34.95 + * divide-and-conquer approach. Here is a class that sums the squares
34.96 + * of each element of a double array, by subdividing out only the
34.97 + * right-hand-sides of repeated divisions by two, and keeping track of
34.98 + * them with a chain of {@code next} references. It uses a dynamic
34.99 + * threshold based on method {@code getSurplusQueuedTaskCount}, but
34.100 + * counterbalances potential excess partitioning by directly
34.101 + * performing leaf actions on unstolen tasks rather than further
34.102 + * subdividing.
34.103 + *
34.104 + * <pre> {@code
34.105 + * double sumOfSquares(ForkJoinPool pool, double[] array) {
34.106 + * int n = array.length;
34.107 + * Applyer a = new Applyer(array, 0, n, null);
34.108 + * pool.invoke(a);
34.109 + * return a.result;
34.110 + * }
34.111 + *
34.112 + * class Applyer extends RecursiveAction {
34.113 + * final double[] array;
34.114 + * final int lo, hi;
34.115 + * double result;
34.116 + * Applyer next; // keeps track of right-hand-side tasks
34.117 + * Applyer(double[] array, int lo, int hi, Applyer next) {
34.118 + * this.array = array; this.lo = lo; this.hi = hi;
34.119 + * this.next = next;
34.120 + * }
34.121 + *
34.122 + * double atLeaf(int l, int h) {
34.123 + * double sum = 0;
34.124 + * for (int i = l; i < h; ++i) // perform leftmost base step
34.125 + * sum += array[i] * array[i];
34.126 + * return sum;
34.127 + * }
34.128 + *
34.129 + * protected void compute() {
34.130 + * int l = lo;
34.131 + * int h = hi;
34.132 + * Applyer right = null;
34.133 + * while (h - l > 1 && getSurplusQueuedTaskCount() <= 3) {
34.134 + * int mid = (l + h) >>> 1;
34.135 + * right = new Applyer(array, mid, h, right);
34.136 + * right.fork();
34.137 + * h = mid;
34.138 + * }
34.139 + * double sum = atLeaf(l, h);
34.140 + * while (right != null) {
34.141 + * if (right.tryUnfork()) // directly calculate if not stolen
34.142 + * sum += right.atLeaf(right.lo, right.hi);
34.143 + * else {
34.144 + * right.join();
34.145 + * sum += right.result;
34.146 + * }
34.147 + * right = right.next;
34.148 + * }
34.149 + * result = sum;
34.150 + * }
34.151 + * }}</pre>
34.152 + *
34.153 + * @since 1.7
34.154 + * @author Doug Lea
34.155 + */
34.156 +public abstract class RecursiveAction extends ForkJoinTask<Void> {
34.157 + private static final long serialVersionUID = 5232453952276485070L;
34.158 +
34.159 + /**
34.160 + * The main computation performed by this task.
34.161 + */
34.162 + protected abstract void compute();
34.163 +
34.164 + /**
34.165 + * Always returns {@code null}.
34.166 + *
34.167 + * @return {@code null} always
34.168 + */
34.169 + public final Void getRawResult() { return null; }
34.170 +
34.171 + /**
34.172 + * Requires null completion value.
34.173 + */
34.174 + protected final void setRawResult(Void mustBeNull) { }
34.175 +
34.176 + /**
34.177 + * Implements execution conventions for RecursiveActions.
34.178 + */
34.179 + protected final boolean exec() {
34.180 + compute();
34.181 + return true;
34.182 + }
34.183 +
34.184 +}
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
35.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/RecursiveTask.java Sat Mar 19 10:48:29 2016 +0100
35.3 @@ -0,0 +1,97 @@
35.4 +/*
35.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
35.6 + *
35.7 + * This code is free software; you can redistribute it and/or modify it
35.8 + * under the terms of the GNU General Public License version 2 only, as
35.9 + * published by the Free Software Foundation. Oracle designates this
35.10 + * particular file as subject to the "Classpath" exception as provided
35.11 + * by Oracle in the LICENSE file that accompanied this code.
35.12 + *
35.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
35.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
35.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
35.16 + * version 2 for more details (a copy is included in the LICENSE file that
35.17 + * accompanied this code).
35.18 + *
35.19 + * You should have received a copy of the GNU General Public License version
35.20 + * 2 along with this work; if not, write to the Free Software Foundation,
35.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
35.22 + *
35.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
35.24 + * or visit www.oracle.com if you need additional information or have any
35.25 + * questions.
35.26 + */
35.27 +
35.28 +/*
35.29 + * This file is available under and governed by the GNU General Public
35.30 + * License version 2 only, as published by the Free Software Foundation.
35.31 + * However, the following notice accompanied the original version of this
35.32 + * file:
35.33 + *
35.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
35.35 + * Expert Group and released to the public domain, as explained at
35.36 + * http://creativecommons.org/publicdomain/zero/1.0/
35.37 + */
35.38 +
35.39 +package java.util.concurrent;
35.40 +
35.41 +/**
35.42 + * A recursive result-bearing {@link ForkJoinTask}.
35.43 + *
35.44 + * <p>For a classic example, here is a task computing Fibonacci numbers:
35.45 + *
35.46 + * <pre> {@code
35.47 + * class Fibonacci extends RecursiveTask<Integer> {
35.48 + * final int n;
35.49 + * Fibonacci(int n) { this.n = n; }
35.50 + * Integer compute() {
35.51 + * if (n <= 1)
35.52 + * return n;
35.53 + * Fibonacci f1 = new Fibonacci(n - 1);
35.54 + * f1.fork();
35.55 + * Fibonacci f2 = new Fibonacci(n - 2);
35.56 + * return f2.compute() + f1.join();
35.57 + * }
35.58 + * }}</pre>
35.59 + *
35.60 + * However, besides being a dumb way to compute Fibonacci functions
35.61 + * (there is a simple fast linear algorithm that you'd use in
35.62 + * practice), this is likely to perform poorly because the smallest
35.63 + * subtasks are too small to be worthwhile splitting up. Instead, as
35.64 + * is the case for nearly all fork/join applications, you'd pick some
35.65 + * minimum granularity size (for example 10 here) for which you always
35.66 + * sequentially solve rather than subdividing.
35.67 + *
35.68 + * @since 1.7
35.69 + * @author Doug Lea
35.70 + */
35.71 +public abstract class RecursiveTask<V> extends ForkJoinTask<V> {
35.72 + private static final long serialVersionUID = 5232453952276485270L;
35.73 +
35.74 + /**
35.75 + * The result of the computation.
35.76 + */
35.77 + V result;
35.78 +
35.79 + /**
35.80 + * The main computation performed by this task.
35.81 + */
35.82 + protected abstract V compute();
35.83 +
35.84 + public final V getRawResult() {
35.85 + return result;
35.86 + }
35.87 +
35.88 + protected final void setRawResult(V value) {
35.89 + result = value;
35.90 + }
35.91 +
35.92 + /**
35.93 + * Implements execution conventions for RecursiveTask.
35.94 + */
35.95 + protected final boolean exec() {
35.96 + result = compute();
35.97 + return true;
35.98 + }
35.99 +
35.100 +}
36.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
36.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/RejectedExecutionException.java Sat Mar 19 10:48:29 2016 +0100
36.3 @@ -0,0 +1,91 @@
36.4 +/*
36.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
36.6 + *
36.7 + * This code is free software; you can redistribute it and/or modify it
36.8 + * under the terms of the GNU General Public License version 2 only, as
36.9 + * published by the Free Software Foundation. Oracle designates this
36.10 + * particular file as subject to the "Classpath" exception as provided
36.11 + * by Oracle in the LICENSE file that accompanied this code.
36.12 + *
36.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
36.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
36.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
36.16 + * version 2 for more details (a copy is included in the LICENSE file that
36.17 + * accompanied this code).
36.18 + *
36.19 + * You should have received a copy of the GNU General Public License version
36.20 + * 2 along with this work; if not, write to the Free Software Foundation,
36.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
36.22 + *
36.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
36.24 + * or visit www.oracle.com if you need additional information or have any
36.25 + * questions.
36.26 + */
36.27 +
36.28 +/*
36.29 + * This file is available under and governed by the GNU General Public
36.30 + * License version 2 only, as published by the Free Software Foundation.
36.31 + * However, the following notice accompanied the original version of this
36.32 + * file:
36.33 + *
36.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
36.35 + * Expert Group and released to the public domain, as explained at
36.36 + * http://creativecommons.org/publicdomain/zero/1.0/
36.37 + */
36.38 +
36.39 +package java.util.concurrent;
36.40 +
36.41 +/**
36.42 + * Exception thrown by an {@link Executor} when a task cannot be
36.43 + * accepted for execution.
36.44 + *
36.45 + * @since 1.5
36.46 + * @author Doug Lea
36.47 + */
36.48 +public class RejectedExecutionException extends RuntimeException {
36.49 + private static final long serialVersionUID = -375805702767069545L;
36.50 +
36.51 + /**
36.52 + * Constructs a <tt>RejectedExecutionException</tt> with no detail message.
36.53 + * The cause is not initialized, and may subsequently be
36.54 + * initialized by a call to {@link #initCause(Throwable) initCause}.
36.55 + */
36.56 + public RejectedExecutionException() { }
36.57 +
36.58 + /**
36.59 + * Constructs a <tt>RejectedExecutionException</tt> with the
36.60 + * specified detail message. The cause is not initialized, and may
36.61 + * subsequently be initialized by a call to {@link
36.62 + * #initCause(Throwable) initCause}.
36.63 + *
36.64 + * @param message the detail message
36.65 + */
36.66 + public RejectedExecutionException(String message) {
36.67 + super(message);
36.68 + }
36.69 +
36.70 + /**
36.71 + * Constructs a <tt>RejectedExecutionException</tt> with the
36.72 + * specified detail message and cause.
36.73 + *
36.74 + * @param message the detail message
36.75 + * @param cause the cause (which is saved for later retrieval by the
36.76 + * {@link #getCause()} method)
36.77 + */
36.78 + public RejectedExecutionException(String message, Throwable cause) {
36.79 + super(message, cause);
36.80 + }
36.81 +
36.82 + /**
36.83 + * Constructs a <tt>RejectedExecutionException</tt> with the
36.84 + * specified cause. The detail message is set to: <pre> (cause ==
36.85 + * null ? null : cause.toString())</pre> (which typically contains
36.86 + * the class and detail message of <tt>cause</tt>).
36.87 + *
36.88 + * @param cause the cause (which is saved for later retrieval by the
36.89 + * {@link #getCause()} method)
36.90 + */
36.91 + public RejectedExecutionException(Throwable cause) {
36.92 + super(cause);
36.93 + }
36.94 +}
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
37.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/RejectedExecutionHandler.java Sat Mar 19 10:48:29 2016 +0100
37.3 @@ -0,0 +1,62 @@
37.4 +/*
37.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
37.6 + *
37.7 + * This code is free software; you can redistribute it and/or modify it
37.8 + * under the terms of the GNU General Public License version 2 only, as
37.9 + * published by the Free Software Foundation. Oracle designates this
37.10 + * particular file as subject to the "Classpath" exception as provided
37.11 + * by Oracle in the LICENSE file that accompanied this code.
37.12 + *
37.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
37.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
37.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
37.16 + * version 2 for more details (a copy is included in the LICENSE file that
37.17 + * accompanied this code).
37.18 + *
37.19 + * You should have received a copy of the GNU General Public License version
37.20 + * 2 along with this work; if not, write to the Free Software Foundation,
37.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
37.22 + *
37.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
37.24 + * or visit www.oracle.com if you need additional information or have any
37.25 + * questions.
37.26 + */
37.27 +
37.28 +/*
37.29 + * This file is available under and governed by the GNU General Public
37.30 + * License version 2 only, as published by the Free Software Foundation.
37.31 + * However, the following notice accompanied the original version of this
37.32 + * file:
37.33 + *
37.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
37.35 + * Expert Group and released to the public domain, as explained at
37.36 + * http://creativecommons.org/publicdomain/zero/1.0/
37.37 + */
37.38 +
37.39 +package java.util.concurrent;
37.40 +
37.41 +/**
37.42 + * A handler for tasks that cannot be executed by a {@link ThreadPoolExecutor}.
37.43 + *
37.44 + * @since 1.5
37.45 + * @author Doug Lea
37.46 + */
37.47 +public interface RejectedExecutionHandler {
37.48 +
37.49 + /**
37.50 + * Method that may be invoked by a {@link ThreadPoolExecutor} when
37.51 + * {@link ThreadPoolExecutor#execute execute} cannot accept a
37.52 + * task. This may occur when no more threads or queue slots are
37.53 + * available because their bounds would be exceeded, or upon
37.54 + * shutdown of the Executor.
37.55 + *
37.56 + * <p>In the absence of other alternatives, the method may throw
37.57 + * an unchecked {@link RejectedExecutionException}, which will be
37.58 + * propagated to the caller of {@code execute}.
37.59 + *
37.60 + * @param r the runnable task requested to be executed
37.61 + * @param executor the executor attempting to execute this task
37.62 + * @throws RejectedExecutionException if there is no remedy
37.63 + */
37.64 + void rejectedExecution(Runnable r, ThreadPoolExecutor executor);
37.65 +}
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
38.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/RunnableFuture.java Sat Mar 19 10:48:29 2016 +0100
38.3 @@ -0,0 +1,54 @@
38.4 +/*
38.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
38.6 + *
38.7 + * This code is free software; you can redistribute it and/or modify it
38.8 + * under the terms of the GNU General Public License version 2 only, as
38.9 + * published by the Free Software Foundation. Oracle designates this
38.10 + * particular file as subject to the "Classpath" exception as provided
38.11 + * by Oracle in the LICENSE file that accompanied this code.
38.12 + *
38.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
38.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
38.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
38.16 + * version 2 for more details (a copy is included in the LICENSE file that
38.17 + * accompanied this code).
38.18 + *
38.19 + * You should have received a copy of the GNU General Public License version
38.20 + * 2 along with this work; if not, write to the Free Software Foundation,
38.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
38.22 + *
38.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
38.24 + * or visit www.oracle.com if you need additional information or have any
38.25 + * questions.
38.26 + */
38.27 +
38.28 +/*
38.29 + * This file is available under and governed by the GNU General Public
38.30 + * License version 2 only, as published by the Free Software Foundation.
38.31 + * However, the following notice accompanied the original version of this
38.32 + * file:
38.33 + *
38.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
38.35 + * Expert Group and released to the public domain, as explained at
38.36 + * http://creativecommons.org/publicdomain/zero/1.0/
38.37 + */
38.38 +
38.39 +package java.util.concurrent;
38.40 +
38.41 +/**
38.42 + * A {@link Future} that is {@link Runnable}. Successful execution of
38.43 + * the <tt>run</tt> method causes completion of the <tt>Future</tt>
38.44 + * and allows access to its results.
38.45 + * @see FutureTask
38.46 + * @see Executor
38.47 + * @since 1.6
38.48 + * @author Doug Lea
38.49 + * @param <V> The result type returned by this Future's <tt>get</tt> method
38.50 + */
38.51 +public interface RunnableFuture<V> extends Runnable, Future<V> {
38.52 + /**
38.53 + * Sets this Future to the result of its computation
38.54 + * unless it has been cancelled.
38.55 + */
38.56 + void run();
38.57 +}
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
39.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/RunnableScheduledFuture.java Sat Mar 19 10:48:29 2016 +0100
39.3 @@ -0,0 +1,58 @@
39.4 +/*
39.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
39.6 + *
39.7 + * This code is free software; you can redistribute it and/or modify it
39.8 + * under the terms of the GNU General Public License version 2 only, as
39.9 + * published by the Free Software Foundation. Oracle designates this
39.10 + * particular file as subject to the "Classpath" exception as provided
39.11 + * by Oracle in the LICENSE file that accompanied this code.
39.12 + *
39.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
39.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
39.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
39.16 + * version 2 for more details (a copy is included in the LICENSE file that
39.17 + * accompanied this code).
39.18 + *
39.19 + * You should have received a copy of the GNU General Public License version
39.20 + * 2 along with this work; if not, write to the Free Software Foundation,
39.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
39.22 + *
39.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
39.24 + * or visit www.oracle.com if you need additional information or have any
39.25 + * questions.
39.26 + */
39.27 +
39.28 +/*
39.29 + * This file is available under and governed by the GNU General Public
39.30 + * License version 2 only, as published by the Free Software Foundation.
39.31 + * However, the following notice accompanied the original version of this
39.32 + * file:
39.33 + *
39.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
39.35 + * Expert Group and released to the public domain, as explained at
39.36 + * http://creativecommons.org/publicdomain/zero/1.0/
39.37 + */
39.38 +
39.39 +package java.util.concurrent;
39.40 +
39.41 +/**
39.42 + * A {@link ScheduledFuture} that is {@link Runnable}. Successful
39.43 + * execution of the <tt>run</tt> method causes completion of the
39.44 + * <tt>Future</tt> and allows access to its results.
39.45 + * @see FutureTask
39.46 + * @see Executor
39.47 + * @since 1.6
39.48 + * @author Doug Lea
39.49 + * @param <V> The result type returned by this Future's <tt>get</tt> method
39.50 + */
39.51 +public interface RunnableScheduledFuture<V> extends RunnableFuture<V>, ScheduledFuture<V> {
39.52 +
39.53 + /**
39.54 + * Returns true if this is a periodic task. A periodic task may
39.55 + * re-run according to some schedule. A non-periodic task can be
39.56 + * run only once.
39.57 + *
39.58 + * @return true if this task is periodic
39.59 + */
39.60 + boolean isPeriodic();
39.61 +}
40.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
40.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ScheduledExecutorService.java Sat Mar 19 10:48:29 2016 +0100
40.3 @@ -0,0 +1,187 @@
40.4 +/*
40.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
40.6 + *
40.7 + * This code is free software; you can redistribute it and/or modify it
40.8 + * under the terms of the GNU General Public License version 2 only, as
40.9 + * published by the Free Software Foundation. Oracle designates this
40.10 + * particular file as subject to the "Classpath" exception as provided
40.11 + * by Oracle in the LICENSE file that accompanied this code.
40.12 + *
40.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
40.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
40.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
40.16 + * version 2 for more details (a copy is included in the LICENSE file that
40.17 + * accompanied this code).
40.18 + *
40.19 + * You should have received a copy of the GNU General Public License version
40.20 + * 2 along with this work; if not, write to the Free Software Foundation,
40.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
40.22 + *
40.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
40.24 + * or visit www.oracle.com if you need additional information or have any
40.25 + * questions.
40.26 + */
40.27 +
40.28 +/*
40.29 + * This file is available under and governed by the GNU General Public
40.30 + * License version 2 only, as published by the Free Software Foundation.
40.31 + * However, the following notice accompanied the original version of this
40.32 + * file:
40.33 + *
40.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
40.35 + * Expert Group and released to the public domain, as explained at
40.36 + * http://creativecommons.org/publicdomain/zero/1.0/
40.37 + */
40.38 +
40.39 +package java.util.concurrent;
40.40 +import java.util.concurrent.atomic.*;
40.41 +import java.util.*;
40.42 +
40.43 +/**
40.44 + * An {@link ExecutorService} that can schedule commands to run after a given
40.45 + * delay, or to execute periodically.
40.46 + *
40.47 + * <p> The <tt>schedule</tt> methods create tasks with various delays
40.48 + * and return a task object that can be used to cancel or check
40.49 + * execution. The <tt>scheduleAtFixedRate</tt> and
40.50 + * <tt>scheduleWithFixedDelay</tt> methods create and execute tasks
40.51 + * that run periodically until cancelled.
40.52 + *
40.53 + * <p> Commands submitted using the {@link Executor#execute} and
40.54 + * {@link ExecutorService} <tt>submit</tt> methods are scheduled with
40.55 + * a requested delay of zero. Zero and negative delays (but not
40.56 + * periods) are also allowed in <tt>schedule</tt> methods, and are
40.57 + * treated as requests for immediate execution.
40.58 + *
40.59 + * <p>All <tt>schedule</tt> methods accept <em>relative</em> delays and
40.60 + * periods as arguments, not absolute times or dates. It is a simple
40.61 + * matter to transform an absolute time represented as a {@link
40.62 + * java.util.Date} to the required form. For example, to schedule at
40.63 + * a certain future <tt>date</tt>, you can use: <tt>schedule(task,
40.64 + * date.getTime() - System.currentTimeMillis(),
40.65 + * TimeUnit.MILLISECONDS)</tt>. Beware however that expiration of a
40.66 + * relative delay need not coincide with the current <tt>Date</tt> at
40.67 + * which the task is enabled due to network time synchronization
40.68 + * protocols, clock drift, or other factors.
40.69 + *
40.70 + * The {@link Executors} class provides convenient factory methods for
40.71 + * the ScheduledExecutorService implementations provided in this package.
40.72 + *
40.73 + * <h3>Usage Example</h3>
40.74 + *
40.75 + * Here is a class with a method that sets up a ScheduledExecutorService
40.76 + * to beep every ten seconds for an hour:
40.77 + *
40.78 + * <pre> {@code
40.79 + * import static java.util.concurrent.TimeUnit.*;
40.80 + * class BeeperControl {
40.81 + * private final ScheduledExecutorService scheduler =
40.82 + * Executors.newScheduledThreadPool(1);
40.83 + *
40.84 + * public void beepForAnHour() {
40.85 + * final Runnable beeper = new Runnable() {
40.86 + * public void run() { System.out.println("beep"); }
40.87 + * };
40.88 + * final ScheduledFuture<?> beeperHandle =
40.89 + * scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);
40.90 + * scheduler.schedule(new Runnable() {
40.91 + * public void run() { beeperHandle.cancel(true); }
40.92 + * }, 60 * 60, SECONDS);
40.93 + * }
40.94 + * }}</pre>
40.95 + *
40.96 + * @since 1.5
40.97 + * @author Doug Lea
40.98 + */
40.99 +public interface ScheduledExecutorService extends ExecutorService {
40.100 +
40.101 + /**
40.102 + * Creates and executes a one-shot action that becomes enabled
40.103 + * after the given delay.
40.104 + *
40.105 + * @param command the task to execute
40.106 + * @param delay the time from now to delay execution
40.107 + * @param unit the time unit of the delay parameter
40.108 + * @return a ScheduledFuture representing pending completion of
40.109 + * the task and whose <tt>get()</tt> method will return
40.110 + * <tt>null</tt> upon completion
40.111 + * @throws RejectedExecutionException if the task cannot be
40.112 + * scheduled for execution
40.113 + * @throws NullPointerException if command is null
40.114 + */
40.115 + public ScheduledFuture<?> schedule(Runnable command,
40.116 + long delay, TimeUnit unit);
40.117 +
40.118 + /**
40.119 + * Creates and executes a ScheduledFuture that becomes enabled after the
40.120 + * given delay.
40.121 + *
40.122 + * @param callable the function to execute
40.123 + * @param delay the time from now to delay execution
40.124 + * @param unit the time unit of the delay parameter
40.125 + * @return a ScheduledFuture that can be used to extract result or cancel
40.126 + * @throws RejectedExecutionException if the task cannot be
40.127 + * scheduled for execution
40.128 + * @throws NullPointerException if callable is null
40.129 + */
40.130 + public <V> ScheduledFuture<V> schedule(Callable<V> callable,
40.131 + long delay, TimeUnit unit);
40.132 +
40.133 + /**
40.134 + * Creates and executes a periodic action that becomes enabled first
40.135 + * after the given initial delay, and subsequently with the given
40.136 + * period; that is executions will commence after
40.137 + * <tt>initialDelay</tt> then <tt>initialDelay+period</tt>, then
40.138 + * <tt>initialDelay + 2 * period</tt>, and so on.
40.139 + * If any execution of the task
40.140 + * encounters an exception, subsequent executions are suppressed.
40.141 + * Otherwise, the task will only terminate via cancellation or
40.142 + * termination of the executor. If any execution of this task
40.143 + * takes longer than its period, then subsequent executions
40.144 + * may start late, but will not concurrently execute.
40.145 + *
40.146 + * @param command the task to execute
40.147 + * @param initialDelay the time to delay first execution
40.148 + * @param period the period between successive executions
40.149 + * @param unit the time unit of the initialDelay and period parameters
40.150 + * @return a ScheduledFuture representing pending completion of
40.151 + * the task, and whose <tt>get()</tt> method will throw an
40.152 + * exception upon cancellation
40.153 + * @throws RejectedExecutionException if the task cannot be
40.154 + * scheduled for execution
40.155 + * @throws NullPointerException if command is null
40.156 + * @throws IllegalArgumentException if period less than or equal to zero
40.157 + */
40.158 + public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
40.159 + long initialDelay,
40.160 + long period,
40.161 + TimeUnit unit);
40.162 +
40.163 + /**
40.164 + * Creates and executes a periodic action that becomes enabled first
40.165 + * after the given initial delay, and subsequently with the
40.166 + * given delay between the termination of one execution and the
40.167 + * commencement of the next. If any execution of the task
40.168 + * encounters an exception, subsequent executions are suppressed.
40.169 + * Otherwise, the task will only terminate via cancellation or
40.170 + * termination of the executor.
40.171 + *
40.172 + * @param command the task to execute
40.173 + * @param initialDelay the time to delay first execution
40.174 + * @param delay the delay between the termination of one
40.175 + * execution and the commencement of the next
40.176 + * @param unit the time unit of the initialDelay and delay parameters
40.177 + * @return a ScheduledFuture representing pending completion of
40.178 + * the task, and whose <tt>get()</tt> method will throw an
40.179 + * exception upon cancellation
40.180 + * @throws RejectedExecutionException if the task cannot be
40.181 + * scheduled for execution
40.182 + * @throws NullPointerException if command is null
40.183 + * @throws IllegalArgumentException if delay less than or equal to zero
40.184 + */
40.185 + public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
40.186 + long initialDelay,
40.187 + long delay,
40.188 + TimeUnit unit);
40.189 +
40.190 +}
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
41.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ScheduledFuture.java Sat Mar 19 10:48:29 2016 +0100
41.3 @@ -0,0 +1,48 @@
41.4 +/*
41.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
41.6 + *
41.7 + * This code is free software; you can redistribute it and/or modify it
41.8 + * under the terms of the GNU General Public License version 2 only, as
41.9 + * published by the Free Software Foundation. Oracle designates this
41.10 + * particular file as subject to the "Classpath" exception as provided
41.11 + * by Oracle in the LICENSE file that accompanied this code.
41.12 + *
41.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
41.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
41.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
41.16 + * version 2 for more details (a copy is included in the LICENSE file that
41.17 + * accompanied this code).
41.18 + *
41.19 + * You should have received a copy of the GNU General Public License version
41.20 + * 2 along with this work; if not, write to the Free Software Foundation,
41.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
41.22 + *
41.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
41.24 + * or visit www.oracle.com if you need additional information or have any
41.25 + * questions.
41.26 + */
41.27 +
41.28 +/*
41.29 + * This file is available under and governed by the GNU General Public
41.30 + * License version 2 only, as published by the Free Software Foundation.
41.31 + * However, the following notice accompanied the original version of this
41.32 + * file:
41.33 + *
41.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
41.35 + * Expert Group and released to the public domain, as explained at
41.36 + * http://creativecommons.org/publicdomain/zero/1.0/
41.37 + */
41.38 +
41.39 +package java.util.concurrent;
41.40 +
41.41 +/**
41.42 + * A delayed result-bearing action that can be cancelled.
41.43 + * Usually a scheduled future is the result of scheduling
41.44 + * a task with a {@link ScheduledExecutorService}.
41.45 + *
41.46 + * @since 1.5
41.47 + * @author Doug Lea
41.48 + * @param <V> The result type returned by this Future
41.49 + */
41.50 +public interface ScheduledFuture<V> extends Delayed, Future<V> {
41.51 +}
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
42.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ScheduledThreadPoolExecutor.java Sat Mar 19 10:48:29 2016 +0100
42.3 @@ -0,0 +1,1277 @@
42.4 +/*
42.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
42.6 + *
42.7 + * This code is free software; you can redistribute it and/or modify it
42.8 + * under the terms of the GNU General Public License version 2 only, as
42.9 + * published by the Free Software Foundation. Oracle designates this
42.10 + * particular file as subject to the "Classpath" exception as provided
42.11 + * by Oracle in the LICENSE file that accompanied this code.
42.12 + *
42.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
42.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
42.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
42.16 + * version 2 for more details (a copy is included in the LICENSE file that
42.17 + * accompanied this code).
42.18 + *
42.19 + * You should have received a copy of the GNU General Public License version
42.20 + * 2 along with this work; if not, write to the Free Software Foundation,
42.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
42.22 + *
42.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
42.24 + * or visit www.oracle.com if you need additional information or have any
42.25 + * questions.
42.26 + */
42.27 +
42.28 +/*
42.29 + * This file is available under and governed by the GNU General Public
42.30 + * License version 2 only, as published by the Free Software Foundation.
42.31 + * However, the following notice accompanied the original version of this
42.32 + * file:
42.33 + *
42.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
42.35 + * Expert Group and released to the public domain, as explained at
42.36 + * http://creativecommons.org/publicdomain/zero/1.0/
42.37 + */
42.38 +
42.39 +package java.util.concurrent;
42.40 +import java.util.concurrent.atomic.*;
42.41 +import java.util.concurrent.locks.*;
42.42 +import java.util.*;
42.43 +
42.44 +/**
42.45 + * A {@link ThreadPoolExecutor} that can additionally schedule
42.46 + * commands to run after a given delay, or to execute
42.47 + * periodically. This class is preferable to {@link java.util.Timer}
42.48 + * when multiple worker threads are needed, or when the additional
42.49 + * flexibility or capabilities of {@link ThreadPoolExecutor} (which
42.50 + * this class extends) are required.
42.51 + *
42.52 + * <p>Delayed tasks execute no sooner than they are enabled, but
42.53 + * without any real-time guarantees about when, after they are
42.54 + * enabled, they will commence. Tasks scheduled for exactly the same
42.55 + * execution time are enabled in first-in-first-out (FIFO) order of
42.56 + * submission.
42.57 + *
42.58 + * <p>When a submitted task is cancelled before it is run, execution
42.59 + * is suppressed. By default, such a cancelled task is not
42.60 + * automatically removed from the work queue until its delay
42.61 + * elapses. While this enables further inspection and monitoring, it
42.62 + * may also cause unbounded retention of cancelled tasks. To avoid
42.63 + * this, set {@link #setRemoveOnCancelPolicy} to {@code true}, which
42.64 + * causes tasks to be immediately removed from the work queue at
42.65 + * time of cancellation.
42.66 + *
42.67 + * <p>Successive executions of a task scheduled via
42.68 + * {@code scheduleAtFixedRate} or
42.69 + * {@code scheduleWithFixedDelay} do not overlap. While different
42.70 + * executions may be performed by different threads, the effects of
42.71 + * prior executions <a
42.72 + * href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
42.73 + * those of subsequent ones.
42.74 + *
42.75 + * <p>While this class inherits from {@link ThreadPoolExecutor}, a few
42.76 + * of the inherited tuning methods are not useful for it. In
42.77 + * particular, because it acts as a fixed-sized pool using
42.78 + * {@code corePoolSize} threads and an unbounded queue, adjustments
42.79 + * to {@code maximumPoolSize} have no useful effect. Additionally, it
42.80 + * is almost never a good idea to set {@code corePoolSize} to zero or
42.81 + * use {@code allowCoreThreadTimeOut} because this may leave the pool
42.82 + * without threads to handle tasks once they become eligible to run.
42.83 + *
42.84 + * <p><b>Extension notes:</b> This class overrides the
42.85 + * {@link ThreadPoolExecutor#execute execute} and
42.86 + * {@link AbstractExecutorService#submit(Runnable) submit}
42.87 + * methods to generate internal {@link ScheduledFuture} objects to
42.88 + * control per-task delays and scheduling. To preserve
42.89 + * functionality, any further overrides of these methods in
42.90 + * subclasses must invoke superclass versions, which effectively
42.91 + * disables additional task customization. However, this class
42.92 + * provides alternative protected extension method
42.93 + * {@code decorateTask} (one version each for {@code Runnable} and
42.94 + * {@code Callable}) that can be used to customize the concrete task
42.95 + * types used to execute commands entered via {@code execute},
42.96 + * {@code submit}, {@code schedule}, {@code scheduleAtFixedRate},
42.97 + * and {@code scheduleWithFixedDelay}. By default, a
42.98 + * {@code ScheduledThreadPoolExecutor} uses a task type extending
42.99 + * {@link FutureTask}. However, this may be modified or replaced using
42.100 + * subclasses of the form:
42.101 + *
42.102 + * <pre> {@code
42.103 + * public class CustomScheduledExecutor extends ScheduledThreadPoolExecutor {
42.104 + *
42.105 + * static class CustomTask<V> implements RunnableScheduledFuture<V> { ... }
42.106 + *
42.107 + * protected <V> RunnableScheduledFuture<V> decorateTask(
42.108 + * Runnable r, RunnableScheduledFuture<V> task) {
42.109 + * return new CustomTask<V>(r, task);
42.110 + * }
42.111 + *
42.112 + * protected <V> RunnableScheduledFuture<V> decorateTask(
42.113 + * Callable<V> c, RunnableScheduledFuture<V> task) {
42.114 + * return new CustomTask<V>(c, task);
42.115 + * }
42.116 + * // ... add constructors, etc.
42.117 + * }}</pre>
42.118 + *
42.119 + * @since 1.5
42.120 + * @author Doug Lea
42.121 + */
42.122 +public class ScheduledThreadPoolExecutor
42.123 + extends ThreadPoolExecutor
42.124 + implements ScheduledExecutorService {
42.125 +
42.126 + /*
42.127 + * This class specializes ThreadPoolExecutor implementation by
42.128 + *
42.129 + * 1. Using a custom task type, ScheduledFutureTask for
42.130 + * tasks, even those that don't require scheduling (i.e.,
42.131 + * those submitted using ExecutorService execute, not
42.132 + * ScheduledExecutorService methods) which are treated as
42.133 + * delayed tasks with a delay of zero.
42.134 + *
42.135 + * 2. Using a custom queue (DelayedWorkQueue), a variant of
42.136 + * unbounded DelayQueue. The lack of capacity constraint and
42.137 + * the fact that corePoolSize and maximumPoolSize are
42.138 + * effectively identical simplifies some execution mechanics
42.139 + * (see delayedExecute) compared to ThreadPoolExecutor.
42.140 + *
42.141 + * 3. Supporting optional run-after-shutdown parameters, which
42.142 + * leads to overrides of shutdown methods to remove and cancel
42.143 + * tasks that should NOT be run after shutdown, as well as
42.144 + * different recheck logic when task (re)submission overlaps
42.145 + * with a shutdown.
42.146 + *
42.147 + * 4. Task decoration methods to allow interception and
42.148 + * instrumentation, which are needed because subclasses cannot
42.149 + * otherwise override submit methods to get this effect. These
42.150 + * don't have any impact on pool control logic though.
42.151 + */
42.152 +
42.153 + /**
42.154 + * False if should cancel/suppress periodic tasks on shutdown.
42.155 + */
42.156 + private volatile boolean continueExistingPeriodicTasksAfterShutdown;
42.157 +
42.158 + /**
42.159 + * False if should cancel non-periodic tasks on shutdown.
42.160 + */
42.161 + private volatile boolean executeExistingDelayedTasksAfterShutdown = true;
42.162 +
42.163 + /**
42.164 + * True if ScheduledFutureTask.cancel should remove from queue
42.165 + */
42.166 + private volatile boolean removeOnCancel = false;
42.167 +
42.168 + /**
42.169 + * Sequence number to break scheduling ties, and in turn to
42.170 + * guarantee FIFO order among tied entries.
42.171 + */
42.172 + private static final AtomicLong sequencer = new AtomicLong(0);
42.173 +
42.174 + /**
42.175 + * Returns current nanosecond time.
42.176 + */
42.177 + final long now() {
42.178 + return System.nanoTime();
42.179 + }
42.180 +
42.181 + private class ScheduledFutureTask<V>
42.182 + extends FutureTask<V> implements RunnableScheduledFuture<V> {
42.183 +
42.184 + /** Sequence number to break ties FIFO */
42.185 + private final long sequenceNumber;
42.186 +
42.187 + /** The time the task is enabled to execute in nanoTime units */
42.188 + private long time;
42.189 +
42.190 + /**
42.191 + * Period in nanoseconds for repeating tasks. A positive
42.192 + * value indicates fixed-rate execution. A negative value
42.193 + * indicates fixed-delay execution. A value of 0 indicates a
42.194 + * non-repeating task.
42.195 + */
42.196 + private final long period;
42.197 +
42.198 + /** The actual task to be re-enqueued by reExecutePeriodic */
42.199 + RunnableScheduledFuture<V> outerTask = this;
42.200 +
42.201 + /**
42.202 + * Index into delay queue, to support faster cancellation.
42.203 + */
42.204 + int heapIndex;
42.205 +
42.206 + /**
42.207 + * Creates a one-shot action with given nanoTime-based trigger time.
42.208 + */
42.209 + ScheduledFutureTask(Runnable r, V result, long ns) {
42.210 + super(r, result);
42.211 + this.time = ns;
42.212 + this.period = 0;
42.213 + this.sequenceNumber = sequencer.getAndIncrement();
42.214 + }
42.215 +
42.216 + /**
42.217 + * Creates a periodic action with given nano time and period.
42.218 + */
42.219 + ScheduledFutureTask(Runnable r, V result, long ns, long period) {
42.220 + super(r, result);
42.221 + this.time = ns;
42.222 + this.period = period;
42.223 + this.sequenceNumber = sequencer.getAndIncrement();
42.224 + }
42.225 +
42.226 + /**
42.227 + * Creates a one-shot action with given nanoTime-based trigger.
42.228 + */
42.229 + ScheduledFutureTask(Callable<V> callable, long ns) {
42.230 + super(callable);
42.231 + this.time = ns;
42.232 + this.period = 0;
42.233 + this.sequenceNumber = sequencer.getAndIncrement();
42.234 + }
42.235 +
42.236 + public long getDelay(TimeUnit unit) {
42.237 + return unit.convert(time - now(), TimeUnit.NANOSECONDS);
42.238 + }
42.239 +
42.240 + public int compareTo(Delayed other) {
42.241 + if (other == this) // compare zero ONLY if same object
42.242 + return 0;
42.243 + if (other instanceof ScheduledFutureTask) {
42.244 + ScheduledFutureTask<?> x = (ScheduledFutureTask<?>)other;
42.245 + long diff = time - x.time;
42.246 + if (diff < 0)
42.247 + return -1;
42.248 + else if (diff > 0)
42.249 + return 1;
42.250 + else if (sequenceNumber < x.sequenceNumber)
42.251 + return -1;
42.252 + else
42.253 + return 1;
42.254 + }
42.255 + long d = (getDelay(TimeUnit.NANOSECONDS) -
42.256 + other.getDelay(TimeUnit.NANOSECONDS));
42.257 + return (d == 0) ? 0 : ((d < 0) ? -1 : 1);
42.258 + }
42.259 +
42.260 + /**
42.261 + * Returns true if this is a periodic (not a one-shot) action.
42.262 + *
42.263 + * @return true if periodic
42.264 + */
42.265 + public boolean isPeriodic() {
42.266 + return period != 0;
42.267 + }
42.268 +
42.269 + /**
42.270 + * Sets the next time to run for a periodic task.
42.271 + */
42.272 + private void setNextRunTime() {
42.273 + long p = period;
42.274 + if (p > 0)
42.275 + time += p;
42.276 + else
42.277 + time = triggerTime(-p);
42.278 + }
42.279 +
42.280 + public boolean cancel(boolean mayInterruptIfRunning) {
42.281 + boolean cancelled = super.cancel(mayInterruptIfRunning);
42.282 + if (cancelled && removeOnCancel && heapIndex >= 0)
42.283 + remove(this);
42.284 + return cancelled;
42.285 + }
42.286 +
42.287 + /**
42.288 + * Overrides FutureTask version so as to reset/requeue if periodic.
42.289 + */
42.290 + public void run() {
42.291 + boolean periodic = isPeriodic();
42.292 + if (!canRunInCurrentRunState(periodic))
42.293 + cancel(false);
42.294 + else if (!periodic)
42.295 + ScheduledFutureTask.super.run();
42.296 + else if (ScheduledFutureTask.super.runAndReset()) {
42.297 + setNextRunTime();
42.298 + reExecutePeriodic(outerTask);
42.299 + }
42.300 + }
42.301 + }
42.302 +
42.303 + /**
42.304 + * Returns true if can run a task given current run state
42.305 + * and run-after-shutdown parameters.
42.306 + *
42.307 + * @param periodic true if this task periodic, false if delayed
42.308 + */
42.309 + boolean canRunInCurrentRunState(boolean periodic) {
42.310 + return isRunningOrShutdown(periodic ?
42.311 + continueExistingPeriodicTasksAfterShutdown :
42.312 + executeExistingDelayedTasksAfterShutdown);
42.313 + }
42.314 +
42.315 + /**
42.316 + * Main execution method for delayed or periodic tasks. If pool
42.317 + * is shut down, rejects the task. Otherwise adds task to queue
42.318 + * and starts a thread, if necessary, to run it. (We cannot
42.319 + * prestart the thread to run the task because the task (probably)
42.320 + * shouldn't be run yet,) If the pool is shut down while the task
42.321 + * is being added, cancel and remove it if required by state and
42.322 + * run-after-shutdown parameters.
42.323 + *
42.324 + * @param task the task
42.325 + */
42.326 + private void delayedExecute(RunnableScheduledFuture<?> task) {
42.327 + if (isShutdown())
42.328 + reject(task);
42.329 + else {
42.330 + super.getQueue().add(task);
42.331 + if (isShutdown() &&
42.332 + !canRunInCurrentRunState(task.isPeriodic()) &&
42.333 + remove(task))
42.334 + task.cancel(false);
42.335 + else
42.336 + prestartCoreThread();
42.337 + }
42.338 + }
42.339 +
42.340 + /**
42.341 + * Requeues a periodic task unless current run state precludes it.
42.342 + * Same idea as delayedExecute except drops task rather than rejecting.
42.343 + *
42.344 + * @param task the task
42.345 + */
42.346 + void reExecutePeriodic(RunnableScheduledFuture<?> task) {
42.347 + if (canRunInCurrentRunState(true)) {
42.348 + super.getQueue().add(task);
42.349 + if (!canRunInCurrentRunState(true) && remove(task))
42.350 + task.cancel(false);
42.351 + else
42.352 + prestartCoreThread();
42.353 + }
42.354 + }
42.355 +
42.356 + /**
42.357 + * Cancels and clears the queue of all tasks that should not be run
42.358 + * due to shutdown policy. Invoked within super.shutdown.
42.359 + */
42.360 + @Override void onShutdown() {
42.361 + BlockingQueue<Runnable> q = super.getQueue();
42.362 + boolean keepDelayed =
42.363 + getExecuteExistingDelayedTasksAfterShutdownPolicy();
42.364 + boolean keepPeriodic =
42.365 + getContinueExistingPeriodicTasksAfterShutdownPolicy();
42.366 + if (!keepDelayed && !keepPeriodic) {
42.367 + for (Object e : q.toArray())
42.368 + if (e instanceof RunnableScheduledFuture<?>)
42.369 + ((RunnableScheduledFuture<?>) e).cancel(false);
42.370 + q.clear();
42.371 + }
42.372 + else {
42.373 + // Traverse snapshot to avoid iterator exceptions
42.374 + for (Object e : q.toArray()) {
42.375 + if (e instanceof RunnableScheduledFuture) {
42.376 + RunnableScheduledFuture<?> t =
42.377 + (RunnableScheduledFuture<?>)e;
42.378 + if ((t.isPeriodic() ? !keepPeriodic : !keepDelayed) ||
42.379 + t.isCancelled()) { // also remove if already cancelled
42.380 + if (q.remove(t))
42.381 + t.cancel(false);
42.382 + }
42.383 + }
42.384 + }
42.385 + }
42.386 + tryTerminate();
42.387 + }
42.388 +
42.389 + /**
42.390 + * Modifies or replaces the task used to execute a runnable.
42.391 + * This method can be used to override the concrete
42.392 + * class used for managing internal tasks.
42.393 + * The default implementation simply returns the given task.
42.394 + *
42.395 + * @param runnable the submitted Runnable
42.396 + * @param task the task created to execute the runnable
42.397 + * @return a task that can execute the runnable
42.398 + * @since 1.6
42.399 + */
42.400 + protected <V> RunnableScheduledFuture<V> decorateTask(
42.401 + Runnable runnable, RunnableScheduledFuture<V> task) {
42.402 + return task;
42.403 + }
42.404 +
42.405 + /**
42.406 + * Modifies or replaces the task used to execute a callable.
42.407 + * This method can be used to override the concrete
42.408 + * class used for managing internal tasks.
42.409 + * The default implementation simply returns the given task.
42.410 + *
42.411 + * @param callable the submitted Callable
42.412 + * @param task the task created to execute the callable
42.413 + * @return a task that can execute the callable
42.414 + * @since 1.6
42.415 + */
42.416 + protected <V> RunnableScheduledFuture<V> decorateTask(
42.417 + Callable<V> callable, RunnableScheduledFuture<V> task) {
42.418 + return task;
42.419 + }
42.420 +
42.421 + /**
42.422 + * Creates a new {@code ScheduledThreadPoolExecutor} with the
42.423 + * given core pool size.
42.424 + *
42.425 + * @param corePoolSize the number of threads to keep in the pool, even
42.426 + * if they are idle, unless {@code allowCoreThreadTimeOut} is set
42.427 + * @throws IllegalArgumentException if {@code corePoolSize < 0}
42.428 + */
42.429 + public ScheduledThreadPoolExecutor(int corePoolSize) {
42.430 + super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
42.431 + new DelayedWorkQueue());
42.432 + }
42.433 +
42.434 + /**
42.435 + * Creates a new {@code ScheduledThreadPoolExecutor} with the
42.436 + * given initial parameters.
42.437 + *
42.438 + * @param corePoolSize the number of threads to keep in the pool, even
42.439 + * if they are idle, unless {@code allowCoreThreadTimeOut} is set
42.440 + * @param threadFactory the factory to use when the executor
42.441 + * creates a new thread
42.442 + * @throws IllegalArgumentException if {@code corePoolSize < 0}
42.443 + * @throws NullPointerException if {@code threadFactory} is null
42.444 + */
42.445 + public ScheduledThreadPoolExecutor(int corePoolSize,
42.446 + ThreadFactory threadFactory) {
42.447 + super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
42.448 + new DelayedWorkQueue(), threadFactory);
42.449 + }
42.450 +
42.451 + /**
42.452 + * Creates a new ScheduledThreadPoolExecutor with the given
42.453 + * initial parameters.
42.454 + *
42.455 + * @param corePoolSize the number of threads to keep in the pool, even
42.456 + * if they are idle, unless {@code allowCoreThreadTimeOut} is set
42.457 + * @param handler the handler to use when execution is blocked
42.458 + * because the thread bounds and queue capacities are reached
42.459 + * @throws IllegalArgumentException if {@code corePoolSize < 0}
42.460 + * @throws NullPointerException if {@code handler} is null
42.461 + */
42.462 + public ScheduledThreadPoolExecutor(int corePoolSize,
42.463 + RejectedExecutionHandler handler) {
42.464 + super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
42.465 + new DelayedWorkQueue(), handler);
42.466 + }
42.467 +
42.468 + /**
42.469 + * Creates a new ScheduledThreadPoolExecutor with the given
42.470 + * initial parameters.
42.471 + *
42.472 + * @param corePoolSize the number of threads to keep in the pool, even
42.473 + * if they are idle, unless {@code allowCoreThreadTimeOut} is set
42.474 + * @param threadFactory the factory to use when the executor
42.475 + * creates a new thread
42.476 + * @param handler the handler to use when execution is blocked
42.477 + * because the thread bounds and queue capacities are reached
42.478 + * @throws IllegalArgumentException if {@code corePoolSize < 0}
42.479 + * @throws NullPointerException if {@code threadFactory} or
42.480 + * {@code handler} is null
42.481 + */
42.482 + public ScheduledThreadPoolExecutor(int corePoolSize,
42.483 + ThreadFactory threadFactory,
42.484 + RejectedExecutionHandler handler) {
42.485 + super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
42.486 + new DelayedWorkQueue(), threadFactory, handler);
42.487 + }
42.488 +
42.489 + /**
42.490 + * Returns the trigger time of a delayed action.
42.491 + */
42.492 + private long triggerTime(long delay, TimeUnit unit) {
42.493 + return triggerTime(unit.toNanos((delay < 0) ? 0 : delay));
42.494 + }
42.495 +
42.496 + /**
42.497 + * Returns the trigger time of a delayed action.
42.498 + */
42.499 + long triggerTime(long delay) {
42.500 + return now() +
42.501 + ((delay < (Long.MAX_VALUE >> 1)) ? delay : overflowFree(delay));
42.502 + }
42.503 +
42.504 + /**
42.505 + * Constrains the values of all delays in the queue to be within
42.506 + * Long.MAX_VALUE of each other, to avoid overflow in compareTo.
42.507 + * This may occur if a task is eligible to be dequeued, but has
42.508 + * not yet been, while some other task is added with a delay of
42.509 + * Long.MAX_VALUE.
42.510 + */
42.511 + private long overflowFree(long delay) {
42.512 + Delayed head = (Delayed) super.getQueue().peek();
42.513 + if (head != null) {
42.514 + long headDelay = head.getDelay(TimeUnit.NANOSECONDS);
42.515 + if (headDelay < 0 && (delay - headDelay < 0))
42.516 + delay = Long.MAX_VALUE + headDelay;
42.517 + }
42.518 + return delay;
42.519 + }
42.520 +
42.521 + /**
42.522 + * @throws RejectedExecutionException {@inheritDoc}
42.523 + * @throws NullPointerException {@inheritDoc}
42.524 + */
42.525 + public ScheduledFuture<?> schedule(Runnable command,
42.526 + long delay,
42.527 + TimeUnit unit) {
42.528 + if (command == null || unit == null)
42.529 + throw new NullPointerException();
42.530 + RunnableScheduledFuture<?> t = decorateTask(command,
42.531 + new ScheduledFutureTask<Void>(command, null,
42.532 + triggerTime(delay, unit)));
42.533 + delayedExecute(t);
42.534 + return t;
42.535 + }
42.536 +
42.537 + /**
42.538 + * @throws RejectedExecutionException {@inheritDoc}
42.539 + * @throws NullPointerException {@inheritDoc}
42.540 + */
42.541 + public <V> ScheduledFuture<V> schedule(Callable<V> callable,
42.542 + long delay,
42.543 + TimeUnit unit) {
42.544 + if (callable == null || unit == null)
42.545 + throw new NullPointerException();
42.546 + RunnableScheduledFuture<V> t = decorateTask(callable,
42.547 + new ScheduledFutureTask<V>(callable,
42.548 + triggerTime(delay, unit)));
42.549 + delayedExecute(t);
42.550 + return t;
42.551 + }
42.552 +
42.553 + /**
42.554 + * @throws RejectedExecutionException {@inheritDoc}
42.555 + * @throws NullPointerException {@inheritDoc}
42.556 + * @throws IllegalArgumentException {@inheritDoc}
42.557 + */
42.558 + public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
42.559 + long initialDelay,
42.560 + long period,
42.561 + TimeUnit unit) {
42.562 + if (command == null || unit == null)
42.563 + throw new NullPointerException();
42.564 + if (period <= 0)
42.565 + throw new IllegalArgumentException();
42.566 + ScheduledFutureTask<Void> sft =
42.567 + new ScheduledFutureTask<Void>(command,
42.568 + null,
42.569 + triggerTime(initialDelay, unit),
42.570 + unit.toNanos(period));
42.571 + RunnableScheduledFuture<Void> t = decorateTask(command, sft);
42.572 + sft.outerTask = t;
42.573 + delayedExecute(t);
42.574 + return t;
42.575 + }
42.576 +
42.577 + /**
42.578 + * @throws RejectedExecutionException {@inheritDoc}
42.579 + * @throws NullPointerException {@inheritDoc}
42.580 + * @throws IllegalArgumentException {@inheritDoc}
42.581 + */
42.582 + public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
42.583 + long initialDelay,
42.584 + long delay,
42.585 + TimeUnit unit) {
42.586 + if (command == null || unit == null)
42.587 + throw new NullPointerException();
42.588 + if (delay <= 0)
42.589 + throw new IllegalArgumentException();
42.590 + ScheduledFutureTask<Void> sft =
42.591 + new ScheduledFutureTask<Void>(command,
42.592 + null,
42.593 + triggerTime(initialDelay, unit),
42.594 + unit.toNanos(-delay));
42.595 + RunnableScheduledFuture<Void> t = decorateTask(command, sft);
42.596 + sft.outerTask = t;
42.597 + delayedExecute(t);
42.598 + return t;
42.599 + }
42.600 +
42.601 + /**
42.602 + * Executes {@code command} with zero required delay.
42.603 + * This has effect equivalent to
42.604 + * {@link #schedule(Runnable,long,TimeUnit) schedule(command, 0, anyUnit)}.
42.605 + * Note that inspections of the queue and of the list returned by
42.606 + * {@code shutdownNow} will access the zero-delayed
42.607 + * {@link ScheduledFuture}, not the {@code command} itself.
42.608 + *
42.609 + * <p>A consequence of the use of {@code ScheduledFuture} objects is
42.610 + * that {@link ThreadPoolExecutor#afterExecute afterExecute} is always
42.611 + * called with a null second {@code Throwable} argument, even if the
42.612 + * {@code command} terminated abruptly. Instead, the {@code Throwable}
42.613 + * thrown by such a task can be obtained via {@link Future#get}.
42.614 + *
42.615 + * @throws RejectedExecutionException at discretion of
42.616 + * {@code RejectedExecutionHandler}, if the task
42.617 + * cannot be accepted for execution because the
42.618 + * executor has been shut down
42.619 + * @throws NullPointerException {@inheritDoc}
42.620 + */
42.621 + public void execute(Runnable command) {
42.622 + schedule(command, 0, TimeUnit.NANOSECONDS);
42.623 + }
42.624 +
42.625 + // Override AbstractExecutorService methods
42.626 +
42.627 + /**
42.628 + * @throws RejectedExecutionException {@inheritDoc}
42.629 + * @throws NullPointerException {@inheritDoc}
42.630 + */
42.631 + public Future<?> submit(Runnable task) {
42.632 + return schedule(task, 0, TimeUnit.NANOSECONDS);
42.633 + }
42.634 +
42.635 + /**
42.636 + * @throws RejectedExecutionException {@inheritDoc}
42.637 + * @throws NullPointerException {@inheritDoc}
42.638 + */
42.639 + public <T> Future<T> submit(Runnable task, T result) {
42.640 + return schedule(Executors.callable(task, result),
42.641 + 0, TimeUnit.NANOSECONDS);
42.642 + }
42.643 +
42.644 + /**
42.645 + * @throws RejectedExecutionException {@inheritDoc}
42.646 + * @throws NullPointerException {@inheritDoc}
42.647 + */
42.648 + public <T> Future<T> submit(Callable<T> task) {
42.649 + return schedule(task, 0, TimeUnit.NANOSECONDS);
42.650 + }
42.651 +
42.652 + /**
42.653 + * Sets the policy on whether to continue executing existing
42.654 + * periodic tasks even when this executor has been {@code shutdown}.
42.655 + * In this case, these tasks will only terminate upon
42.656 + * {@code shutdownNow} or after setting the policy to
42.657 + * {@code false} when already shutdown.
42.658 + * This value is by default {@code false}.
42.659 + *
42.660 + * @param value if {@code true}, continue after shutdown, else don't.
42.661 + * @see #getContinueExistingPeriodicTasksAfterShutdownPolicy
42.662 + */
42.663 + public void setContinueExistingPeriodicTasksAfterShutdownPolicy(boolean value) {
42.664 + continueExistingPeriodicTasksAfterShutdown = value;
42.665 + if (!value && isShutdown())
42.666 + onShutdown();
42.667 + }
42.668 +
42.669 + /**
42.670 + * Gets the policy on whether to continue executing existing
42.671 + * periodic tasks even when this executor has been {@code shutdown}.
42.672 + * In this case, these tasks will only terminate upon
42.673 + * {@code shutdownNow} or after setting the policy to
42.674 + * {@code false} when already shutdown.
42.675 + * This value is by default {@code false}.
42.676 + *
42.677 + * @return {@code true} if will continue after shutdown
42.678 + * @see #setContinueExistingPeriodicTasksAfterShutdownPolicy
42.679 + */
42.680 + public boolean getContinueExistingPeriodicTasksAfterShutdownPolicy() {
42.681 + return continueExistingPeriodicTasksAfterShutdown;
42.682 + }
42.683 +
42.684 + /**
42.685 + * Sets the policy on whether to execute existing delayed
42.686 + * tasks even when this executor has been {@code shutdown}.
42.687 + * In this case, these tasks will only terminate upon
42.688 + * {@code shutdownNow}, or after setting the policy to
42.689 + * {@code false} when already shutdown.
42.690 + * This value is by default {@code true}.
42.691 + *
42.692 + * @param value if {@code true}, execute after shutdown, else don't.
42.693 + * @see #getExecuteExistingDelayedTasksAfterShutdownPolicy
42.694 + */
42.695 + public void setExecuteExistingDelayedTasksAfterShutdownPolicy(boolean value) {
42.696 + executeExistingDelayedTasksAfterShutdown = value;
42.697 + if (!value && isShutdown())
42.698 + onShutdown();
42.699 + }
42.700 +
42.701 + /**
42.702 + * Gets the policy on whether to execute existing delayed
42.703 + * tasks even when this executor has been {@code shutdown}.
42.704 + * In this case, these tasks will only terminate upon
42.705 + * {@code shutdownNow}, or after setting the policy to
42.706 + * {@code false} when already shutdown.
42.707 + * This value is by default {@code true}.
42.708 + *
42.709 + * @return {@code true} if will execute after shutdown
42.710 + * @see #setExecuteExistingDelayedTasksAfterShutdownPolicy
42.711 + */
42.712 + public boolean getExecuteExistingDelayedTasksAfterShutdownPolicy() {
42.713 + return executeExistingDelayedTasksAfterShutdown;
42.714 + }
42.715 +
42.716 + /**
42.717 + * Sets the policy on whether cancelled tasks should be immediately
42.718 + * removed from the work queue at time of cancellation. This value is
42.719 + * by default {@code false}.
42.720 + *
42.721 + * @param value if {@code true}, remove on cancellation, else don't
42.722 + * @see #getRemoveOnCancelPolicy
42.723 + * @since 1.7
42.724 + */
42.725 + public void setRemoveOnCancelPolicy(boolean value) {
42.726 + removeOnCancel = value;
42.727 + }
42.728 +
42.729 + /**
42.730 + * Gets the policy on whether cancelled tasks should be immediately
42.731 + * removed from the work queue at time of cancellation. This value is
42.732 + * by default {@code false}.
42.733 + *
42.734 + * @return {@code true} if cancelled tasks are immediately removed
42.735 + * from the queue
42.736 + * @see #setRemoveOnCancelPolicy
42.737 + * @since 1.7
42.738 + */
42.739 + public boolean getRemoveOnCancelPolicy() {
42.740 + return removeOnCancel;
42.741 + }
42.742 +
42.743 + /**
42.744 + * Initiates an orderly shutdown in which previously submitted
42.745 + * tasks are executed, but no new tasks will be accepted.
42.746 + * Invocation has no additional effect if already shut down.
42.747 + *
42.748 + * <p>This method does not wait for previously submitted tasks to
42.749 + * complete execution. Use {@link #awaitTermination awaitTermination}
42.750 + * to do that.
42.751 + *
42.752 + * <p>If the {@code ExecuteExistingDelayedTasksAfterShutdownPolicy}
42.753 + * has been set {@code false}, existing delayed tasks whose delays
42.754 + * have not yet elapsed are cancelled. And unless the {@code
42.755 + * ContinueExistingPeriodicTasksAfterShutdownPolicy} has been set
42.756 + * {@code true}, future executions of existing periodic tasks will
42.757 + * be cancelled.
42.758 + *
42.759 + * @throws SecurityException {@inheritDoc}
42.760 + */
42.761 + public void shutdown() {
42.762 + super.shutdown();
42.763 + }
42.764 +
42.765 + /**
42.766 + * Attempts to stop all actively executing tasks, halts the
42.767 + * processing of waiting tasks, and returns a list of the tasks
42.768 + * that were awaiting execution.
42.769 + *
42.770 + * <p>This method does not wait for actively executing tasks to
42.771 + * terminate. Use {@link #awaitTermination awaitTermination} to
42.772 + * do that.
42.773 + *
42.774 + * <p>There are no guarantees beyond best-effort attempts to stop
42.775 + * processing actively executing tasks. This implementation
42.776 + * cancels tasks via {@link Thread#interrupt}, so any task that
42.777 + * fails to respond to interrupts may never terminate.
42.778 + *
42.779 + * @return list of tasks that never commenced execution.
42.780 + * Each element of this list is a {@link ScheduledFuture},
42.781 + * including those tasks submitted using {@code execute},
42.782 + * which are for scheduling purposes used as the basis of a
42.783 + * zero-delay {@code ScheduledFuture}.
42.784 + * @throws SecurityException {@inheritDoc}
42.785 + */
42.786 + public List<Runnable> shutdownNow() {
42.787 + return super.shutdownNow();
42.788 + }
42.789 +
42.790 + /**
42.791 + * Returns the task queue used by this executor. Each element of
42.792 + * this queue is a {@link ScheduledFuture}, including those
42.793 + * tasks submitted using {@code execute} which are for scheduling
42.794 + * purposes used as the basis of a zero-delay
42.795 + * {@code ScheduledFuture}. Iteration over this queue is
42.796 + * <em>not</em> guaranteed to traverse tasks in the order in
42.797 + * which they will execute.
42.798 + *
42.799 + * @return the task queue
42.800 + */
42.801 + public BlockingQueue<Runnable> getQueue() {
42.802 + return super.getQueue();
42.803 + }
42.804 +
42.805 + /**
42.806 + * Specialized delay queue. To mesh with TPE declarations, this
42.807 + * class must be declared as a BlockingQueue<Runnable> even though
42.808 + * it can only hold RunnableScheduledFutures.
42.809 + */
42.810 + static class DelayedWorkQueue extends AbstractQueue<Runnable>
42.811 + implements BlockingQueue<Runnable> {
42.812 +
42.813 + /*
42.814 + * A DelayedWorkQueue is based on a heap-based data structure
42.815 + * like those in DelayQueue and PriorityQueue, except that
42.816 + * every ScheduledFutureTask also records its index into the
42.817 + * heap array. This eliminates the need to find a task upon
42.818 + * cancellation, greatly speeding up removal (down from O(n)
42.819 + * to O(log n)), and reducing garbage retention that would
42.820 + * otherwise occur by waiting for the element to rise to top
42.821 + * before clearing. But because the queue may also hold
42.822 + * RunnableScheduledFutures that are not ScheduledFutureTasks,
42.823 + * we are not guaranteed to have such indices available, in
42.824 + * which case we fall back to linear search. (We expect that
42.825 + * most tasks will not be decorated, and that the faster cases
42.826 + * will be much more common.)
42.827 + *
42.828 + * All heap operations must record index changes -- mainly
42.829 + * within siftUp and siftDown. Upon removal, a task's
42.830 + * heapIndex is set to -1. Note that ScheduledFutureTasks can
42.831 + * appear at most once in the queue (this need not be true for
42.832 + * other kinds of tasks or work queues), so are uniquely
42.833 + * identified by heapIndex.
42.834 + */
42.835 +
42.836 + private static final int INITIAL_CAPACITY = 16;
42.837 + private RunnableScheduledFuture[] queue =
42.838 + new RunnableScheduledFuture[INITIAL_CAPACITY];
42.839 + private final ReentrantLock lock = new ReentrantLock();
42.840 + private int size = 0;
42.841 +
42.842 + /**
42.843 + * Thread designated to wait for the task at the head of the
42.844 + * queue. This variant of the Leader-Follower pattern
42.845 + * (http://www.cs.wustl.edu/~schmidt/POSA/POSA2/) serves to
42.846 + * minimize unnecessary timed waiting. When a thread becomes
42.847 + * the leader, it waits only for the next delay to elapse, but
42.848 + * other threads await indefinitely. The leader thread must
42.849 + * signal some other thread before returning from take() or
42.850 + * poll(...), unless some other thread becomes leader in the
42.851 + * interim. Whenever the head of the queue is replaced with a
42.852 + * task with an earlier expiration time, the leader field is
42.853 + * invalidated by being reset to null, and some waiting
42.854 + * thread, but not necessarily the current leader, is
42.855 + * signalled. So waiting threads must be prepared to acquire
42.856 + * and lose leadership while waiting.
42.857 + */
42.858 + private Thread leader = null;
42.859 +
42.860 + /**
42.861 + * Condition signalled when a newer task becomes available at the
42.862 + * head of the queue or a new thread may need to become leader.
42.863 + */
42.864 + private final Condition available = lock.newCondition();
42.865 +
42.866 + /**
42.867 + * Set f's heapIndex if it is a ScheduledFutureTask.
42.868 + */
42.869 + private void setIndex(RunnableScheduledFuture f, int idx) {
42.870 + if (f instanceof ScheduledFutureTask)
42.871 + ((ScheduledFutureTask)f).heapIndex = idx;
42.872 + }
42.873 +
42.874 + /**
42.875 + * Sift element added at bottom up to its heap-ordered spot.
42.876 + * Call only when holding lock.
42.877 + */
42.878 + private void siftUp(int k, RunnableScheduledFuture key) {
42.879 + while (k > 0) {
42.880 + int parent = (k - 1) >>> 1;
42.881 + RunnableScheduledFuture e = queue[parent];
42.882 + if (key.compareTo(e) >= 0)
42.883 + break;
42.884 + queue[k] = e;
42.885 + setIndex(e, k);
42.886 + k = parent;
42.887 + }
42.888 + queue[k] = key;
42.889 + setIndex(key, k);
42.890 + }
42.891 +
42.892 + /**
42.893 + * Sift element added at top down to its heap-ordered spot.
42.894 + * Call only when holding lock.
42.895 + */
42.896 + private void siftDown(int k, RunnableScheduledFuture key) {
42.897 + int half = size >>> 1;
42.898 + while (k < half) {
42.899 + int child = (k << 1) + 1;
42.900 + RunnableScheduledFuture c = queue[child];
42.901 + int right = child + 1;
42.902 + if (right < size && c.compareTo(queue[right]) > 0)
42.903 + c = queue[child = right];
42.904 + if (key.compareTo(c) <= 0)
42.905 + break;
42.906 + queue[k] = c;
42.907 + setIndex(c, k);
42.908 + k = child;
42.909 + }
42.910 + queue[k] = key;
42.911 + setIndex(key, k);
42.912 + }
42.913 +
42.914 + /**
42.915 + * Resize the heap array. Call only when holding lock.
42.916 + */
42.917 + private void grow() {
42.918 + int oldCapacity = queue.length;
42.919 + int newCapacity = oldCapacity + (oldCapacity >> 1); // grow 50%
42.920 + if (newCapacity < 0) // overflow
42.921 + newCapacity = Integer.MAX_VALUE;
42.922 + queue = Arrays.copyOf(queue, newCapacity);
42.923 + }
42.924 +
42.925 + /**
42.926 + * Find index of given object, or -1 if absent
42.927 + */
42.928 + private int indexOf(Object x) {
42.929 + if (x != null) {
42.930 + if (x instanceof ScheduledFutureTask) {
42.931 + int i = ((ScheduledFutureTask) x).heapIndex;
42.932 + // Sanity check; x could conceivably be a
42.933 + // ScheduledFutureTask from some other pool.
42.934 + if (i >= 0 && i < size && queue[i] == x)
42.935 + return i;
42.936 + } else {
42.937 + for (int i = 0; i < size; i++)
42.938 + if (x.equals(queue[i]))
42.939 + return i;
42.940 + }
42.941 + }
42.942 + return -1;
42.943 + }
42.944 +
42.945 + public boolean contains(Object x) {
42.946 + final ReentrantLock lock = this.lock;
42.947 + lock.lock();
42.948 + try {
42.949 + return indexOf(x) != -1;
42.950 + } finally {
42.951 + lock.unlock();
42.952 + }
42.953 + }
42.954 +
42.955 + public boolean remove(Object x) {
42.956 + final ReentrantLock lock = this.lock;
42.957 + lock.lock();
42.958 + try {
42.959 + int i = indexOf(x);
42.960 + if (i < 0)
42.961 + return false;
42.962 +
42.963 + setIndex(queue[i], -1);
42.964 + int s = --size;
42.965 + RunnableScheduledFuture replacement = queue[s];
42.966 + queue[s] = null;
42.967 + if (s != i) {
42.968 + siftDown(i, replacement);
42.969 + if (queue[i] == replacement)
42.970 + siftUp(i, replacement);
42.971 + }
42.972 + return true;
42.973 + } finally {
42.974 + lock.unlock();
42.975 + }
42.976 + }
42.977 +
42.978 + public int size() {
42.979 + final ReentrantLock lock = this.lock;
42.980 + lock.lock();
42.981 + try {
42.982 + return size;
42.983 + } finally {
42.984 + lock.unlock();
42.985 + }
42.986 + }
42.987 +
42.988 + public boolean isEmpty() {
42.989 + return size() == 0;
42.990 + }
42.991 +
42.992 + public int remainingCapacity() {
42.993 + return Integer.MAX_VALUE;
42.994 + }
42.995 +
42.996 + public RunnableScheduledFuture peek() {
42.997 + final ReentrantLock lock = this.lock;
42.998 + lock.lock();
42.999 + try {
42.1000 + return queue[0];
42.1001 + } finally {
42.1002 + lock.unlock();
42.1003 + }
42.1004 + }
42.1005 +
42.1006 + public boolean offer(Runnable x) {
42.1007 + if (x == null)
42.1008 + throw new NullPointerException();
42.1009 + RunnableScheduledFuture e = (RunnableScheduledFuture)x;
42.1010 + final ReentrantLock lock = this.lock;
42.1011 + lock.lock();
42.1012 + try {
42.1013 + int i = size;
42.1014 + if (i >= queue.length)
42.1015 + grow();
42.1016 + size = i + 1;
42.1017 + if (i == 0) {
42.1018 + queue[0] = e;
42.1019 + setIndex(e, 0);
42.1020 + } else {
42.1021 + siftUp(i, e);
42.1022 + }
42.1023 + if (queue[0] == e) {
42.1024 + leader = null;
42.1025 + available.signal();
42.1026 + }
42.1027 + } finally {
42.1028 + lock.unlock();
42.1029 + }
42.1030 + return true;
42.1031 + }
42.1032 +
42.1033 + public void put(Runnable e) {
42.1034 + offer(e);
42.1035 + }
42.1036 +
42.1037 + public boolean add(Runnable e) {
42.1038 + return offer(e);
42.1039 + }
42.1040 +
42.1041 + public boolean offer(Runnable e, long timeout, TimeUnit unit) {
42.1042 + return offer(e);
42.1043 + }
42.1044 +
42.1045 + /**
42.1046 + * Performs common bookkeeping for poll and take: Replaces
42.1047 + * first element with last and sifts it down. Call only when
42.1048 + * holding lock.
42.1049 + * @param f the task to remove and return
42.1050 + */
42.1051 + private RunnableScheduledFuture finishPoll(RunnableScheduledFuture f) {
42.1052 + int s = --size;
42.1053 + RunnableScheduledFuture x = queue[s];
42.1054 + queue[s] = null;
42.1055 + if (s != 0)
42.1056 + siftDown(0, x);
42.1057 + setIndex(f, -1);
42.1058 + return f;
42.1059 + }
42.1060 +
42.1061 + public RunnableScheduledFuture poll() {
42.1062 + final ReentrantLock lock = this.lock;
42.1063 + lock.lock();
42.1064 + try {
42.1065 + RunnableScheduledFuture first = queue[0];
42.1066 + if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
42.1067 + return null;
42.1068 + else
42.1069 + return finishPoll(first);
42.1070 + } finally {
42.1071 + lock.unlock();
42.1072 + }
42.1073 + }
42.1074 +
42.1075 + public RunnableScheduledFuture take() throws InterruptedException {
42.1076 + final ReentrantLock lock = this.lock;
42.1077 + lock.lockInterruptibly();
42.1078 + try {
42.1079 + for (;;) {
42.1080 + RunnableScheduledFuture first = queue[0];
42.1081 + if (first == null)
42.1082 + available.await();
42.1083 + else {
42.1084 + long delay = first.getDelay(TimeUnit.NANOSECONDS);
42.1085 + if (delay <= 0)
42.1086 + return finishPoll(first);
42.1087 + else if (leader != null)
42.1088 + available.await();
42.1089 + else {
42.1090 + Thread thisThread = Thread.currentThread();
42.1091 + leader = thisThread;
42.1092 + try {
42.1093 + available.awaitNanos(delay);
42.1094 + } finally {
42.1095 + if (leader == thisThread)
42.1096 + leader = null;
42.1097 + }
42.1098 + }
42.1099 + }
42.1100 + }
42.1101 + } finally {
42.1102 + if (leader == null && queue[0] != null)
42.1103 + available.signal();
42.1104 + lock.unlock();
42.1105 + }
42.1106 + }
42.1107 +
42.1108 + public RunnableScheduledFuture poll(long timeout, TimeUnit unit)
42.1109 + throws InterruptedException {
42.1110 + long nanos = unit.toNanos(timeout);
42.1111 + final ReentrantLock lock = this.lock;
42.1112 + lock.lockInterruptibly();
42.1113 + try {
42.1114 + for (;;) {
42.1115 + RunnableScheduledFuture first = queue[0];
42.1116 + if (first == null) {
42.1117 + if (nanos <= 0)
42.1118 + return null;
42.1119 + else
42.1120 + nanos = available.awaitNanos(nanos);
42.1121 + } else {
42.1122 + long delay = first.getDelay(TimeUnit.NANOSECONDS);
42.1123 + if (delay <= 0)
42.1124 + return finishPoll(first);
42.1125 + if (nanos <= 0)
42.1126 + return null;
42.1127 + if (nanos < delay || leader != null)
42.1128 + nanos = available.awaitNanos(nanos);
42.1129 + else {
42.1130 + Thread thisThread = Thread.currentThread();
42.1131 + leader = thisThread;
42.1132 + try {
42.1133 + long timeLeft = available.awaitNanos(delay);
42.1134 + nanos -= delay - timeLeft;
42.1135 + } finally {
42.1136 + if (leader == thisThread)
42.1137 + leader = null;
42.1138 + }
42.1139 + }
42.1140 + }
42.1141 + }
42.1142 + } finally {
42.1143 + if (leader == null && queue[0] != null)
42.1144 + available.signal();
42.1145 + lock.unlock();
42.1146 + }
42.1147 + }
42.1148 +
42.1149 + public void clear() {
42.1150 + final ReentrantLock lock = this.lock;
42.1151 + lock.lock();
42.1152 + try {
42.1153 + for (int i = 0; i < size; i++) {
42.1154 + RunnableScheduledFuture t = queue[i];
42.1155 + if (t != null) {
42.1156 + queue[i] = null;
42.1157 + setIndex(t, -1);
42.1158 + }
42.1159 + }
42.1160 + size = 0;
42.1161 + } finally {
42.1162 + lock.unlock();
42.1163 + }
42.1164 + }
42.1165 +
42.1166 + /**
42.1167 + * Return and remove first element only if it is expired.
42.1168 + * Used only by drainTo. Call only when holding lock.
42.1169 + */
42.1170 + private RunnableScheduledFuture pollExpired() {
42.1171 + RunnableScheduledFuture first = queue[0];
42.1172 + if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
42.1173 + return null;
42.1174 + return finishPoll(first);
42.1175 + }
42.1176 +
42.1177 + public int drainTo(Collection<? super Runnable> c) {
42.1178 + if (c == null)
42.1179 + throw new NullPointerException();
42.1180 + if (c == this)
42.1181 + throw new IllegalArgumentException();
42.1182 + final ReentrantLock lock = this.lock;
42.1183 + lock.lock();
42.1184 + try {
42.1185 + RunnableScheduledFuture first;
42.1186 + int n = 0;
42.1187 + while ((first = pollExpired()) != null) {
42.1188 + c.add(first);
42.1189 + ++n;
42.1190 + }
42.1191 + return n;
42.1192 + } finally {
42.1193 + lock.unlock();
42.1194 + }
42.1195 + }
42.1196 +
42.1197 + public int drainTo(Collection<? super Runnable> c, int maxElements) {
42.1198 + if (c == null)
42.1199 + throw new NullPointerException();
42.1200 + if (c == this)
42.1201 + throw new IllegalArgumentException();
42.1202 + if (maxElements <= 0)
42.1203 + return 0;
42.1204 + final ReentrantLock lock = this.lock;
42.1205 + lock.lock();
42.1206 + try {
42.1207 + RunnableScheduledFuture first;
42.1208 + int n = 0;
42.1209 + while (n < maxElements && (first = pollExpired()) != null) {
42.1210 + c.add(first);
42.1211 + ++n;
42.1212 + }
42.1213 + return n;
42.1214 + } finally {
42.1215 + lock.unlock();
42.1216 + }
42.1217 + }
42.1218 +
42.1219 + public Object[] toArray() {
42.1220 + final ReentrantLock lock = this.lock;
42.1221 + lock.lock();
42.1222 + try {
42.1223 + return Arrays.copyOf(queue, size, Object[].class);
42.1224 + } finally {
42.1225 + lock.unlock();
42.1226 + }
42.1227 + }
42.1228 +
42.1229 + @SuppressWarnings("unchecked")
42.1230 + public <T> T[] toArray(T[] a) {
42.1231 + final ReentrantLock lock = this.lock;
42.1232 + lock.lock();
42.1233 + try {
42.1234 + if (a.length < size)
42.1235 + return (T[]) Arrays.copyOf(queue, size, a.getClass());
42.1236 + System.arraycopy(queue, 0, a, 0, size);
42.1237 + if (a.length > size)
42.1238 + a[size] = null;
42.1239 + return a;
42.1240 + } finally {
42.1241 + lock.unlock();
42.1242 + }
42.1243 + }
42.1244 +
42.1245 + public Iterator<Runnable> iterator() {
42.1246 + return new Itr(Arrays.copyOf(queue, size));
42.1247 + }
42.1248 +
42.1249 + /**
42.1250 + * Snapshot iterator that works off copy of underlying q array.
42.1251 + */
42.1252 + private class Itr implements Iterator<Runnable> {
42.1253 + final RunnableScheduledFuture[] array;
42.1254 + int cursor = 0; // index of next element to return
42.1255 + int lastRet = -1; // index of last element, or -1 if no such
42.1256 +
42.1257 + Itr(RunnableScheduledFuture[] array) {
42.1258 + this.array = array;
42.1259 + }
42.1260 +
42.1261 + public boolean hasNext() {
42.1262 + return cursor < array.length;
42.1263 + }
42.1264 +
42.1265 + public Runnable next() {
42.1266 + if (cursor >= array.length)
42.1267 + throw new NoSuchElementException();
42.1268 + lastRet = cursor;
42.1269 + return array[cursor++];
42.1270 + }
42.1271 +
42.1272 + public void remove() {
42.1273 + if (lastRet < 0)
42.1274 + throw new IllegalStateException();
42.1275 + DelayedWorkQueue.this.remove(array[lastRet]);
42.1276 + lastRet = -1;
42.1277 + }
42.1278 + }
42.1279 + }
42.1280 +}
43.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
43.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/Semaphore.java Sat Mar 19 10:48:29 2016 +0100
43.3 @@ -0,0 +1,713 @@
43.4 +/*
43.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
43.6 + *
43.7 + * This code is free software; you can redistribute it and/or modify it
43.8 + * under the terms of the GNU General Public License version 2 only, as
43.9 + * published by the Free Software Foundation. Oracle designates this
43.10 + * particular file as subject to the "Classpath" exception as provided
43.11 + * by Oracle in the LICENSE file that accompanied this code.
43.12 + *
43.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
43.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
43.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
43.16 + * version 2 for more details (a copy is included in the LICENSE file that
43.17 + * accompanied this code).
43.18 + *
43.19 + * You should have received a copy of the GNU General Public License version
43.20 + * 2 along with this work; if not, write to the Free Software Foundation,
43.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
43.22 + *
43.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
43.24 + * or visit www.oracle.com if you need additional information or have any
43.25 + * questions.
43.26 + */
43.27 +
43.28 +/*
43.29 + * This file is available under and governed by the GNU General Public
43.30 + * License version 2 only, as published by the Free Software Foundation.
43.31 + * However, the following notice accompanied the original version of this
43.32 + * file:
43.33 + *
43.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
43.35 + * Expert Group and released to the public domain, as explained at
43.36 + * http://creativecommons.org/publicdomain/zero/1.0/
43.37 + */
43.38 +
43.39 +package java.util.concurrent;
43.40 +import java.util.*;
43.41 +import java.util.concurrent.locks.*;
43.42 +import java.util.concurrent.atomic.*;
43.43 +
43.44 +/**
43.45 + * A counting semaphore. Conceptually, a semaphore maintains a set of
43.46 + * permits. Each {@link #acquire} blocks if necessary until a permit is
43.47 + * available, and then takes it. Each {@link #release} adds a permit,
43.48 + * potentially releasing a blocking acquirer.
43.49 + * However, no actual permit objects are used; the {@code Semaphore} just
43.50 + * keeps a count of the number available and acts accordingly.
43.51 + *
43.52 + * <p>Semaphores are often used to restrict the number of threads than can
43.53 + * access some (physical or logical) resource. For example, here is
43.54 + * a class that uses a semaphore to control access to a pool of items:
43.55 + * <pre>
43.56 + * class Pool {
43.57 + * private static final int MAX_AVAILABLE = 100;
43.58 + * private final Semaphore available = new Semaphore(MAX_AVAILABLE, true);
43.59 + *
43.60 + * public Object getItem() throws InterruptedException {
43.61 + * available.acquire();
43.62 + * return getNextAvailableItem();
43.63 + * }
43.64 + *
43.65 + * public void putItem(Object x) {
43.66 + * if (markAsUnused(x))
43.67 + * available.release();
43.68 + * }
43.69 + *
43.70 + * // Not a particularly efficient data structure; just for demo
43.71 + *
43.72 + * protected Object[] items = ... whatever kinds of items being managed
43.73 + * protected boolean[] used = new boolean[MAX_AVAILABLE];
43.74 + *
43.75 + * protected synchronized Object getNextAvailableItem() {
43.76 + * for (int i = 0; i < MAX_AVAILABLE; ++i) {
43.77 + * if (!used[i]) {
43.78 + * used[i] = true;
43.79 + * return items[i];
43.80 + * }
43.81 + * }
43.82 + * return null; // not reached
43.83 + * }
43.84 + *
43.85 + * protected synchronized boolean markAsUnused(Object item) {
43.86 + * for (int i = 0; i < MAX_AVAILABLE; ++i) {
43.87 + * if (item == items[i]) {
43.88 + * if (used[i]) {
43.89 + * used[i] = false;
43.90 + * return true;
43.91 + * } else
43.92 + * return false;
43.93 + * }
43.94 + * }
43.95 + * return false;
43.96 + * }
43.97 + *
43.98 + * }
43.99 + * </pre>
43.100 + *
43.101 + * <p>Before obtaining an item each thread must acquire a permit from
43.102 + * the semaphore, guaranteeing that an item is available for use. When
43.103 + * the thread has finished with the item it is returned back to the
43.104 + * pool and a permit is returned to the semaphore, allowing another
43.105 + * thread to acquire that item. Note that no synchronization lock is
43.106 + * held when {@link #acquire} is called as that would prevent an item
43.107 + * from being returned to the pool. The semaphore encapsulates the
43.108 + * synchronization needed to restrict access to the pool, separately
43.109 + * from any synchronization needed to maintain the consistency of the
43.110 + * pool itself.
43.111 + *
43.112 + * <p>A semaphore initialized to one, and which is used such that it
43.113 + * only has at most one permit available, can serve as a mutual
43.114 + * exclusion lock. This is more commonly known as a <em>binary
43.115 + * semaphore</em>, because it only has two states: one permit
43.116 + * available, or zero permits available. When used in this way, the
43.117 + * binary semaphore has the property (unlike many {@link Lock}
43.118 + * implementations), that the "lock" can be released by a
43.119 + * thread other than the owner (as semaphores have no notion of
43.120 + * ownership). This can be useful in some specialized contexts, such
43.121 + * as deadlock recovery.
43.122 + *
43.123 + * <p> The constructor for this class optionally accepts a
43.124 + * <em>fairness</em> parameter. When set false, this class makes no
43.125 + * guarantees about the order in which threads acquire permits. In
43.126 + * particular, <em>barging</em> is permitted, that is, a thread
43.127 + * invoking {@link #acquire} can be allocated a permit ahead of a
43.128 + * thread that has been waiting - logically the new thread places itself at
43.129 + * the head of the queue of waiting threads. When fairness is set true, the
43.130 + * semaphore guarantees that threads invoking any of the {@link
43.131 + * #acquire() acquire} methods are selected to obtain permits in the order in
43.132 + * which their invocation of those methods was processed
43.133 + * (first-in-first-out; FIFO). Note that FIFO ordering necessarily
43.134 + * applies to specific internal points of execution within these
43.135 + * methods. So, it is possible for one thread to invoke
43.136 + * {@code acquire} before another, but reach the ordering point after
43.137 + * the other, and similarly upon return from the method.
43.138 + * Also note that the untimed {@link #tryAcquire() tryAcquire} methods do not
43.139 + * honor the fairness setting, but will take any permits that are
43.140 + * available.
43.141 + *
43.142 + * <p>Generally, semaphores used to control resource access should be
43.143 + * initialized as fair, to ensure that no thread is starved out from
43.144 + * accessing a resource. When using semaphores for other kinds of
43.145 + * synchronization control, the throughput advantages of non-fair
43.146 + * ordering often outweigh fairness considerations.
43.147 + *
43.148 + * <p>This class also provides convenience methods to {@link
43.149 + * #acquire(int) acquire} and {@link #release(int) release} multiple
43.150 + * permits at a time. Beware of the increased risk of indefinite
43.151 + * postponement when these methods are used without fairness set true.
43.152 + *
43.153 + * <p>Memory consistency effects: Actions in a thread prior to calling
43.154 + * a "release" method such as {@code release()}
43.155 + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
43.156 + * actions following a successful "acquire" method such as {@code acquire()}
43.157 + * in another thread.
43.158 + *
43.159 + * @since 1.5
43.160 + * @author Doug Lea
43.161 + *
43.162 + */
43.163 +
43.164 +public class Semaphore implements java.io.Serializable {
43.165 + private static final long serialVersionUID = -3222578661600680210L;
43.166 + /** All mechanics via AbstractQueuedSynchronizer subclass */
43.167 + private final Sync sync;
43.168 +
43.169 + /**
43.170 + * Synchronization implementation for semaphore. Uses AQS state
43.171 + * to represent permits. Subclassed into fair and nonfair
43.172 + * versions.
43.173 + */
43.174 + abstract static class Sync extends AbstractQueuedSynchronizer {
43.175 + private static final long serialVersionUID = 1192457210091910933L;
43.176 +
43.177 + Sync(int permits) {
43.178 + setState(permits);
43.179 + }
43.180 +
43.181 + final int getPermits() {
43.182 + return getState();
43.183 + }
43.184 +
43.185 + final int nonfairTryAcquireShared(int acquires) {
43.186 + for (;;) {
43.187 + int available = getState();
43.188 + int remaining = available - acquires;
43.189 + if (remaining < 0 ||
43.190 + compareAndSetState(available, remaining))
43.191 + return remaining;
43.192 + }
43.193 + }
43.194 +
43.195 + protected final boolean tryReleaseShared(int releases) {
43.196 + for (;;) {
43.197 + int current = getState();
43.198 + int next = current + releases;
43.199 + if (next < current) // overflow
43.200 + throw new Error("Maximum permit count exceeded");
43.201 + if (compareAndSetState(current, next))
43.202 + return true;
43.203 + }
43.204 + }
43.205 +
43.206 + final void reducePermits(int reductions) {
43.207 + for (;;) {
43.208 + int current = getState();
43.209 + int next = current - reductions;
43.210 + if (next > current) // underflow
43.211 + throw new Error("Permit count underflow");
43.212 + if (compareAndSetState(current, next))
43.213 + return;
43.214 + }
43.215 + }
43.216 +
43.217 + final int drainPermits() {
43.218 + for (;;) {
43.219 + int current = getState();
43.220 + if (current == 0 || compareAndSetState(current, 0))
43.221 + return current;
43.222 + }
43.223 + }
43.224 + }
43.225 +
43.226 + /**
43.227 + * NonFair version
43.228 + */
43.229 + static final class NonfairSync extends Sync {
43.230 + private static final long serialVersionUID = -2694183684443567898L;
43.231 +
43.232 + NonfairSync(int permits) {
43.233 + super(permits);
43.234 + }
43.235 +
43.236 + protected int tryAcquireShared(int acquires) {
43.237 + return nonfairTryAcquireShared(acquires);
43.238 + }
43.239 + }
43.240 +
43.241 + /**
43.242 + * Fair version
43.243 + */
43.244 + static final class FairSync extends Sync {
43.245 + private static final long serialVersionUID = 2014338818796000944L;
43.246 +
43.247 + FairSync(int permits) {
43.248 + super(permits);
43.249 + }
43.250 +
43.251 + protected int tryAcquireShared(int acquires) {
43.252 + for (;;) {
43.253 + if (hasQueuedPredecessors())
43.254 + return -1;
43.255 + int available = getState();
43.256 + int remaining = available - acquires;
43.257 + if (remaining < 0 ||
43.258 + compareAndSetState(available, remaining))
43.259 + return remaining;
43.260 + }
43.261 + }
43.262 + }
43.263 +
43.264 + /**
43.265 + * Creates a {@code Semaphore} with the given number of
43.266 + * permits and nonfair fairness setting.
43.267 + *
43.268 + * @param permits the initial number of permits available.
43.269 + * This value may be negative, in which case releases
43.270 + * must occur before any acquires will be granted.
43.271 + */
43.272 + public Semaphore(int permits) {
43.273 + sync = new NonfairSync(permits);
43.274 + }
43.275 +
43.276 + /**
43.277 + * Creates a {@code Semaphore} with the given number of
43.278 + * permits and the given fairness setting.
43.279 + *
43.280 + * @param permits the initial number of permits available.
43.281 + * This value may be negative, in which case releases
43.282 + * must occur before any acquires will be granted.
43.283 + * @param fair {@code true} if this semaphore will guarantee
43.284 + * first-in first-out granting of permits under contention,
43.285 + * else {@code false}
43.286 + */
43.287 + public Semaphore(int permits, boolean fair) {
43.288 + sync = fair ? new FairSync(permits) : new NonfairSync(permits);
43.289 + }
43.290 +
43.291 + /**
43.292 + * Acquires a permit from this semaphore, blocking until one is
43.293 + * available, or the thread is {@linkplain Thread#interrupt interrupted}.
43.294 + *
43.295 + * <p>Acquires a permit, if one is available and returns immediately,
43.296 + * reducing the number of available permits by one.
43.297 + *
43.298 + * <p>If no permit is available then the current thread becomes
43.299 + * disabled for thread scheduling purposes and lies dormant until
43.300 + * one of two things happens:
43.301 + * <ul>
43.302 + * <li>Some other thread invokes the {@link #release} method for this
43.303 + * semaphore and the current thread is next to be assigned a permit; or
43.304 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
43.305 + * the current thread.
43.306 + * </ul>
43.307 + *
43.308 + * <p>If the current thread:
43.309 + * <ul>
43.310 + * <li>has its interrupted status set on entry to this method; or
43.311 + * <li>is {@linkplain Thread#interrupt interrupted} while waiting
43.312 + * for a permit,
43.313 + * </ul>
43.314 + * then {@link InterruptedException} is thrown and the current thread's
43.315 + * interrupted status is cleared.
43.316 + *
43.317 + * @throws InterruptedException if the current thread is interrupted
43.318 + */
43.319 + public void acquire() throws InterruptedException {
43.320 + sync.acquireSharedInterruptibly(1);
43.321 + }
43.322 +
43.323 + /**
43.324 + * Acquires a permit from this semaphore, blocking until one is
43.325 + * available.
43.326 + *
43.327 + * <p>Acquires a permit, if one is available and returns immediately,
43.328 + * reducing the number of available permits by one.
43.329 + *
43.330 + * <p>If no permit is available then the current thread becomes
43.331 + * disabled for thread scheduling purposes and lies dormant until
43.332 + * some other thread invokes the {@link #release} method for this
43.333 + * semaphore and the current thread is next to be assigned a permit.
43.334 + *
43.335 + * <p>If the current thread is {@linkplain Thread#interrupt interrupted}
43.336 + * while waiting for a permit then it will continue to wait, but the
43.337 + * time at which the thread is assigned a permit may change compared to
43.338 + * the time it would have received the permit had no interruption
43.339 + * occurred. When the thread does return from this method its interrupt
43.340 + * status will be set.
43.341 + */
43.342 + public void acquireUninterruptibly() {
43.343 + sync.acquireShared(1);
43.344 + }
43.345 +
43.346 + /**
43.347 + * Acquires a permit from this semaphore, only if one is available at the
43.348 + * time of invocation.
43.349 + *
43.350 + * <p>Acquires a permit, if one is available and returns immediately,
43.351 + * with the value {@code true},
43.352 + * reducing the number of available permits by one.
43.353 + *
43.354 + * <p>If no permit is available then this method will return
43.355 + * immediately with the value {@code false}.
43.356 + *
43.357 + * <p>Even when this semaphore has been set to use a
43.358 + * fair ordering policy, a call to {@code tryAcquire()} <em>will</em>
43.359 + * immediately acquire a permit if one is available, whether or not
43.360 + * other threads are currently waiting.
43.361 + * This "barging" behavior can be useful in certain
43.362 + * circumstances, even though it breaks fairness. If you want to honor
43.363 + * the fairness setting, then use
43.364 + * {@link #tryAcquire(long, TimeUnit) tryAcquire(0, TimeUnit.SECONDS) }
43.365 + * which is almost equivalent (it also detects interruption).
43.366 + *
43.367 + * @return {@code true} if a permit was acquired and {@code false}
43.368 + * otherwise
43.369 + */
43.370 + public boolean tryAcquire() {
43.371 + return sync.nonfairTryAcquireShared(1) >= 0;
43.372 + }
43.373 +
43.374 + /**
43.375 + * Acquires a permit from this semaphore, if one becomes available
43.376 + * within the given waiting time and the current thread has not
43.377 + * been {@linkplain Thread#interrupt interrupted}.
43.378 + *
43.379 + * <p>Acquires a permit, if one is available and returns immediately,
43.380 + * with the value {@code true},
43.381 + * reducing the number of available permits by one.
43.382 + *
43.383 + * <p>If no permit is available then the current thread becomes
43.384 + * disabled for thread scheduling purposes and lies dormant until
43.385 + * one of three things happens:
43.386 + * <ul>
43.387 + * <li>Some other thread invokes the {@link #release} method for this
43.388 + * semaphore and the current thread is next to be assigned a permit; or
43.389 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
43.390 + * the current thread; or
43.391 + * <li>The specified waiting time elapses.
43.392 + * </ul>
43.393 + *
43.394 + * <p>If a permit is acquired then the value {@code true} is returned.
43.395 + *
43.396 + * <p>If the current thread:
43.397 + * <ul>
43.398 + * <li>has its interrupted status set on entry to this method; or
43.399 + * <li>is {@linkplain Thread#interrupt interrupted} while waiting
43.400 + * to acquire a permit,
43.401 + * </ul>
43.402 + * then {@link InterruptedException} is thrown and the current thread's
43.403 + * interrupted status is cleared.
43.404 + *
43.405 + * <p>If the specified waiting time elapses then the value {@code false}
43.406 + * is returned. If the time is less than or equal to zero, the method
43.407 + * will not wait at all.
43.408 + *
43.409 + * @param timeout the maximum time to wait for a permit
43.410 + * @param unit the time unit of the {@code timeout} argument
43.411 + * @return {@code true} if a permit was acquired and {@code false}
43.412 + * if the waiting time elapsed before a permit was acquired
43.413 + * @throws InterruptedException if the current thread is interrupted
43.414 + */
43.415 + public boolean tryAcquire(long timeout, TimeUnit unit)
43.416 + throws InterruptedException {
43.417 + return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
43.418 + }
43.419 +
43.420 + /**
43.421 + * Releases a permit, returning it to the semaphore.
43.422 + *
43.423 + * <p>Releases a permit, increasing the number of available permits by
43.424 + * one. If any threads are trying to acquire a permit, then one is
43.425 + * selected and given the permit that was just released. That thread
43.426 + * is (re)enabled for thread scheduling purposes.
43.427 + *
43.428 + * <p>There is no requirement that a thread that releases a permit must
43.429 + * have acquired that permit by calling {@link #acquire}.
43.430 + * Correct usage of a semaphore is established by programming convention
43.431 + * in the application.
43.432 + */
43.433 + public void release() {
43.434 + sync.releaseShared(1);
43.435 + }
43.436 +
43.437 + /**
43.438 + * Acquires the given number of permits from this semaphore,
43.439 + * blocking until all are available,
43.440 + * or the thread is {@linkplain Thread#interrupt interrupted}.
43.441 + *
43.442 + * <p>Acquires the given number of permits, if they are available,
43.443 + * and returns immediately, reducing the number of available permits
43.444 + * by the given amount.
43.445 + *
43.446 + * <p>If insufficient permits are available then the current thread becomes
43.447 + * disabled for thread scheduling purposes and lies dormant until
43.448 + * one of two things happens:
43.449 + * <ul>
43.450 + * <li>Some other thread invokes one of the {@link #release() release}
43.451 + * methods for this semaphore, the current thread is next to be assigned
43.452 + * permits and the number of available permits satisfies this request; or
43.453 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
43.454 + * the current thread.
43.455 + * </ul>
43.456 + *
43.457 + * <p>If the current thread:
43.458 + * <ul>
43.459 + * <li>has its interrupted status set on entry to this method; or
43.460 + * <li>is {@linkplain Thread#interrupt interrupted} while waiting
43.461 + * for a permit,
43.462 + * </ul>
43.463 + * then {@link InterruptedException} is thrown and the current thread's
43.464 + * interrupted status is cleared.
43.465 + * Any permits that were to be assigned to this thread are instead
43.466 + * assigned to other threads trying to acquire permits, as if
43.467 + * permits had been made available by a call to {@link #release()}.
43.468 + *
43.469 + * @param permits the number of permits to acquire
43.470 + * @throws InterruptedException if the current thread is interrupted
43.471 + * @throws IllegalArgumentException if {@code permits} is negative
43.472 + */
43.473 + public void acquire(int permits) throws InterruptedException {
43.474 + if (permits < 0) throw new IllegalArgumentException();
43.475 + sync.acquireSharedInterruptibly(permits);
43.476 + }
43.477 +
43.478 + /**
43.479 + * Acquires the given number of permits from this semaphore,
43.480 + * blocking until all are available.
43.481 + *
43.482 + * <p>Acquires the given number of permits, if they are available,
43.483 + * and returns immediately, reducing the number of available permits
43.484 + * by the given amount.
43.485 + *
43.486 + * <p>If insufficient permits are available then the current thread becomes
43.487 + * disabled for thread scheduling purposes and lies dormant until
43.488 + * some other thread invokes one of the {@link #release() release}
43.489 + * methods for this semaphore, the current thread is next to be assigned
43.490 + * permits and the number of available permits satisfies this request.
43.491 + *
43.492 + * <p>If the current thread is {@linkplain Thread#interrupt interrupted}
43.493 + * while waiting for permits then it will continue to wait and its
43.494 + * position in the queue is not affected. When the thread does return
43.495 + * from this method its interrupt status will be set.
43.496 + *
43.497 + * @param permits the number of permits to acquire
43.498 + * @throws IllegalArgumentException if {@code permits} is negative
43.499 + *
43.500 + */
43.501 + public void acquireUninterruptibly(int permits) {
43.502 + if (permits < 0) throw new IllegalArgumentException();
43.503 + sync.acquireShared(permits);
43.504 + }
43.505 +
43.506 + /**
43.507 + * Acquires the given number of permits from this semaphore, only
43.508 + * if all are available at the time of invocation.
43.509 + *
43.510 + * <p>Acquires the given number of permits, if they are available, and
43.511 + * returns immediately, with the value {@code true},
43.512 + * reducing the number of available permits by the given amount.
43.513 + *
43.514 + * <p>If insufficient permits are available then this method will return
43.515 + * immediately with the value {@code false} and the number of available
43.516 + * permits is unchanged.
43.517 + *
43.518 + * <p>Even when this semaphore has been set to use a fair ordering
43.519 + * policy, a call to {@code tryAcquire} <em>will</em>
43.520 + * immediately acquire a permit if one is available, whether or
43.521 + * not other threads are currently waiting. This
43.522 + * "barging" behavior can be useful in certain
43.523 + * circumstances, even though it breaks fairness. If you want to
43.524 + * honor the fairness setting, then use {@link #tryAcquire(int,
43.525 + * long, TimeUnit) tryAcquire(permits, 0, TimeUnit.SECONDS) }
43.526 + * which is almost equivalent (it also detects interruption).
43.527 + *
43.528 + * @param permits the number of permits to acquire
43.529 + * @return {@code true} if the permits were acquired and
43.530 + * {@code false} otherwise
43.531 + * @throws IllegalArgumentException if {@code permits} is negative
43.532 + */
43.533 + public boolean tryAcquire(int permits) {
43.534 + if (permits < 0) throw new IllegalArgumentException();
43.535 + return sync.nonfairTryAcquireShared(permits) >= 0;
43.536 + }
43.537 +
43.538 + /**
43.539 + * Acquires the given number of permits from this semaphore, if all
43.540 + * become available within the given waiting time and the current
43.541 + * thread has not been {@linkplain Thread#interrupt interrupted}.
43.542 + *
43.543 + * <p>Acquires the given number of permits, if they are available and
43.544 + * returns immediately, with the value {@code true},
43.545 + * reducing the number of available permits by the given amount.
43.546 + *
43.547 + * <p>If insufficient permits are available then
43.548 + * the current thread becomes disabled for thread scheduling
43.549 + * purposes and lies dormant until one of three things happens:
43.550 + * <ul>
43.551 + * <li>Some other thread invokes one of the {@link #release() release}
43.552 + * methods for this semaphore, the current thread is next to be assigned
43.553 + * permits and the number of available permits satisfies this request; or
43.554 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
43.555 + * the current thread; or
43.556 + * <li>The specified waiting time elapses.
43.557 + * </ul>
43.558 + *
43.559 + * <p>If the permits are acquired then the value {@code true} is returned.
43.560 + *
43.561 + * <p>If the current thread:
43.562 + * <ul>
43.563 + * <li>has its interrupted status set on entry to this method; or
43.564 + * <li>is {@linkplain Thread#interrupt interrupted} while waiting
43.565 + * to acquire the permits,
43.566 + * </ul>
43.567 + * then {@link InterruptedException} is thrown and the current thread's
43.568 + * interrupted status is cleared.
43.569 + * Any permits that were to be assigned to this thread, are instead
43.570 + * assigned to other threads trying to acquire permits, as if
43.571 + * the permits had been made available by a call to {@link #release()}.
43.572 + *
43.573 + * <p>If the specified waiting time elapses then the value {@code false}
43.574 + * is returned. If the time is less than or equal to zero, the method
43.575 + * will not wait at all. Any permits that were to be assigned to this
43.576 + * thread, are instead assigned to other threads trying to acquire
43.577 + * permits, as if the permits had been made available by a call to
43.578 + * {@link #release()}.
43.579 + *
43.580 + * @param permits the number of permits to acquire
43.581 + * @param timeout the maximum time to wait for the permits
43.582 + * @param unit the time unit of the {@code timeout} argument
43.583 + * @return {@code true} if all permits were acquired and {@code false}
43.584 + * if the waiting time elapsed before all permits were acquired
43.585 + * @throws InterruptedException if the current thread is interrupted
43.586 + * @throws IllegalArgumentException if {@code permits} is negative
43.587 + */
43.588 + public boolean tryAcquire(int permits, long timeout, TimeUnit unit)
43.589 + throws InterruptedException {
43.590 + if (permits < 0) throw new IllegalArgumentException();
43.591 + return sync.tryAcquireSharedNanos(permits, unit.toNanos(timeout));
43.592 + }
43.593 +
43.594 + /**
43.595 + * Releases the given number of permits, returning them to the semaphore.
43.596 + *
43.597 + * <p>Releases the given number of permits, increasing the number of
43.598 + * available permits by that amount.
43.599 + * If any threads are trying to acquire permits, then one
43.600 + * is selected and given the permits that were just released.
43.601 + * If the number of available permits satisfies that thread's request
43.602 + * then that thread is (re)enabled for thread scheduling purposes;
43.603 + * otherwise the thread will wait until sufficient permits are available.
43.604 + * If there are still permits available
43.605 + * after this thread's request has been satisfied, then those permits
43.606 + * are assigned in turn to other threads trying to acquire permits.
43.607 + *
43.608 + * <p>There is no requirement that a thread that releases a permit must
43.609 + * have acquired that permit by calling {@link Semaphore#acquire acquire}.
43.610 + * Correct usage of a semaphore is established by programming convention
43.611 + * in the application.
43.612 + *
43.613 + * @param permits the number of permits to release
43.614 + * @throws IllegalArgumentException if {@code permits} is negative
43.615 + */
43.616 + public void release(int permits) {
43.617 + if (permits < 0) throw new IllegalArgumentException();
43.618 + sync.releaseShared(permits);
43.619 + }
43.620 +
43.621 + /**
43.622 + * Returns the current number of permits available in this semaphore.
43.623 + *
43.624 + * <p>This method is typically used for debugging and testing purposes.
43.625 + *
43.626 + * @return the number of permits available in this semaphore
43.627 + */
43.628 + public int availablePermits() {
43.629 + return sync.getPermits();
43.630 + }
43.631 +
43.632 + /**
43.633 + * Acquires and returns all permits that are immediately available.
43.634 + *
43.635 + * @return the number of permits acquired
43.636 + */
43.637 + public int drainPermits() {
43.638 + return sync.drainPermits();
43.639 + }
43.640 +
43.641 + /**
43.642 + * Shrinks the number of available permits by the indicated
43.643 + * reduction. This method can be useful in subclasses that use
43.644 + * semaphores to track resources that become unavailable. This
43.645 + * method differs from {@code acquire} in that it does not block
43.646 + * waiting for permits to become available.
43.647 + *
43.648 + * @param reduction the number of permits to remove
43.649 + * @throws IllegalArgumentException if {@code reduction} is negative
43.650 + */
43.651 + protected void reducePermits(int reduction) {
43.652 + if (reduction < 0) throw new IllegalArgumentException();
43.653 + sync.reducePermits(reduction);
43.654 + }
43.655 +
43.656 + /**
43.657 + * Returns {@code true} if this semaphore has fairness set true.
43.658 + *
43.659 + * @return {@code true} if this semaphore has fairness set true
43.660 + */
43.661 + public boolean isFair() {
43.662 + return sync instanceof FairSync;
43.663 + }
43.664 +
43.665 + /**
43.666 + * Queries whether any threads are waiting to acquire. Note that
43.667 + * because cancellations may occur at any time, a {@code true}
43.668 + * return does not guarantee that any other thread will ever
43.669 + * acquire. This method is designed primarily for use in
43.670 + * monitoring of the system state.
43.671 + *
43.672 + * @return {@code true} if there may be other threads waiting to
43.673 + * acquire the lock
43.674 + */
43.675 + public final boolean hasQueuedThreads() {
43.676 + return sync.hasQueuedThreads();
43.677 + }
43.678 +
43.679 + /**
43.680 + * Returns an estimate of the number of threads waiting to acquire.
43.681 + * The value is only an estimate because the number of threads may
43.682 + * change dynamically while this method traverses internal data
43.683 + * structures. This method is designed for use in monitoring of the
43.684 + * system state, not for synchronization control.
43.685 + *
43.686 + * @return the estimated number of threads waiting for this lock
43.687 + */
43.688 + public final int getQueueLength() {
43.689 + return sync.getQueueLength();
43.690 + }
43.691 +
43.692 + /**
43.693 + * Returns a collection containing threads that may be waiting to acquire.
43.694 + * Because the actual set of threads may change dynamically while
43.695 + * constructing this result, the returned collection is only a best-effort
43.696 + * estimate. The elements of the returned collection are in no particular
43.697 + * order. This method is designed to facilitate construction of
43.698 + * subclasses that provide more extensive monitoring facilities.
43.699 + *
43.700 + * @return the collection of threads
43.701 + */
43.702 + protected Collection<Thread> getQueuedThreads() {
43.703 + return sync.getQueuedThreads();
43.704 + }
43.705 +
43.706 + /**
43.707 + * Returns a string identifying this semaphore, as well as its state.
43.708 + * The state, in brackets, includes the String {@code "Permits ="}
43.709 + * followed by the number of permits.
43.710 + *
43.711 + * @return a string identifying this semaphore, as well as its state
43.712 + */
43.713 + public String toString() {
43.714 + return super.toString() + "[Permits = " + sync.getPermits() + "]";
43.715 + }
43.716 +}
44.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
44.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/SynchronousQueue.java Sat Mar 19 10:48:29 2016 +0100
44.3 @@ -0,0 +1,1196 @@
44.4 +/*
44.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44.6 + *
44.7 + * This code is free software; you can redistribute it and/or modify it
44.8 + * under the terms of the GNU General Public License version 2 only, as
44.9 + * published by the Free Software Foundation. Oracle designates this
44.10 + * particular file as subject to the "Classpath" exception as provided
44.11 + * by Oracle in the LICENSE file that accompanied this code.
44.12 + *
44.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
44.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
44.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
44.16 + * version 2 for more details (a copy is included in the LICENSE file that
44.17 + * accompanied this code).
44.18 + *
44.19 + * You should have received a copy of the GNU General Public License version
44.20 + * 2 along with this work; if not, write to the Free Software Foundation,
44.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
44.22 + *
44.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
44.24 + * or visit www.oracle.com if you need additional information or have any
44.25 + * questions.
44.26 + */
44.27 +
44.28 +/*
44.29 + * This file is available under and governed by the GNU General Public
44.30 + * License version 2 only, as published by the Free Software Foundation.
44.31 + * However, the following notice accompanied the original version of this
44.32 + * file:
44.33 + *
44.34 + * Written by Doug Lea, Bill Scherer, and Michael Scott with
44.35 + * assistance from members of JCP JSR-166 Expert Group and released to
44.36 + * the public domain, as explained at
44.37 + * http://creativecommons.org/publicdomain/zero/1.0/
44.38 + */
44.39 +
44.40 +package java.util.concurrent;
44.41 +import java.util.concurrent.locks.*;
44.42 +import java.util.concurrent.atomic.*;
44.43 +import java.util.*;
44.44 +
44.45 +/**
44.46 + * A {@linkplain BlockingQueue blocking queue} in which each insert
44.47 + * operation must wait for a corresponding remove operation by another
44.48 + * thread, and vice versa. A synchronous queue does not have any
44.49 + * internal capacity, not even a capacity of one. You cannot
44.50 + * <tt>peek</tt> at a synchronous queue because an element is only
44.51 + * present when you try to remove it; you cannot insert an element
44.52 + * (using any method) unless another thread is trying to remove it;
44.53 + * you cannot iterate as there is nothing to iterate. The
44.54 + * <em>head</em> of the queue is the element that the first queued
44.55 + * inserting thread is trying to add to the queue; if there is no such
44.56 + * queued thread then no element is available for removal and
44.57 + * <tt>poll()</tt> will return <tt>null</tt>. For purposes of other
44.58 + * <tt>Collection</tt> methods (for example <tt>contains</tt>), a
44.59 + * <tt>SynchronousQueue</tt> acts as an empty collection. This queue
44.60 + * does not permit <tt>null</tt> elements.
44.61 + *
44.62 + * <p>Synchronous queues are similar to rendezvous channels used in
44.63 + * CSP and Ada. They are well suited for handoff designs, in which an
44.64 + * object running in one thread must sync up with an object running
44.65 + * in another thread in order to hand it some information, event, or
44.66 + * task.
44.67 + *
44.68 + * <p> This class supports an optional fairness policy for ordering
44.69 + * waiting producer and consumer threads. By default, this ordering
44.70 + * is not guaranteed. However, a queue constructed with fairness set
44.71 + * to <tt>true</tt> grants threads access in FIFO order.
44.72 + *
44.73 + * <p>This class and its iterator implement all of the
44.74 + * <em>optional</em> methods of the {@link Collection} and {@link
44.75 + * Iterator} interfaces.
44.76 + *
44.77 + * <p>This class is a member of the
44.78 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
44.79 + * Java Collections Framework</a>.
44.80 + *
44.81 + * @since 1.5
44.82 + * @author Doug Lea and Bill Scherer and Michael Scott
44.83 + * @param <E> the type of elements held in this collection
44.84 + */
44.85 +public class SynchronousQueue<E> extends AbstractQueue<E>
44.86 + implements BlockingQueue<E>, java.io.Serializable {
44.87 + private static final long serialVersionUID = -3223113410248163686L;
44.88 +
44.89 + /*
44.90 + * This class implements extensions of the dual stack and dual
44.91 + * queue algorithms described in "Nonblocking Concurrent Objects
44.92 + * with Condition Synchronization", by W. N. Scherer III and
44.93 + * M. L. Scott. 18th Annual Conf. on Distributed Computing,
44.94 + * Oct. 2004 (see also
44.95 + * http://www.cs.rochester.edu/u/scott/synchronization/pseudocode/duals.html).
44.96 + * The (Lifo) stack is used for non-fair mode, and the (Fifo)
44.97 + * queue for fair mode. The performance of the two is generally
44.98 + * similar. Fifo usually supports higher throughput under
44.99 + * contention but Lifo maintains higher thread locality in common
44.100 + * applications.
44.101 + *
44.102 + * A dual queue (and similarly stack) is one that at any given
44.103 + * time either holds "data" -- items provided by put operations,
44.104 + * or "requests" -- slots representing take operations, or is
44.105 + * empty. A call to "fulfill" (i.e., a call requesting an item
44.106 + * from a queue holding data or vice versa) dequeues a
44.107 + * complementary node. The most interesting feature of these
44.108 + * queues is that any operation can figure out which mode the
44.109 + * queue is in, and act accordingly without needing locks.
44.110 + *
44.111 + * Both the queue and stack extend abstract class Transferer
44.112 + * defining the single method transfer that does a put or a
44.113 + * take. These are unified into a single method because in dual
44.114 + * data structures, the put and take operations are symmetrical,
44.115 + * so nearly all code can be combined. The resulting transfer
44.116 + * methods are on the long side, but are easier to follow than
44.117 + * they would be if broken up into nearly-duplicated parts.
44.118 + *
44.119 + * The queue and stack data structures share many conceptual
44.120 + * similarities but very few concrete details. For simplicity,
44.121 + * they are kept distinct so that they can later evolve
44.122 + * separately.
44.123 + *
44.124 + * The algorithms here differ from the versions in the above paper
44.125 + * in extending them for use in synchronous queues, as well as
44.126 + * dealing with cancellation. The main differences include:
44.127 + *
44.128 + * 1. The original algorithms used bit-marked pointers, but
44.129 + * the ones here use mode bits in nodes, leading to a number
44.130 + * of further adaptations.
44.131 + * 2. SynchronousQueues must block threads waiting to become
44.132 + * fulfilled.
44.133 + * 3. Support for cancellation via timeout and interrupts,
44.134 + * including cleaning out cancelled nodes/threads
44.135 + * from lists to avoid garbage retention and memory depletion.
44.136 + *
44.137 + * Blocking is mainly accomplished using LockSupport park/unpark,
44.138 + * except that nodes that appear to be the next ones to become
44.139 + * fulfilled first spin a bit (on multiprocessors only). On very
44.140 + * busy synchronous queues, spinning can dramatically improve
44.141 + * throughput. And on less busy ones, the amount of spinning is
44.142 + * small enough not to be noticeable.
44.143 + *
44.144 + * Cleaning is done in different ways in queues vs stacks. For
44.145 + * queues, we can almost always remove a node immediately in O(1)
44.146 + * time (modulo retries for consistency checks) when it is
44.147 + * cancelled. But if it may be pinned as the current tail, it must
44.148 + * wait until some subsequent cancellation. For stacks, we need a
44.149 + * potentially O(n) traversal to be sure that we can remove the
44.150 + * node, but this can run concurrently with other threads
44.151 + * accessing the stack.
44.152 + *
44.153 + * While garbage collection takes care of most node reclamation
44.154 + * issues that otherwise complicate nonblocking algorithms, care
44.155 + * is taken to "forget" references to data, other nodes, and
44.156 + * threads that might be held on to long-term by blocked
44.157 + * threads. In cases where setting to null would otherwise
44.158 + * conflict with main algorithms, this is done by changing a
44.159 + * node's link to now point to the node itself. This doesn't arise
44.160 + * much for Stack nodes (because blocked threads do not hang on to
44.161 + * old head pointers), but references in Queue nodes must be
44.162 + * aggressively forgotten to avoid reachability of everything any
44.163 + * node has ever referred to since arrival.
44.164 + */
44.165 +
44.166 + /**
44.167 + * Shared internal API for dual stacks and queues.
44.168 + */
44.169 + abstract static class Transferer {
44.170 + /**
44.171 + * Performs a put or take.
44.172 + *
44.173 + * @param e if non-null, the item to be handed to a consumer;
44.174 + * if null, requests that transfer return an item
44.175 + * offered by producer.
44.176 + * @param timed if this operation should timeout
44.177 + * @param nanos the timeout, in nanoseconds
44.178 + * @return if non-null, the item provided or received; if null,
44.179 + * the operation failed due to timeout or interrupt --
44.180 + * the caller can distinguish which of these occurred
44.181 + * by checking Thread.interrupted.
44.182 + */
44.183 + abstract Object transfer(Object e, boolean timed, long nanos);
44.184 + }
44.185 +
44.186 + /** The number of CPUs, for spin control */
44.187 + static final int NCPUS = Runtime.getRuntime().availableProcessors();
44.188 +
44.189 + /**
44.190 + * The number of times to spin before blocking in timed waits.
44.191 + * The value is empirically derived -- it works well across a
44.192 + * variety of processors and OSes. Empirically, the best value
44.193 + * seems not to vary with number of CPUs (beyond 2) so is just
44.194 + * a constant.
44.195 + */
44.196 + static final int maxTimedSpins = (NCPUS < 2) ? 0 : 32;
44.197 +
44.198 + /**
44.199 + * The number of times to spin before blocking in untimed waits.
44.200 + * This is greater than timed value because untimed waits spin
44.201 + * faster since they don't need to check times on each spin.
44.202 + */
44.203 + static final int maxUntimedSpins = maxTimedSpins * 16;
44.204 +
44.205 + /**
44.206 + * The number of nanoseconds for which it is faster to spin
44.207 + * rather than to use timed park. A rough estimate suffices.
44.208 + */
44.209 + static final long spinForTimeoutThreshold = 1000L;
44.210 +
44.211 + /** Dual stack */
44.212 + static final class TransferStack extends Transferer {
44.213 + /*
44.214 + * This extends Scherer-Scott dual stack algorithm, differing,
44.215 + * among other ways, by using "covering" nodes rather than
44.216 + * bit-marked pointers: Fulfilling operations push on marker
44.217 + * nodes (with FULFILLING bit set in mode) to reserve a spot
44.218 + * to match a waiting node.
44.219 + */
44.220 +
44.221 + /* Modes for SNodes, ORed together in node fields */
44.222 + /** Node represents an unfulfilled consumer */
44.223 + static final int REQUEST = 0;
44.224 + /** Node represents an unfulfilled producer */
44.225 + static final int DATA = 1;
44.226 + /** Node is fulfilling another unfulfilled DATA or REQUEST */
44.227 + static final int FULFILLING = 2;
44.228 +
44.229 + /** Return true if m has fulfilling bit set */
44.230 + static boolean isFulfilling(int m) { return (m & FULFILLING) != 0; }
44.231 +
44.232 + /** Node class for TransferStacks. */
44.233 + static final class SNode {
44.234 + volatile SNode next; // next node in stack
44.235 + volatile SNode match; // the node matched to this
44.236 + volatile Thread waiter; // to control park/unpark
44.237 + Object item; // data; or null for REQUESTs
44.238 + int mode;
44.239 + // Note: item and mode fields don't need to be volatile
44.240 + // since they are always written before, and read after,
44.241 + // other volatile/atomic operations.
44.242 +
44.243 + SNode(Object item) {
44.244 + this.item = item;
44.245 + }
44.246 +
44.247 + boolean casNext(SNode cmp, SNode val) {
44.248 + return cmp == next &&
44.249 + UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
44.250 + }
44.251 +
44.252 + /**
44.253 + * Tries to match node s to this node, if so, waking up thread.
44.254 + * Fulfillers call tryMatch to identify their waiters.
44.255 + * Waiters block until they have been matched.
44.256 + *
44.257 + * @param s the node to match
44.258 + * @return true if successfully matched to s
44.259 + */
44.260 + boolean tryMatch(SNode s) {
44.261 + if (match == null &&
44.262 + UNSAFE.compareAndSwapObject(this, matchOffset, null, s)) {
44.263 + Thread w = waiter;
44.264 + if (w != null) { // waiters need at most one unpark
44.265 + waiter = null;
44.266 + LockSupport.unpark(w);
44.267 + }
44.268 + return true;
44.269 + }
44.270 + return match == s;
44.271 + }
44.272 +
44.273 + /**
44.274 + * Tries to cancel a wait by matching node to itself.
44.275 + */
44.276 + void tryCancel() {
44.277 + UNSAFE.compareAndSwapObject(this, matchOffset, null, this);
44.278 + }
44.279 +
44.280 + boolean isCancelled() {
44.281 + return match == this;
44.282 + }
44.283 +
44.284 + // Unsafe mechanics
44.285 + private static final sun.misc.Unsafe UNSAFE;
44.286 + private static final long matchOffset;
44.287 + private static final long nextOffset;
44.288 +
44.289 + static {
44.290 + try {
44.291 + UNSAFE = sun.misc.Unsafe.getUnsafe();
44.292 + Class k = SNode.class;
44.293 + matchOffset = UNSAFE.objectFieldOffset
44.294 + (k.getDeclaredField("match"));
44.295 + nextOffset = UNSAFE.objectFieldOffset
44.296 + (k.getDeclaredField("next"));
44.297 + } catch (Exception e) {
44.298 + throw new Error(e);
44.299 + }
44.300 + }
44.301 + }
44.302 +
44.303 + /** The head (top) of the stack */
44.304 + volatile SNode head;
44.305 +
44.306 + boolean casHead(SNode h, SNode nh) {
44.307 + return h == head &&
44.308 + UNSAFE.compareAndSwapObject(this, headOffset, h, nh);
44.309 + }
44.310 +
44.311 + /**
44.312 + * Creates or resets fields of a node. Called only from transfer
44.313 + * where the node to push on stack is lazily created and
44.314 + * reused when possible to help reduce intervals between reads
44.315 + * and CASes of head and to avoid surges of garbage when CASes
44.316 + * to push nodes fail due to contention.
44.317 + */
44.318 + static SNode snode(SNode s, Object e, SNode next, int mode) {
44.319 + if (s == null) s = new SNode(e);
44.320 + s.mode = mode;
44.321 + s.next = next;
44.322 + return s;
44.323 + }
44.324 +
44.325 + /**
44.326 + * Puts or takes an item.
44.327 + */
44.328 + Object transfer(Object e, boolean timed, long nanos) {
44.329 + /*
44.330 + * Basic algorithm is to loop trying one of three actions:
44.331 + *
44.332 + * 1. If apparently empty or already containing nodes of same
44.333 + * mode, try to push node on stack and wait for a match,
44.334 + * returning it, or null if cancelled.
44.335 + *
44.336 + * 2. If apparently containing node of complementary mode,
44.337 + * try to push a fulfilling node on to stack, match
44.338 + * with corresponding waiting node, pop both from
44.339 + * stack, and return matched item. The matching or
44.340 + * unlinking might not actually be necessary because of
44.341 + * other threads performing action 3:
44.342 + *
44.343 + * 3. If top of stack already holds another fulfilling node,
44.344 + * help it out by doing its match and/or pop
44.345 + * operations, and then continue. The code for helping
44.346 + * is essentially the same as for fulfilling, except
44.347 + * that it doesn't return the item.
44.348 + */
44.349 +
44.350 + SNode s = null; // constructed/reused as needed
44.351 + int mode = (e == null) ? REQUEST : DATA;
44.352 +
44.353 + for (;;) {
44.354 + SNode h = head;
44.355 + if (h == null || h.mode == mode) { // empty or same-mode
44.356 + if (timed && nanos <= 0) { // can't wait
44.357 + if (h != null && h.isCancelled())
44.358 + casHead(h, h.next); // pop cancelled node
44.359 + else
44.360 + return null;
44.361 + } else if (casHead(h, s = snode(s, e, h, mode))) {
44.362 + SNode m = awaitFulfill(s, timed, nanos);
44.363 + if (m == s) { // wait was cancelled
44.364 + clean(s);
44.365 + return null;
44.366 + }
44.367 + if ((h = head) != null && h.next == s)
44.368 + casHead(h, s.next); // help s's fulfiller
44.369 + return (mode == REQUEST) ? m.item : s.item;
44.370 + }
44.371 + } else if (!isFulfilling(h.mode)) { // try to fulfill
44.372 + if (h.isCancelled()) // already cancelled
44.373 + casHead(h, h.next); // pop and retry
44.374 + else if (casHead(h, s=snode(s, e, h, FULFILLING|mode))) {
44.375 + for (;;) { // loop until matched or waiters disappear
44.376 + SNode m = s.next; // m is s's match
44.377 + if (m == null) { // all waiters are gone
44.378 + casHead(s, null); // pop fulfill node
44.379 + s = null; // use new node next time
44.380 + break; // restart main loop
44.381 + }
44.382 + SNode mn = m.next;
44.383 + if (m.tryMatch(s)) {
44.384 + casHead(s, mn); // pop both s and m
44.385 + return (mode == REQUEST) ? m.item : s.item;
44.386 + } else // lost match
44.387 + s.casNext(m, mn); // help unlink
44.388 + }
44.389 + }
44.390 + } else { // help a fulfiller
44.391 + SNode m = h.next; // m is h's match
44.392 + if (m == null) // waiter is gone
44.393 + casHead(h, null); // pop fulfilling node
44.394 + else {
44.395 + SNode mn = m.next;
44.396 + if (m.tryMatch(h)) // help match
44.397 + casHead(h, mn); // pop both h and m
44.398 + else // lost match
44.399 + h.casNext(m, mn); // help unlink
44.400 + }
44.401 + }
44.402 + }
44.403 + }
44.404 +
44.405 + /**
44.406 + * Spins/blocks until node s is matched by a fulfill operation.
44.407 + *
44.408 + * @param s the waiting node
44.409 + * @param timed true if timed wait
44.410 + * @param nanos timeout value
44.411 + * @return matched node, or s if cancelled
44.412 + */
44.413 + SNode awaitFulfill(SNode s, boolean timed, long nanos) {
44.414 + /*
44.415 + * When a node/thread is about to block, it sets its waiter
44.416 + * field and then rechecks state at least one more time
44.417 + * before actually parking, thus covering race vs
44.418 + * fulfiller noticing that waiter is non-null so should be
44.419 + * woken.
44.420 + *
44.421 + * When invoked by nodes that appear at the point of call
44.422 + * to be at the head of the stack, calls to park are
44.423 + * preceded by spins to avoid blocking when producers and
44.424 + * consumers are arriving very close in time. This can
44.425 + * happen enough to bother only on multiprocessors.
44.426 + *
44.427 + * The order of checks for returning out of main loop
44.428 + * reflects fact that interrupts have precedence over
44.429 + * normal returns, which have precedence over
44.430 + * timeouts. (So, on timeout, one last check for match is
44.431 + * done before giving up.) Except that calls from untimed
44.432 + * SynchronousQueue.{poll/offer} don't check interrupts
44.433 + * and don't wait at all, so are trapped in transfer
44.434 + * method rather than calling awaitFulfill.
44.435 + */
44.436 + long lastTime = timed ? System.nanoTime() : 0;
44.437 + Thread w = Thread.currentThread();
44.438 + SNode h = head;
44.439 + int spins = (shouldSpin(s) ?
44.440 + (timed ? maxTimedSpins : maxUntimedSpins) : 0);
44.441 + for (;;) {
44.442 + if (w.isInterrupted())
44.443 + s.tryCancel();
44.444 + SNode m = s.match;
44.445 + if (m != null)
44.446 + return m;
44.447 + if (timed) {
44.448 + long now = System.nanoTime();
44.449 + nanos -= now - lastTime;
44.450 + lastTime = now;
44.451 + if (nanos <= 0) {
44.452 + s.tryCancel();
44.453 + continue;
44.454 + }
44.455 + }
44.456 + if (spins > 0)
44.457 + spins = shouldSpin(s) ? (spins-1) : 0;
44.458 + else if (s.waiter == null)
44.459 + s.waiter = w; // establish waiter so can park next iter
44.460 + else if (!timed)
44.461 + LockSupport.park(this);
44.462 + else if (nanos > spinForTimeoutThreshold)
44.463 + LockSupport.parkNanos(this, nanos);
44.464 + }
44.465 + }
44.466 +
44.467 + /**
44.468 + * Returns true if node s is at head or there is an active
44.469 + * fulfiller.
44.470 + */
44.471 + boolean shouldSpin(SNode s) {
44.472 + SNode h = head;
44.473 + return (h == s || h == null || isFulfilling(h.mode));
44.474 + }
44.475 +
44.476 + /**
44.477 + * Unlinks s from the stack.
44.478 + */
44.479 + void clean(SNode s) {
44.480 + s.item = null; // forget item
44.481 + s.waiter = null; // forget thread
44.482 +
44.483 + /*
44.484 + * At worst we may need to traverse entire stack to unlink
44.485 + * s. If there are multiple concurrent calls to clean, we
44.486 + * might not see s if another thread has already removed
44.487 + * it. But we can stop when we see any node known to
44.488 + * follow s. We use s.next unless it too is cancelled, in
44.489 + * which case we try the node one past. We don't check any
44.490 + * further because we don't want to doubly traverse just to
44.491 + * find sentinel.
44.492 + */
44.493 +
44.494 + SNode past = s.next;
44.495 + if (past != null && past.isCancelled())
44.496 + past = past.next;
44.497 +
44.498 + // Absorb cancelled nodes at head
44.499 + SNode p;
44.500 + while ((p = head) != null && p != past && p.isCancelled())
44.501 + casHead(p, p.next);
44.502 +
44.503 + // Unsplice embedded nodes
44.504 + while (p != null && p != past) {
44.505 + SNode n = p.next;
44.506 + if (n != null && n.isCancelled())
44.507 + p.casNext(n, n.next);
44.508 + else
44.509 + p = n;
44.510 + }
44.511 + }
44.512 +
44.513 + // Unsafe mechanics
44.514 + private static final sun.misc.Unsafe UNSAFE;
44.515 + private static final long headOffset;
44.516 + static {
44.517 + try {
44.518 + UNSAFE = sun.misc.Unsafe.getUnsafe();
44.519 + Class k = TransferStack.class;
44.520 + headOffset = UNSAFE.objectFieldOffset
44.521 + (k.getDeclaredField("head"));
44.522 + } catch (Exception e) {
44.523 + throw new Error(e);
44.524 + }
44.525 + }
44.526 + }
44.527 +
44.528 + /** Dual Queue */
44.529 + static final class TransferQueue extends Transferer {
44.530 + /*
44.531 + * This extends Scherer-Scott dual queue algorithm, differing,
44.532 + * among other ways, by using modes within nodes rather than
44.533 + * marked pointers. The algorithm is a little simpler than
44.534 + * that for stacks because fulfillers do not need explicit
44.535 + * nodes, and matching is done by CAS'ing QNode.item field
44.536 + * from non-null to null (for put) or vice versa (for take).
44.537 + */
44.538 +
44.539 + /** Node class for TransferQueue. */
44.540 + static final class QNode {
44.541 + volatile QNode next; // next node in queue
44.542 + volatile Object item; // CAS'ed to or from null
44.543 + volatile Thread waiter; // to control park/unpark
44.544 + final boolean isData;
44.545 +
44.546 + QNode(Object item, boolean isData) {
44.547 + this.item = item;
44.548 + this.isData = isData;
44.549 + }
44.550 +
44.551 + boolean casNext(QNode cmp, QNode val) {
44.552 + return next == cmp &&
44.553 + UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
44.554 + }
44.555 +
44.556 + boolean casItem(Object cmp, Object val) {
44.557 + return item == cmp &&
44.558 + UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);
44.559 + }
44.560 +
44.561 + /**
44.562 + * Tries to cancel by CAS'ing ref to this as item.
44.563 + */
44.564 + void tryCancel(Object cmp) {
44.565 + UNSAFE.compareAndSwapObject(this, itemOffset, cmp, this);
44.566 + }
44.567 +
44.568 + boolean isCancelled() {
44.569 + return item == this;
44.570 + }
44.571 +
44.572 + /**
44.573 + * Returns true if this node is known to be off the queue
44.574 + * because its next pointer has been forgotten due to
44.575 + * an advanceHead operation.
44.576 + */
44.577 + boolean isOffList() {
44.578 + return next == this;
44.579 + }
44.580 +
44.581 + // Unsafe mechanics
44.582 + private static final sun.misc.Unsafe UNSAFE;
44.583 + private static final long itemOffset;
44.584 + private static final long nextOffset;
44.585 +
44.586 + static {
44.587 + try {
44.588 + UNSAFE = sun.misc.Unsafe.getUnsafe();
44.589 + Class k = QNode.class;
44.590 + itemOffset = UNSAFE.objectFieldOffset
44.591 + (k.getDeclaredField("item"));
44.592 + nextOffset = UNSAFE.objectFieldOffset
44.593 + (k.getDeclaredField("next"));
44.594 + } catch (Exception e) {
44.595 + throw new Error(e);
44.596 + }
44.597 + }
44.598 + }
44.599 +
44.600 + /** Head of queue */
44.601 + transient volatile QNode head;
44.602 + /** Tail of queue */
44.603 + transient volatile QNode tail;
44.604 + /**
44.605 + * Reference to a cancelled node that might not yet have been
44.606 + * unlinked from queue because it was the last inserted node
44.607 + * when it cancelled.
44.608 + */
44.609 + transient volatile QNode cleanMe;
44.610 +
44.611 + TransferQueue() {
44.612 + QNode h = new QNode(null, false); // initialize to dummy node.
44.613 + head = h;
44.614 + tail = h;
44.615 + }
44.616 +
44.617 + /**
44.618 + * Tries to cas nh as new head; if successful, unlink
44.619 + * old head's next node to avoid garbage retention.
44.620 + */
44.621 + void advanceHead(QNode h, QNode nh) {
44.622 + if (h == head &&
44.623 + UNSAFE.compareAndSwapObject(this, headOffset, h, nh))
44.624 + h.next = h; // forget old next
44.625 + }
44.626 +
44.627 + /**
44.628 + * Tries to cas nt as new tail.
44.629 + */
44.630 + void advanceTail(QNode t, QNode nt) {
44.631 + if (tail == t)
44.632 + UNSAFE.compareAndSwapObject(this, tailOffset, t, nt);
44.633 + }
44.634 +
44.635 + /**
44.636 + * Tries to CAS cleanMe slot.
44.637 + */
44.638 + boolean casCleanMe(QNode cmp, QNode val) {
44.639 + return cleanMe == cmp &&
44.640 + UNSAFE.compareAndSwapObject(this, cleanMeOffset, cmp, val);
44.641 + }
44.642 +
44.643 + /**
44.644 + * Puts or takes an item.
44.645 + */
44.646 + Object transfer(Object e, boolean timed, long nanos) {
44.647 + /* Basic algorithm is to loop trying to take either of
44.648 + * two actions:
44.649 + *
44.650 + * 1. If queue apparently empty or holding same-mode nodes,
44.651 + * try to add node to queue of waiters, wait to be
44.652 + * fulfilled (or cancelled) and return matching item.
44.653 + *
44.654 + * 2. If queue apparently contains waiting items, and this
44.655 + * call is of complementary mode, try to fulfill by CAS'ing
44.656 + * item field of waiting node and dequeuing it, and then
44.657 + * returning matching item.
44.658 + *
44.659 + * In each case, along the way, check for and try to help
44.660 + * advance head and tail on behalf of other stalled/slow
44.661 + * threads.
44.662 + *
44.663 + * The loop starts off with a null check guarding against
44.664 + * seeing uninitialized head or tail values. This never
44.665 + * happens in current SynchronousQueue, but could if
44.666 + * callers held non-volatile/final ref to the
44.667 + * transferer. The check is here anyway because it places
44.668 + * null checks at top of loop, which is usually faster
44.669 + * than having them implicitly interspersed.
44.670 + */
44.671 +
44.672 + QNode s = null; // constructed/reused as needed
44.673 + boolean isData = (e != null);
44.674 +
44.675 + for (;;) {
44.676 + QNode t = tail;
44.677 + QNode h = head;
44.678 + if (t == null || h == null) // saw uninitialized value
44.679 + continue; // spin
44.680 +
44.681 + if (h == t || t.isData == isData) { // empty or same-mode
44.682 + QNode tn = t.next;
44.683 + if (t != tail) // inconsistent read
44.684 + continue;
44.685 + if (tn != null) { // lagging tail
44.686 + advanceTail(t, tn);
44.687 + continue;
44.688 + }
44.689 + if (timed && nanos <= 0) // can't wait
44.690 + return null;
44.691 + if (s == null)
44.692 + s = new QNode(e, isData);
44.693 + if (!t.casNext(null, s)) // failed to link in
44.694 + continue;
44.695 +
44.696 + advanceTail(t, s); // swing tail and wait
44.697 + Object x = awaitFulfill(s, e, timed, nanos);
44.698 + if (x == s) { // wait was cancelled
44.699 + clean(t, s);
44.700 + return null;
44.701 + }
44.702 +
44.703 + if (!s.isOffList()) { // not already unlinked
44.704 + advanceHead(t, s); // unlink if head
44.705 + if (x != null) // and forget fields
44.706 + s.item = s;
44.707 + s.waiter = null;
44.708 + }
44.709 + return (x != null) ? x : e;
44.710 +
44.711 + } else { // complementary-mode
44.712 + QNode m = h.next; // node to fulfill
44.713 + if (t != tail || m == null || h != head)
44.714 + continue; // inconsistent read
44.715 +
44.716 + Object x = m.item;
44.717 + if (isData == (x != null) || // m already fulfilled
44.718 + x == m || // m cancelled
44.719 + !m.casItem(x, e)) { // lost CAS
44.720 + advanceHead(h, m); // dequeue and retry
44.721 + continue;
44.722 + }
44.723 +
44.724 + advanceHead(h, m); // successfully fulfilled
44.725 + LockSupport.unpark(m.waiter);
44.726 + return (x != null) ? x : e;
44.727 + }
44.728 + }
44.729 + }
44.730 +
44.731 + /**
44.732 + * Spins/blocks until node s is fulfilled.
44.733 + *
44.734 + * @param s the waiting node
44.735 + * @param e the comparison value for checking match
44.736 + * @param timed true if timed wait
44.737 + * @param nanos timeout value
44.738 + * @return matched item, or s if cancelled
44.739 + */
44.740 + Object awaitFulfill(QNode s, Object e, boolean timed, long nanos) {
44.741 + /* Same idea as TransferStack.awaitFulfill */
44.742 + long lastTime = timed ? System.nanoTime() : 0;
44.743 + Thread w = Thread.currentThread();
44.744 + int spins = ((head.next == s) ?
44.745 + (timed ? maxTimedSpins : maxUntimedSpins) : 0);
44.746 + for (;;) {
44.747 + if (w.isInterrupted())
44.748 + s.tryCancel(e);
44.749 + Object x = s.item;
44.750 + if (x != e)
44.751 + return x;
44.752 + if (timed) {
44.753 + long now = System.nanoTime();
44.754 + nanos -= now - lastTime;
44.755 + lastTime = now;
44.756 + if (nanos <= 0) {
44.757 + s.tryCancel(e);
44.758 + continue;
44.759 + }
44.760 + }
44.761 + if (spins > 0)
44.762 + --spins;
44.763 + else if (s.waiter == null)
44.764 + s.waiter = w;
44.765 + else if (!timed)
44.766 + LockSupport.park(this);
44.767 + else if (nanos > spinForTimeoutThreshold)
44.768 + LockSupport.parkNanos(this, nanos);
44.769 + }
44.770 + }
44.771 +
44.772 + /**
44.773 + * Gets rid of cancelled node s with original predecessor pred.
44.774 + */
44.775 + void clean(QNode pred, QNode s) {
44.776 + s.waiter = null; // forget thread
44.777 + /*
44.778 + * At any given time, exactly one node on list cannot be
44.779 + * deleted -- the last inserted node. To accommodate this,
44.780 + * if we cannot delete s, we save its predecessor as
44.781 + * "cleanMe", deleting the previously saved version
44.782 + * first. At least one of node s or the node previously
44.783 + * saved can always be deleted, so this always terminates.
44.784 + */
44.785 + while (pred.next == s) { // Return early if already unlinked
44.786 + QNode h = head;
44.787 + QNode hn = h.next; // Absorb cancelled first node as head
44.788 + if (hn != null && hn.isCancelled()) {
44.789 + advanceHead(h, hn);
44.790 + continue;
44.791 + }
44.792 + QNode t = tail; // Ensure consistent read for tail
44.793 + if (t == h)
44.794 + return;
44.795 + QNode tn = t.next;
44.796 + if (t != tail)
44.797 + continue;
44.798 + if (tn != null) {
44.799 + advanceTail(t, tn);
44.800 + continue;
44.801 + }
44.802 + if (s != t) { // If not tail, try to unsplice
44.803 + QNode sn = s.next;
44.804 + if (sn == s || pred.casNext(s, sn))
44.805 + return;
44.806 + }
44.807 + QNode dp = cleanMe;
44.808 + if (dp != null) { // Try unlinking previous cancelled node
44.809 + QNode d = dp.next;
44.810 + QNode dn;
44.811 + if (d == null || // d is gone or
44.812 + d == dp || // d is off list or
44.813 + !d.isCancelled() || // d not cancelled or
44.814 + (d != t && // d not tail and
44.815 + (dn = d.next) != null && // has successor
44.816 + dn != d && // that is on list
44.817 + dp.casNext(d, dn))) // d unspliced
44.818 + casCleanMe(dp, null);
44.819 + if (dp == pred)
44.820 + return; // s is already saved node
44.821 + } else if (casCleanMe(null, pred))
44.822 + return; // Postpone cleaning s
44.823 + }
44.824 + }
44.825 +
44.826 + private static final sun.misc.Unsafe UNSAFE;
44.827 + private static final long headOffset;
44.828 + private static final long tailOffset;
44.829 + private static final long cleanMeOffset;
44.830 + static {
44.831 + try {
44.832 + UNSAFE = sun.misc.Unsafe.getUnsafe();
44.833 + Class k = TransferQueue.class;
44.834 + headOffset = UNSAFE.objectFieldOffset
44.835 + (k.getDeclaredField("head"));
44.836 + tailOffset = UNSAFE.objectFieldOffset
44.837 + (k.getDeclaredField("tail"));
44.838 + cleanMeOffset = UNSAFE.objectFieldOffset
44.839 + (k.getDeclaredField("cleanMe"));
44.840 + } catch (Exception e) {
44.841 + throw new Error(e);
44.842 + }
44.843 + }
44.844 + }
44.845 +
44.846 + /**
44.847 + * The transferer. Set only in constructor, but cannot be declared
44.848 + * as final without further complicating serialization. Since
44.849 + * this is accessed only at most once per public method, there
44.850 + * isn't a noticeable performance penalty for using volatile
44.851 + * instead of final here.
44.852 + */
44.853 + private transient volatile Transferer transferer;
44.854 +
44.855 + /**
44.856 + * Creates a <tt>SynchronousQueue</tt> with nonfair access policy.
44.857 + */
44.858 + public SynchronousQueue() {
44.859 + this(false);
44.860 + }
44.861 +
44.862 + /**
44.863 + * Creates a <tt>SynchronousQueue</tt> with the specified fairness policy.
44.864 + *
44.865 + * @param fair if true, waiting threads contend in FIFO order for
44.866 + * access; otherwise the order is unspecified.
44.867 + */
44.868 + public SynchronousQueue(boolean fair) {
44.869 + transferer = fair ? new TransferQueue() : new TransferStack();
44.870 + }
44.871 +
44.872 + /**
44.873 + * Adds the specified element to this queue, waiting if necessary for
44.874 + * another thread to receive it.
44.875 + *
44.876 + * @throws InterruptedException {@inheritDoc}
44.877 + * @throws NullPointerException {@inheritDoc}
44.878 + */
44.879 + public void put(E o) throws InterruptedException {
44.880 + if (o == null) throw new NullPointerException();
44.881 + if (transferer.transfer(o, false, 0) == null) {
44.882 + Thread.interrupted();
44.883 + throw new InterruptedException();
44.884 + }
44.885 + }
44.886 +
44.887 + /**
44.888 + * Inserts the specified element into this queue, waiting if necessary
44.889 + * up to the specified wait time for another thread to receive it.
44.890 + *
44.891 + * @return <tt>true</tt> if successful, or <tt>false</tt> if the
44.892 + * specified waiting time elapses before a consumer appears.
44.893 + * @throws InterruptedException {@inheritDoc}
44.894 + * @throws NullPointerException {@inheritDoc}
44.895 + */
44.896 + public boolean offer(E o, long timeout, TimeUnit unit)
44.897 + throws InterruptedException {
44.898 + if (o == null) throw new NullPointerException();
44.899 + if (transferer.transfer(o, true, unit.toNanos(timeout)) != null)
44.900 + return true;
44.901 + if (!Thread.interrupted())
44.902 + return false;
44.903 + throw new InterruptedException();
44.904 + }
44.905 +
44.906 + /**
44.907 + * Inserts the specified element into this queue, if another thread is
44.908 + * waiting to receive it.
44.909 + *
44.910 + * @param e the element to add
44.911 + * @return <tt>true</tt> if the element was added to this queue, else
44.912 + * <tt>false</tt>
44.913 + * @throws NullPointerException if the specified element is null
44.914 + */
44.915 + public boolean offer(E e) {
44.916 + if (e == null) throw new NullPointerException();
44.917 + return transferer.transfer(e, true, 0) != null;
44.918 + }
44.919 +
44.920 + /**
44.921 + * Retrieves and removes the head of this queue, waiting if necessary
44.922 + * for another thread to insert it.
44.923 + *
44.924 + * @return the head of this queue
44.925 + * @throws InterruptedException {@inheritDoc}
44.926 + */
44.927 + public E take() throws InterruptedException {
44.928 + Object e = transferer.transfer(null, false, 0);
44.929 + if (e != null)
44.930 + return (E)e;
44.931 + Thread.interrupted();
44.932 + throw new InterruptedException();
44.933 + }
44.934 +
44.935 + /**
44.936 + * Retrieves and removes the head of this queue, waiting
44.937 + * if necessary up to the specified wait time, for another thread
44.938 + * to insert it.
44.939 + *
44.940 + * @return the head of this queue, or <tt>null</tt> if the
44.941 + * specified waiting time elapses before an element is present.
44.942 + * @throws InterruptedException {@inheritDoc}
44.943 + */
44.944 + public E poll(long timeout, TimeUnit unit) throws InterruptedException {
44.945 + Object e = transferer.transfer(null, true, unit.toNanos(timeout));
44.946 + if (e != null || !Thread.interrupted())
44.947 + return (E)e;
44.948 + throw new InterruptedException();
44.949 + }
44.950 +
44.951 + /**
44.952 + * Retrieves and removes the head of this queue, if another thread
44.953 + * is currently making an element available.
44.954 + *
44.955 + * @return the head of this queue, or <tt>null</tt> if no
44.956 + * element is available.
44.957 + */
44.958 + public E poll() {
44.959 + return (E)transferer.transfer(null, true, 0);
44.960 + }
44.961 +
44.962 + /**
44.963 + * Always returns <tt>true</tt>.
44.964 + * A <tt>SynchronousQueue</tt> has no internal capacity.
44.965 + *
44.966 + * @return <tt>true</tt>
44.967 + */
44.968 + public boolean isEmpty() {
44.969 + return true;
44.970 + }
44.971 +
44.972 + /**
44.973 + * Always returns zero.
44.974 + * A <tt>SynchronousQueue</tt> has no internal capacity.
44.975 + *
44.976 + * @return zero.
44.977 + */
44.978 + public int size() {
44.979 + return 0;
44.980 + }
44.981 +
44.982 + /**
44.983 + * Always returns zero.
44.984 + * A <tt>SynchronousQueue</tt> has no internal capacity.
44.985 + *
44.986 + * @return zero.
44.987 + */
44.988 + public int remainingCapacity() {
44.989 + return 0;
44.990 + }
44.991 +
44.992 + /**
44.993 + * Does nothing.
44.994 + * A <tt>SynchronousQueue</tt> has no internal capacity.
44.995 + */
44.996 + public void clear() {
44.997 + }
44.998 +
44.999 + /**
44.1000 + * Always returns <tt>false</tt>.
44.1001 + * A <tt>SynchronousQueue</tt> has no internal capacity.
44.1002 + *
44.1003 + * @param o the element
44.1004 + * @return <tt>false</tt>
44.1005 + */
44.1006 + public boolean contains(Object o) {
44.1007 + return false;
44.1008 + }
44.1009 +
44.1010 + /**
44.1011 + * Always returns <tt>false</tt>.
44.1012 + * A <tt>SynchronousQueue</tt> has no internal capacity.
44.1013 + *
44.1014 + * @param o the element to remove
44.1015 + * @return <tt>false</tt>
44.1016 + */
44.1017 + public boolean remove(Object o) {
44.1018 + return false;
44.1019 + }
44.1020 +
44.1021 + /**
44.1022 + * Returns <tt>false</tt> unless the given collection is empty.
44.1023 + * A <tt>SynchronousQueue</tt> has no internal capacity.
44.1024 + *
44.1025 + * @param c the collection
44.1026 + * @return <tt>false</tt> unless given collection is empty
44.1027 + */
44.1028 + public boolean containsAll(Collection<?> c) {
44.1029 + return c.isEmpty();
44.1030 + }
44.1031 +
44.1032 + /**
44.1033 + * Always returns <tt>false</tt>.
44.1034 + * A <tt>SynchronousQueue</tt> has no internal capacity.
44.1035 + *
44.1036 + * @param c the collection
44.1037 + * @return <tt>false</tt>
44.1038 + */
44.1039 + public boolean removeAll(Collection<?> c) {
44.1040 + return false;
44.1041 + }
44.1042 +
44.1043 + /**
44.1044 + * Always returns <tt>false</tt>.
44.1045 + * A <tt>SynchronousQueue</tt> has no internal capacity.
44.1046 + *
44.1047 + * @param c the collection
44.1048 + * @return <tt>false</tt>
44.1049 + */
44.1050 + public boolean retainAll(Collection<?> c) {
44.1051 + return false;
44.1052 + }
44.1053 +
44.1054 + /**
44.1055 + * Always returns <tt>null</tt>.
44.1056 + * A <tt>SynchronousQueue</tt> does not return elements
44.1057 + * unless actively waited on.
44.1058 + *
44.1059 + * @return <tt>null</tt>
44.1060 + */
44.1061 + public E peek() {
44.1062 + return null;
44.1063 + }
44.1064 +
44.1065 + /**
44.1066 + * Returns an empty iterator in which <tt>hasNext</tt> always returns
44.1067 + * <tt>false</tt>.
44.1068 + *
44.1069 + * @return an empty iterator
44.1070 + */
44.1071 + public Iterator<E> iterator() {
44.1072 + return Collections.emptyIterator();
44.1073 + }
44.1074 +
44.1075 + /**
44.1076 + * Returns a zero-length array.
44.1077 + * @return a zero-length array
44.1078 + */
44.1079 + public Object[] toArray() {
44.1080 + return new Object[0];
44.1081 + }
44.1082 +
44.1083 + /**
44.1084 + * Sets the zeroeth element of the specified array to <tt>null</tt>
44.1085 + * (if the array has non-zero length) and returns it.
44.1086 + *
44.1087 + * @param a the array
44.1088 + * @return the specified array
44.1089 + * @throws NullPointerException if the specified array is null
44.1090 + */
44.1091 + public <T> T[] toArray(T[] a) {
44.1092 + if (a.length > 0)
44.1093 + a[0] = null;
44.1094 + return a;
44.1095 + }
44.1096 +
44.1097 + /**
44.1098 + * @throws UnsupportedOperationException {@inheritDoc}
44.1099 + * @throws ClassCastException {@inheritDoc}
44.1100 + * @throws NullPointerException {@inheritDoc}
44.1101 + * @throws IllegalArgumentException {@inheritDoc}
44.1102 + */
44.1103 + public int drainTo(Collection<? super E> c) {
44.1104 + if (c == null)
44.1105 + throw new NullPointerException();
44.1106 + if (c == this)
44.1107 + throw new IllegalArgumentException();
44.1108 + int n = 0;
44.1109 + E e;
44.1110 + while ( (e = poll()) != null) {
44.1111 + c.add(e);
44.1112 + ++n;
44.1113 + }
44.1114 + return n;
44.1115 + }
44.1116 +
44.1117 + /**
44.1118 + * @throws UnsupportedOperationException {@inheritDoc}
44.1119 + * @throws ClassCastException {@inheritDoc}
44.1120 + * @throws NullPointerException {@inheritDoc}
44.1121 + * @throws IllegalArgumentException {@inheritDoc}
44.1122 + */
44.1123 + public int drainTo(Collection<? super E> c, int maxElements) {
44.1124 + if (c == null)
44.1125 + throw new NullPointerException();
44.1126 + if (c == this)
44.1127 + throw new IllegalArgumentException();
44.1128 + int n = 0;
44.1129 + E e;
44.1130 + while (n < maxElements && (e = poll()) != null) {
44.1131 + c.add(e);
44.1132 + ++n;
44.1133 + }
44.1134 + return n;
44.1135 + }
44.1136 +
44.1137 + /*
44.1138 + * To cope with serialization strategy in the 1.5 version of
44.1139 + * SynchronousQueue, we declare some unused classes and fields
44.1140 + * that exist solely to enable serializability across versions.
44.1141 + * These fields are never used, so are initialized only if this
44.1142 + * object is ever serialized or deserialized.
44.1143 + */
44.1144 +
44.1145 + static class WaitQueue implements java.io.Serializable { }
44.1146 + static class LifoWaitQueue extends WaitQueue {
44.1147 + private static final long serialVersionUID = -3633113410248163686L;
44.1148 + }
44.1149 + static class FifoWaitQueue extends WaitQueue {
44.1150 + private static final long serialVersionUID = -3623113410248163686L;
44.1151 + }
44.1152 + private ReentrantLock qlock;
44.1153 + private WaitQueue waitingProducers;
44.1154 + private WaitQueue waitingConsumers;
44.1155 +
44.1156 + /**
44.1157 + * Save the state to a stream (that is, serialize it).
44.1158 + *
44.1159 + * @param s the stream
44.1160 + */
44.1161 + private void writeObject(java.io.ObjectOutputStream s)
44.1162 + throws java.io.IOException {
44.1163 + boolean fair = transferer instanceof TransferQueue;
44.1164 + if (fair) {
44.1165 + qlock = new ReentrantLock(true);
44.1166 + waitingProducers = new FifoWaitQueue();
44.1167 + waitingConsumers = new FifoWaitQueue();
44.1168 + }
44.1169 + else {
44.1170 + qlock = new ReentrantLock();
44.1171 + waitingProducers = new LifoWaitQueue();
44.1172 + waitingConsumers = new LifoWaitQueue();
44.1173 + }
44.1174 + s.defaultWriteObject();
44.1175 + }
44.1176 +
44.1177 + private void readObject(final java.io.ObjectInputStream s)
44.1178 + throws java.io.IOException, ClassNotFoundException {
44.1179 + s.defaultReadObject();
44.1180 + if (waitingProducers instanceof FifoWaitQueue)
44.1181 + transferer = new TransferQueue();
44.1182 + else
44.1183 + transferer = new TransferStack();
44.1184 + }
44.1185 +
44.1186 + // Unsafe mechanics
44.1187 + static long objectFieldOffset(sun.misc.Unsafe UNSAFE,
44.1188 + String field, Class<?> klazz) {
44.1189 + try {
44.1190 + return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field));
44.1191 + } catch (NoSuchFieldException e) {
44.1192 + // Convert Exception to corresponding Error
44.1193 + NoSuchFieldError error = new NoSuchFieldError(field);
44.1194 + error.initCause(e);
44.1195 + throw error;
44.1196 + }
44.1197 + }
44.1198 +
44.1199 +}
45.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
45.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ThreadFactory.java Sat Mar 19 10:48:29 2016 +0100
45.3 @@ -0,0 +1,70 @@
45.4 +/*
45.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
45.6 + *
45.7 + * This code is free software; you can redistribute it and/or modify it
45.8 + * under the terms of the GNU General Public License version 2 only, as
45.9 + * published by the Free Software Foundation. Oracle designates this
45.10 + * particular file as subject to the "Classpath" exception as provided
45.11 + * by Oracle in the LICENSE file that accompanied this code.
45.12 + *
45.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
45.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
45.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
45.16 + * version 2 for more details (a copy is included in the LICENSE file that
45.17 + * accompanied this code).
45.18 + *
45.19 + * You should have received a copy of the GNU General Public License version
45.20 + * 2 along with this work; if not, write to the Free Software Foundation,
45.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
45.22 + *
45.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
45.24 + * or visit www.oracle.com if you need additional information or have any
45.25 + * questions.
45.26 + */
45.27 +
45.28 +/*
45.29 + * This file is available under and governed by the GNU General Public
45.30 + * License version 2 only, as published by the Free Software Foundation.
45.31 + * However, the following notice accompanied the original version of this
45.32 + * file:
45.33 + *
45.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
45.35 + * Expert Group and released to the public domain, as explained at
45.36 + * http://creativecommons.org/publicdomain/zero/1.0/
45.37 + */
45.38 +
45.39 +package java.util.concurrent;
45.40 +
45.41 +/**
45.42 + * An object that creates new threads on demand. Using thread factories
45.43 + * removes hardwiring of calls to {@link Thread#Thread(Runnable) new Thread},
45.44 + * enabling applications to use special thread subclasses, priorities, etc.
45.45 + *
45.46 + * <p>
45.47 + * The simplest implementation of this interface is just:
45.48 + * <pre>
45.49 + * class SimpleThreadFactory implements ThreadFactory {
45.50 + * public Thread newThread(Runnable r) {
45.51 + * return new Thread(r);
45.52 + * }
45.53 + * }
45.54 + * </pre>
45.55 + *
45.56 + * The {@link Executors#defaultThreadFactory} method provides a more
45.57 + * useful simple implementation, that sets the created thread context
45.58 + * to known values before returning it.
45.59 + * @since 1.5
45.60 + * @author Doug Lea
45.61 + */
45.62 +public interface ThreadFactory {
45.63 +
45.64 + /**
45.65 + * Constructs a new {@code Thread}. Implementations may also initialize
45.66 + * priority, name, daemon status, {@code ThreadGroup}, etc.
45.67 + *
45.68 + * @param r a runnable to be executed by new thread instance
45.69 + * @return constructed thread, or {@code null} if the request to
45.70 + * create a thread is rejected
45.71 + */
45.72 + Thread newThread(Runnable r);
45.73 +}
46.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
46.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ThreadLocalRandom.java Sat Mar 19 10:48:29 2016 +0100
46.3 @@ -0,0 +1,226 @@
46.4 +/*
46.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
46.6 + *
46.7 + * This code is free software; you can redistribute it and/or modify it
46.8 + * under the terms of the GNU General Public License version 2 only, as
46.9 + * published by the Free Software Foundation. Oracle designates this
46.10 + * particular file as subject to the "Classpath" exception as provided
46.11 + * by Oracle in the LICENSE file that accompanied this code.
46.12 + *
46.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
46.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
46.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
46.16 + * version 2 for more details (a copy is included in the LICENSE file that
46.17 + * accompanied this code).
46.18 + *
46.19 + * You should have received a copy of the GNU General Public License version
46.20 + * 2 along with this work; if not, write to the Free Software Foundation,
46.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
46.22 + *
46.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
46.24 + * or visit www.oracle.com if you need additional information or have any
46.25 + * questions.
46.26 + */
46.27 +
46.28 +/*
46.29 + * This file is available under and governed by the GNU General Public
46.30 + * License version 2 only, as published by the Free Software Foundation.
46.31 + * However, the following notice accompanied the original version of this
46.32 + * file:
46.33 + *
46.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
46.35 + * Expert Group and released to the public domain, as explained at
46.36 + * http://creativecommons.org/publicdomain/zero/1.0/
46.37 + */
46.38 +
46.39 +package java.util.concurrent;
46.40 +
46.41 +import java.util.Random;
46.42 +
46.43 +/**
46.44 + * A random number generator isolated to the current thread. Like the
46.45 + * global {@link java.util.Random} generator used by the {@link
46.46 + * java.lang.Math} class, a {@code ThreadLocalRandom} is initialized
46.47 + * with an internally generated seed that may not otherwise be
46.48 + * modified. When applicable, use of {@code ThreadLocalRandom} rather
46.49 + * than shared {@code Random} objects in concurrent programs will
46.50 + * typically encounter much less overhead and contention. Use of
46.51 + * {@code ThreadLocalRandom} is particularly appropriate when multiple
46.52 + * tasks (for example, each a {@link ForkJoinTask}) use random numbers
46.53 + * in parallel in thread pools.
46.54 + *
46.55 + * <p>Usages of this class should typically be of the form:
46.56 + * {@code ThreadLocalRandom.current().nextX(...)} (where
46.57 + * {@code X} is {@code Int}, {@code Long}, etc).
46.58 + * When all usages are of this form, it is never possible to
46.59 + * accidently share a {@code ThreadLocalRandom} across multiple threads.
46.60 + *
46.61 + * <p>This class also provides additional commonly used bounded random
46.62 + * generation methods.
46.63 + *
46.64 + * @since 1.7
46.65 + * @author Doug Lea
46.66 + */
46.67 +public class ThreadLocalRandom extends Random {
46.68 + // same constants as Random, but must be redeclared because private
46.69 + private static final long multiplier = 0x5DEECE66DL;
46.70 + private static final long addend = 0xBL;
46.71 + private static final long mask = (1L << 48) - 1;
46.72 +
46.73 + /**
46.74 + * The random seed. We can't use super.seed.
46.75 + */
46.76 + private long rnd;
46.77 +
46.78 + /**
46.79 + * Initialization flag to permit calls to setSeed to succeed only
46.80 + * while executing the Random constructor. We can't allow others
46.81 + * since it would cause setting seed in one part of a program to
46.82 + * unintentionally impact other usages by the thread.
46.83 + */
46.84 + boolean initialized;
46.85 +
46.86 + // Padding to help avoid memory contention among seed updates in
46.87 + // different TLRs in the common case that they are located near
46.88 + // each other.
46.89 + private long pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7;
46.90 +
46.91 + /**
46.92 + * The actual ThreadLocal
46.93 + */
46.94 + private static final ThreadLocal<ThreadLocalRandom> localRandom =
46.95 + new ThreadLocal<ThreadLocalRandom>() {
46.96 + protected ThreadLocalRandom initialValue() {
46.97 + return new ThreadLocalRandom();
46.98 + }
46.99 + };
46.100 +
46.101 +
46.102 + /**
46.103 + * Constructor called only by localRandom.initialValue.
46.104 + */
46.105 + ThreadLocalRandom() {
46.106 + super();
46.107 + initialized = true;
46.108 + }
46.109 +
46.110 + /**
46.111 + * Returns the current thread's {@code ThreadLocalRandom}.
46.112 + *
46.113 + * @return the current thread's {@code ThreadLocalRandom}
46.114 + */
46.115 + public static ThreadLocalRandom current() {
46.116 + return localRandom.get();
46.117 + }
46.118 +
46.119 + /**
46.120 + * Throws {@code UnsupportedOperationException}. Setting seeds in
46.121 + * this generator is not supported.
46.122 + *
46.123 + * @throws UnsupportedOperationException always
46.124 + */
46.125 + public void setSeed(long seed) {
46.126 + if (initialized)
46.127 + throw new UnsupportedOperationException();
46.128 + rnd = (seed ^ multiplier) & mask;
46.129 + }
46.130 +
46.131 + protected int next(int bits) {
46.132 + rnd = (rnd * multiplier + addend) & mask;
46.133 + return (int) (rnd >>> (48-bits));
46.134 + }
46.135 +
46.136 + /**
46.137 + * Returns a pseudorandom, uniformly distributed value between the
46.138 + * given least value (inclusive) and bound (exclusive).
46.139 + *
46.140 + * @param least the least value returned
46.141 + * @param bound the upper bound (exclusive)
46.142 + * @throws IllegalArgumentException if least greater than or equal
46.143 + * to bound
46.144 + * @return the next value
46.145 + */
46.146 + public int nextInt(int least, int bound) {
46.147 + if (least >= bound)
46.148 + throw new IllegalArgumentException();
46.149 + return nextInt(bound - least) + least;
46.150 + }
46.151 +
46.152 + /**
46.153 + * Returns a pseudorandom, uniformly distributed value
46.154 + * between 0 (inclusive) and the specified value (exclusive).
46.155 + *
46.156 + * @param n the bound on the random number to be returned. Must be
46.157 + * positive.
46.158 + * @return the next value
46.159 + * @throws IllegalArgumentException if n is not positive
46.160 + */
46.161 + public long nextLong(long n) {
46.162 + if (n <= 0)
46.163 + throw new IllegalArgumentException("n must be positive");
46.164 + // Divide n by two until small enough for nextInt. On each
46.165 + // iteration (at most 31 of them but usually much less),
46.166 + // randomly choose both whether to include high bit in result
46.167 + // (offset) and whether to continue with the lower vs upper
46.168 + // half (which makes a difference only if odd).
46.169 + long offset = 0;
46.170 + while (n >= Integer.MAX_VALUE) {
46.171 + int bits = next(2);
46.172 + long half = n >>> 1;
46.173 + long nextn = ((bits & 2) == 0) ? half : n - half;
46.174 + if ((bits & 1) == 0)
46.175 + offset += n - nextn;
46.176 + n = nextn;
46.177 + }
46.178 + return offset + nextInt((int) n);
46.179 + }
46.180 +
46.181 + /**
46.182 + * Returns a pseudorandom, uniformly distributed value between the
46.183 + * given least value (inclusive) and bound (exclusive).
46.184 + *
46.185 + * @param least the least value returned
46.186 + * @param bound the upper bound (exclusive)
46.187 + * @return the next value
46.188 + * @throws IllegalArgumentException if least greater than or equal
46.189 + * to bound
46.190 + */
46.191 + public long nextLong(long least, long bound) {
46.192 + if (least >= bound)
46.193 + throw new IllegalArgumentException();
46.194 + return nextLong(bound - least) + least;
46.195 + }
46.196 +
46.197 + /**
46.198 + * Returns a pseudorandom, uniformly distributed {@code double} value
46.199 + * between 0 (inclusive) and the specified value (exclusive).
46.200 + *
46.201 + * @param n the bound on the random number to be returned. Must be
46.202 + * positive.
46.203 + * @return the next value
46.204 + * @throws IllegalArgumentException if n is not positive
46.205 + */
46.206 + public double nextDouble(double n) {
46.207 + if (n <= 0)
46.208 + throw new IllegalArgumentException("n must be positive");
46.209 + return nextDouble() * n;
46.210 + }
46.211 +
46.212 + /**
46.213 + * Returns a pseudorandom, uniformly distributed value between the
46.214 + * given least value (inclusive) and bound (exclusive).
46.215 + *
46.216 + * @param least the least value returned
46.217 + * @param bound the upper bound (exclusive)
46.218 + * @return the next value
46.219 + * @throws IllegalArgumentException if least greater than or equal
46.220 + * to bound
46.221 + */
46.222 + public double nextDouble(double least, double bound) {
46.223 + if (least >= bound)
46.224 + throw new IllegalArgumentException();
46.225 + return nextDouble() * (bound - least) + least;
46.226 + }
46.227 +
46.228 + private static final long serialVersionUID = -5851777807851030925L;
46.229 +}
47.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
47.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ThreadPoolExecutor.java Sat Mar 19 10:48:29 2016 +0100
47.3 @@ -0,0 +1,2054 @@
47.4 +/*
47.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
47.6 + *
47.7 + * This code is free software; you can redistribute it and/or modify it
47.8 + * under the terms of the GNU General Public License version 2 only, as
47.9 + * published by the Free Software Foundation. Oracle designates this
47.10 + * particular file as subject to the "Classpath" exception as provided
47.11 + * by Oracle in the LICENSE file that accompanied this code.
47.12 + *
47.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
47.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
47.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
47.16 + * version 2 for more details (a copy is included in the LICENSE file that
47.17 + * accompanied this code).
47.18 + *
47.19 + * You should have received a copy of the GNU General Public License version
47.20 + * 2 along with this work; if not, write to the Free Software Foundation,
47.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
47.22 + *
47.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
47.24 + * or visit www.oracle.com if you need additional information or have any
47.25 + * questions.
47.26 + */
47.27 +
47.28 +/*
47.29 + * This file is available under and governed by the GNU General Public
47.30 + * License version 2 only, as published by the Free Software Foundation.
47.31 + * However, the following notice accompanied the original version of this
47.32 + * file:
47.33 + *
47.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
47.35 + * Expert Group and released to the public domain, as explained at
47.36 + * http://creativecommons.org/publicdomain/zero/1.0/
47.37 + */
47.38 +
47.39 +package java.util.concurrent;
47.40 +import java.util.concurrent.locks.*;
47.41 +import java.util.concurrent.atomic.*;
47.42 +import java.util.*;
47.43 +
47.44 +/**
47.45 + * An {@link ExecutorService} that executes each submitted task using
47.46 + * one of possibly several pooled threads, normally configured
47.47 + * using {@link Executors} factory methods.
47.48 + *
47.49 + * <p>Thread pools address two different problems: they usually
47.50 + * provide improved performance when executing large numbers of
47.51 + * asynchronous tasks, due to reduced per-task invocation overhead,
47.52 + * and they provide a means of bounding and managing the resources,
47.53 + * including threads, consumed when executing a collection of tasks.
47.54 + * Each {@code ThreadPoolExecutor} also maintains some basic
47.55 + * statistics, such as the number of completed tasks.
47.56 + *
47.57 + * <p>To be useful across a wide range of contexts, this class
47.58 + * provides many adjustable parameters and extensibility
47.59 + * hooks. However, programmers are urged to use the more convenient
47.60 + * {@link Executors} factory methods {@link
47.61 + * Executors#newCachedThreadPool} (unbounded thread pool, with
47.62 + * automatic thread reclamation), {@link Executors#newFixedThreadPool}
47.63 + * (fixed size thread pool) and {@link
47.64 + * Executors#newSingleThreadExecutor} (single background thread), that
47.65 + * preconfigure settings for the most common usage
47.66 + * scenarios. Otherwise, use the following guide when manually
47.67 + * configuring and tuning this class:
47.68 + *
47.69 + * <dl>
47.70 + *
47.71 + * <dt>Core and maximum pool sizes</dt>
47.72 + *
47.73 + * <dd>A {@code ThreadPoolExecutor} will automatically adjust the
47.74 + * pool size (see {@link #getPoolSize})
47.75 + * according to the bounds set by
47.76 + * corePoolSize (see {@link #getCorePoolSize}) and
47.77 + * maximumPoolSize (see {@link #getMaximumPoolSize}).
47.78 + *
47.79 + * When a new task is submitted in method {@link #execute}, and fewer
47.80 + * than corePoolSize threads are running, a new thread is created to
47.81 + * handle the request, even if other worker threads are idle. If
47.82 + * there are more than corePoolSize but less than maximumPoolSize
47.83 + * threads running, a new thread will be created only if the queue is
47.84 + * full. By setting corePoolSize and maximumPoolSize the same, you
47.85 + * create a fixed-size thread pool. By setting maximumPoolSize to an
47.86 + * essentially unbounded value such as {@code Integer.MAX_VALUE}, you
47.87 + * allow the pool to accommodate an arbitrary number of concurrent
47.88 + * tasks. Most typically, core and maximum pool sizes are set only
47.89 + * upon construction, but they may also be changed dynamically using
47.90 + * {@link #setCorePoolSize} and {@link #setMaximumPoolSize}. </dd>
47.91 + *
47.92 + * <dt>On-demand construction</dt>
47.93 + *
47.94 + * <dd> By default, even core threads are initially created and
47.95 + * started only when new tasks arrive, but this can be overridden
47.96 + * dynamically using method {@link #prestartCoreThread} or {@link
47.97 + * #prestartAllCoreThreads}. You probably want to prestart threads if
47.98 + * you construct the pool with a non-empty queue. </dd>
47.99 + *
47.100 + * <dt>Creating new threads</dt>
47.101 + *
47.102 + * <dd>New threads are created using a {@link ThreadFactory}. If not
47.103 + * otherwise specified, a {@link Executors#defaultThreadFactory} is
47.104 + * used, that creates threads to all be in the same {@link
47.105 + * ThreadGroup} and with the same {@code NORM_PRIORITY} priority and
47.106 + * non-daemon status. By supplying a different ThreadFactory, you can
47.107 + * alter the thread's name, thread group, priority, daemon status,
47.108 + * etc. If a {@code ThreadFactory} fails to create a thread when asked
47.109 + * by returning null from {@code newThread}, the executor will
47.110 + * continue, but might not be able to execute any tasks. Threads
47.111 + * should possess the "modifyThread" {@code RuntimePermission}. If
47.112 + * worker threads or other threads using the pool do not possess this
47.113 + * permission, service may be degraded: configuration changes may not
47.114 + * take effect in a timely manner, and a shutdown pool may remain in a
47.115 + * state in which termination is possible but not completed.</dd>
47.116 + *
47.117 + * <dt>Keep-alive times</dt>
47.118 + *
47.119 + * <dd>If the pool currently has more than corePoolSize threads,
47.120 + * excess threads will be terminated if they have been idle for more
47.121 + * than the keepAliveTime (see {@link #getKeepAliveTime}). This
47.122 + * provides a means of reducing resource consumption when the pool is
47.123 + * not being actively used. If the pool becomes more active later, new
47.124 + * threads will be constructed. This parameter can also be changed
47.125 + * dynamically using method {@link #setKeepAliveTime}. Using a value
47.126 + * of {@code Long.MAX_VALUE} {@link TimeUnit#NANOSECONDS} effectively
47.127 + * disables idle threads from ever terminating prior to shut down. By
47.128 + * default, the keep-alive policy applies only when there are more
47.129 + * than corePoolSizeThreads. But method {@link
47.130 + * #allowCoreThreadTimeOut(boolean)} can be used to apply this
47.131 + * time-out policy to core threads as well, so long as the
47.132 + * keepAliveTime value is non-zero. </dd>
47.133 + *
47.134 + * <dt>Queuing</dt>
47.135 + *
47.136 + * <dd>Any {@link BlockingQueue} may be used to transfer and hold
47.137 + * submitted tasks. The use of this queue interacts with pool sizing:
47.138 + *
47.139 + * <ul>
47.140 + *
47.141 + * <li> If fewer than corePoolSize threads are running, the Executor
47.142 + * always prefers adding a new thread
47.143 + * rather than queuing.</li>
47.144 + *
47.145 + * <li> If corePoolSize or more threads are running, the Executor
47.146 + * always prefers queuing a request rather than adding a new
47.147 + * thread.</li>
47.148 + *
47.149 + * <li> If a request cannot be queued, a new thread is created unless
47.150 + * this would exceed maximumPoolSize, in which case, the task will be
47.151 + * rejected.</li>
47.152 + *
47.153 + * </ul>
47.154 + *
47.155 + * There are three general strategies for queuing:
47.156 + * <ol>
47.157 + *
47.158 + * <li> <em> Direct handoffs.</em> A good default choice for a work
47.159 + * queue is a {@link SynchronousQueue} that hands off tasks to threads
47.160 + * without otherwise holding them. Here, an attempt to queue a task
47.161 + * will fail if no threads are immediately available to run it, so a
47.162 + * new thread will be constructed. This policy avoids lockups when
47.163 + * handling sets of requests that might have internal dependencies.
47.164 + * Direct handoffs generally require unbounded maximumPoolSizes to
47.165 + * avoid rejection of new submitted tasks. This in turn admits the
47.166 + * possibility of unbounded thread growth when commands continue to
47.167 + * arrive on average faster than they can be processed. </li>
47.168 + *
47.169 + * <li><em> Unbounded queues.</em> Using an unbounded queue (for
47.170 + * example a {@link LinkedBlockingQueue} without a predefined
47.171 + * capacity) will cause new tasks to wait in the queue when all
47.172 + * corePoolSize threads are busy. Thus, no more than corePoolSize
47.173 + * threads will ever be created. (And the value of the maximumPoolSize
47.174 + * therefore doesn't have any effect.) This may be appropriate when
47.175 + * each task is completely independent of others, so tasks cannot
47.176 + * affect each others execution; for example, in a web page server.
47.177 + * While this style of queuing can be useful in smoothing out
47.178 + * transient bursts of requests, it admits the possibility of
47.179 + * unbounded work queue growth when commands continue to arrive on
47.180 + * average faster than they can be processed. </li>
47.181 + *
47.182 + * <li><em>Bounded queues.</em> A bounded queue (for example, an
47.183 + * {@link ArrayBlockingQueue}) helps prevent resource exhaustion when
47.184 + * used with finite maximumPoolSizes, but can be more difficult to
47.185 + * tune and control. Queue sizes and maximum pool sizes may be traded
47.186 + * off for each other: Using large queues and small pools minimizes
47.187 + * CPU usage, OS resources, and context-switching overhead, but can
47.188 + * lead to artificially low throughput. If tasks frequently block (for
47.189 + * example if they are I/O bound), a system may be able to schedule
47.190 + * time for more threads than you otherwise allow. Use of small queues
47.191 + * generally requires larger pool sizes, which keeps CPUs busier but
47.192 + * may encounter unacceptable scheduling overhead, which also
47.193 + * decreases throughput. </li>
47.194 + *
47.195 + * </ol>
47.196 + *
47.197 + * </dd>
47.198 + *
47.199 + * <dt>Rejected tasks</dt>
47.200 + *
47.201 + * <dd> New tasks submitted in method {@link #execute} will be
47.202 + * <em>rejected</em> when the Executor has been shut down, and also
47.203 + * when the Executor uses finite bounds for both maximum threads and
47.204 + * work queue capacity, and is saturated. In either case, the {@code
47.205 + * execute} method invokes the {@link
47.206 + * RejectedExecutionHandler#rejectedExecution} method of its {@link
47.207 + * RejectedExecutionHandler}. Four predefined handler policies are
47.208 + * provided:
47.209 + *
47.210 + * <ol>
47.211 + *
47.212 + * <li> In the default {@link ThreadPoolExecutor.AbortPolicy}, the
47.213 + * handler throws a runtime {@link RejectedExecutionException} upon
47.214 + * rejection. </li>
47.215 + *
47.216 + * <li> In {@link ThreadPoolExecutor.CallerRunsPolicy}, the thread
47.217 + * that invokes {@code execute} itself runs the task. This provides a
47.218 + * simple feedback control mechanism that will slow down the rate that
47.219 + * new tasks are submitted. </li>
47.220 + *
47.221 + * <li> In {@link ThreadPoolExecutor.DiscardPolicy}, a task that
47.222 + * cannot be executed is simply dropped. </li>
47.223 + *
47.224 + * <li>In {@link ThreadPoolExecutor.DiscardOldestPolicy}, if the
47.225 + * executor is not shut down, the task at the head of the work queue
47.226 + * is dropped, and then execution is retried (which can fail again,
47.227 + * causing this to be repeated.) </li>
47.228 + *
47.229 + * </ol>
47.230 + *
47.231 + * It is possible to define and use other kinds of {@link
47.232 + * RejectedExecutionHandler} classes. Doing so requires some care
47.233 + * especially when policies are designed to work only under particular
47.234 + * capacity or queuing policies. </dd>
47.235 + *
47.236 + * <dt>Hook methods</dt>
47.237 + *
47.238 + * <dd>This class provides {@code protected} overridable {@link
47.239 + * #beforeExecute} and {@link #afterExecute} methods that are called
47.240 + * before and after execution of each task. These can be used to
47.241 + * manipulate the execution environment; for example, reinitializing
47.242 + * ThreadLocals, gathering statistics, or adding log
47.243 + * entries. Additionally, method {@link #terminated} can be overridden
47.244 + * to perform any special processing that needs to be done once the
47.245 + * Executor has fully terminated.
47.246 + *
47.247 + * <p>If hook or callback methods throw exceptions, internal worker
47.248 + * threads may in turn fail and abruptly terminate.</dd>
47.249 + *
47.250 + * <dt>Queue maintenance</dt>
47.251 + *
47.252 + * <dd> Method {@link #getQueue} allows access to the work queue for
47.253 + * purposes of monitoring and debugging. Use of this method for any
47.254 + * other purpose is strongly discouraged. Two supplied methods,
47.255 + * {@link #remove} and {@link #purge} are available to assist in
47.256 + * storage reclamation when large numbers of queued tasks become
47.257 + * cancelled.</dd>
47.258 + *
47.259 + * <dt>Finalization</dt>
47.260 + *
47.261 + * <dd> A pool that is no longer referenced in a program <em>AND</em>
47.262 + * has no remaining threads will be {@code shutdown} automatically. If
47.263 + * you would like to ensure that unreferenced pools are reclaimed even
47.264 + * if users forget to call {@link #shutdown}, then you must arrange
47.265 + * that unused threads eventually die, by setting appropriate
47.266 + * keep-alive times, using a lower bound of zero core threads and/or
47.267 + * setting {@link #allowCoreThreadTimeOut(boolean)}. </dd>
47.268 + *
47.269 + * </dl>
47.270 + *
47.271 + * <p> <b>Extension example</b>. Most extensions of this class
47.272 + * override one or more of the protected hook methods. For example,
47.273 + * here is a subclass that adds a simple pause/resume feature:
47.274 + *
47.275 + * <pre> {@code
47.276 + * class PausableThreadPoolExecutor extends ThreadPoolExecutor {
47.277 + * private boolean isPaused;
47.278 + * private ReentrantLock pauseLock = new ReentrantLock();
47.279 + * private Condition unpaused = pauseLock.newCondition();
47.280 + *
47.281 + * public PausableThreadPoolExecutor(...) { super(...); }
47.282 + *
47.283 + * protected void beforeExecute(Thread t, Runnable r) {
47.284 + * super.beforeExecute(t, r);
47.285 + * pauseLock.lock();
47.286 + * try {
47.287 + * while (isPaused) unpaused.await();
47.288 + * } catch (InterruptedException ie) {
47.289 + * t.interrupt();
47.290 + * } finally {
47.291 + * pauseLock.unlock();
47.292 + * }
47.293 + * }
47.294 + *
47.295 + * public void pause() {
47.296 + * pauseLock.lock();
47.297 + * try {
47.298 + * isPaused = true;
47.299 + * } finally {
47.300 + * pauseLock.unlock();
47.301 + * }
47.302 + * }
47.303 + *
47.304 + * public void resume() {
47.305 + * pauseLock.lock();
47.306 + * try {
47.307 + * isPaused = false;
47.308 + * unpaused.signalAll();
47.309 + * } finally {
47.310 + * pauseLock.unlock();
47.311 + * }
47.312 + * }
47.313 + * }}</pre>
47.314 + *
47.315 + * @since 1.5
47.316 + * @author Doug Lea
47.317 + */
47.318 +public class ThreadPoolExecutor extends AbstractExecutorService {
47.319 + /**
47.320 + * The main pool control state, ctl, is an atomic integer packing
47.321 + * two conceptual fields
47.322 + * workerCount, indicating the effective number of threads
47.323 + * runState, indicating whether running, shutting down etc
47.324 + *
47.325 + * In order to pack them into one int, we limit workerCount to
47.326 + * (2^29)-1 (about 500 million) threads rather than (2^31)-1 (2
47.327 + * billion) otherwise representable. If this is ever an issue in
47.328 + * the future, the variable can be changed to be an AtomicLong,
47.329 + * and the shift/mask constants below adjusted. But until the need
47.330 + * arises, this code is a bit faster and simpler using an int.
47.331 + *
47.332 + * The workerCount is the number of workers that have been
47.333 + * permitted to start and not permitted to stop. The value may be
47.334 + * transiently different from the actual number of live threads,
47.335 + * for example when a ThreadFactory fails to create a thread when
47.336 + * asked, and when exiting threads are still performing
47.337 + * bookkeeping before terminating. The user-visible pool size is
47.338 + * reported as the current size of the workers set.
47.339 + *
47.340 + * The runState provides the main lifecyle control, taking on values:
47.341 + *
47.342 + * RUNNING: Accept new tasks and process queued tasks
47.343 + * SHUTDOWN: Don't accept new tasks, but process queued tasks
47.344 + * STOP: Don't accept new tasks, don't process queued tasks,
47.345 + * and interrupt in-progress tasks
47.346 + * TIDYING: All tasks have terminated, workerCount is zero,
47.347 + * the thread transitioning to state TIDYING
47.348 + * will run the terminated() hook method
47.349 + * TERMINATED: terminated() has completed
47.350 + *
47.351 + * The numerical order among these values matters, to allow
47.352 + * ordered comparisons. The runState monotonically increases over
47.353 + * time, but need not hit each state. The transitions are:
47.354 + *
47.355 + * RUNNING -> SHUTDOWN
47.356 + * On invocation of shutdown(), perhaps implicitly in finalize()
47.357 + * (RUNNING or SHUTDOWN) -> STOP
47.358 + * On invocation of shutdownNow()
47.359 + * SHUTDOWN -> TIDYING
47.360 + * When both queue and pool are empty
47.361 + * STOP -> TIDYING
47.362 + * When pool is empty
47.363 + * TIDYING -> TERMINATED
47.364 + * When the terminated() hook method has completed
47.365 + *
47.366 + * Threads waiting in awaitTermination() will return when the
47.367 + * state reaches TERMINATED.
47.368 + *
47.369 + * Detecting the transition from SHUTDOWN to TIDYING is less
47.370 + * straightforward than you'd like because the queue may become
47.371 + * empty after non-empty and vice versa during SHUTDOWN state, but
47.372 + * we can only terminate if, after seeing that it is empty, we see
47.373 + * that workerCount is 0 (which sometimes entails a recheck -- see
47.374 + * below).
47.375 + */
47.376 + private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
47.377 + private static final int COUNT_BITS = Integer.SIZE - 3;
47.378 + private static final int CAPACITY = (1 << COUNT_BITS) - 1;
47.379 +
47.380 + // runState is stored in the high-order bits
47.381 + private static final int RUNNING = -1 << COUNT_BITS;
47.382 + private static final int SHUTDOWN = 0 << COUNT_BITS;
47.383 + private static final int STOP = 1 << COUNT_BITS;
47.384 + private static final int TIDYING = 2 << COUNT_BITS;
47.385 + private static final int TERMINATED = 3 << COUNT_BITS;
47.386 +
47.387 + // Packing and unpacking ctl
47.388 + private static int runStateOf(int c) { return c & ~CAPACITY; }
47.389 + private static int workerCountOf(int c) { return c & CAPACITY; }
47.390 + private static int ctlOf(int rs, int wc) { return rs | wc; }
47.391 +
47.392 + /*
47.393 + * Bit field accessors that don't require unpacking ctl.
47.394 + * These depend on the bit layout and on workerCount being never negative.
47.395 + */
47.396 +
47.397 + private static boolean runStateLessThan(int c, int s) {
47.398 + return c < s;
47.399 + }
47.400 +
47.401 + private static boolean runStateAtLeast(int c, int s) {
47.402 + return c >= s;
47.403 + }
47.404 +
47.405 + private static boolean isRunning(int c) {
47.406 + return c < SHUTDOWN;
47.407 + }
47.408 +
47.409 + /**
47.410 + * Attempt to CAS-increment the workerCount field of ctl.
47.411 + */
47.412 + private boolean compareAndIncrementWorkerCount(int expect) {
47.413 + return ctl.compareAndSet(expect, expect + 1);
47.414 + }
47.415 +
47.416 + /**
47.417 + * Attempt to CAS-decrement the workerCount field of ctl.
47.418 + */
47.419 + private boolean compareAndDecrementWorkerCount(int expect) {
47.420 + return ctl.compareAndSet(expect, expect - 1);
47.421 + }
47.422 +
47.423 + /**
47.424 + * Decrements the workerCount field of ctl. This is called only on
47.425 + * abrupt termination of a thread (see processWorkerExit). Other
47.426 + * decrements are performed within getTask.
47.427 + */
47.428 + private void decrementWorkerCount() {
47.429 + do {} while (! compareAndDecrementWorkerCount(ctl.get()));
47.430 + }
47.431 +
47.432 + /**
47.433 + * The queue used for holding tasks and handing off to worker
47.434 + * threads. We do not require that workQueue.poll() returning
47.435 + * null necessarily means that workQueue.isEmpty(), so rely
47.436 + * solely on isEmpty to see if the queue is empty (which we must
47.437 + * do for example when deciding whether to transition from
47.438 + * SHUTDOWN to TIDYING). This accommodates special-purpose
47.439 + * queues such as DelayQueues for which poll() is allowed to
47.440 + * return null even if it may later return non-null when delays
47.441 + * expire.
47.442 + */
47.443 + private final BlockingQueue<Runnable> workQueue;
47.444 +
47.445 + /**
47.446 + * Lock held on access to workers set and related bookkeeping.
47.447 + * While we could use a concurrent set of some sort, it turns out
47.448 + * to be generally preferable to use a lock. Among the reasons is
47.449 + * that this serializes interruptIdleWorkers, which avoids
47.450 + * unnecessary interrupt storms, especially during shutdown.
47.451 + * Otherwise exiting threads would concurrently interrupt those
47.452 + * that have not yet interrupted. It also simplifies some of the
47.453 + * associated statistics bookkeeping of largestPoolSize etc. We
47.454 + * also hold mainLock on shutdown and shutdownNow, for the sake of
47.455 + * ensuring workers set is stable while separately checking
47.456 + * permission to interrupt and actually interrupting.
47.457 + */
47.458 + private final ReentrantLock mainLock = new ReentrantLock();
47.459 +
47.460 + /**
47.461 + * Set containing all worker threads in pool. Accessed only when
47.462 + * holding mainLock.
47.463 + */
47.464 + private final HashSet<Worker> workers = new HashSet<Worker>();
47.465 +
47.466 + /**
47.467 + * Wait condition to support awaitTermination
47.468 + */
47.469 + private final Condition termination = mainLock.newCondition();
47.470 +
47.471 + /**
47.472 + * Tracks largest attained pool size. Accessed only under
47.473 + * mainLock.
47.474 + */
47.475 + private int largestPoolSize;
47.476 +
47.477 + /**
47.478 + * Counter for completed tasks. Updated only on termination of
47.479 + * worker threads. Accessed only under mainLock.
47.480 + */
47.481 + private long completedTaskCount;
47.482 +
47.483 + /*
47.484 + * All user control parameters are declared as volatiles so that
47.485 + * ongoing actions are based on freshest values, but without need
47.486 + * for locking, since no internal invariants depend on them
47.487 + * changing synchronously with respect to other actions.
47.488 + */
47.489 +
47.490 + /**
47.491 + * Factory for new threads. All threads are created using this
47.492 + * factory (via method addWorker). All callers must be prepared
47.493 + * for addWorker to fail, which may reflect a system or user's
47.494 + * policy limiting the number of threads. Even though it is not
47.495 + * treated as an error, failure to create threads may result in
47.496 + * new tasks being rejected or existing ones remaining stuck in
47.497 + * the queue. On the other hand, no special precautions exist to
47.498 + * handle OutOfMemoryErrors that might be thrown while trying to
47.499 + * create threads, since there is generally no recourse from
47.500 + * within this class.
47.501 + */
47.502 + private volatile ThreadFactory threadFactory;
47.503 +
47.504 + /**
47.505 + * Handler called when saturated or shutdown in execute.
47.506 + */
47.507 + private volatile RejectedExecutionHandler handler;
47.508 +
47.509 + /**
47.510 + * Timeout in nanoseconds for idle threads waiting for work.
47.511 + * Threads use this timeout when there are more than corePoolSize
47.512 + * present or if allowCoreThreadTimeOut. Otherwise they wait
47.513 + * forever for new work.
47.514 + */
47.515 + private volatile long keepAliveTime;
47.516 +
47.517 + /**
47.518 + * If false (default), core threads stay alive even when idle.
47.519 + * If true, core threads use keepAliveTime to time out waiting
47.520 + * for work.
47.521 + */
47.522 + private volatile boolean allowCoreThreadTimeOut;
47.523 +
47.524 + /**
47.525 + * Core pool size is the minimum number of workers to keep alive
47.526 + * (and not allow to time out etc) unless allowCoreThreadTimeOut
47.527 + * is set, in which case the minimum is zero.
47.528 + */
47.529 + private volatile int corePoolSize;
47.530 +
47.531 + /**
47.532 + * Maximum pool size. Note that the actual maximum is internally
47.533 + * bounded by CAPACITY.
47.534 + */
47.535 + private volatile int maximumPoolSize;
47.536 +
47.537 + /**
47.538 + * The default rejected execution handler
47.539 + */
47.540 + private static final RejectedExecutionHandler defaultHandler =
47.541 + new AbortPolicy();
47.542 +
47.543 + /**
47.544 + * Permission required for callers of shutdown and shutdownNow.
47.545 + * We additionally require (see checkShutdownAccess) that callers
47.546 + * have permission to actually interrupt threads in the worker set
47.547 + * (as governed by Thread.interrupt, which relies on
47.548 + * ThreadGroup.checkAccess, which in turn relies on
47.549 + * SecurityManager.checkAccess). Shutdowns are attempted only if
47.550 + * these checks pass.
47.551 + *
47.552 + * All actual invocations of Thread.interrupt (see
47.553 + * interruptIdleWorkers and interruptWorkers) ignore
47.554 + * SecurityExceptions, meaning that the attempted interrupts
47.555 + * silently fail. In the case of shutdown, they should not fail
47.556 + * unless the SecurityManager has inconsistent policies, sometimes
47.557 + * allowing access to a thread and sometimes not. In such cases,
47.558 + * failure to actually interrupt threads may disable or delay full
47.559 + * termination. Other uses of interruptIdleWorkers are advisory,
47.560 + * and failure to actually interrupt will merely delay response to
47.561 + * configuration changes so is not handled exceptionally.
47.562 + */
47.563 + private static final RuntimePermission shutdownPerm =
47.564 + new RuntimePermission("modifyThread");
47.565 +
47.566 + /**
47.567 + * Class Worker mainly maintains interrupt control state for
47.568 + * threads running tasks, along with other minor bookkeeping.
47.569 + * This class opportunistically extends AbstractQueuedSynchronizer
47.570 + * to simplify acquiring and releasing a lock surrounding each
47.571 + * task execution. This protects against interrupts that are
47.572 + * intended to wake up a worker thread waiting for a task from
47.573 + * instead interrupting a task being run. We implement a simple
47.574 + * non-reentrant mutual exclusion lock rather than use ReentrantLock
47.575 + * because we do not want worker tasks to be able to reacquire the
47.576 + * lock when they invoke pool control methods like setCorePoolSize.
47.577 + */
47.578 + private final class Worker
47.579 + extends AbstractQueuedSynchronizer
47.580 + implements Runnable
47.581 + {
47.582 + /**
47.583 + * This class will never be serialized, but we provide a
47.584 + * serialVersionUID to suppress a javac warning.
47.585 + */
47.586 + private static final long serialVersionUID = 6138294804551838833L;
47.587 +
47.588 + /** Thread this worker is running in. Null if factory fails. */
47.589 + final Thread thread;
47.590 + /** Initial task to run. Possibly null. */
47.591 + Runnable firstTask;
47.592 + /** Per-thread task counter */
47.593 + volatile long completedTasks;
47.594 +
47.595 + /**
47.596 + * Creates with given first task and thread from ThreadFactory.
47.597 + * @param firstTask the first task (null if none)
47.598 + */
47.599 + Worker(Runnable firstTask) {
47.600 + this.firstTask = firstTask;
47.601 + this.thread = getThreadFactory().newThread(this);
47.602 + }
47.603 +
47.604 + /** Delegates main run loop to outer runWorker */
47.605 + public void run() {
47.606 + runWorker(this);
47.607 + }
47.608 +
47.609 + // Lock methods
47.610 + //
47.611 + // The value 0 represents the unlocked state.
47.612 + // The value 1 represents the locked state.
47.613 +
47.614 + protected boolean isHeldExclusively() {
47.615 + return getState() == 1;
47.616 + }
47.617 +
47.618 + protected boolean tryAcquire(int unused) {
47.619 + if (compareAndSetState(0, 1)) {
47.620 + setExclusiveOwnerThread(Thread.currentThread());
47.621 + return true;
47.622 + }
47.623 + return false;
47.624 + }
47.625 +
47.626 + protected boolean tryRelease(int unused) {
47.627 + setExclusiveOwnerThread(null);
47.628 + setState(0);
47.629 + return true;
47.630 + }
47.631 +
47.632 + public void lock() { acquire(1); }
47.633 + public boolean tryLock() { return tryAcquire(1); }
47.634 + public void unlock() { release(1); }
47.635 + public boolean isLocked() { return isHeldExclusively(); }
47.636 + }
47.637 +
47.638 + /*
47.639 + * Methods for setting control state
47.640 + */
47.641 +
47.642 + /**
47.643 + * Transitions runState to given target, or leaves it alone if
47.644 + * already at least the given target.
47.645 + *
47.646 + * @param targetState the desired state, either SHUTDOWN or STOP
47.647 + * (but not TIDYING or TERMINATED -- use tryTerminate for that)
47.648 + */
47.649 + private void advanceRunState(int targetState) {
47.650 + for (;;) {
47.651 + int c = ctl.get();
47.652 + if (runStateAtLeast(c, targetState) ||
47.653 + ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))))
47.654 + break;
47.655 + }
47.656 + }
47.657 +
47.658 + /**
47.659 + * Transitions to TERMINATED state if either (SHUTDOWN and pool
47.660 + * and queue empty) or (STOP and pool empty). If otherwise
47.661 + * eligible to terminate but workerCount is nonzero, interrupts an
47.662 + * idle worker to ensure that shutdown signals propagate. This
47.663 + * method must be called following any action that might make
47.664 + * termination possible -- reducing worker count or removing tasks
47.665 + * from the queue during shutdown. The method is non-private to
47.666 + * allow access from ScheduledThreadPoolExecutor.
47.667 + */
47.668 + final void tryTerminate() {
47.669 + for (;;) {
47.670 + int c = ctl.get();
47.671 + if (isRunning(c) ||
47.672 + runStateAtLeast(c, TIDYING) ||
47.673 + (runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
47.674 + return;
47.675 + if (workerCountOf(c) != 0) { // Eligible to terminate
47.676 + interruptIdleWorkers(ONLY_ONE);
47.677 + return;
47.678 + }
47.679 +
47.680 + final ReentrantLock mainLock = this.mainLock;
47.681 + mainLock.lock();
47.682 + try {
47.683 + if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
47.684 + try {
47.685 + terminated();
47.686 + } finally {
47.687 + ctl.set(ctlOf(TERMINATED, 0));
47.688 + termination.signalAll();
47.689 + }
47.690 + return;
47.691 + }
47.692 + } finally {
47.693 + mainLock.unlock();
47.694 + }
47.695 + // else retry on failed CAS
47.696 + }
47.697 + }
47.698 +
47.699 + /*
47.700 + * Methods for controlling interrupts to worker threads.
47.701 + */
47.702 +
47.703 + /**
47.704 + * If there is a security manager, makes sure caller has
47.705 + * permission to shut down threads in general (see shutdownPerm).
47.706 + * If this passes, additionally makes sure the caller is allowed
47.707 + * to interrupt each worker thread. This might not be true even if
47.708 + * first check passed, if the SecurityManager treats some threads
47.709 + * specially.
47.710 + */
47.711 + private void checkShutdownAccess() {
47.712 + SecurityManager security = System.getSecurityManager();
47.713 + if (security != null) {
47.714 + security.checkPermission(shutdownPerm);
47.715 + final ReentrantLock mainLock = this.mainLock;
47.716 + mainLock.lock();
47.717 + try {
47.718 + for (Worker w : workers)
47.719 + security.checkAccess(w.thread);
47.720 + } finally {
47.721 + mainLock.unlock();
47.722 + }
47.723 + }
47.724 + }
47.725 +
47.726 + /**
47.727 + * Interrupts all threads, even if active. Ignores SecurityExceptions
47.728 + * (in which case some threads may remain uninterrupted).
47.729 + */
47.730 + private void interruptWorkers() {
47.731 + final ReentrantLock mainLock = this.mainLock;
47.732 + mainLock.lock();
47.733 + try {
47.734 + for (Worker w : workers) {
47.735 + try {
47.736 + w.thread.interrupt();
47.737 + } catch (SecurityException ignore) {
47.738 + }
47.739 + }
47.740 + } finally {
47.741 + mainLock.unlock();
47.742 + }
47.743 + }
47.744 +
47.745 + /**
47.746 + * Interrupts threads that might be waiting for tasks (as
47.747 + * indicated by not being locked) so they can check for
47.748 + * termination or configuration changes. Ignores
47.749 + * SecurityExceptions (in which case some threads may remain
47.750 + * uninterrupted).
47.751 + *
47.752 + * @param onlyOne If true, interrupt at most one worker. This is
47.753 + * called only from tryTerminate when termination is otherwise
47.754 + * enabled but there are still other workers. In this case, at
47.755 + * most one waiting worker is interrupted to propagate shutdown
47.756 + * signals in case all threads are currently waiting.
47.757 + * Interrupting any arbitrary thread ensures that newly arriving
47.758 + * workers since shutdown began will also eventually exit.
47.759 + * To guarantee eventual termination, it suffices to always
47.760 + * interrupt only one idle worker, but shutdown() interrupts all
47.761 + * idle workers so that redundant workers exit promptly, not
47.762 + * waiting for a straggler task to finish.
47.763 + */
47.764 + private void interruptIdleWorkers(boolean onlyOne) {
47.765 + final ReentrantLock mainLock = this.mainLock;
47.766 + mainLock.lock();
47.767 + try {
47.768 + for (Worker w : workers) {
47.769 + Thread t = w.thread;
47.770 + if (!t.isInterrupted() && w.tryLock()) {
47.771 + try {
47.772 + t.interrupt();
47.773 + } catch (SecurityException ignore) {
47.774 + } finally {
47.775 + w.unlock();
47.776 + }
47.777 + }
47.778 + if (onlyOne)
47.779 + break;
47.780 + }
47.781 + } finally {
47.782 + mainLock.unlock();
47.783 + }
47.784 + }
47.785 +
47.786 + /**
47.787 + * Common form of interruptIdleWorkers, to avoid having to
47.788 + * remember what the boolean argument means.
47.789 + */
47.790 + private void interruptIdleWorkers() {
47.791 + interruptIdleWorkers(false);
47.792 + }
47.793 +
47.794 + private static final boolean ONLY_ONE = true;
47.795 +
47.796 + /**
47.797 + * Ensures that unless the pool is stopping, the current thread
47.798 + * does not have its interrupt set. This requires a double-check
47.799 + * of state in case the interrupt was cleared concurrently with a
47.800 + * shutdownNow -- if so, the interrupt is re-enabled.
47.801 + */
47.802 + private void clearInterruptsForTaskRun() {
47.803 + if (runStateLessThan(ctl.get(), STOP) &&
47.804 + Thread.interrupted() &&
47.805 + runStateAtLeast(ctl.get(), STOP))
47.806 + Thread.currentThread().interrupt();
47.807 + }
47.808 +
47.809 + /*
47.810 + * Misc utilities, most of which are also exported to
47.811 + * ScheduledThreadPoolExecutor
47.812 + */
47.813 +
47.814 + /**
47.815 + * Invokes the rejected execution handler for the given command.
47.816 + * Package-protected for use by ScheduledThreadPoolExecutor.
47.817 + */
47.818 + final void reject(Runnable command) {
47.819 + handler.rejectedExecution(command, this);
47.820 + }
47.821 +
47.822 + /**
47.823 + * Performs any further cleanup following run state transition on
47.824 + * invocation of shutdown. A no-op here, but used by
47.825 + * ScheduledThreadPoolExecutor to cancel delayed tasks.
47.826 + */
47.827 + void onShutdown() {
47.828 + }
47.829 +
47.830 + /**
47.831 + * State check needed by ScheduledThreadPoolExecutor to
47.832 + * enable running tasks during shutdown.
47.833 + *
47.834 + * @param shutdownOK true if should return true if SHUTDOWN
47.835 + */
47.836 + final boolean isRunningOrShutdown(boolean shutdownOK) {
47.837 + int rs = runStateOf(ctl.get());
47.838 + return rs == RUNNING || (rs == SHUTDOWN && shutdownOK);
47.839 + }
47.840 +
47.841 + /**
47.842 + * Drains the task queue into a new list, normally using
47.843 + * drainTo. But if the queue is a DelayQueue or any other kind of
47.844 + * queue for which poll or drainTo may fail to remove some
47.845 + * elements, it deletes them one by one.
47.846 + */
47.847 + private List<Runnable> drainQueue() {
47.848 + BlockingQueue<Runnable> q = workQueue;
47.849 + List<Runnable> taskList = new ArrayList<Runnable>();
47.850 + q.drainTo(taskList);
47.851 + if (!q.isEmpty()) {
47.852 + for (Runnable r : q.toArray(new Runnable[0])) {
47.853 + if (q.remove(r))
47.854 + taskList.add(r);
47.855 + }
47.856 + }
47.857 + return taskList;
47.858 + }
47.859 +
47.860 + /*
47.861 + * Methods for creating, running and cleaning up after workers
47.862 + */
47.863 +
47.864 + /**
47.865 + * Checks if a new worker can be added with respect to current
47.866 + * pool state and the given bound (either core or maximum). If so,
47.867 + * the worker count is adjusted accordingly, and, if possible, a
47.868 + * new worker is created and started running firstTask as its
47.869 + * first task. This method returns false if the pool is stopped or
47.870 + * eligible to shut down. It also returns false if the thread
47.871 + * factory fails to create a thread when asked, which requires a
47.872 + * backout of workerCount, and a recheck for termination, in case
47.873 + * the existence of this worker was holding up termination.
47.874 + *
47.875 + * @param firstTask the task the new thread should run first (or
47.876 + * null if none). Workers are created with an initial first task
47.877 + * (in method execute()) to bypass queuing when there are fewer
47.878 + * than corePoolSize threads (in which case we always start one),
47.879 + * or when the queue is full (in which case we must bypass queue).
47.880 + * Initially idle threads are usually created via
47.881 + * prestartCoreThread or to replace other dying workers.
47.882 + *
47.883 + * @param core if true use corePoolSize as bound, else
47.884 + * maximumPoolSize. (A boolean indicator is used here rather than a
47.885 + * value to ensure reads of fresh values after checking other pool
47.886 + * state).
47.887 + * @return true if successful
47.888 + */
47.889 + private boolean addWorker(Runnable firstTask, boolean core) {
47.890 + retry:
47.891 + for (;;) {
47.892 + int c = ctl.get();
47.893 + int rs = runStateOf(c);
47.894 +
47.895 + // Check if queue empty only if necessary.
47.896 + if (rs >= SHUTDOWN &&
47.897 + ! (rs == SHUTDOWN &&
47.898 + firstTask == null &&
47.899 + ! workQueue.isEmpty()))
47.900 + return false;
47.901 +
47.902 + for (;;) {
47.903 + int wc = workerCountOf(c);
47.904 + if (wc >= CAPACITY ||
47.905 + wc >= (core ? corePoolSize : maximumPoolSize))
47.906 + return false;
47.907 + if (compareAndIncrementWorkerCount(c))
47.908 + break retry;
47.909 + c = ctl.get(); // Re-read ctl
47.910 + if (runStateOf(c) != rs)
47.911 + continue retry;
47.912 + // else CAS failed due to workerCount change; retry inner loop
47.913 + }
47.914 + }
47.915 +
47.916 + Worker w = new Worker(firstTask);
47.917 + Thread t = w.thread;
47.918 +
47.919 + final ReentrantLock mainLock = this.mainLock;
47.920 + mainLock.lock();
47.921 + try {
47.922 + // Recheck while holding lock.
47.923 + // Back out on ThreadFactory failure or if
47.924 + // shut down before lock acquired.
47.925 + int c = ctl.get();
47.926 + int rs = runStateOf(c);
47.927 +
47.928 + if (t == null ||
47.929 + (rs >= SHUTDOWN &&
47.930 + ! (rs == SHUTDOWN &&
47.931 + firstTask == null))) {
47.932 + decrementWorkerCount();
47.933 + tryTerminate();
47.934 + return false;
47.935 + }
47.936 +
47.937 + workers.add(w);
47.938 +
47.939 + int s = workers.size();
47.940 + if (s > largestPoolSize)
47.941 + largestPoolSize = s;
47.942 + } finally {
47.943 + mainLock.unlock();
47.944 + }
47.945 +
47.946 + t.start();
47.947 + // It is possible (but unlikely) for a thread to have been
47.948 + // added to workers, but not yet started, during transition to
47.949 + // STOP, which could result in a rare missed interrupt,
47.950 + // because Thread.interrupt is not guaranteed to have any effect
47.951 + // on a non-yet-started Thread (see Thread#interrupt).
47.952 + if (runStateOf(ctl.get()) == STOP && ! t.isInterrupted())
47.953 + t.interrupt();
47.954 +
47.955 + return true;
47.956 + }
47.957 +
47.958 + /**
47.959 + * Performs cleanup and bookkeeping for a dying worker. Called
47.960 + * only from worker threads. Unless completedAbruptly is set,
47.961 + * assumes that workerCount has already been adjusted to account
47.962 + * for exit. This method removes thread from worker set, and
47.963 + * possibly terminates the pool or replaces the worker if either
47.964 + * it exited due to user task exception or if fewer than
47.965 + * corePoolSize workers are running or queue is non-empty but
47.966 + * there are no workers.
47.967 + *
47.968 + * @param w the worker
47.969 + * @param completedAbruptly if the worker died due to user exception
47.970 + */
47.971 + private void processWorkerExit(Worker w, boolean completedAbruptly) {
47.972 + if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
47.973 + decrementWorkerCount();
47.974 +
47.975 + final ReentrantLock mainLock = this.mainLock;
47.976 + mainLock.lock();
47.977 + try {
47.978 + completedTaskCount += w.completedTasks;
47.979 + workers.remove(w);
47.980 + } finally {
47.981 + mainLock.unlock();
47.982 + }
47.983 +
47.984 + tryTerminate();
47.985 +
47.986 + int c = ctl.get();
47.987 + if (runStateLessThan(c, STOP)) {
47.988 + if (!completedAbruptly) {
47.989 + int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
47.990 + if (min == 0 && ! workQueue.isEmpty())
47.991 + min = 1;
47.992 + if (workerCountOf(c) >= min)
47.993 + return; // replacement not needed
47.994 + }
47.995 + addWorker(null, false);
47.996 + }
47.997 + }
47.998 +
47.999 + /**
47.1000 + * Performs blocking or timed wait for a task, depending on
47.1001 + * current configuration settings, or returns null if this worker
47.1002 + * must exit because of any of:
47.1003 + * 1. There are more than maximumPoolSize workers (due to
47.1004 + * a call to setMaximumPoolSize).
47.1005 + * 2. The pool is stopped.
47.1006 + * 3. The pool is shutdown and the queue is empty.
47.1007 + * 4. This worker timed out waiting for a task, and timed-out
47.1008 + * workers are subject to termination (that is,
47.1009 + * {@code allowCoreThreadTimeOut || workerCount > corePoolSize})
47.1010 + * both before and after the timed wait.
47.1011 + *
47.1012 + * @return task, or null if the worker must exit, in which case
47.1013 + * workerCount is decremented
47.1014 + */
47.1015 + private Runnable getTask() {
47.1016 + boolean timedOut = false; // Did the last poll() time out?
47.1017 +
47.1018 + retry:
47.1019 + for (;;) {
47.1020 + int c = ctl.get();
47.1021 + int rs = runStateOf(c);
47.1022 +
47.1023 + // Check if queue empty only if necessary.
47.1024 + if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
47.1025 + decrementWorkerCount();
47.1026 + return null;
47.1027 + }
47.1028 +
47.1029 + boolean timed; // Are workers subject to culling?
47.1030 +
47.1031 + for (;;) {
47.1032 + int wc = workerCountOf(c);
47.1033 + timed = allowCoreThreadTimeOut || wc > corePoolSize;
47.1034 +
47.1035 + if (wc <= maximumPoolSize && ! (timedOut && timed))
47.1036 + break;
47.1037 + if (compareAndDecrementWorkerCount(c))
47.1038 + return null;
47.1039 + c = ctl.get(); // Re-read ctl
47.1040 + if (runStateOf(c) != rs)
47.1041 + continue retry;
47.1042 + // else CAS failed due to workerCount change; retry inner loop
47.1043 + }
47.1044 +
47.1045 + try {
47.1046 + Runnable r = timed ?
47.1047 + workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
47.1048 + workQueue.take();
47.1049 + if (r != null)
47.1050 + return r;
47.1051 + timedOut = true;
47.1052 + } catch (InterruptedException retry) {
47.1053 + timedOut = false;
47.1054 + }
47.1055 + }
47.1056 + }
47.1057 +
47.1058 + /**
47.1059 + * Main worker run loop. Repeatedly gets tasks from queue and
47.1060 + * executes them, while coping with a number of issues:
47.1061 + *
47.1062 + * 1. We may start out with an initial task, in which case we
47.1063 + * don't need to get the first one. Otherwise, as long as pool is
47.1064 + * running, we get tasks from getTask. If it returns null then the
47.1065 + * worker exits due to changed pool state or configuration
47.1066 + * parameters. Other exits result from exception throws in
47.1067 + * external code, in which case completedAbruptly holds, which
47.1068 + * usually leads processWorkerExit to replace this thread.
47.1069 + *
47.1070 + * 2. Before running any task, the lock is acquired to prevent
47.1071 + * other pool interrupts while the task is executing, and
47.1072 + * clearInterruptsForTaskRun called to ensure that unless pool is
47.1073 + * stopping, this thread does not have its interrupt set.
47.1074 + *
47.1075 + * 3. Each task run is preceded by a call to beforeExecute, which
47.1076 + * might throw an exception, in which case we cause thread to die
47.1077 + * (breaking loop with completedAbruptly true) without processing
47.1078 + * the task.
47.1079 + *
47.1080 + * 4. Assuming beforeExecute completes normally, we run the task,
47.1081 + * gathering any of its thrown exceptions to send to
47.1082 + * afterExecute. We separately handle RuntimeException, Error
47.1083 + * (both of which the specs guarantee that we trap) and arbitrary
47.1084 + * Throwables. Because we cannot rethrow Throwables within
47.1085 + * Runnable.run, we wrap them within Errors on the way out (to the
47.1086 + * thread's UncaughtExceptionHandler). Any thrown exception also
47.1087 + * conservatively causes thread to die.
47.1088 + *
47.1089 + * 5. After task.run completes, we call afterExecute, which may
47.1090 + * also throw an exception, which will also cause thread to
47.1091 + * die. According to JLS Sec 14.20, this exception is the one that
47.1092 + * will be in effect even if task.run throws.
47.1093 + *
47.1094 + * The net effect of the exception mechanics is that afterExecute
47.1095 + * and the thread's UncaughtExceptionHandler have as accurate
47.1096 + * information as we can provide about any problems encountered by
47.1097 + * user code.
47.1098 + *
47.1099 + * @param w the worker
47.1100 + */
47.1101 + final void runWorker(Worker w) {
47.1102 + Runnable task = w.firstTask;
47.1103 + w.firstTask = null;
47.1104 + boolean completedAbruptly = true;
47.1105 + try {
47.1106 + while (task != null || (task = getTask()) != null) {
47.1107 + w.lock();
47.1108 + clearInterruptsForTaskRun();
47.1109 + try {
47.1110 + beforeExecute(w.thread, task);
47.1111 + Throwable thrown = null;
47.1112 + try {
47.1113 + task.run();
47.1114 + } catch (RuntimeException x) {
47.1115 + thrown = x; throw x;
47.1116 + } catch (Error x) {
47.1117 + thrown = x; throw x;
47.1118 + } catch (Throwable x) {
47.1119 + thrown = x; throw new Error(x);
47.1120 + } finally {
47.1121 + afterExecute(task, thrown);
47.1122 + }
47.1123 + } finally {
47.1124 + task = null;
47.1125 + w.completedTasks++;
47.1126 + w.unlock();
47.1127 + }
47.1128 + }
47.1129 + completedAbruptly = false;
47.1130 + } finally {
47.1131 + processWorkerExit(w, completedAbruptly);
47.1132 + }
47.1133 + }
47.1134 +
47.1135 + // Public constructors and methods
47.1136 +
47.1137 + /**
47.1138 + * Creates a new {@code ThreadPoolExecutor} with the given initial
47.1139 + * parameters and default thread factory and rejected execution handler.
47.1140 + * It may be more convenient to use one of the {@link Executors} factory
47.1141 + * methods instead of this general purpose constructor.
47.1142 + *
47.1143 + * @param corePoolSize the number of threads to keep in the pool, even
47.1144 + * if they are idle, unless {@code allowCoreThreadTimeOut} is set
47.1145 + * @param maximumPoolSize the maximum number of threads to allow in the
47.1146 + * pool
47.1147 + * @param keepAliveTime when the number of threads is greater than
47.1148 + * the core, this is the maximum time that excess idle threads
47.1149 + * will wait for new tasks before terminating.
47.1150 + * @param unit the time unit for the {@code keepAliveTime} argument
47.1151 + * @param workQueue the queue to use for holding tasks before they are
47.1152 + * executed. This queue will hold only the {@code Runnable}
47.1153 + * tasks submitted by the {@code execute} method.
47.1154 + * @throws IllegalArgumentException if one of the following holds:<br>
47.1155 + * {@code corePoolSize < 0}<br>
47.1156 + * {@code keepAliveTime < 0}<br>
47.1157 + * {@code maximumPoolSize <= 0}<br>
47.1158 + * {@code maximumPoolSize < corePoolSize}
47.1159 + * @throws NullPointerException if {@code workQueue} is null
47.1160 + */
47.1161 + public ThreadPoolExecutor(int corePoolSize,
47.1162 + int maximumPoolSize,
47.1163 + long keepAliveTime,
47.1164 + TimeUnit unit,
47.1165 + BlockingQueue<Runnable> workQueue) {
47.1166 + this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
47.1167 + Executors.defaultThreadFactory(), defaultHandler);
47.1168 + }
47.1169 +
47.1170 + /**
47.1171 + * Creates a new {@code ThreadPoolExecutor} with the given initial
47.1172 + * parameters and default rejected execution handler.
47.1173 + *
47.1174 + * @param corePoolSize the number of threads to keep in the pool, even
47.1175 + * if they are idle, unless {@code allowCoreThreadTimeOut} is set
47.1176 + * @param maximumPoolSize the maximum number of threads to allow in the
47.1177 + * pool
47.1178 + * @param keepAliveTime when the number of threads is greater than
47.1179 + * the core, this is the maximum time that excess idle threads
47.1180 + * will wait for new tasks before terminating.
47.1181 + * @param unit the time unit for the {@code keepAliveTime} argument
47.1182 + * @param workQueue the queue to use for holding tasks before they are
47.1183 + * executed. This queue will hold only the {@code Runnable}
47.1184 + * tasks submitted by the {@code execute} method.
47.1185 + * @param threadFactory the factory to use when the executor
47.1186 + * creates a new thread
47.1187 + * @throws IllegalArgumentException if one of the following holds:<br>
47.1188 + * {@code corePoolSize < 0}<br>
47.1189 + * {@code keepAliveTime < 0}<br>
47.1190 + * {@code maximumPoolSize <= 0}<br>
47.1191 + * {@code maximumPoolSize < corePoolSize}
47.1192 + * @throws NullPointerException if {@code workQueue}
47.1193 + * or {@code threadFactory} is null
47.1194 + */
47.1195 + public ThreadPoolExecutor(int corePoolSize,
47.1196 + int maximumPoolSize,
47.1197 + long keepAliveTime,
47.1198 + TimeUnit unit,
47.1199 + BlockingQueue<Runnable> workQueue,
47.1200 + ThreadFactory threadFactory) {
47.1201 + this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
47.1202 + threadFactory, defaultHandler);
47.1203 + }
47.1204 +
47.1205 + /**
47.1206 + * Creates a new {@code ThreadPoolExecutor} with the given initial
47.1207 + * parameters and default thread factory.
47.1208 + *
47.1209 + * @param corePoolSize the number of threads to keep in the pool, even
47.1210 + * if they are idle, unless {@code allowCoreThreadTimeOut} is set
47.1211 + * @param maximumPoolSize the maximum number of threads to allow in the
47.1212 + * pool
47.1213 + * @param keepAliveTime when the number of threads is greater than
47.1214 + * the core, this is the maximum time that excess idle threads
47.1215 + * will wait for new tasks before terminating.
47.1216 + * @param unit the time unit for the {@code keepAliveTime} argument
47.1217 + * @param workQueue the queue to use for holding tasks before they are
47.1218 + * executed. This queue will hold only the {@code Runnable}
47.1219 + * tasks submitted by the {@code execute} method.
47.1220 + * @param handler the handler to use when execution is blocked
47.1221 + * because the thread bounds and queue capacities are reached
47.1222 + * @throws IllegalArgumentException if one of the following holds:<br>
47.1223 + * {@code corePoolSize < 0}<br>
47.1224 + * {@code keepAliveTime < 0}<br>
47.1225 + * {@code maximumPoolSize <= 0}<br>
47.1226 + * {@code maximumPoolSize < corePoolSize}
47.1227 + * @throws NullPointerException if {@code workQueue}
47.1228 + * or {@code handler} is null
47.1229 + */
47.1230 + public ThreadPoolExecutor(int corePoolSize,
47.1231 + int maximumPoolSize,
47.1232 + long keepAliveTime,
47.1233 + TimeUnit unit,
47.1234 + BlockingQueue<Runnable> workQueue,
47.1235 + RejectedExecutionHandler handler) {
47.1236 + this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
47.1237 + Executors.defaultThreadFactory(), handler);
47.1238 + }
47.1239 +
47.1240 + /**
47.1241 + * Creates a new {@code ThreadPoolExecutor} with the given initial
47.1242 + * parameters.
47.1243 + *
47.1244 + * @param corePoolSize the number of threads to keep in the pool, even
47.1245 + * if they are idle, unless {@code allowCoreThreadTimeOut} is set
47.1246 + * @param maximumPoolSize the maximum number of threads to allow in the
47.1247 + * pool
47.1248 + * @param keepAliveTime when the number of threads is greater than
47.1249 + * the core, this is the maximum time that excess idle threads
47.1250 + * will wait for new tasks before terminating.
47.1251 + * @param unit the time unit for the {@code keepAliveTime} argument
47.1252 + * @param workQueue the queue to use for holding tasks before they are
47.1253 + * executed. This queue will hold only the {@code Runnable}
47.1254 + * tasks submitted by the {@code execute} method.
47.1255 + * @param threadFactory the factory to use when the executor
47.1256 + * creates a new thread
47.1257 + * @param handler the handler to use when execution is blocked
47.1258 + * because the thread bounds and queue capacities are reached
47.1259 + * @throws IllegalArgumentException if one of the following holds:<br>
47.1260 + * {@code corePoolSize < 0}<br>
47.1261 + * {@code keepAliveTime < 0}<br>
47.1262 + * {@code maximumPoolSize <= 0}<br>
47.1263 + * {@code maximumPoolSize < corePoolSize}
47.1264 + * @throws NullPointerException if {@code workQueue}
47.1265 + * or {@code threadFactory} or {@code handler} is null
47.1266 + */
47.1267 + public ThreadPoolExecutor(int corePoolSize,
47.1268 + int maximumPoolSize,
47.1269 + long keepAliveTime,
47.1270 + TimeUnit unit,
47.1271 + BlockingQueue<Runnable> workQueue,
47.1272 + ThreadFactory threadFactory,
47.1273 + RejectedExecutionHandler handler) {
47.1274 + if (corePoolSize < 0 ||
47.1275 + maximumPoolSize <= 0 ||
47.1276 + maximumPoolSize < corePoolSize ||
47.1277 + keepAliveTime < 0)
47.1278 + throw new IllegalArgumentException();
47.1279 + if (workQueue == null || threadFactory == null || handler == null)
47.1280 + throw new NullPointerException();
47.1281 + this.corePoolSize = corePoolSize;
47.1282 + this.maximumPoolSize = maximumPoolSize;
47.1283 + this.workQueue = workQueue;
47.1284 + this.keepAliveTime = unit.toNanos(keepAliveTime);
47.1285 + this.threadFactory = threadFactory;
47.1286 + this.handler = handler;
47.1287 + }
47.1288 +
47.1289 + /**
47.1290 + * Executes the given task sometime in the future. The task
47.1291 + * may execute in a new thread or in an existing pooled thread.
47.1292 + *
47.1293 + * If the task cannot be submitted for execution, either because this
47.1294 + * executor has been shutdown or because its capacity has been reached,
47.1295 + * the task is handled by the current {@code RejectedExecutionHandler}.
47.1296 + *
47.1297 + * @param command the task to execute
47.1298 + * @throws RejectedExecutionException at discretion of
47.1299 + * {@code RejectedExecutionHandler}, if the task
47.1300 + * cannot be accepted for execution
47.1301 + * @throws NullPointerException if {@code command} is null
47.1302 + */
47.1303 + public void execute(Runnable command) {
47.1304 + if (command == null)
47.1305 + throw new NullPointerException();
47.1306 + /*
47.1307 + * Proceed in 3 steps:
47.1308 + *
47.1309 + * 1. If fewer than corePoolSize threads are running, try to
47.1310 + * start a new thread with the given command as its first
47.1311 + * task. The call to addWorker atomically checks runState and
47.1312 + * workerCount, and so prevents false alarms that would add
47.1313 + * threads when it shouldn't, by returning false.
47.1314 + *
47.1315 + * 2. If a task can be successfully queued, then we still need
47.1316 + * to double-check whether we should have added a thread
47.1317 + * (because existing ones died since last checking) or that
47.1318 + * the pool shut down since entry into this method. So we
47.1319 + * recheck state and if necessary roll back the enqueuing if
47.1320 + * stopped, or start a new thread if there are none.
47.1321 + *
47.1322 + * 3. If we cannot queue task, then we try to add a new
47.1323 + * thread. If it fails, we know we are shut down or saturated
47.1324 + * and so reject the task.
47.1325 + */
47.1326 + int c = ctl.get();
47.1327 + if (workerCountOf(c) < corePoolSize) {
47.1328 + if (addWorker(command, true))
47.1329 + return;
47.1330 + c = ctl.get();
47.1331 + }
47.1332 + if (isRunning(c) && workQueue.offer(command)) {
47.1333 + int recheck = ctl.get();
47.1334 + if (! isRunning(recheck) && remove(command))
47.1335 + reject(command);
47.1336 + else if (workerCountOf(recheck) == 0)
47.1337 + addWorker(null, false);
47.1338 + }
47.1339 + else if (!addWorker(command, false))
47.1340 + reject(command);
47.1341 + }
47.1342 +
47.1343 + /**
47.1344 + * Initiates an orderly shutdown in which previously submitted
47.1345 + * tasks are executed, but no new tasks will be accepted.
47.1346 + * Invocation has no additional effect if already shut down.
47.1347 + *
47.1348 + * <p>This method does not wait for previously submitted tasks to
47.1349 + * complete execution. Use {@link #awaitTermination awaitTermination}
47.1350 + * to do that.
47.1351 + *
47.1352 + * @throws SecurityException {@inheritDoc}
47.1353 + */
47.1354 + public void shutdown() {
47.1355 + final ReentrantLock mainLock = this.mainLock;
47.1356 + mainLock.lock();
47.1357 + try {
47.1358 + checkShutdownAccess();
47.1359 + advanceRunState(SHUTDOWN);
47.1360 + interruptIdleWorkers();
47.1361 + onShutdown(); // hook for ScheduledThreadPoolExecutor
47.1362 + } finally {
47.1363 + mainLock.unlock();
47.1364 + }
47.1365 + tryTerminate();
47.1366 + }
47.1367 +
47.1368 + /**
47.1369 + * Attempts to stop all actively executing tasks, halts the
47.1370 + * processing of waiting tasks, and returns a list of the tasks
47.1371 + * that were awaiting execution. These tasks are drained (removed)
47.1372 + * from the task queue upon return from this method.
47.1373 + *
47.1374 + * <p>This method does not wait for actively executing tasks to
47.1375 + * terminate. Use {@link #awaitTermination awaitTermination} to
47.1376 + * do that.
47.1377 + *
47.1378 + * <p>There are no guarantees beyond best-effort attempts to stop
47.1379 + * processing actively executing tasks. This implementation
47.1380 + * cancels tasks via {@link Thread#interrupt}, so any task that
47.1381 + * fails to respond to interrupts may never terminate.
47.1382 + *
47.1383 + * @throws SecurityException {@inheritDoc}
47.1384 + */
47.1385 + public List<Runnable> shutdownNow() {
47.1386 + List<Runnable> tasks;
47.1387 + final ReentrantLock mainLock = this.mainLock;
47.1388 + mainLock.lock();
47.1389 + try {
47.1390 + checkShutdownAccess();
47.1391 + advanceRunState(STOP);
47.1392 + interruptWorkers();
47.1393 + tasks = drainQueue();
47.1394 + } finally {
47.1395 + mainLock.unlock();
47.1396 + }
47.1397 + tryTerminate();
47.1398 + return tasks;
47.1399 + }
47.1400 +
47.1401 + public boolean isShutdown() {
47.1402 + return ! isRunning(ctl.get());
47.1403 + }
47.1404 +
47.1405 + /**
47.1406 + * Returns true if this executor is in the process of terminating
47.1407 + * after {@link #shutdown} or {@link #shutdownNow} but has not
47.1408 + * completely terminated. This method may be useful for
47.1409 + * debugging. A return of {@code true} reported a sufficient
47.1410 + * period after shutdown may indicate that submitted tasks have
47.1411 + * ignored or suppressed interruption, causing this executor not
47.1412 + * to properly terminate.
47.1413 + *
47.1414 + * @return true if terminating but not yet terminated
47.1415 + */
47.1416 + public boolean isTerminating() {
47.1417 + int c = ctl.get();
47.1418 + return ! isRunning(c) && runStateLessThan(c, TERMINATED);
47.1419 + }
47.1420 +
47.1421 + public boolean isTerminated() {
47.1422 + return runStateAtLeast(ctl.get(), TERMINATED);
47.1423 + }
47.1424 +
47.1425 + public boolean awaitTermination(long timeout, TimeUnit unit)
47.1426 + throws InterruptedException {
47.1427 + long nanos = unit.toNanos(timeout);
47.1428 + final ReentrantLock mainLock = this.mainLock;
47.1429 + mainLock.lock();
47.1430 + try {
47.1431 + for (;;) {
47.1432 + if (runStateAtLeast(ctl.get(), TERMINATED))
47.1433 + return true;
47.1434 + if (nanos <= 0)
47.1435 + return false;
47.1436 + nanos = termination.awaitNanos(nanos);
47.1437 + }
47.1438 + } finally {
47.1439 + mainLock.unlock();
47.1440 + }
47.1441 + }
47.1442 +
47.1443 + /**
47.1444 + * Invokes {@code shutdown} when this executor is no longer
47.1445 + * referenced and it has no threads.
47.1446 + */
47.1447 + protected void finalize() {
47.1448 + shutdown();
47.1449 + }
47.1450 +
47.1451 + /**
47.1452 + * Sets the thread factory used to create new threads.
47.1453 + *
47.1454 + * @param threadFactory the new thread factory
47.1455 + * @throws NullPointerException if threadFactory is null
47.1456 + * @see #getThreadFactory
47.1457 + */
47.1458 + public void setThreadFactory(ThreadFactory threadFactory) {
47.1459 + if (threadFactory == null)
47.1460 + throw new NullPointerException();
47.1461 + this.threadFactory = threadFactory;
47.1462 + }
47.1463 +
47.1464 + /**
47.1465 + * Returns the thread factory used to create new threads.
47.1466 + *
47.1467 + * @return the current thread factory
47.1468 + * @see #setThreadFactory
47.1469 + */
47.1470 + public ThreadFactory getThreadFactory() {
47.1471 + return threadFactory;
47.1472 + }
47.1473 +
47.1474 + /**
47.1475 + * Sets a new handler for unexecutable tasks.
47.1476 + *
47.1477 + * @param handler the new handler
47.1478 + * @throws NullPointerException if handler is null
47.1479 + * @see #getRejectedExecutionHandler
47.1480 + */
47.1481 + public void setRejectedExecutionHandler(RejectedExecutionHandler handler) {
47.1482 + if (handler == null)
47.1483 + throw new NullPointerException();
47.1484 + this.handler = handler;
47.1485 + }
47.1486 +
47.1487 + /**
47.1488 + * Returns the current handler for unexecutable tasks.
47.1489 + *
47.1490 + * @return the current handler
47.1491 + * @see #setRejectedExecutionHandler
47.1492 + */
47.1493 + public RejectedExecutionHandler getRejectedExecutionHandler() {
47.1494 + return handler;
47.1495 + }
47.1496 +
47.1497 + /**
47.1498 + * Sets the core number of threads. This overrides any value set
47.1499 + * in the constructor. If the new value is smaller than the
47.1500 + * current value, excess existing threads will be terminated when
47.1501 + * they next become idle. If larger, new threads will, if needed,
47.1502 + * be started to execute any queued tasks.
47.1503 + *
47.1504 + * @param corePoolSize the new core size
47.1505 + * @throws IllegalArgumentException if {@code corePoolSize < 0}
47.1506 + * @see #getCorePoolSize
47.1507 + */
47.1508 + public void setCorePoolSize(int corePoolSize) {
47.1509 + if (corePoolSize < 0)
47.1510 + throw new IllegalArgumentException();
47.1511 + int delta = corePoolSize - this.corePoolSize;
47.1512 + this.corePoolSize = corePoolSize;
47.1513 + if (workerCountOf(ctl.get()) > corePoolSize)
47.1514 + interruptIdleWorkers();
47.1515 + else if (delta > 0) {
47.1516 + // We don't really know how many new threads are "needed".
47.1517 + // As a heuristic, prestart enough new workers (up to new
47.1518 + // core size) to handle the current number of tasks in
47.1519 + // queue, but stop if queue becomes empty while doing so.
47.1520 + int k = Math.min(delta, workQueue.size());
47.1521 + while (k-- > 0 && addWorker(null, true)) {
47.1522 + if (workQueue.isEmpty())
47.1523 + break;
47.1524 + }
47.1525 + }
47.1526 + }
47.1527 +
47.1528 + /**
47.1529 + * Returns the core number of threads.
47.1530 + *
47.1531 + * @return the core number of threads
47.1532 + * @see #setCorePoolSize
47.1533 + */
47.1534 + public int getCorePoolSize() {
47.1535 + return corePoolSize;
47.1536 + }
47.1537 +
47.1538 + /**
47.1539 + * Starts a core thread, causing it to idly wait for work. This
47.1540 + * overrides the default policy of starting core threads only when
47.1541 + * new tasks are executed. This method will return {@code false}
47.1542 + * if all core threads have already been started.
47.1543 + *
47.1544 + * @return {@code true} if a thread was started
47.1545 + */
47.1546 + public boolean prestartCoreThread() {
47.1547 + return workerCountOf(ctl.get()) < corePoolSize &&
47.1548 + addWorker(null, true);
47.1549 + }
47.1550 +
47.1551 + /**
47.1552 + * Starts all core threads, causing them to idly wait for work. This
47.1553 + * overrides the default policy of starting core threads only when
47.1554 + * new tasks are executed.
47.1555 + *
47.1556 + * @return the number of threads started
47.1557 + */
47.1558 + public int prestartAllCoreThreads() {
47.1559 + int n = 0;
47.1560 + while (addWorker(null, true))
47.1561 + ++n;
47.1562 + return n;
47.1563 + }
47.1564 +
47.1565 + /**
47.1566 + * Returns true if this pool allows core threads to time out and
47.1567 + * terminate if no tasks arrive within the keepAlive time, being
47.1568 + * replaced if needed when new tasks arrive. When true, the same
47.1569 + * keep-alive policy applying to non-core threads applies also to
47.1570 + * core threads. When false (the default), core threads are never
47.1571 + * terminated due to lack of incoming tasks.
47.1572 + *
47.1573 + * @return {@code true} if core threads are allowed to time out,
47.1574 + * else {@code false}
47.1575 + *
47.1576 + * @since 1.6
47.1577 + */
47.1578 + public boolean allowsCoreThreadTimeOut() {
47.1579 + return allowCoreThreadTimeOut;
47.1580 + }
47.1581 +
47.1582 + /**
47.1583 + * Sets the policy governing whether core threads may time out and
47.1584 + * terminate if no tasks arrive within the keep-alive time, being
47.1585 + * replaced if needed when new tasks arrive. When false, core
47.1586 + * threads are never terminated due to lack of incoming
47.1587 + * tasks. When true, the same keep-alive policy applying to
47.1588 + * non-core threads applies also to core threads. To avoid
47.1589 + * continual thread replacement, the keep-alive time must be
47.1590 + * greater than zero when setting {@code true}. This method
47.1591 + * should in general be called before the pool is actively used.
47.1592 + *
47.1593 + * @param value {@code true} if should time out, else {@code false}
47.1594 + * @throws IllegalArgumentException if value is {@code true}
47.1595 + * and the current keep-alive time is not greater than zero
47.1596 + *
47.1597 + * @since 1.6
47.1598 + */
47.1599 + public void allowCoreThreadTimeOut(boolean value) {
47.1600 + if (value && keepAliveTime <= 0)
47.1601 + throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
47.1602 + if (value != allowCoreThreadTimeOut) {
47.1603 + allowCoreThreadTimeOut = value;
47.1604 + if (value)
47.1605 + interruptIdleWorkers();
47.1606 + }
47.1607 + }
47.1608 +
47.1609 + /**
47.1610 + * Sets the maximum allowed number of threads. This overrides any
47.1611 + * value set in the constructor. If the new value is smaller than
47.1612 + * the current value, excess existing threads will be
47.1613 + * terminated when they next become idle.
47.1614 + *
47.1615 + * @param maximumPoolSize the new maximum
47.1616 + * @throws IllegalArgumentException if the new maximum is
47.1617 + * less than or equal to zero, or
47.1618 + * less than the {@linkplain #getCorePoolSize core pool size}
47.1619 + * @see #getMaximumPoolSize
47.1620 + */
47.1621 + public void setMaximumPoolSize(int maximumPoolSize) {
47.1622 + if (maximumPoolSize <= 0 || maximumPoolSize < corePoolSize)
47.1623 + throw new IllegalArgumentException();
47.1624 + this.maximumPoolSize = maximumPoolSize;
47.1625 + if (workerCountOf(ctl.get()) > maximumPoolSize)
47.1626 + interruptIdleWorkers();
47.1627 + }
47.1628 +
47.1629 + /**
47.1630 + * Returns the maximum allowed number of threads.
47.1631 + *
47.1632 + * @return the maximum allowed number of threads
47.1633 + * @see #setMaximumPoolSize
47.1634 + */
47.1635 + public int getMaximumPoolSize() {
47.1636 + return maximumPoolSize;
47.1637 + }
47.1638 +
47.1639 + /**
47.1640 + * Sets the time limit for which threads may remain idle before
47.1641 + * being terminated. If there are more than the core number of
47.1642 + * threads currently in the pool, after waiting this amount of
47.1643 + * time without processing a task, excess threads will be
47.1644 + * terminated. This overrides any value set in the constructor.
47.1645 + *
47.1646 + * @param time the time to wait. A time value of zero will cause
47.1647 + * excess threads to terminate immediately after executing tasks.
47.1648 + * @param unit the time unit of the {@code time} argument
47.1649 + * @throws IllegalArgumentException if {@code time} less than zero or
47.1650 + * if {@code time} is zero and {@code allowsCoreThreadTimeOut}
47.1651 + * @see #getKeepAliveTime
47.1652 + */
47.1653 + public void setKeepAliveTime(long time, TimeUnit unit) {
47.1654 + if (time < 0)
47.1655 + throw new IllegalArgumentException();
47.1656 + if (time == 0 && allowsCoreThreadTimeOut())
47.1657 + throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
47.1658 + long keepAliveTime = unit.toNanos(time);
47.1659 + long delta = keepAliveTime - this.keepAliveTime;
47.1660 + this.keepAliveTime = keepAliveTime;
47.1661 + if (delta < 0)
47.1662 + interruptIdleWorkers();
47.1663 + }
47.1664 +
47.1665 + /**
47.1666 + * Returns the thread keep-alive time, which is the amount of time
47.1667 + * that threads in excess of the core pool size may remain
47.1668 + * idle before being terminated.
47.1669 + *
47.1670 + * @param unit the desired time unit of the result
47.1671 + * @return the time limit
47.1672 + * @see #setKeepAliveTime
47.1673 + */
47.1674 + public long getKeepAliveTime(TimeUnit unit) {
47.1675 + return unit.convert(keepAliveTime, TimeUnit.NANOSECONDS);
47.1676 + }
47.1677 +
47.1678 + /* User-level queue utilities */
47.1679 +
47.1680 + /**
47.1681 + * Returns the task queue used by this executor. Access to the
47.1682 + * task queue is intended primarily for debugging and monitoring.
47.1683 + * This queue may be in active use. Retrieving the task queue
47.1684 + * does not prevent queued tasks from executing.
47.1685 + *
47.1686 + * @return the task queue
47.1687 + */
47.1688 + public BlockingQueue<Runnable> getQueue() {
47.1689 + return workQueue;
47.1690 + }
47.1691 +
47.1692 + /**
47.1693 + * Removes this task from the executor's internal queue if it is
47.1694 + * present, thus causing it not to be run if it has not already
47.1695 + * started.
47.1696 + *
47.1697 + * <p> This method may be useful as one part of a cancellation
47.1698 + * scheme. It may fail to remove tasks that have been converted
47.1699 + * into other forms before being placed on the internal queue. For
47.1700 + * example, a task entered using {@code submit} might be
47.1701 + * converted into a form that maintains {@code Future} status.
47.1702 + * However, in such cases, method {@link #purge} may be used to
47.1703 + * remove those Futures that have been cancelled.
47.1704 + *
47.1705 + * @param task the task to remove
47.1706 + * @return true if the task was removed
47.1707 + */
47.1708 + public boolean remove(Runnable task) {
47.1709 + boolean removed = workQueue.remove(task);
47.1710 + tryTerminate(); // In case SHUTDOWN and now empty
47.1711 + return removed;
47.1712 + }
47.1713 +
47.1714 + /**
47.1715 + * Tries to remove from the work queue all {@link Future}
47.1716 + * tasks that have been cancelled. This method can be useful as a
47.1717 + * storage reclamation operation, that has no other impact on
47.1718 + * functionality. Cancelled tasks are never executed, but may
47.1719 + * accumulate in work queues until worker threads can actively
47.1720 + * remove them. Invoking this method instead tries to remove them now.
47.1721 + * However, this method may fail to remove tasks in
47.1722 + * the presence of interference by other threads.
47.1723 + */
47.1724 + public void purge() {
47.1725 + final BlockingQueue<Runnable> q = workQueue;
47.1726 + try {
47.1727 + Iterator<Runnable> it = q.iterator();
47.1728 + while (it.hasNext()) {
47.1729 + Runnable r = it.next();
47.1730 + if (r instanceof Future<?> && ((Future<?>)r).isCancelled())
47.1731 + it.remove();
47.1732 + }
47.1733 + } catch (ConcurrentModificationException fallThrough) {
47.1734 + // Take slow path if we encounter interference during traversal.
47.1735 + // Make copy for traversal and call remove for cancelled entries.
47.1736 + // The slow path is more likely to be O(N*N).
47.1737 + for (Object r : q.toArray())
47.1738 + if (r instanceof Future<?> && ((Future<?>)r).isCancelled())
47.1739 + q.remove(r);
47.1740 + }
47.1741 +
47.1742 + tryTerminate(); // In case SHUTDOWN and now empty
47.1743 + }
47.1744 +
47.1745 + /* Statistics */
47.1746 +
47.1747 + /**
47.1748 + * Returns the current number of threads in the pool.
47.1749 + *
47.1750 + * @return the number of threads
47.1751 + */
47.1752 + public int getPoolSize() {
47.1753 + final ReentrantLock mainLock = this.mainLock;
47.1754 + mainLock.lock();
47.1755 + try {
47.1756 + // Remove rare and surprising possibility of
47.1757 + // isTerminated() && getPoolSize() > 0
47.1758 + return runStateAtLeast(ctl.get(), TIDYING) ? 0
47.1759 + : workers.size();
47.1760 + } finally {
47.1761 + mainLock.unlock();
47.1762 + }
47.1763 + }
47.1764 +
47.1765 + /**
47.1766 + * Returns the approximate number of threads that are actively
47.1767 + * executing tasks.
47.1768 + *
47.1769 + * @return the number of threads
47.1770 + */
47.1771 + public int getActiveCount() {
47.1772 + final ReentrantLock mainLock = this.mainLock;
47.1773 + mainLock.lock();
47.1774 + try {
47.1775 + int n = 0;
47.1776 + for (Worker w : workers)
47.1777 + if (w.isLocked())
47.1778 + ++n;
47.1779 + return n;
47.1780 + } finally {
47.1781 + mainLock.unlock();
47.1782 + }
47.1783 + }
47.1784 +
47.1785 + /**
47.1786 + * Returns the largest number of threads that have ever
47.1787 + * simultaneously been in the pool.
47.1788 + *
47.1789 + * @return the number of threads
47.1790 + */
47.1791 + public int getLargestPoolSize() {
47.1792 + final ReentrantLock mainLock = this.mainLock;
47.1793 + mainLock.lock();
47.1794 + try {
47.1795 + return largestPoolSize;
47.1796 + } finally {
47.1797 + mainLock.unlock();
47.1798 + }
47.1799 + }
47.1800 +
47.1801 + /**
47.1802 + * Returns the approximate total number of tasks that have ever been
47.1803 + * scheduled for execution. Because the states of tasks and
47.1804 + * threads may change dynamically during computation, the returned
47.1805 + * value is only an approximation.
47.1806 + *
47.1807 + * @return the number of tasks
47.1808 + */
47.1809 + public long getTaskCount() {
47.1810 + final ReentrantLock mainLock = this.mainLock;
47.1811 + mainLock.lock();
47.1812 + try {
47.1813 + long n = completedTaskCount;
47.1814 + for (Worker w : workers) {
47.1815 + n += w.completedTasks;
47.1816 + if (w.isLocked())
47.1817 + ++n;
47.1818 + }
47.1819 + return n + workQueue.size();
47.1820 + } finally {
47.1821 + mainLock.unlock();
47.1822 + }
47.1823 + }
47.1824 +
47.1825 + /**
47.1826 + * Returns the approximate total number of tasks that have
47.1827 + * completed execution. Because the states of tasks and threads
47.1828 + * may change dynamically during computation, the returned value
47.1829 + * is only an approximation, but one that does not ever decrease
47.1830 + * across successive calls.
47.1831 + *
47.1832 + * @return the number of tasks
47.1833 + */
47.1834 + public long getCompletedTaskCount() {
47.1835 + final ReentrantLock mainLock = this.mainLock;
47.1836 + mainLock.lock();
47.1837 + try {
47.1838 + long n = completedTaskCount;
47.1839 + for (Worker w : workers)
47.1840 + n += w.completedTasks;
47.1841 + return n;
47.1842 + } finally {
47.1843 + mainLock.unlock();
47.1844 + }
47.1845 + }
47.1846 +
47.1847 + /**
47.1848 + * Returns a string identifying this pool, as well as its state,
47.1849 + * including indications of run state and estimated worker and
47.1850 + * task counts.
47.1851 + *
47.1852 + * @return a string identifying this pool, as well as its state
47.1853 + */
47.1854 + public String toString() {
47.1855 + long ncompleted;
47.1856 + int nworkers, nactive;
47.1857 + final ReentrantLock mainLock = this.mainLock;
47.1858 + mainLock.lock();
47.1859 + try {
47.1860 + ncompleted = completedTaskCount;
47.1861 + nactive = 0;
47.1862 + nworkers = workers.size();
47.1863 + for (Worker w : workers) {
47.1864 + ncompleted += w.completedTasks;
47.1865 + if (w.isLocked())
47.1866 + ++nactive;
47.1867 + }
47.1868 + } finally {
47.1869 + mainLock.unlock();
47.1870 + }
47.1871 + int c = ctl.get();
47.1872 + String rs = (runStateLessThan(c, SHUTDOWN) ? "Running" :
47.1873 + (runStateAtLeast(c, TERMINATED) ? "Terminated" :
47.1874 + "Shutting down"));
47.1875 + return super.toString() +
47.1876 + "[" + rs +
47.1877 + ", pool size = " + nworkers +
47.1878 + ", active threads = " + nactive +
47.1879 + ", queued tasks = " + workQueue.size() +
47.1880 + ", completed tasks = " + ncompleted +
47.1881 + "]";
47.1882 + }
47.1883 +
47.1884 + /* Extension hooks */
47.1885 +
47.1886 + /**
47.1887 + * Method invoked prior to executing the given Runnable in the
47.1888 + * given thread. This method is invoked by thread {@code t} that
47.1889 + * will execute task {@code r}, and may be used to re-initialize
47.1890 + * ThreadLocals, or to perform logging.
47.1891 + *
47.1892 + * <p>This implementation does nothing, but may be customized in
47.1893 + * subclasses. Note: To properly nest multiple overridings, subclasses
47.1894 + * should generally invoke {@code super.beforeExecute} at the end of
47.1895 + * this method.
47.1896 + *
47.1897 + * @param t the thread that will run task {@code r}
47.1898 + * @param r the task that will be executed
47.1899 + */
47.1900 + protected void beforeExecute(Thread t, Runnable r) { }
47.1901 +
47.1902 + /**
47.1903 + * Method invoked upon completion of execution of the given Runnable.
47.1904 + * This method is invoked by the thread that executed the task. If
47.1905 + * non-null, the Throwable is the uncaught {@code RuntimeException}
47.1906 + * or {@code Error} that caused execution to terminate abruptly.
47.1907 + *
47.1908 + * <p>This implementation does nothing, but may be customized in
47.1909 + * subclasses. Note: To properly nest multiple overridings, subclasses
47.1910 + * should generally invoke {@code super.afterExecute} at the
47.1911 + * beginning of this method.
47.1912 + *
47.1913 + * <p><b>Note:</b> When actions are enclosed in tasks (such as
47.1914 + * {@link FutureTask}) either explicitly or via methods such as
47.1915 + * {@code submit}, these task objects catch and maintain
47.1916 + * computational exceptions, and so they do not cause abrupt
47.1917 + * termination, and the internal exceptions are <em>not</em>
47.1918 + * passed to this method. If you would like to trap both kinds of
47.1919 + * failures in this method, you can further probe for such cases,
47.1920 + * as in this sample subclass that prints either the direct cause
47.1921 + * or the underlying exception if a task has been aborted:
47.1922 + *
47.1923 + * <pre> {@code
47.1924 + * class ExtendedExecutor extends ThreadPoolExecutor {
47.1925 + * // ...
47.1926 + * protected void afterExecute(Runnable r, Throwable t) {
47.1927 + * super.afterExecute(r, t);
47.1928 + * if (t == null && r instanceof Future<?>) {
47.1929 + * try {
47.1930 + * Object result = ((Future<?>) r).get();
47.1931 + * } catch (CancellationException ce) {
47.1932 + * t = ce;
47.1933 + * } catch (ExecutionException ee) {
47.1934 + * t = ee.getCause();
47.1935 + * } catch (InterruptedException ie) {
47.1936 + * Thread.currentThread().interrupt(); // ignore/reset
47.1937 + * }
47.1938 + * }
47.1939 + * if (t != null)
47.1940 + * System.out.println(t);
47.1941 + * }
47.1942 + * }}</pre>
47.1943 + *
47.1944 + * @param r the runnable that has completed
47.1945 + * @param t the exception that caused termination, or null if
47.1946 + * execution completed normally
47.1947 + */
47.1948 + protected void afterExecute(Runnable r, Throwable t) { }
47.1949 +
47.1950 + /**
47.1951 + * Method invoked when the Executor has terminated. Default
47.1952 + * implementation does nothing. Note: To properly nest multiple
47.1953 + * overridings, subclasses should generally invoke
47.1954 + * {@code super.terminated} within this method.
47.1955 + */
47.1956 + protected void terminated() { }
47.1957 +
47.1958 + /* Predefined RejectedExecutionHandlers */
47.1959 +
47.1960 + /**
47.1961 + * A handler for rejected tasks that runs the rejected task
47.1962 + * directly in the calling thread of the {@code execute} method,
47.1963 + * unless the executor has been shut down, in which case the task
47.1964 + * is discarded.
47.1965 + */
47.1966 + public static class CallerRunsPolicy implements RejectedExecutionHandler {
47.1967 + /**
47.1968 + * Creates a {@code CallerRunsPolicy}.
47.1969 + */
47.1970 + public CallerRunsPolicy() { }
47.1971 +
47.1972 + /**
47.1973 + * Executes task r in the caller's thread, unless the executor
47.1974 + * has been shut down, in which case the task is discarded.
47.1975 + *
47.1976 + * @param r the runnable task requested to be executed
47.1977 + * @param e the executor attempting to execute this task
47.1978 + */
47.1979 + public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
47.1980 + if (!e.isShutdown()) {
47.1981 + r.run();
47.1982 + }
47.1983 + }
47.1984 + }
47.1985 +
47.1986 + /**
47.1987 + * A handler for rejected tasks that throws a
47.1988 + * {@code RejectedExecutionException}.
47.1989 + */
47.1990 + public static class AbortPolicy implements RejectedExecutionHandler {
47.1991 + /**
47.1992 + * Creates an {@code AbortPolicy}.
47.1993 + */
47.1994 + public AbortPolicy() { }
47.1995 +
47.1996 + /**
47.1997 + * Always throws RejectedExecutionException.
47.1998 + *
47.1999 + * @param r the runnable task requested to be executed
47.2000 + * @param e the executor attempting to execute this task
47.2001 + * @throws RejectedExecutionException always.
47.2002 + */
47.2003 + public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
47.2004 + throw new RejectedExecutionException("Task " + r.toString() +
47.2005 + " rejected from " +
47.2006 + e.toString());
47.2007 + }
47.2008 + }
47.2009 +
47.2010 + /**
47.2011 + * A handler for rejected tasks that silently discards the
47.2012 + * rejected task.
47.2013 + */
47.2014 + public static class DiscardPolicy implements RejectedExecutionHandler {
47.2015 + /**
47.2016 + * Creates a {@code DiscardPolicy}.
47.2017 + */
47.2018 + public DiscardPolicy() { }
47.2019 +
47.2020 + /**
47.2021 + * Does nothing, which has the effect of discarding task r.
47.2022 + *
47.2023 + * @param r the runnable task requested to be executed
47.2024 + * @param e the executor attempting to execute this task
47.2025 + */
47.2026 + public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
47.2027 + }
47.2028 + }
47.2029 +
47.2030 + /**
47.2031 + * A handler for rejected tasks that discards the oldest unhandled
47.2032 + * request and then retries {@code execute}, unless the executor
47.2033 + * is shut down, in which case the task is discarded.
47.2034 + */
47.2035 + public static class DiscardOldestPolicy implements RejectedExecutionHandler {
47.2036 + /**
47.2037 + * Creates a {@code DiscardOldestPolicy} for the given executor.
47.2038 + */
47.2039 + public DiscardOldestPolicy() { }
47.2040 +
47.2041 + /**
47.2042 + * Obtains and ignores the next task that the executor
47.2043 + * would otherwise execute, if one is immediately available,
47.2044 + * and then retries execution of task r, unless the executor
47.2045 + * is shut down, in which case task r is instead discarded.
47.2046 + *
47.2047 + * @param r the runnable task requested to be executed
47.2048 + * @param e the executor attempting to execute this task
47.2049 + */
47.2050 + public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
47.2051 + if (!e.isShutdown()) {
47.2052 + e.getQueue().poll();
47.2053 + e.execute(r);
47.2054 + }
47.2055 + }
47.2056 + }
47.2057 +}
48.1 --- a/rt/emul/compact/src/main/java/java/util/concurrent/TimeUnit.java Sat Mar 19 10:31:13 2016 +0100
48.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/TimeUnit.java Sat Mar 19 10:48:29 2016 +0100
48.3 @@ -357,11 +357,11 @@
48.4 if (timeout > 0) {
48.5 long ms = toMillis(timeout);
48.6 int ns = excessNanos(timeout, ms);
48.7 - Object o = new Object();
48.8 - synchronized (o) {
48.9 - o.wait(ms, ns);
48.10 - }
48.11 + Thread.sleep(ms, ns);
48.12 }
48.13 }
48.14
48.15 }
48.16 + }
48.17 +
48.18 +}
49.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
49.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/TimeoutException.java Sat Mar 19 10:48:29 2016 +0100
49.3 @@ -0,0 +1,67 @@
49.4 +/*
49.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
49.6 + *
49.7 + * This code is free software; you can redistribute it and/or modify it
49.8 + * under the terms of the GNU General Public License version 2 only, as
49.9 + * published by the Free Software Foundation. Oracle designates this
49.10 + * particular file as subject to the "Classpath" exception as provided
49.11 + * by Oracle in the LICENSE file that accompanied this code.
49.12 + *
49.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
49.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
49.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
49.16 + * version 2 for more details (a copy is included in the LICENSE file that
49.17 + * accompanied this code).
49.18 + *
49.19 + * You should have received a copy of the GNU General Public License version
49.20 + * 2 along with this work; if not, write to the Free Software Foundation,
49.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
49.22 + *
49.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
49.24 + * or visit www.oracle.com if you need additional information or have any
49.25 + * questions.
49.26 + */
49.27 +
49.28 +/*
49.29 + * This file is available under and governed by the GNU General Public
49.30 + * License version 2 only, as published by the Free Software Foundation.
49.31 + * However, the following notice accompanied the original version of this
49.32 + * file:
49.33 + *
49.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
49.35 + * Expert Group and released to the public domain, as explained at
49.36 + * http://creativecommons.org/publicdomain/zero/1.0/
49.37 + */
49.38 +
49.39 +package java.util.concurrent;
49.40 +
49.41 +/**
49.42 + * Exception thrown when a blocking operation times out. Blocking
49.43 + * operations for which a timeout is specified need a means to
49.44 + * indicate that the timeout has occurred. For many such operations it
49.45 + * is possible to return a value that indicates timeout; when that is
49.46 + * not possible or desirable then <tt>TimeoutException</tt> should be
49.47 + * declared and thrown.
49.48 + *
49.49 + * @since 1.5
49.50 + * @author Doug Lea
49.51 + */
49.52 +public class TimeoutException extends Exception {
49.53 + private static final long serialVersionUID = 1900926677490660714L;
49.54 +
49.55 + /**
49.56 + * Constructs a <tt>TimeoutException</tt> with no specified detail
49.57 + * message.
49.58 + */
49.59 + public TimeoutException() {}
49.60 +
49.61 + /**
49.62 + * Constructs a <tt>TimeoutException</tt> with the specified detail
49.63 + * message.
49.64 + *
49.65 + * @param message the detail message
49.66 + */
49.67 + public TimeoutException(String message) {
49.68 + super(message);
49.69 + }
49.70 +}
50.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
50.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/TransferQueue.java Sat Mar 19 10:48:29 2016 +0100
50.3 @@ -0,0 +1,161 @@
50.4 +/*
50.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
50.6 + *
50.7 + * This code is free software; you can redistribute it and/or modify it
50.8 + * under the terms of the GNU General Public License version 2 only, as
50.9 + * published by the Free Software Foundation. Oracle designates this
50.10 + * particular file as subject to the "Classpath" exception as provided
50.11 + * by Oracle in the LICENSE file that accompanied this code.
50.12 + *
50.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
50.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
50.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
50.16 + * version 2 for more details (a copy is included in the LICENSE file that
50.17 + * accompanied this code).
50.18 + *
50.19 + * You should have received a copy of the GNU General Public License version
50.20 + * 2 along with this work; if not, write to the Free Software Foundation,
50.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
50.22 + *
50.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
50.24 + * or visit www.oracle.com if you need additional information or have any
50.25 + * questions.
50.26 + */
50.27 +
50.28 +/*
50.29 + * This file is available under and governed by the GNU General Public
50.30 + * License version 2 only, as published by the Free Software Foundation.
50.31 + * However, the following notice accompanied the original version of this
50.32 + * file:
50.33 + *
50.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
50.35 + * Expert Group and released to the public domain, as explained at
50.36 + * http://creativecommons.org/publicdomain/zero/1.0/
50.37 + */
50.38 +
50.39 +package java.util.concurrent;
50.40 +
50.41 +/**
50.42 + * A {@link BlockingQueue} in which producers may wait for consumers
50.43 + * to receive elements. A {@code TransferQueue} may be useful for
50.44 + * example in message passing applications in which producers
50.45 + * sometimes (using method {@link #transfer}) await receipt of
50.46 + * elements by consumers invoking {@code take} or {@code poll}, while
50.47 + * at other times enqueue elements (via method {@code put}) without
50.48 + * waiting for receipt.
50.49 + * {@linkplain #tryTransfer(Object) Non-blocking} and
50.50 + * {@linkplain #tryTransfer(Object,long,TimeUnit) time-out} versions of
50.51 + * {@code tryTransfer} are also available.
50.52 + * A {@code TransferQueue} may also be queried, via {@link
50.53 + * #hasWaitingConsumer}, whether there are any threads waiting for
50.54 + * items, which is a converse analogy to a {@code peek} operation.
50.55 + *
50.56 + * <p>Like other blocking queues, a {@code TransferQueue} may be
50.57 + * capacity bounded. If so, an attempted transfer operation may
50.58 + * initially block waiting for available space, and/or subsequently
50.59 + * block waiting for reception by a consumer. Note that in a queue
50.60 + * with zero capacity, such as {@link SynchronousQueue}, {@code put}
50.61 + * and {@code transfer} are effectively synonymous.
50.62 + *
50.63 + * <p>This interface is a member of the
50.64 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
50.65 + * Java Collections Framework</a>.
50.66 + *
50.67 + * @since 1.7
50.68 + * @author Doug Lea
50.69 + * @param <E> the type of elements held in this collection
50.70 + */
50.71 +public interface TransferQueue<E> extends BlockingQueue<E> {
50.72 + /**
50.73 + * Transfers the element to a waiting consumer immediately, if possible.
50.74 + *
50.75 + * <p>More precisely, transfers the specified element immediately
50.76 + * if there exists a consumer already waiting to receive it (in
50.77 + * {@link #take} or timed {@link #poll(long,TimeUnit) poll}),
50.78 + * otherwise returning {@code false} without enqueuing the element.
50.79 + *
50.80 + * @param e the element to transfer
50.81 + * @return {@code true} if the element was transferred, else
50.82 + * {@code false}
50.83 + * @throws ClassCastException if the class of the specified element
50.84 + * prevents it from being added to this queue
50.85 + * @throws NullPointerException if the specified element is null
50.86 + * @throws IllegalArgumentException if some property of the specified
50.87 + * element prevents it from being added to this queue
50.88 + */
50.89 + boolean tryTransfer(E e);
50.90 +
50.91 + /**
50.92 + * Transfers the element to a consumer, waiting if necessary to do so.
50.93 + *
50.94 + * <p>More precisely, transfers the specified element immediately
50.95 + * if there exists a consumer already waiting to receive it (in
50.96 + * {@link #take} or timed {@link #poll(long,TimeUnit) poll}),
50.97 + * else waits until the element is received by a consumer.
50.98 + *
50.99 + * @param e the element to transfer
50.100 + * @throws InterruptedException if interrupted while waiting,
50.101 + * in which case the element is not left enqueued
50.102 + * @throws ClassCastException if the class of the specified element
50.103 + * prevents it from being added to this queue
50.104 + * @throws NullPointerException if the specified element is null
50.105 + * @throws IllegalArgumentException if some property of the specified
50.106 + * element prevents it from being added to this queue
50.107 + */
50.108 + void transfer(E e) throws InterruptedException;
50.109 +
50.110 + /**
50.111 + * Transfers the element to a consumer if it is possible to do so
50.112 + * before the timeout elapses.
50.113 + *
50.114 + * <p>More precisely, transfers the specified element immediately
50.115 + * if there exists a consumer already waiting to receive it (in
50.116 + * {@link #take} or timed {@link #poll(long,TimeUnit) poll}),
50.117 + * else waits until the element is received by a consumer,
50.118 + * returning {@code false} if the specified wait time elapses
50.119 + * before the element can be transferred.
50.120 + *
50.121 + * @param e the element to transfer
50.122 + * @param timeout how long to wait before giving up, in units of
50.123 + * {@code unit}
50.124 + * @param unit a {@code TimeUnit} determining how to interpret the
50.125 + * {@code timeout} parameter
50.126 + * @return {@code true} if successful, or {@code false} if
50.127 + * the specified waiting time elapses before completion,
50.128 + * in which case the element is not left enqueued
50.129 + * @throws InterruptedException if interrupted while waiting,
50.130 + * in which case the element is not left enqueued
50.131 + * @throws ClassCastException if the class of the specified element
50.132 + * prevents it from being added to this queue
50.133 + * @throws NullPointerException if the specified element is null
50.134 + * @throws IllegalArgumentException if some property of the specified
50.135 + * element prevents it from being added to this queue
50.136 + */
50.137 + boolean tryTransfer(E e, long timeout, TimeUnit unit)
50.138 + throws InterruptedException;
50.139 +
50.140 + /**
50.141 + * Returns {@code true} if there is at least one consumer waiting
50.142 + * to receive an element via {@link #take} or
50.143 + * timed {@link #poll(long,TimeUnit) poll}.
50.144 + * The return value represents a momentary state of affairs.
50.145 + *
50.146 + * @return {@code true} if there is at least one waiting consumer
50.147 + */
50.148 + boolean hasWaitingConsumer();
50.149 +
50.150 + /**
50.151 + * Returns an estimate of the number of consumers waiting to
50.152 + * receive elements via {@link #take} or timed
50.153 + * {@link #poll(long,TimeUnit) poll}. The return value is an
50.154 + * approximation of a momentary state of affairs, that may be
50.155 + * inaccurate if consumers have completed or given up waiting.
50.156 + * The value may be useful for monitoring and heuristics, but
50.157 + * not for synchronization control. Implementations of this
50.158 + * method are likely to be noticeably slower than those for
50.159 + * {@link #hasWaitingConsumer}.
50.160 + *
50.161 + * @return the number of consumers waiting to receive elements
50.162 + */
50.163 + int getWaitingConsumerCount();
50.164 +}
51.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
51.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/locks/AbstractOwnableSynchronizer.java Sat Mar 19 10:48:29 2016 +0100
51.3 @@ -0,0 +1,86 @@
51.4 +/*
51.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
51.6 + *
51.7 + * This code is free software; you can redistribute it and/or modify it
51.8 + * under the terms of the GNU General Public License version 2 only, as
51.9 + * published by the Free Software Foundation. Oracle designates this
51.10 + * particular file as subject to the "Classpath" exception as provided
51.11 + * by Oracle in the LICENSE file that accompanied this code.
51.12 + *
51.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
51.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
51.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
51.16 + * version 2 for more details (a copy is included in the LICENSE file that
51.17 + * accompanied this code).
51.18 + *
51.19 + * You should have received a copy of the GNU General Public License version
51.20 + * 2 along with this work; if not, write to the Free Software Foundation,
51.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
51.22 + *
51.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
51.24 + * or visit www.oracle.com if you need additional information or have any
51.25 + * questions.
51.26 + */
51.27 +
51.28 +/*
51.29 + * This file is available under and governed by the GNU General Public
51.30 + * License version 2 only, as published by the Free Software Foundation.
51.31 + * However, the following notice accompanied the original version of this
51.32 + * file:
51.33 + *
51.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
51.35 + * Expert Group and released to the public domain, as explained at
51.36 + * http://creativecommons.org/publicdomain/zero/1.0/
51.37 + */
51.38 +
51.39 +package java.util.concurrent.locks;
51.40 +
51.41 +/**
51.42 + * A synchronizer that may be exclusively owned by a thread. This
51.43 + * class provides a basis for creating locks and related synchronizers
51.44 + * that may entail a notion of ownership. The
51.45 + * <tt>AbstractOwnableSynchronizer</tt> class itself does not manage or
51.46 + * use this information. However, subclasses and tools may use
51.47 + * appropriately maintained values to help control and monitor access
51.48 + * and provide diagnostics.
51.49 + *
51.50 + * @since 1.6
51.51 + * @author Doug Lea
51.52 + */
51.53 +public abstract class AbstractOwnableSynchronizer
51.54 + implements java.io.Serializable {
51.55 +
51.56 + /** Use serial ID even though all fields transient. */
51.57 + private static final long serialVersionUID = 3737899427754241961L;
51.58 +
51.59 + /**
51.60 + * Empty constructor for use by subclasses.
51.61 + */
51.62 + protected AbstractOwnableSynchronizer() { }
51.63 +
51.64 + /**
51.65 + * The current owner of exclusive mode synchronization.
51.66 + */
51.67 + private transient Thread exclusiveOwnerThread;
51.68 +
51.69 + /**
51.70 + * Sets the thread that currently owns exclusive access. A
51.71 + * <tt>null</tt> argument indicates that no thread owns access.
51.72 + * This method does not otherwise impose any synchronization or
51.73 + * <tt>volatile</tt> field accesses.
51.74 + */
51.75 + protected final void setExclusiveOwnerThread(Thread t) {
51.76 + exclusiveOwnerThread = t;
51.77 + }
51.78 +
51.79 + /**
51.80 + * Returns the thread last set by
51.81 + * <tt>setExclusiveOwnerThread</tt>, or <tt>null</tt> if never
51.82 + * set. This method does not otherwise impose any synchronization
51.83 + * or <tt>volatile</tt> field accesses.
51.84 + * @return the owner thread
51.85 + */
51.86 + protected final Thread getExclusiveOwnerThread() {
51.87 + return exclusiveOwnerThread;
51.88 + }
51.89 +}
52.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
52.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java Sat Mar 19 10:48:29 2016 +0100
52.3 @@ -0,0 +1,2109 @@
52.4 +/*
52.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
52.6 + *
52.7 + * This code is free software; you can redistribute it and/or modify it
52.8 + * under the terms of the GNU General Public License version 2 only, as
52.9 + * published by the Free Software Foundation. Oracle designates this
52.10 + * particular file as subject to the "Classpath" exception as provided
52.11 + * by Oracle in the LICENSE file that accompanied this code.
52.12 + *
52.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
52.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
52.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
52.16 + * version 2 for more details (a copy is included in the LICENSE file that
52.17 + * accompanied this code).
52.18 + *
52.19 + * You should have received a copy of the GNU General Public License version
52.20 + * 2 along with this work; if not, write to the Free Software Foundation,
52.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
52.22 + *
52.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
52.24 + * or visit www.oracle.com if you need additional information or have any
52.25 + * questions.
52.26 + */
52.27 +
52.28 +/*
52.29 + * This file is available under and governed by the GNU General Public
52.30 + * License version 2 only, as published by the Free Software Foundation.
52.31 + * However, the following notice accompanied the original version of this
52.32 + * file:
52.33 + *
52.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
52.35 + * Expert Group and released to the public domain, as explained at
52.36 + * http://creativecommons.org/publicdomain/zero/1.0/
52.37 + */
52.38 +
52.39 +package java.util.concurrent.locks;
52.40 +import java.util.*;
52.41 +import java.util.concurrent.*;
52.42 +import java.util.concurrent.atomic.*;
52.43 +import sun.misc.Unsafe;
52.44 +
52.45 +/**
52.46 + * A version of {@link AbstractQueuedSynchronizer} in
52.47 + * which synchronization state is maintained as a <tt>long</tt>.
52.48 + * This class has exactly the same structure, properties, and methods
52.49 + * as <tt>AbstractQueuedSynchronizer</tt> with the exception
52.50 + * that all state-related parameters and results are defined
52.51 + * as <tt>long</tt> rather than <tt>int</tt>. This class
52.52 + * may be useful when creating synchronizers such as
52.53 + * multilevel locks and barriers that require
52.54 + * 64 bits of state.
52.55 + *
52.56 + * <p>See {@link AbstractQueuedSynchronizer} for usage
52.57 + * notes and examples.
52.58 + *
52.59 + * @since 1.6
52.60 + * @author Doug Lea
52.61 + */
52.62 +public abstract class AbstractQueuedLongSynchronizer
52.63 + extends AbstractOwnableSynchronizer
52.64 + implements java.io.Serializable {
52.65 +
52.66 + private static final long serialVersionUID = 7373984972572414692L;
52.67 +
52.68 + /*
52.69 + To keep sources in sync, the remainder of this source file is
52.70 + exactly cloned from AbstractQueuedSynchronizer, replacing class
52.71 + name and changing ints related with sync state to longs. Please
52.72 + keep it that way.
52.73 + */
52.74 +
52.75 + /**
52.76 + * Creates a new <tt>AbstractQueuedLongSynchronizer</tt> instance
52.77 + * with initial synchronization state of zero.
52.78 + */
52.79 + protected AbstractQueuedLongSynchronizer() { }
52.80 +
52.81 + /**
52.82 + * Wait queue node class.
52.83 + *
52.84 + * <p>The wait queue is a variant of a "CLH" (Craig, Landin, and
52.85 + * Hagersten) lock queue. CLH locks are normally used for
52.86 + * spinlocks. We instead use them for blocking synchronizers, but
52.87 + * use the same basic tactic of holding some of the control
52.88 + * information about a thread in the predecessor of its node. A
52.89 + * "status" field in each node keeps track of whether a thread
52.90 + * should block. A node is signalled when its predecessor
52.91 + * releases. Each node of the queue otherwise serves as a
52.92 + * specific-notification-style monitor holding a single waiting
52.93 + * thread. The status field does NOT control whether threads are
52.94 + * granted locks etc though. A thread may try to acquire if it is
52.95 + * first in the queue. But being first does not guarantee success;
52.96 + * it only gives the right to contend. So the currently released
52.97 + * contender thread may need to rewait.
52.98 + *
52.99 + * <p>To enqueue into a CLH lock, you atomically splice it in as new
52.100 + * tail. To dequeue, you just set the head field.
52.101 + * <pre>
52.102 + * +------+ prev +-----+ +-----+
52.103 + * head | | <---- | | <---- | | tail
52.104 + * +------+ +-----+ +-----+
52.105 + * </pre>
52.106 + *
52.107 + * <p>Insertion into a CLH queue requires only a single atomic
52.108 + * operation on "tail", so there is a simple atomic point of
52.109 + * demarcation from unqueued to queued. Similarly, dequeing
52.110 + * involves only updating the "head". However, it takes a bit
52.111 + * more work for nodes to determine who their successors are,
52.112 + * in part to deal with possible cancellation due to timeouts
52.113 + * and interrupts.
52.114 + *
52.115 + * <p>The "prev" links (not used in original CLH locks), are mainly
52.116 + * needed to handle cancellation. If a node is cancelled, its
52.117 + * successor is (normally) relinked to a non-cancelled
52.118 + * predecessor. For explanation of similar mechanics in the case
52.119 + * of spin locks, see the papers by Scott and Scherer at
52.120 + * http://www.cs.rochester.edu/u/scott/synchronization/
52.121 + *
52.122 + * <p>We also use "next" links to implement blocking mechanics.
52.123 + * The thread id for each node is kept in its own node, so a
52.124 + * predecessor signals the next node to wake up by traversing
52.125 + * next link to determine which thread it is. Determination of
52.126 + * successor must avoid races with newly queued nodes to set
52.127 + * the "next" fields of their predecessors. This is solved
52.128 + * when necessary by checking backwards from the atomically
52.129 + * updated "tail" when a node's successor appears to be null.
52.130 + * (Or, said differently, the next-links are an optimization
52.131 + * so that we don't usually need a backward scan.)
52.132 + *
52.133 + * <p>Cancellation introduces some conservatism to the basic
52.134 + * algorithms. Since we must poll for cancellation of other
52.135 + * nodes, we can miss noticing whether a cancelled node is
52.136 + * ahead or behind us. This is dealt with by always unparking
52.137 + * successors upon cancellation, allowing them to stabilize on
52.138 + * a new predecessor, unless we can identify an uncancelled
52.139 + * predecessor who will carry this responsibility.
52.140 + *
52.141 + * <p>CLH queues need a dummy header node to get started. But
52.142 + * we don't create them on construction, because it would be wasted
52.143 + * effort if there is never contention. Instead, the node
52.144 + * is constructed and head and tail pointers are set upon first
52.145 + * contention.
52.146 + *
52.147 + * <p>Threads waiting on Conditions use the same nodes, but
52.148 + * use an additional link. Conditions only need to link nodes
52.149 + * in simple (non-concurrent) linked queues because they are
52.150 + * only accessed when exclusively held. Upon await, a node is
52.151 + * inserted into a condition queue. Upon signal, the node is
52.152 + * transferred to the main queue. A special value of status
52.153 + * field is used to mark which queue a node is on.
52.154 + *
52.155 + * <p>Thanks go to Dave Dice, Mark Moir, Victor Luchangco, Bill
52.156 + * Scherer and Michael Scott, along with members of JSR-166
52.157 + * expert group, for helpful ideas, discussions, and critiques
52.158 + * on the design of this class.
52.159 + */
52.160 + static final class Node {
52.161 + /** Marker to indicate a node is waiting in shared mode */
52.162 + static final Node SHARED = new Node();
52.163 + /** Marker to indicate a node is waiting in exclusive mode */
52.164 + static final Node EXCLUSIVE = null;
52.165 +
52.166 + /** waitStatus value to indicate thread has cancelled */
52.167 + static final int CANCELLED = 1;
52.168 + /** waitStatus value to indicate successor's thread needs unparking */
52.169 + static final int SIGNAL = -1;
52.170 + /** waitStatus value to indicate thread is waiting on condition */
52.171 + static final int CONDITION = -2;
52.172 + /**
52.173 + * waitStatus value to indicate the next acquireShared should
52.174 + * unconditionally propagate
52.175 + */
52.176 + static final int PROPAGATE = -3;
52.177 +
52.178 + /**
52.179 + * Status field, taking on only the values:
52.180 + * SIGNAL: The successor of this node is (or will soon be)
52.181 + * blocked (via park), so the current node must
52.182 + * unpark its successor when it releases or
52.183 + * cancels. To avoid races, acquire methods must
52.184 + * first indicate they need a signal,
52.185 + * then retry the atomic acquire, and then,
52.186 + * on failure, block.
52.187 + * CANCELLED: This node is cancelled due to timeout or interrupt.
52.188 + * Nodes never leave this state. In particular,
52.189 + * a thread with cancelled node never again blocks.
52.190 + * CONDITION: This node is currently on a condition queue.
52.191 + * It will not be used as a sync queue node
52.192 + * until transferred, at which time the status
52.193 + * will be set to 0. (Use of this value here has
52.194 + * nothing to do with the other uses of the
52.195 + * field, but simplifies mechanics.)
52.196 + * PROPAGATE: A releaseShared should be propagated to other
52.197 + * nodes. This is set (for head node only) in
52.198 + * doReleaseShared to ensure propagation
52.199 + * continues, even if other operations have
52.200 + * since intervened.
52.201 + * 0: None of the above
52.202 + *
52.203 + * The values are arranged numerically to simplify use.
52.204 + * Non-negative values mean that a node doesn't need to
52.205 + * signal. So, most code doesn't need to check for particular
52.206 + * values, just for sign.
52.207 + *
52.208 + * The field is initialized to 0 for normal sync nodes, and
52.209 + * CONDITION for condition nodes. It is modified using CAS
52.210 + * (or when possible, unconditional volatile writes).
52.211 + */
52.212 + volatile int waitStatus;
52.213 +
52.214 + /**
52.215 + * Link to predecessor node that current node/thread relies on
52.216 + * for checking waitStatus. Assigned during enqueing, and nulled
52.217 + * out (for sake of GC) only upon dequeuing. Also, upon
52.218 + * cancellation of a predecessor, we short-circuit while
52.219 + * finding a non-cancelled one, which will always exist
52.220 + * because the head node is never cancelled: A node becomes
52.221 + * head only as a result of successful acquire. A
52.222 + * cancelled thread never succeeds in acquiring, and a thread only
52.223 + * cancels itself, not any other node.
52.224 + */
52.225 + volatile Node prev;
52.226 +
52.227 + /**
52.228 + * Link to the successor node that the current node/thread
52.229 + * unparks upon release. Assigned during enqueuing, adjusted
52.230 + * when bypassing cancelled predecessors, and nulled out (for
52.231 + * sake of GC) when dequeued. The enq operation does not
52.232 + * assign next field of a predecessor until after attachment,
52.233 + * so seeing a null next field does not necessarily mean that
52.234 + * node is at end of queue. However, if a next field appears
52.235 + * to be null, we can scan prev's from the tail to
52.236 + * double-check. The next field of cancelled nodes is set to
52.237 + * point to the node itself instead of null, to make life
52.238 + * easier for isOnSyncQueue.
52.239 + */
52.240 + volatile Node next;
52.241 +
52.242 + /**
52.243 + * The thread that enqueued this node. Initialized on
52.244 + * construction and nulled out after use.
52.245 + */
52.246 + volatile Thread thread;
52.247 +
52.248 + /**
52.249 + * Link to next node waiting on condition, or the special
52.250 + * value SHARED. Because condition queues are accessed only
52.251 + * when holding in exclusive mode, we just need a simple
52.252 + * linked queue to hold nodes while they are waiting on
52.253 + * conditions. They are then transferred to the queue to
52.254 + * re-acquire. And because conditions can only be exclusive,
52.255 + * we save a field by using special value to indicate shared
52.256 + * mode.
52.257 + */
52.258 + Node nextWaiter;
52.259 +
52.260 + /**
52.261 + * Returns true if node is waiting in shared mode
52.262 + */
52.263 + final boolean isShared() {
52.264 + return nextWaiter == SHARED;
52.265 + }
52.266 +
52.267 + /**
52.268 + * Returns previous node, or throws NullPointerException if null.
52.269 + * Use when predecessor cannot be null. The null check could
52.270 + * be elided, but is present to help the VM.
52.271 + *
52.272 + * @return the predecessor of this node
52.273 + */
52.274 + final Node predecessor() throws NullPointerException {
52.275 + Node p = prev;
52.276 + if (p == null)
52.277 + throw new NullPointerException();
52.278 + else
52.279 + return p;
52.280 + }
52.281 +
52.282 + Node() { // Used to establish initial head or SHARED marker
52.283 + }
52.284 +
52.285 + Node(Thread thread, Node mode) { // Used by addWaiter
52.286 + this.nextWaiter = mode;
52.287 + this.thread = thread;
52.288 + }
52.289 +
52.290 + Node(Thread thread, int waitStatus) { // Used by Condition
52.291 + this.waitStatus = waitStatus;
52.292 + this.thread = thread;
52.293 + }
52.294 + }
52.295 +
52.296 + /**
52.297 + * Head of the wait queue, lazily initialized. Except for
52.298 + * initialization, it is modified only via method setHead. Note:
52.299 + * If head exists, its waitStatus is guaranteed not to be
52.300 + * CANCELLED.
52.301 + */
52.302 + private transient volatile Node head;
52.303 +
52.304 + /**
52.305 + * Tail of the wait queue, lazily initialized. Modified only via
52.306 + * method enq to add new wait node.
52.307 + */
52.308 + private transient volatile Node tail;
52.309 +
52.310 + /**
52.311 + * The synchronization state.
52.312 + */
52.313 + private volatile long state;
52.314 +
52.315 + /**
52.316 + * Returns the current value of synchronization state.
52.317 + * This operation has memory semantics of a <tt>volatile</tt> read.
52.318 + * @return current state value
52.319 + */
52.320 + protected final long getState() {
52.321 + return state;
52.322 + }
52.323 +
52.324 + /**
52.325 + * Sets the value of synchronization state.
52.326 + * This operation has memory semantics of a <tt>volatile</tt> write.
52.327 + * @param newState the new state value
52.328 + */
52.329 + protected final void setState(long newState) {
52.330 + state = newState;
52.331 + }
52.332 +
52.333 + /**
52.334 + * Atomically sets synchronization state to the given updated
52.335 + * value if the current state value equals the expected value.
52.336 + * This operation has memory semantics of a <tt>volatile</tt> read
52.337 + * and write.
52.338 + *
52.339 + * @param expect the expected value
52.340 + * @param update the new value
52.341 + * @return true if successful. False return indicates that the actual
52.342 + * value was not equal to the expected value.
52.343 + */
52.344 + protected final boolean compareAndSetState(long expect, long update) {
52.345 + // See below for intrinsics setup to support this
52.346 + return unsafe.compareAndSwapLong(this, stateOffset, expect, update);
52.347 + }
52.348 +
52.349 + // Queuing utilities
52.350 +
52.351 + /**
52.352 + * The number of nanoseconds for which it is faster to spin
52.353 + * rather than to use timed park. A rough estimate suffices
52.354 + * to improve responsiveness with very short timeouts.
52.355 + */
52.356 + static final long spinForTimeoutThreshold = 1000L;
52.357 +
52.358 + /**
52.359 + * Inserts node into queue, initializing if necessary. See picture above.
52.360 + * @param node the node to insert
52.361 + * @return node's predecessor
52.362 + */
52.363 + private Node enq(final Node node) {
52.364 + for (;;) {
52.365 + Node t = tail;
52.366 + if (t == null) { // Must initialize
52.367 + if (compareAndSetHead(new Node()))
52.368 + tail = head;
52.369 + } else {
52.370 + node.prev = t;
52.371 + if (compareAndSetTail(t, node)) {
52.372 + t.next = node;
52.373 + return t;
52.374 + }
52.375 + }
52.376 + }
52.377 + }
52.378 +
52.379 + /**
52.380 + * Creates and enqueues node for current thread and given mode.
52.381 + *
52.382 + * @param mode Node.EXCLUSIVE for exclusive, Node.SHARED for shared
52.383 + * @return the new node
52.384 + */
52.385 + private Node addWaiter(Node mode) {
52.386 + Node node = new Node(Thread.currentThread(), mode);
52.387 + // Try the fast path of enq; backup to full enq on failure
52.388 + Node pred = tail;
52.389 + if (pred != null) {
52.390 + node.prev = pred;
52.391 + if (compareAndSetTail(pred, node)) {
52.392 + pred.next = node;
52.393 + return node;
52.394 + }
52.395 + }
52.396 + enq(node);
52.397 + return node;
52.398 + }
52.399 +
52.400 + /**
52.401 + * Sets head of queue to be node, thus dequeuing. Called only by
52.402 + * acquire methods. Also nulls out unused fields for sake of GC
52.403 + * and to suppress unnecessary signals and traversals.
52.404 + *
52.405 + * @param node the node
52.406 + */
52.407 + private void setHead(Node node) {
52.408 + head = node;
52.409 + node.thread = null;
52.410 + node.prev = null;
52.411 + }
52.412 +
52.413 + /**
52.414 + * Wakes up node's successor, if one exists.
52.415 + *
52.416 + * @param node the node
52.417 + */
52.418 + private void unparkSuccessor(Node node) {
52.419 + /*
52.420 + * If status is negative (i.e., possibly needing signal) try
52.421 + * to clear in anticipation of signalling. It is OK if this
52.422 + * fails or if status is changed by waiting thread.
52.423 + */
52.424 + int ws = node.waitStatus;
52.425 + if (ws < 0)
52.426 + compareAndSetWaitStatus(node, ws, 0);
52.427 +
52.428 + /*
52.429 + * Thread to unpark is held in successor, which is normally
52.430 + * just the next node. But if cancelled or apparently null,
52.431 + * traverse backwards from tail to find the actual
52.432 + * non-cancelled successor.
52.433 + */
52.434 + Node s = node.next;
52.435 + if (s == null || s.waitStatus > 0) {
52.436 + s = null;
52.437 + for (Node t = tail; t != null && t != node; t = t.prev)
52.438 + if (t.waitStatus <= 0)
52.439 + s = t;
52.440 + }
52.441 + if (s != null)
52.442 + LockSupport.unpark(s.thread);
52.443 + }
52.444 +
52.445 + /**
52.446 + * Release action for shared mode -- signal successor and ensure
52.447 + * propagation. (Note: For exclusive mode, release just amounts
52.448 + * to calling unparkSuccessor of head if it needs signal.)
52.449 + */
52.450 + private void doReleaseShared() {
52.451 + /*
52.452 + * Ensure that a release propagates, even if there are other
52.453 + * in-progress acquires/releases. This proceeds in the usual
52.454 + * way of trying to unparkSuccessor of head if it needs
52.455 + * signal. But if it does not, status is set to PROPAGATE to
52.456 + * ensure that upon release, propagation continues.
52.457 + * Additionally, we must loop in case a new node is added
52.458 + * while we are doing this. Also, unlike other uses of
52.459 + * unparkSuccessor, we need to know if CAS to reset status
52.460 + * fails, if so rechecking.
52.461 + */
52.462 + for (;;) {
52.463 + Node h = head;
52.464 + if (h != null && h != tail) {
52.465 + int ws = h.waitStatus;
52.466 + if (ws == Node.SIGNAL) {
52.467 + if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))
52.468 + continue; // loop to recheck cases
52.469 + unparkSuccessor(h);
52.470 + }
52.471 + else if (ws == 0 &&
52.472 + !compareAndSetWaitStatus(h, 0, Node.PROPAGATE))
52.473 + continue; // loop on failed CAS
52.474 + }
52.475 + if (h == head) // loop if head changed
52.476 + break;
52.477 + }
52.478 + }
52.479 +
52.480 + /**
52.481 + * Sets head of queue, and checks if successor may be waiting
52.482 + * in shared mode, if so propagating if either propagate > 0 or
52.483 + * PROPAGATE status was set.
52.484 + *
52.485 + * @param node the node
52.486 + * @param propagate the return value from a tryAcquireShared
52.487 + */
52.488 + private void setHeadAndPropagate(Node node, long propagate) {
52.489 + Node h = head; // Record old head for check below
52.490 + setHead(node);
52.491 + /*
52.492 + * Try to signal next queued node if:
52.493 + * Propagation was indicated by caller,
52.494 + * or was recorded (as h.waitStatus) by a previous operation
52.495 + * (note: this uses sign-check of waitStatus because
52.496 + * PROPAGATE status may transition to SIGNAL.)
52.497 + * and
52.498 + * The next node is waiting in shared mode,
52.499 + * or we don't know, because it appears null
52.500 + *
52.501 + * The conservatism in both of these checks may cause
52.502 + * unnecessary wake-ups, but only when there are multiple
52.503 + * racing acquires/releases, so most need signals now or soon
52.504 + * anyway.
52.505 + */
52.506 + if (propagate > 0 || h == null || h.waitStatus < 0) {
52.507 + Node s = node.next;
52.508 + if (s == null || s.isShared())
52.509 + doReleaseShared();
52.510 + }
52.511 + }
52.512 +
52.513 + // Utilities for various versions of acquire
52.514 +
52.515 + /**
52.516 + * Cancels an ongoing attempt to acquire.
52.517 + *
52.518 + * @param node the node
52.519 + */
52.520 + private void cancelAcquire(Node node) {
52.521 + // Ignore if node doesn't exist
52.522 + if (node == null)
52.523 + return;
52.524 +
52.525 + node.thread = null;
52.526 +
52.527 + // Skip cancelled predecessors
52.528 + Node pred = node.prev;
52.529 + while (pred.waitStatus > 0)
52.530 + node.prev = pred = pred.prev;
52.531 +
52.532 + // predNext is the apparent node to unsplice. CASes below will
52.533 + // fail if not, in which case, we lost race vs another cancel
52.534 + // or signal, so no further action is necessary.
52.535 + Node predNext = pred.next;
52.536 +
52.537 + // Can use unconditional write instead of CAS here.
52.538 + // After this atomic step, other Nodes can skip past us.
52.539 + // Before, we are free of interference from other threads.
52.540 + node.waitStatus = Node.CANCELLED;
52.541 +
52.542 + // If we are the tail, remove ourselves.
52.543 + if (node == tail && compareAndSetTail(node, pred)) {
52.544 + compareAndSetNext(pred, predNext, null);
52.545 + } else {
52.546 + // If successor needs signal, try to set pred's next-link
52.547 + // so it will get one. Otherwise wake it up to propagate.
52.548 + int ws;
52.549 + if (pred != head &&
52.550 + ((ws = pred.waitStatus) == Node.SIGNAL ||
52.551 + (ws <= 0 && compareAndSetWaitStatus(pred, ws, Node.SIGNAL))) &&
52.552 + pred.thread != null) {
52.553 + Node next = node.next;
52.554 + if (next != null && next.waitStatus <= 0)
52.555 + compareAndSetNext(pred, predNext, next);
52.556 + } else {
52.557 + unparkSuccessor(node);
52.558 + }
52.559 +
52.560 + node.next = node; // help GC
52.561 + }
52.562 + }
52.563 +
52.564 + /**
52.565 + * Checks and updates status for a node that failed to acquire.
52.566 + * Returns true if thread should block. This is the main signal
52.567 + * control in all acquire loops. Requires that pred == node.prev
52.568 + *
52.569 + * @param pred node's predecessor holding status
52.570 + * @param node the node
52.571 + * @return {@code true} if thread should block
52.572 + */
52.573 + private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
52.574 + int ws = pred.waitStatus;
52.575 + if (ws == Node.SIGNAL)
52.576 + /*
52.577 + * This node has already set status asking a release
52.578 + * to signal it, so it can safely park.
52.579 + */
52.580 + return true;
52.581 + if (ws > 0) {
52.582 + /*
52.583 + * Predecessor was cancelled. Skip over predecessors and
52.584 + * indicate retry.
52.585 + */
52.586 + do {
52.587 + node.prev = pred = pred.prev;
52.588 + } while (pred.waitStatus > 0);
52.589 + pred.next = node;
52.590 + } else {
52.591 + /*
52.592 + * waitStatus must be 0 or PROPAGATE. Indicate that we
52.593 + * need a signal, but don't park yet. Caller will need to
52.594 + * retry to make sure it cannot acquire before parking.
52.595 + */
52.596 + compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
52.597 + }
52.598 + return false;
52.599 + }
52.600 +
52.601 + /**
52.602 + * Convenience method to interrupt current thread.
52.603 + */
52.604 + private static void selfInterrupt() {
52.605 + Thread.currentThread().interrupt();
52.606 + }
52.607 +
52.608 + /**
52.609 + * Convenience method to park and then check if interrupted
52.610 + *
52.611 + * @return {@code true} if interrupted
52.612 + */
52.613 + private final boolean parkAndCheckInterrupt() {
52.614 + LockSupport.park(this);
52.615 + return Thread.interrupted();
52.616 + }
52.617 +
52.618 + /*
52.619 + * Various flavors of acquire, varying in exclusive/shared and
52.620 + * control modes. Each is mostly the same, but annoyingly
52.621 + * different. Only a little bit of factoring is possible due to
52.622 + * interactions of exception mechanics (including ensuring that we
52.623 + * cancel if tryAcquire throws exception) and other control, at
52.624 + * least not without hurting performance too much.
52.625 + */
52.626 +
52.627 + /**
52.628 + * Acquires in exclusive uninterruptible mode for thread already in
52.629 + * queue. Used by condition wait methods as well as acquire.
52.630 + *
52.631 + * @param node the node
52.632 + * @param arg the acquire argument
52.633 + * @return {@code true} if interrupted while waiting
52.634 + */
52.635 + final boolean acquireQueued(final Node node, long arg) {
52.636 + boolean failed = true;
52.637 + try {
52.638 + boolean interrupted = false;
52.639 + for (;;) {
52.640 + final Node p = node.predecessor();
52.641 + if (p == head && tryAcquire(arg)) {
52.642 + setHead(node);
52.643 + p.next = null; // help GC
52.644 + failed = false;
52.645 + return interrupted;
52.646 + }
52.647 + if (shouldParkAfterFailedAcquire(p, node) &&
52.648 + parkAndCheckInterrupt())
52.649 + interrupted = true;
52.650 + }
52.651 + } finally {
52.652 + if (failed)
52.653 + cancelAcquire(node);
52.654 + }
52.655 + }
52.656 +
52.657 + /**
52.658 + * Acquires in exclusive interruptible mode.
52.659 + * @param arg the acquire argument
52.660 + */
52.661 + private void doAcquireInterruptibly(long arg)
52.662 + throws InterruptedException {
52.663 + final Node node = addWaiter(Node.EXCLUSIVE);
52.664 + boolean failed = true;
52.665 + try {
52.666 + for (;;) {
52.667 + final Node p = node.predecessor();
52.668 + if (p == head && tryAcquire(arg)) {
52.669 + setHead(node);
52.670 + p.next = null; // help GC
52.671 + failed = false;
52.672 + return;
52.673 + }
52.674 + if (shouldParkAfterFailedAcquire(p, node) &&
52.675 + parkAndCheckInterrupt())
52.676 + throw new InterruptedException();
52.677 + }
52.678 + } finally {
52.679 + if (failed)
52.680 + cancelAcquire(node);
52.681 + }
52.682 + }
52.683 +
52.684 + /**
52.685 + * Acquires in exclusive timed mode.
52.686 + *
52.687 + * @param arg the acquire argument
52.688 + * @param nanosTimeout max wait time
52.689 + * @return {@code true} if acquired
52.690 + */
52.691 + private boolean doAcquireNanos(long arg, long nanosTimeout)
52.692 + throws InterruptedException {
52.693 + long lastTime = System.nanoTime();
52.694 + final Node node = addWaiter(Node.EXCLUSIVE);
52.695 + boolean failed = true;
52.696 + try {
52.697 + for (;;) {
52.698 + final Node p = node.predecessor();
52.699 + if (p == head && tryAcquire(arg)) {
52.700 + setHead(node);
52.701 + p.next = null; // help GC
52.702 + failed = false;
52.703 + return true;
52.704 + }
52.705 + if (nanosTimeout <= 0)
52.706 + return false;
52.707 + if (shouldParkAfterFailedAcquire(p, node) &&
52.708 + nanosTimeout > spinForTimeoutThreshold)
52.709 + LockSupport.parkNanos(this, nanosTimeout);
52.710 + long now = System.nanoTime();
52.711 + nanosTimeout -= now - lastTime;
52.712 + lastTime = now;
52.713 + if (Thread.interrupted())
52.714 + throw new InterruptedException();
52.715 + }
52.716 + } finally {
52.717 + if (failed)
52.718 + cancelAcquire(node);
52.719 + }
52.720 + }
52.721 +
52.722 + /**
52.723 + * Acquires in shared uninterruptible mode.
52.724 + * @param arg the acquire argument
52.725 + */
52.726 + private void doAcquireShared(long arg) {
52.727 + final Node node = addWaiter(Node.SHARED);
52.728 + boolean failed = true;
52.729 + try {
52.730 + boolean interrupted = false;
52.731 + for (;;) {
52.732 + final Node p = node.predecessor();
52.733 + if (p == head) {
52.734 + long r = tryAcquireShared(arg);
52.735 + if (r >= 0) {
52.736 + setHeadAndPropagate(node, r);
52.737 + p.next = null; // help GC
52.738 + if (interrupted)
52.739 + selfInterrupt();
52.740 + failed = false;
52.741 + return;
52.742 + }
52.743 + }
52.744 + if (shouldParkAfterFailedAcquire(p, node) &&
52.745 + parkAndCheckInterrupt())
52.746 + interrupted = true;
52.747 + }
52.748 + } finally {
52.749 + if (failed)
52.750 + cancelAcquire(node);
52.751 + }
52.752 + }
52.753 +
52.754 + /**
52.755 + * Acquires in shared interruptible mode.
52.756 + * @param arg the acquire argument
52.757 + */
52.758 + private void doAcquireSharedInterruptibly(long arg)
52.759 + throws InterruptedException {
52.760 + final Node node = addWaiter(Node.SHARED);
52.761 + boolean failed = true;
52.762 + try {
52.763 + for (;;) {
52.764 + final Node p = node.predecessor();
52.765 + if (p == head) {
52.766 + long r = tryAcquireShared(arg);
52.767 + if (r >= 0) {
52.768 + setHeadAndPropagate(node, r);
52.769 + p.next = null; // help GC
52.770 + failed = false;
52.771 + return;
52.772 + }
52.773 + }
52.774 + if (shouldParkAfterFailedAcquire(p, node) &&
52.775 + parkAndCheckInterrupt())
52.776 + throw new InterruptedException();
52.777 + }
52.778 + } finally {
52.779 + if (failed)
52.780 + cancelAcquire(node);
52.781 + }
52.782 + }
52.783 +
52.784 + /**
52.785 + * Acquires in shared timed mode.
52.786 + *
52.787 + * @param arg the acquire argument
52.788 + * @param nanosTimeout max wait time
52.789 + * @return {@code true} if acquired
52.790 + */
52.791 + private boolean doAcquireSharedNanos(long arg, long nanosTimeout)
52.792 + throws InterruptedException {
52.793 +
52.794 + long lastTime = System.nanoTime();
52.795 + final Node node = addWaiter(Node.SHARED);
52.796 + boolean failed = true;
52.797 + try {
52.798 + for (;;) {
52.799 + final Node p = node.predecessor();
52.800 + if (p == head) {
52.801 + long r = tryAcquireShared(arg);
52.802 + if (r >= 0) {
52.803 + setHeadAndPropagate(node, r);
52.804 + p.next = null; // help GC
52.805 + failed = false;
52.806 + return true;
52.807 + }
52.808 + }
52.809 + if (nanosTimeout <= 0)
52.810 + return false;
52.811 + if (shouldParkAfterFailedAcquire(p, node) &&
52.812 + nanosTimeout > spinForTimeoutThreshold)
52.813 + LockSupport.parkNanos(this, nanosTimeout);
52.814 + long now = System.nanoTime();
52.815 + nanosTimeout -= now - lastTime;
52.816 + lastTime = now;
52.817 + if (Thread.interrupted())
52.818 + throw new InterruptedException();
52.819 + }
52.820 + } finally {
52.821 + if (failed)
52.822 + cancelAcquire(node);
52.823 + }
52.824 + }
52.825 +
52.826 + // Main exported methods
52.827 +
52.828 + /**
52.829 + * Attempts to acquire in exclusive mode. This method should query
52.830 + * if the state of the object permits it to be acquired in the
52.831 + * exclusive mode, and if so to acquire it.
52.832 + *
52.833 + * <p>This method is always invoked by the thread performing
52.834 + * acquire. If this method reports failure, the acquire method
52.835 + * may queue the thread, if it is not already queued, until it is
52.836 + * signalled by a release from some other thread. This can be used
52.837 + * to implement method {@link Lock#tryLock()}.
52.838 + *
52.839 + * <p>The default
52.840 + * implementation throws {@link UnsupportedOperationException}.
52.841 + *
52.842 + * @param arg the acquire argument. This value is always the one
52.843 + * passed to an acquire method, or is the value saved on entry
52.844 + * to a condition wait. The value is otherwise uninterpreted
52.845 + * and can represent anything you like.
52.846 + * @return {@code true} if successful. Upon success, this object has
52.847 + * been acquired.
52.848 + * @throws IllegalMonitorStateException if acquiring would place this
52.849 + * synchronizer in an illegal state. This exception must be
52.850 + * thrown in a consistent fashion for synchronization to work
52.851 + * correctly.
52.852 + * @throws UnsupportedOperationException if exclusive mode is not supported
52.853 + */
52.854 + protected boolean tryAcquire(long arg) {
52.855 + throw new UnsupportedOperationException();
52.856 + }
52.857 +
52.858 + /**
52.859 + * Attempts to set the state to reflect a release in exclusive
52.860 + * mode.
52.861 + *
52.862 + * <p>This method is always invoked by the thread performing release.
52.863 + *
52.864 + * <p>The default implementation throws
52.865 + * {@link UnsupportedOperationException}.
52.866 + *
52.867 + * @param arg the release argument. This value is always the one
52.868 + * passed to a release method, or the current state value upon
52.869 + * entry to a condition wait. The value is otherwise
52.870 + * uninterpreted and can represent anything you like.
52.871 + * @return {@code true} if this object is now in a fully released
52.872 + * state, so that any waiting threads may attempt to acquire;
52.873 + * and {@code false} otherwise.
52.874 + * @throws IllegalMonitorStateException if releasing would place this
52.875 + * synchronizer in an illegal state. This exception must be
52.876 + * thrown in a consistent fashion for synchronization to work
52.877 + * correctly.
52.878 + * @throws UnsupportedOperationException if exclusive mode is not supported
52.879 + */
52.880 + protected boolean tryRelease(long arg) {
52.881 + throw new UnsupportedOperationException();
52.882 + }
52.883 +
52.884 + /**
52.885 + * Attempts to acquire in shared mode. This method should query if
52.886 + * the state of the object permits it to be acquired in the shared
52.887 + * mode, and if so to acquire it.
52.888 + *
52.889 + * <p>This method is always invoked by the thread performing
52.890 + * acquire. If this method reports failure, the acquire method
52.891 + * may queue the thread, if it is not already queued, until it is
52.892 + * signalled by a release from some other thread.
52.893 + *
52.894 + * <p>The default implementation throws {@link
52.895 + * UnsupportedOperationException}.
52.896 + *
52.897 + * @param arg the acquire argument. This value is always the one
52.898 + * passed to an acquire method, or is the value saved on entry
52.899 + * to a condition wait. The value is otherwise uninterpreted
52.900 + * and can represent anything you like.
52.901 + * @return a negative value on failure; zero if acquisition in shared
52.902 + * mode succeeded but no subsequent shared-mode acquire can
52.903 + * succeed; and a positive value if acquisition in shared
52.904 + * mode succeeded and subsequent shared-mode acquires might
52.905 + * also succeed, in which case a subsequent waiting thread
52.906 + * must check availability. (Support for three different
52.907 + * return values enables this method to be used in contexts
52.908 + * where acquires only sometimes act exclusively.) Upon
52.909 + * success, this object has been acquired.
52.910 + * @throws IllegalMonitorStateException if acquiring would place this
52.911 + * synchronizer in an illegal state. This exception must be
52.912 + * thrown in a consistent fashion for synchronization to work
52.913 + * correctly.
52.914 + * @throws UnsupportedOperationException if shared mode is not supported
52.915 + */
52.916 + protected long tryAcquireShared(long arg) {
52.917 + throw new UnsupportedOperationException();
52.918 + }
52.919 +
52.920 + /**
52.921 + * Attempts to set the state to reflect a release in shared mode.
52.922 + *
52.923 + * <p>This method is always invoked by the thread performing release.
52.924 + *
52.925 + * <p>The default implementation throws
52.926 + * {@link UnsupportedOperationException}.
52.927 + *
52.928 + * @param arg the release argument. This value is always the one
52.929 + * passed to a release method, or the current state value upon
52.930 + * entry to a condition wait. The value is otherwise
52.931 + * uninterpreted and can represent anything you like.
52.932 + * @return {@code true} if this release of shared mode may permit a
52.933 + * waiting acquire (shared or exclusive) to succeed; and
52.934 + * {@code false} otherwise
52.935 + * @throws IllegalMonitorStateException if releasing would place this
52.936 + * synchronizer in an illegal state. This exception must be
52.937 + * thrown in a consistent fashion for synchronization to work
52.938 + * correctly.
52.939 + * @throws UnsupportedOperationException if shared mode is not supported
52.940 + */
52.941 + protected boolean tryReleaseShared(long arg) {
52.942 + throw new UnsupportedOperationException();
52.943 + }
52.944 +
52.945 + /**
52.946 + * Returns {@code true} if synchronization is held exclusively with
52.947 + * respect to the current (calling) thread. This method is invoked
52.948 + * upon each call to a non-waiting {@link ConditionObject} method.
52.949 + * (Waiting methods instead invoke {@link #release}.)
52.950 + *
52.951 + * <p>The default implementation throws {@link
52.952 + * UnsupportedOperationException}. This method is invoked
52.953 + * internally only within {@link ConditionObject} methods, so need
52.954 + * not be defined if conditions are not used.
52.955 + *
52.956 + * @return {@code true} if synchronization is held exclusively;
52.957 + * {@code false} otherwise
52.958 + * @throws UnsupportedOperationException if conditions are not supported
52.959 + */
52.960 + protected boolean isHeldExclusively() {
52.961 + throw new UnsupportedOperationException();
52.962 + }
52.963 +
52.964 + /**
52.965 + * Acquires in exclusive mode, ignoring interrupts. Implemented
52.966 + * by invoking at least once {@link #tryAcquire},
52.967 + * returning on success. Otherwise the thread is queued, possibly
52.968 + * repeatedly blocking and unblocking, invoking {@link
52.969 + * #tryAcquire} until success. This method can be used
52.970 + * to implement method {@link Lock#lock}.
52.971 + *
52.972 + * @param arg the acquire argument. This value is conveyed to
52.973 + * {@link #tryAcquire} but is otherwise uninterpreted and
52.974 + * can represent anything you like.
52.975 + */
52.976 + public final void acquire(long arg) {
52.977 + if (!tryAcquire(arg) &&
52.978 + acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
52.979 + selfInterrupt();
52.980 + }
52.981 +
52.982 + /**
52.983 + * Acquires in exclusive mode, aborting if interrupted.
52.984 + * Implemented by first checking interrupt status, then invoking
52.985 + * at least once {@link #tryAcquire}, returning on
52.986 + * success. Otherwise the thread is queued, possibly repeatedly
52.987 + * blocking and unblocking, invoking {@link #tryAcquire}
52.988 + * until success or the thread is interrupted. This method can be
52.989 + * used to implement method {@link Lock#lockInterruptibly}.
52.990 + *
52.991 + * @param arg the acquire argument. This value is conveyed to
52.992 + * {@link #tryAcquire} but is otherwise uninterpreted and
52.993 + * can represent anything you like.
52.994 + * @throws InterruptedException if the current thread is interrupted
52.995 + */
52.996 + public final void acquireInterruptibly(long arg)
52.997 + throws InterruptedException {
52.998 + if (Thread.interrupted())
52.999 + throw new InterruptedException();
52.1000 + if (!tryAcquire(arg))
52.1001 + doAcquireInterruptibly(arg);
52.1002 + }
52.1003 +
52.1004 + /**
52.1005 + * Attempts to acquire in exclusive mode, aborting if interrupted,
52.1006 + * and failing if the given timeout elapses. Implemented by first
52.1007 + * checking interrupt status, then invoking at least once {@link
52.1008 + * #tryAcquire}, returning on success. Otherwise, the thread is
52.1009 + * queued, possibly repeatedly blocking and unblocking, invoking
52.1010 + * {@link #tryAcquire} until success or the thread is interrupted
52.1011 + * or the timeout elapses. This method can be used to implement
52.1012 + * method {@link Lock#tryLock(long, TimeUnit)}.
52.1013 + *
52.1014 + * @param arg the acquire argument. This value is conveyed to
52.1015 + * {@link #tryAcquire} but is otherwise uninterpreted and
52.1016 + * can represent anything you like.
52.1017 + * @param nanosTimeout the maximum number of nanoseconds to wait
52.1018 + * @return {@code true} if acquired; {@code false} if timed out
52.1019 + * @throws InterruptedException if the current thread is interrupted
52.1020 + */
52.1021 + public final boolean tryAcquireNanos(long arg, long nanosTimeout)
52.1022 + throws InterruptedException {
52.1023 + if (Thread.interrupted())
52.1024 + throw new InterruptedException();
52.1025 + return tryAcquire(arg) ||
52.1026 + doAcquireNanos(arg, nanosTimeout);
52.1027 + }
52.1028 +
52.1029 + /**
52.1030 + * Releases in exclusive mode. Implemented by unblocking one or
52.1031 + * more threads if {@link #tryRelease} returns true.
52.1032 + * This method can be used to implement method {@link Lock#unlock}.
52.1033 + *
52.1034 + * @param arg the release argument. This value is conveyed to
52.1035 + * {@link #tryRelease} but is otherwise uninterpreted and
52.1036 + * can represent anything you like.
52.1037 + * @return the value returned from {@link #tryRelease}
52.1038 + */
52.1039 + public final boolean release(long arg) {
52.1040 + if (tryRelease(arg)) {
52.1041 + Node h = head;
52.1042 + if (h != null && h.waitStatus != 0)
52.1043 + unparkSuccessor(h);
52.1044 + return true;
52.1045 + }
52.1046 + return false;
52.1047 + }
52.1048 +
52.1049 + /**
52.1050 + * Acquires in shared mode, ignoring interrupts. Implemented by
52.1051 + * first invoking at least once {@link #tryAcquireShared},
52.1052 + * returning on success. Otherwise the thread is queued, possibly
52.1053 + * repeatedly blocking and unblocking, invoking {@link
52.1054 + * #tryAcquireShared} until success.
52.1055 + *
52.1056 + * @param arg the acquire argument. This value is conveyed to
52.1057 + * {@link #tryAcquireShared} but is otherwise uninterpreted
52.1058 + * and can represent anything you like.
52.1059 + */
52.1060 + public final void acquireShared(long arg) {
52.1061 + if (tryAcquireShared(arg) < 0)
52.1062 + doAcquireShared(arg);
52.1063 + }
52.1064 +
52.1065 + /**
52.1066 + * Acquires in shared mode, aborting if interrupted. Implemented
52.1067 + * by first checking interrupt status, then invoking at least once
52.1068 + * {@link #tryAcquireShared}, returning on success. Otherwise the
52.1069 + * thread is queued, possibly repeatedly blocking and unblocking,
52.1070 + * invoking {@link #tryAcquireShared} until success or the thread
52.1071 + * is interrupted.
52.1072 + * @param arg the acquire argument
52.1073 + * This value is conveyed to {@link #tryAcquireShared} but is
52.1074 + * otherwise uninterpreted and can represent anything
52.1075 + * you like.
52.1076 + * @throws InterruptedException if the current thread is interrupted
52.1077 + */
52.1078 + public final void acquireSharedInterruptibly(long arg)
52.1079 + throws InterruptedException {
52.1080 + if (Thread.interrupted())
52.1081 + throw new InterruptedException();
52.1082 + if (tryAcquireShared(arg) < 0)
52.1083 + doAcquireSharedInterruptibly(arg);
52.1084 + }
52.1085 +
52.1086 + /**
52.1087 + * Attempts to acquire in shared mode, aborting if interrupted, and
52.1088 + * failing if the given timeout elapses. Implemented by first
52.1089 + * checking interrupt status, then invoking at least once {@link
52.1090 + * #tryAcquireShared}, returning on success. Otherwise, the
52.1091 + * thread is queued, possibly repeatedly blocking and unblocking,
52.1092 + * invoking {@link #tryAcquireShared} until success or the thread
52.1093 + * is interrupted or the timeout elapses.
52.1094 + *
52.1095 + * @param arg the acquire argument. This value is conveyed to
52.1096 + * {@link #tryAcquireShared} but is otherwise uninterpreted
52.1097 + * and can represent anything you like.
52.1098 + * @param nanosTimeout the maximum number of nanoseconds to wait
52.1099 + * @return {@code true} if acquired; {@code false} if timed out
52.1100 + * @throws InterruptedException if the current thread is interrupted
52.1101 + */
52.1102 + public final boolean tryAcquireSharedNanos(long arg, long nanosTimeout)
52.1103 + throws InterruptedException {
52.1104 + if (Thread.interrupted())
52.1105 + throw new InterruptedException();
52.1106 + return tryAcquireShared(arg) >= 0 ||
52.1107 + doAcquireSharedNanos(arg, nanosTimeout);
52.1108 + }
52.1109 +
52.1110 + /**
52.1111 + * Releases in shared mode. Implemented by unblocking one or more
52.1112 + * threads if {@link #tryReleaseShared} returns true.
52.1113 + *
52.1114 + * @param arg the release argument. This value is conveyed to
52.1115 + * {@link #tryReleaseShared} but is otherwise uninterpreted
52.1116 + * and can represent anything you like.
52.1117 + * @return the value returned from {@link #tryReleaseShared}
52.1118 + */
52.1119 + public final boolean releaseShared(long arg) {
52.1120 + if (tryReleaseShared(arg)) {
52.1121 + doReleaseShared();
52.1122 + return true;
52.1123 + }
52.1124 + return false;
52.1125 + }
52.1126 +
52.1127 + // Queue inspection methods
52.1128 +
52.1129 + /**
52.1130 + * Queries whether any threads are waiting to acquire. Note that
52.1131 + * because cancellations due to interrupts and timeouts may occur
52.1132 + * at any time, a {@code true} return does not guarantee that any
52.1133 + * other thread will ever acquire.
52.1134 + *
52.1135 + * <p>In this implementation, this operation returns in
52.1136 + * constant time.
52.1137 + *
52.1138 + * @return {@code true} if there may be other threads waiting to acquire
52.1139 + */
52.1140 + public final boolean hasQueuedThreads() {
52.1141 + return head != tail;
52.1142 + }
52.1143 +
52.1144 + /**
52.1145 + * Queries whether any threads have ever contended to acquire this
52.1146 + * synchronizer; that is if an acquire method has ever blocked.
52.1147 + *
52.1148 + * <p>In this implementation, this operation returns in
52.1149 + * constant time.
52.1150 + *
52.1151 + * @return {@code true} if there has ever been contention
52.1152 + */
52.1153 + public final boolean hasContended() {
52.1154 + return head != null;
52.1155 + }
52.1156 +
52.1157 + /**
52.1158 + * Returns the first (longest-waiting) thread in the queue, or
52.1159 + * {@code null} if no threads are currently queued.
52.1160 + *
52.1161 + * <p>In this implementation, this operation normally returns in
52.1162 + * constant time, but may iterate upon contention if other threads are
52.1163 + * concurrently modifying the queue.
52.1164 + *
52.1165 + * @return the first (longest-waiting) thread in the queue, or
52.1166 + * {@code null} if no threads are currently queued
52.1167 + */
52.1168 + public final Thread getFirstQueuedThread() {
52.1169 + // handle only fast path, else relay
52.1170 + return (head == tail) ? null : fullGetFirstQueuedThread();
52.1171 + }
52.1172 +
52.1173 + /**
52.1174 + * Version of getFirstQueuedThread called when fastpath fails
52.1175 + */
52.1176 + private Thread fullGetFirstQueuedThread() {
52.1177 + /*
52.1178 + * The first node is normally head.next. Try to get its
52.1179 + * thread field, ensuring consistent reads: If thread
52.1180 + * field is nulled out or s.prev is no longer head, then
52.1181 + * some other thread(s) concurrently performed setHead in
52.1182 + * between some of our reads. We try this twice before
52.1183 + * resorting to traversal.
52.1184 + */
52.1185 + Node h, s;
52.1186 + Thread st;
52.1187 + if (((h = head) != null && (s = h.next) != null &&
52.1188 + s.prev == head && (st = s.thread) != null) ||
52.1189 + ((h = head) != null && (s = h.next) != null &&
52.1190 + s.prev == head && (st = s.thread) != null))
52.1191 + return st;
52.1192 +
52.1193 + /*
52.1194 + * Head's next field might not have been set yet, or may have
52.1195 + * been unset after setHead. So we must check to see if tail
52.1196 + * is actually first node. If not, we continue on, safely
52.1197 + * traversing from tail back to head to find first,
52.1198 + * guaranteeing termination.
52.1199 + */
52.1200 +
52.1201 + Node t = tail;
52.1202 + Thread firstThread = null;
52.1203 + while (t != null && t != head) {
52.1204 + Thread tt = t.thread;
52.1205 + if (tt != null)
52.1206 + firstThread = tt;
52.1207 + t = t.prev;
52.1208 + }
52.1209 + return firstThread;
52.1210 + }
52.1211 +
52.1212 + /**
52.1213 + * Returns true if the given thread is currently queued.
52.1214 + *
52.1215 + * <p>This implementation traverses the queue to determine
52.1216 + * presence of the given thread.
52.1217 + *
52.1218 + * @param thread the thread
52.1219 + * @return {@code true} if the given thread is on the queue
52.1220 + * @throws NullPointerException if the thread is null
52.1221 + */
52.1222 + public final boolean isQueued(Thread thread) {
52.1223 + if (thread == null)
52.1224 + throw new NullPointerException();
52.1225 + for (Node p = tail; p != null; p = p.prev)
52.1226 + if (p.thread == thread)
52.1227 + return true;
52.1228 + return false;
52.1229 + }
52.1230 +
52.1231 + /**
52.1232 + * Returns {@code true} if the apparent first queued thread, if one
52.1233 + * exists, is waiting in exclusive mode. If this method returns
52.1234 + * {@code true}, and the current thread is attempting to acquire in
52.1235 + * shared mode (that is, this method is invoked from {@link
52.1236 + * #tryAcquireShared}) then it is guaranteed that the current thread
52.1237 + * is not the first queued thread. Used only as a heuristic in
52.1238 + * ReentrantReadWriteLock.
52.1239 + */
52.1240 + final boolean apparentlyFirstQueuedIsExclusive() {
52.1241 + Node h, s;
52.1242 + return (h = head) != null &&
52.1243 + (s = h.next) != null &&
52.1244 + !s.isShared() &&
52.1245 + s.thread != null;
52.1246 + }
52.1247 +
52.1248 + /**
52.1249 + * Queries whether any threads have been waiting to acquire longer
52.1250 + * than the current thread.
52.1251 + *
52.1252 + * <p>An invocation of this method is equivalent to (but may be
52.1253 + * more efficient than):
52.1254 + * <pre> {@code
52.1255 + * getFirstQueuedThread() != Thread.currentThread() &&
52.1256 + * hasQueuedThreads()}</pre>
52.1257 + *
52.1258 + * <p>Note that because cancellations due to interrupts and
52.1259 + * timeouts may occur at any time, a {@code true} return does not
52.1260 + * guarantee that some other thread will acquire before the current
52.1261 + * thread. Likewise, it is possible for another thread to win a
52.1262 + * race to enqueue after this method has returned {@code false},
52.1263 + * due to the queue being empty.
52.1264 + *
52.1265 + * <p>This method is designed to be used by a fair synchronizer to
52.1266 + * avoid <a href="AbstractQueuedSynchronizer#barging">barging</a>.
52.1267 + * Such a synchronizer's {@link #tryAcquire} method should return
52.1268 + * {@code false}, and its {@link #tryAcquireShared} method should
52.1269 + * return a negative value, if this method returns {@code true}
52.1270 + * (unless this is a reentrant acquire). For example, the {@code
52.1271 + * tryAcquire} method for a fair, reentrant, exclusive mode
52.1272 + * synchronizer might look like this:
52.1273 + *
52.1274 + * <pre> {@code
52.1275 + * protected boolean tryAcquire(int arg) {
52.1276 + * if (isHeldExclusively()) {
52.1277 + * // A reentrant acquire; increment hold count
52.1278 + * return true;
52.1279 + * } else if (hasQueuedPredecessors()) {
52.1280 + * return false;
52.1281 + * } else {
52.1282 + * // try to acquire normally
52.1283 + * }
52.1284 + * }}</pre>
52.1285 + *
52.1286 + * @return {@code true} if there is a queued thread preceding the
52.1287 + * current thread, and {@code false} if the current thread
52.1288 + * is at the head of the queue or the queue is empty
52.1289 + * @since 1.7
52.1290 + */
52.1291 + public final boolean hasQueuedPredecessors() {
52.1292 + // The correctness of this depends on head being initialized
52.1293 + // before tail and on head.next being accurate if the current
52.1294 + // thread is first in queue.
52.1295 + Node t = tail; // Read fields in reverse initialization order
52.1296 + Node h = head;
52.1297 + Node s;
52.1298 + return h != t &&
52.1299 + ((s = h.next) == null || s.thread != Thread.currentThread());
52.1300 + }
52.1301 +
52.1302 +
52.1303 + // Instrumentation and monitoring methods
52.1304 +
52.1305 + /**
52.1306 + * Returns an estimate of the number of threads waiting to
52.1307 + * acquire. The value is only an estimate because the number of
52.1308 + * threads may change dynamically while this method traverses
52.1309 + * internal data structures. This method is designed for use in
52.1310 + * monitoring system state, not for synchronization
52.1311 + * control.
52.1312 + *
52.1313 + * @return the estimated number of threads waiting to acquire
52.1314 + */
52.1315 + public final int getQueueLength() {
52.1316 + int n = 0;
52.1317 + for (Node p = tail; p != null; p = p.prev) {
52.1318 + if (p.thread != null)
52.1319 + ++n;
52.1320 + }
52.1321 + return n;
52.1322 + }
52.1323 +
52.1324 + /**
52.1325 + * Returns a collection containing threads that may be waiting to
52.1326 + * acquire. Because the actual set of threads may change
52.1327 + * dynamically while constructing this result, the returned
52.1328 + * collection is only a best-effort estimate. The elements of the
52.1329 + * returned collection are in no particular order. This method is
52.1330 + * designed to facilitate construction of subclasses that provide
52.1331 + * more extensive monitoring facilities.
52.1332 + *
52.1333 + * @return the collection of threads
52.1334 + */
52.1335 + public final Collection<Thread> getQueuedThreads() {
52.1336 + ArrayList<Thread> list = new ArrayList<Thread>();
52.1337 + for (Node p = tail; p != null; p = p.prev) {
52.1338 + Thread t = p.thread;
52.1339 + if (t != null)
52.1340 + list.add(t);
52.1341 + }
52.1342 + return list;
52.1343 + }
52.1344 +
52.1345 + /**
52.1346 + * Returns a collection containing threads that may be waiting to
52.1347 + * acquire in exclusive mode. This has the same properties
52.1348 + * as {@link #getQueuedThreads} except that it only returns
52.1349 + * those threads waiting due to an exclusive acquire.
52.1350 + *
52.1351 + * @return the collection of threads
52.1352 + */
52.1353 + public final Collection<Thread> getExclusiveQueuedThreads() {
52.1354 + ArrayList<Thread> list = new ArrayList<Thread>();
52.1355 + for (Node p = tail; p != null; p = p.prev) {
52.1356 + if (!p.isShared()) {
52.1357 + Thread t = p.thread;
52.1358 + if (t != null)
52.1359 + list.add(t);
52.1360 + }
52.1361 + }
52.1362 + return list;
52.1363 + }
52.1364 +
52.1365 + /**
52.1366 + * Returns a collection containing threads that may be waiting to
52.1367 + * acquire in shared mode. This has the same properties
52.1368 + * as {@link #getQueuedThreads} except that it only returns
52.1369 + * those threads waiting due to a shared acquire.
52.1370 + *
52.1371 + * @return the collection of threads
52.1372 + */
52.1373 + public final Collection<Thread> getSharedQueuedThreads() {
52.1374 + ArrayList<Thread> list = new ArrayList<Thread>();
52.1375 + for (Node p = tail; p != null; p = p.prev) {
52.1376 + if (p.isShared()) {
52.1377 + Thread t = p.thread;
52.1378 + if (t != null)
52.1379 + list.add(t);
52.1380 + }
52.1381 + }
52.1382 + return list;
52.1383 + }
52.1384 +
52.1385 + /**
52.1386 + * Returns a string identifying this synchronizer, as well as its state.
52.1387 + * The state, in brackets, includes the String {@code "State ="}
52.1388 + * followed by the current value of {@link #getState}, and either
52.1389 + * {@code "nonempty"} or {@code "empty"} depending on whether the
52.1390 + * queue is empty.
52.1391 + *
52.1392 + * @return a string identifying this synchronizer, as well as its state
52.1393 + */
52.1394 + public String toString() {
52.1395 + long s = getState();
52.1396 + String q = hasQueuedThreads() ? "non" : "";
52.1397 + return super.toString() +
52.1398 + "[State = " + s + ", " + q + "empty queue]";
52.1399 + }
52.1400 +
52.1401 +
52.1402 + // Internal support methods for Conditions
52.1403 +
52.1404 + /**
52.1405 + * Returns true if a node, always one that was initially placed on
52.1406 + * a condition queue, is now waiting to reacquire on sync queue.
52.1407 + * @param node the node
52.1408 + * @return true if is reacquiring
52.1409 + */
52.1410 + final boolean isOnSyncQueue(Node node) {
52.1411 + if (node.waitStatus == Node.CONDITION || node.prev == null)
52.1412 + return false;
52.1413 + if (node.next != null) // If has successor, it must be on queue
52.1414 + return true;
52.1415 + /*
52.1416 + * node.prev can be non-null, but not yet on queue because
52.1417 + * the CAS to place it on queue can fail. So we have to
52.1418 + * traverse from tail to make sure it actually made it. It
52.1419 + * will always be near the tail in calls to this method, and
52.1420 + * unless the CAS failed (which is unlikely), it will be
52.1421 + * there, so we hardly ever traverse much.
52.1422 + */
52.1423 + return findNodeFromTail(node);
52.1424 + }
52.1425 +
52.1426 + /**
52.1427 + * Returns true if node is on sync queue by searching backwards from tail.
52.1428 + * Called only when needed by isOnSyncQueue.
52.1429 + * @return true if present
52.1430 + */
52.1431 + private boolean findNodeFromTail(Node node) {
52.1432 + Node t = tail;
52.1433 + for (;;) {
52.1434 + if (t == node)
52.1435 + return true;
52.1436 + if (t == null)
52.1437 + return false;
52.1438 + t = t.prev;
52.1439 + }
52.1440 + }
52.1441 +
52.1442 + /**
52.1443 + * Transfers a node from a condition queue onto sync queue.
52.1444 + * Returns true if successful.
52.1445 + * @param node the node
52.1446 + * @return true if successfully transferred (else the node was
52.1447 + * cancelled before signal).
52.1448 + */
52.1449 + final boolean transferForSignal(Node node) {
52.1450 + /*
52.1451 + * If cannot change waitStatus, the node has been cancelled.
52.1452 + */
52.1453 + if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))
52.1454 + return false;
52.1455 +
52.1456 + /*
52.1457 + * Splice onto queue and try to set waitStatus of predecessor to
52.1458 + * indicate that thread is (probably) waiting. If cancelled or
52.1459 + * attempt to set waitStatus fails, wake up to resync (in which
52.1460 + * case the waitStatus can be transiently and harmlessly wrong).
52.1461 + */
52.1462 + Node p = enq(node);
52.1463 + int ws = p.waitStatus;
52.1464 + if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))
52.1465 + LockSupport.unpark(node.thread);
52.1466 + return true;
52.1467 + }
52.1468 +
52.1469 + /**
52.1470 + * Transfers node, if necessary, to sync queue after a cancelled
52.1471 + * wait. Returns true if thread was cancelled before being
52.1472 + * signalled.
52.1473 + * @param current the waiting thread
52.1474 + * @param node its node
52.1475 + * @return true if cancelled before the node was signalled
52.1476 + */
52.1477 + final boolean transferAfterCancelledWait(Node node) {
52.1478 + if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) {
52.1479 + enq(node);
52.1480 + return true;
52.1481 + }
52.1482 + /*
52.1483 + * If we lost out to a signal(), then we can't proceed
52.1484 + * until it finishes its enq(). Cancelling during an
52.1485 + * incomplete transfer is both rare and transient, so just
52.1486 + * spin.
52.1487 + */
52.1488 + while (!isOnSyncQueue(node))
52.1489 + Thread.yield();
52.1490 + return false;
52.1491 + }
52.1492 +
52.1493 + /**
52.1494 + * Invokes release with current state value; returns saved state.
52.1495 + * Cancels node and throws exception on failure.
52.1496 + * @param node the condition node for this wait
52.1497 + * @return previous sync state
52.1498 + */
52.1499 + final long fullyRelease(Node node) {
52.1500 + boolean failed = true;
52.1501 + try {
52.1502 + long savedState = getState();
52.1503 + if (release(savedState)) {
52.1504 + failed = false;
52.1505 + return savedState;
52.1506 + } else {
52.1507 + throw new IllegalMonitorStateException();
52.1508 + }
52.1509 + } finally {
52.1510 + if (failed)
52.1511 + node.waitStatus = Node.CANCELLED;
52.1512 + }
52.1513 + }
52.1514 +
52.1515 + // Instrumentation methods for conditions
52.1516 +
52.1517 + /**
52.1518 + * Queries whether the given ConditionObject
52.1519 + * uses this synchronizer as its lock.
52.1520 + *
52.1521 + * @param condition the condition
52.1522 + * @return <tt>true</tt> if owned
52.1523 + * @throws NullPointerException if the condition is null
52.1524 + */
52.1525 + public final boolean owns(ConditionObject condition) {
52.1526 + if (condition == null)
52.1527 + throw new NullPointerException();
52.1528 + return condition.isOwnedBy(this);
52.1529 + }
52.1530 +
52.1531 + /**
52.1532 + * Queries whether any threads are waiting on the given condition
52.1533 + * associated with this synchronizer. Note that because timeouts
52.1534 + * and interrupts may occur at any time, a <tt>true</tt> return
52.1535 + * does not guarantee that a future <tt>signal</tt> will awaken
52.1536 + * any threads. This method is designed primarily for use in
52.1537 + * monitoring of the system state.
52.1538 + *
52.1539 + * @param condition the condition
52.1540 + * @return <tt>true</tt> if there are any waiting threads
52.1541 + * @throws IllegalMonitorStateException if exclusive synchronization
52.1542 + * is not held
52.1543 + * @throws IllegalArgumentException if the given condition is
52.1544 + * not associated with this synchronizer
52.1545 + * @throws NullPointerException if the condition is null
52.1546 + */
52.1547 + public final boolean hasWaiters(ConditionObject condition) {
52.1548 + if (!owns(condition))
52.1549 + throw new IllegalArgumentException("Not owner");
52.1550 + return condition.hasWaiters();
52.1551 + }
52.1552 +
52.1553 + /**
52.1554 + * Returns an estimate of the number of threads waiting on the
52.1555 + * given condition associated with this synchronizer. Note that
52.1556 + * because timeouts and interrupts may occur at any time, the
52.1557 + * estimate serves only as an upper bound on the actual number of
52.1558 + * waiters. This method is designed for use in monitoring of the
52.1559 + * system state, not for synchronization control.
52.1560 + *
52.1561 + * @param condition the condition
52.1562 + * @return the estimated number of waiting threads
52.1563 + * @throws IllegalMonitorStateException if exclusive synchronization
52.1564 + * is not held
52.1565 + * @throws IllegalArgumentException if the given condition is
52.1566 + * not associated with this synchronizer
52.1567 + * @throws NullPointerException if the condition is null
52.1568 + */
52.1569 + public final int getWaitQueueLength(ConditionObject condition) {
52.1570 + if (!owns(condition))
52.1571 + throw new IllegalArgumentException("Not owner");
52.1572 + return condition.getWaitQueueLength();
52.1573 + }
52.1574 +
52.1575 + /**
52.1576 + * Returns a collection containing those threads that may be
52.1577 + * waiting on the given condition associated with this
52.1578 + * synchronizer. Because the actual set of threads may change
52.1579 + * dynamically while constructing this result, the returned
52.1580 + * collection is only a best-effort estimate. The elements of the
52.1581 + * returned collection are in no particular order.
52.1582 + *
52.1583 + * @param condition the condition
52.1584 + * @return the collection of threads
52.1585 + * @throws IllegalMonitorStateException if exclusive synchronization
52.1586 + * is not held
52.1587 + * @throws IllegalArgumentException if the given condition is
52.1588 + * not associated with this synchronizer
52.1589 + * @throws NullPointerException if the condition is null
52.1590 + */
52.1591 + public final Collection<Thread> getWaitingThreads(ConditionObject condition) {
52.1592 + if (!owns(condition))
52.1593 + throw new IllegalArgumentException("Not owner");
52.1594 + return condition.getWaitingThreads();
52.1595 + }
52.1596 +
52.1597 + /**
52.1598 + * Condition implementation for a {@link
52.1599 + * AbstractQueuedLongSynchronizer} serving as the basis of a {@link
52.1600 + * Lock} implementation.
52.1601 + *
52.1602 + * <p>Method documentation for this class describes mechanics,
52.1603 + * not behavioral specifications from the point of view of Lock
52.1604 + * and Condition users. Exported versions of this class will in
52.1605 + * general need to be accompanied by documentation describing
52.1606 + * condition semantics that rely on those of the associated
52.1607 + * <tt>AbstractQueuedLongSynchronizer</tt>.
52.1608 + *
52.1609 + * <p>This class is Serializable, but all fields are transient,
52.1610 + * so deserialized conditions have no waiters.
52.1611 + *
52.1612 + * @since 1.6
52.1613 + */
52.1614 + public class ConditionObject implements Condition, java.io.Serializable {
52.1615 + private static final long serialVersionUID = 1173984872572414699L;
52.1616 + /** First node of condition queue. */
52.1617 + private transient Node firstWaiter;
52.1618 + /** Last node of condition queue. */
52.1619 + private transient Node lastWaiter;
52.1620 +
52.1621 + /**
52.1622 + * Creates a new <tt>ConditionObject</tt> instance.
52.1623 + */
52.1624 + public ConditionObject() { }
52.1625 +
52.1626 + // Internal methods
52.1627 +
52.1628 + /**
52.1629 + * Adds a new waiter to wait queue.
52.1630 + * @return its new wait node
52.1631 + */
52.1632 + private Node addConditionWaiter() {
52.1633 + Node t = lastWaiter;
52.1634 + // If lastWaiter is cancelled, clean out.
52.1635 + if (t != null && t.waitStatus != Node.CONDITION) {
52.1636 + unlinkCancelledWaiters();
52.1637 + t = lastWaiter;
52.1638 + }
52.1639 + Node node = new Node(Thread.currentThread(), Node.CONDITION);
52.1640 + if (t == null)
52.1641 + firstWaiter = node;
52.1642 + else
52.1643 + t.nextWaiter = node;
52.1644 + lastWaiter = node;
52.1645 + return node;
52.1646 + }
52.1647 +
52.1648 + /**
52.1649 + * Removes and transfers nodes until hit non-cancelled one or
52.1650 + * null. Split out from signal in part to encourage compilers
52.1651 + * to inline the case of no waiters.
52.1652 + * @param first (non-null) the first node on condition queue
52.1653 + */
52.1654 + private void doSignal(Node first) {
52.1655 + do {
52.1656 + if ( (firstWaiter = first.nextWaiter) == null)
52.1657 + lastWaiter = null;
52.1658 + first.nextWaiter = null;
52.1659 + } while (!transferForSignal(first) &&
52.1660 + (first = firstWaiter) != null);
52.1661 + }
52.1662 +
52.1663 + /**
52.1664 + * Removes and transfers all nodes.
52.1665 + * @param first (non-null) the first node on condition queue
52.1666 + */
52.1667 + private void doSignalAll(Node first) {
52.1668 + lastWaiter = firstWaiter = null;
52.1669 + do {
52.1670 + Node next = first.nextWaiter;
52.1671 + first.nextWaiter = null;
52.1672 + transferForSignal(first);
52.1673 + first = next;
52.1674 + } while (first != null);
52.1675 + }
52.1676 +
52.1677 + /**
52.1678 + * Unlinks cancelled waiter nodes from condition queue.
52.1679 + * Called only while holding lock. This is called when
52.1680 + * cancellation occurred during condition wait, and upon
52.1681 + * insertion of a new waiter when lastWaiter is seen to have
52.1682 + * been cancelled. This method is needed to avoid garbage
52.1683 + * retention in the absence of signals. So even though it may
52.1684 + * require a full traversal, it comes into play only when
52.1685 + * timeouts or cancellations occur in the absence of
52.1686 + * signals. It traverses all nodes rather than stopping at a
52.1687 + * particular target to unlink all pointers to garbage nodes
52.1688 + * without requiring many re-traversals during cancellation
52.1689 + * storms.
52.1690 + */
52.1691 + private void unlinkCancelledWaiters() {
52.1692 + Node t = firstWaiter;
52.1693 + Node trail = null;
52.1694 + while (t != null) {
52.1695 + Node next = t.nextWaiter;
52.1696 + if (t.waitStatus != Node.CONDITION) {
52.1697 + t.nextWaiter = null;
52.1698 + if (trail == null)
52.1699 + firstWaiter = next;
52.1700 + else
52.1701 + trail.nextWaiter = next;
52.1702 + if (next == null)
52.1703 + lastWaiter = trail;
52.1704 + }
52.1705 + else
52.1706 + trail = t;
52.1707 + t = next;
52.1708 + }
52.1709 + }
52.1710 +
52.1711 + // public methods
52.1712 +
52.1713 + /**
52.1714 + * Moves the longest-waiting thread, if one exists, from the
52.1715 + * wait queue for this condition to the wait queue for the
52.1716 + * owning lock.
52.1717 + *
52.1718 + * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
52.1719 + * returns {@code false}
52.1720 + */
52.1721 + public final void signal() {
52.1722 + if (!isHeldExclusively())
52.1723 + throw new IllegalMonitorStateException();
52.1724 + Node first = firstWaiter;
52.1725 + if (first != null)
52.1726 + doSignal(first);
52.1727 + }
52.1728 +
52.1729 + /**
52.1730 + * Moves all threads from the wait queue for this condition to
52.1731 + * the wait queue for the owning lock.
52.1732 + *
52.1733 + * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
52.1734 + * returns {@code false}
52.1735 + */
52.1736 + public final void signalAll() {
52.1737 + if (!isHeldExclusively())
52.1738 + throw new IllegalMonitorStateException();
52.1739 + Node first = firstWaiter;
52.1740 + if (first != null)
52.1741 + doSignalAll(first);
52.1742 + }
52.1743 +
52.1744 + /**
52.1745 + * Implements uninterruptible condition wait.
52.1746 + * <ol>
52.1747 + * <li> Save lock state returned by {@link #getState}.
52.1748 + * <li> Invoke {@link #release} with
52.1749 + * saved state as argument, throwing
52.1750 + * IllegalMonitorStateException if it fails.
52.1751 + * <li> Block until signalled.
52.1752 + * <li> Reacquire by invoking specialized version of
52.1753 + * {@link #acquire} with saved state as argument.
52.1754 + * </ol>
52.1755 + */
52.1756 + public final void awaitUninterruptibly() {
52.1757 + Node node = addConditionWaiter();
52.1758 + long savedState = fullyRelease(node);
52.1759 + boolean interrupted = false;
52.1760 + while (!isOnSyncQueue(node)) {
52.1761 + LockSupport.park(this);
52.1762 + if (Thread.interrupted())
52.1763 + interrupted = true;
52.1764 + }
52.1765 + if (acquireQueued(node, savedState) || interrupted)
52.1766 + selfInterrupt();
52.1767 + }
52.1768 +
52.1769 + /*
52.1770 + * For interruptible waits, we need to track whether to throw
52.1771 + * InterruptedException, if interrupted while blocked on
52.1772 + * condition, versus reinterrupt current thread, if
52.1773 + * interrupted while blocked waiting to re-acquire.
52.1774 + */
52.1775 +
52.1776 + /** Mode meaning to reinterrupt on exit from wait */
52.1777 + private static final int REINTERRUPT = 1;
52.1778 + /** Mode meaning to throw InterruptedException on exit from wait */
52.1779 + private static final int THROW_IE = -1;
52.1780 +
52.1781 + /**
52.1782 + * Checks for interrupt, returning THROW_IE if interrupted
52.1783 + * before signalled, REINTERRUPT if after signalled, or
52.1784 + * 0 if not interrupted.
52.1785 + */
52.1786 + private int checkInterruptWhileWaiting(Node node) {
52.1787 + return Thread.interrupted() ?
52.1788 + (transferAfterCancelledWait(node) ? THROW_IE : REINTERRUPT) :
52.1789 + 0;
52.1790 + }
52.1791 +
52.1792 + /**
52.1793 + * Throws InterruptedException, reinterrupts current thread, or
52.1794 + * does nothing, depending on mode.
52.1795 + */
52.1796 + private void reportInterruptAfterWait(int interruptMode)
52.1797 + throws InterruptedException {
52.1798 + if (interruptMode == THROW_IE)
52.1799 + throw new InterruptedException();
52.1800 + else if (interruptMode == REINTERRUPT)
52.1801 + selfInterrupt();
52.1802 + }
52.1803 +
52.1804 + /**
52.1805 + * Implements interruptible condition wait.
52.1806 + * <ol>
52.1807 + * <li> If current thread is interrupted, throw InterruptedException.
52.1808 + * <li> Save lock state returned by {@link #getState}.
52.1809 + * <li> Invoke {@link #release} with
52.1810 + * saved state as argument, throwing
52.1811 + * IllegalMonitorStateException if it fails.
52.1812 + * <li> Block until signalled or interrupted.
52.1813 + * <li> Reacquire by invoking specialized version of
52.1814 + * {@link #acquire} with saved state as argument.
52.1815 + * <li> If interrupted while blocked in step 4, throw InterruptedException.
52.1816 + * </ol>
52.1817 + */
52.1818 + public final void await() throws InterruptedException {
52.1819 + if (Thread.interrupted())
52.1820 + throw new InterruptedException();
52.1821 + Node node = addConditionWaiter();
52.1822 + long savedState = fullyRelease(node);
52.1823 + int interruptMode = 0;
52.1824 + while (!isOnSyncQueue(node)) {
52.1825 + LockSupport.park(this);
52.1826 + if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
52.1827 + break;
52.1828 + }
52.1829 + if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
52.1830 + interruptMode = REINTERRUPT;
52.1831 + if (node.nextWaiter != null) // clean up if cancelled
52.1832 + unlinkCancelledWaiters();
52.1833 + if (interruptMode != 0)
52.1834 + reportInterruptAfterWait(interruptMode);
52.1835 + }
52.1836 +
52.1837 + /**
52.1838 + * Implements timed condition wait.
52.1839 + * <ol>
52.1840 + * <li> If current thread is interrupted, throw InterruptedException.
52.1841 + * <li> Save lock state returned by {@link #getState}.
52.1842 + * <li> Invoke {@link #release} with
52.1843 + * saved state as argument, throwing
52.1844 + * IllegalMonitorStateException if it fails.
52.1845 + * <li> Block until signalled, interrupted, or timed out.
52.1846 + * <li> Reacquire by invoking specialized version of
52.1847 + * {@link #acquire} with saved state as argument.
52.1848 + * <li> If interrupted while blocked in step 4, throw InterruptedException.
52.1849 + * </ol>
52.1850 + */
52.1851 + public final long awaitNanos(long nanosTimeout)
52.1852 + throws InterruptedException {
52.1853 + if (Thread.interrupted())
52.1854 + throw new InterruptedException();
52.1855 + Node node = addConditionWaiter();
52.1856 + long savedState = fullyRelease(node);
52.1857 + long lastTime = System.nanoTime();
52.1858 + int interruptMode = 0;
52.1859 + while (!isOnSyncQueue(node)) {
52.1860 + if (nanosTimeout <= 0L) {
52.1861 + transferAfterCancelledWait(node);
52.1862 + break;
52.1863 + }
52.1864 + LockSupport.parkNanos(this, nanosTimeout);
52.1865 + if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
52.1866 + break;
52.1867 +
52.1868 + long now = System.nanoTime();
52.1869 + nanosTimeout -= now - lastTime;
52.1870 + lastTime = now;
52.1871 + }
52.1872 + if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
52.1873 + interruptMode = REINTERRUPT;
52.1874 + if (node.nextWaiter != null)
52.1875 + unlinkCancelledWaiters();
52.1876 + if (interruptMode != 0)
52.1877 + reportInterruptAfterWait(interruptMode);
52.1878 + return nanosTimeout - (System.nanoTime() - lastTime);
52.1879 + }
52.1880 +
52.1881 + /**
52.1882 + * Implements absolute timed condition wait.
52.1883 + * <ol>
52.1884 + * <li> If current thread is interrupted, throw InterruptedException.
52.1885 + * <li> Save lock state returned by {@link #getState}.
52.1886 + * <li> Invoke {@link #release} with
52.1887 + * saved state as argument, throwing
52.1888 + * IllegalMonitorStateException if it fails.
52.1889 + * <li> Block until signalled, interrupted, or timed out.
52.1890 + * <li> Reacquire by invoking specialized version of
52.1891 + * {@link #acquire} with saved state as argument.
52.1892 + * <li> If interrupted while blocked in step 4, throw InterruptedException.
52.1893 + * <li> If timed out while blocked in step 4, return false, else true.
52.1894 + * </ol>
52.1895 + */
52.1896 + public final boolean awaitUntil(Date deadline)
52.1897 + throws InterruptedException {
52.1898 + if (deadline == null)
52.1899 + throw new NullPointerException();
52.1900 + long abstime = deadline.getTime();
52.1901 + if (Thread.interrupted())
52.1902 + throw new InterruptedException();
52.1903 + Node node = addConditionWaiter();
52.1904 + long savedState = fullyRelease(node);
52.1905 + boolean timedout = false;
52.1906 + int interruptMode = 0;
52.1907 + while (!isOnSyncQueue(node)) {
52.1908 + if (System.currentTimeMillis() > abstime) {
52.1909 + timedout = transferAfterCancelledWait(node);
52.1910 + break;
52.1911 + }
52.1912 + LockSupport.parkUntil(this, abstime);
52.1913 + if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
52.1914 + break;
52.1915 + }
52.1916 + if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
52.1917 + interruptMode = REINTERRUPT;
52.1918 + if (node.nextWaiter != null)
52.1919 + unlinkCancelledWaiters();
52.1920 + if (interruptMode != 0)
52.1921 + reportInterruptAfterWait(interruptMode);
52.1922 + return !timedout;
52.1923 + }
52.1924 +
52.1925 + /**
52.1926 + * Implements timed condition wait.
52.1927 + * <ol>
52.1928 + * <li> If current thread is interrupted, throw InterruptedException.
52.1929 + * <li> Save lock state returned by {@link #getState}.
52.1930 + * <li> Invoke {@link #release} with
52.1931 + * saved state as argument, throwing
52.1932 + * IllegalMonitorStateException if it fails.
52.1933 + * <li> Block until signalled, interrupted, or timed out.
52.1934 + * <li> Reacquire by invoking specialized version of
52.1935 + * {@link #acquire} with saved state as argument.
52.1936 + * <li> If interrupted while blocked in step 4, throw InterruptedException.
52.1937 + * <li> If timed out while blocked in step 4, return false, else true.
52.1938 + * </ol>
52.1939 + */
52.1940 + public final boolean await(long time, TimeUnit unit)
52.1941 + throws InterruptedException {
52.1942 + if (unit == null)
52.1943 + throw new NullPointerException();
52.1944 + long nanosTimeout = unit.toNanos(time);
52.1945 + if (Thread.interrupted())
52.1946 + throw new InterruptedException();
52.1947 + Node node = addConditionWaiter();
52.1948 + long savedState = fullyRelease(node);
52.1949 + long lastTime = System.nanoTime();
52.1950 + boolean timedout = false;
52.1951 + int interruptMode = 0;
52.1952 + while (!isOnSyncQueue(node)) {
52.1953 + if (nanosTimeout <= 0L) {
52.1954 + timedout = transferAfterCancelledWait(node);
52.1955 + break;
52.1956 + }
52.1957 + if (nanosTimeout >= spinForTimeoutThreshold)
52.1958 + LockSupport.parkNanos(this, nanosTimeout);
52.1959 + if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
52.1960 + break;
52.1961 + long now = System.nanoTime();
52.1962 + nanosTimeout -= now - lastTime;
52.1963 + lastTime = now;
52.1964 + }
52.1965 + if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
52.1966 + interruptMode = REINTERRUPT;
52.1967 + if (node.nextWaiter != null)
52.1968 + unlinkCancelledWaiters();
52.1969 + if (interruptMode != 0)
52.1970 + reportInterruptAfterWait(interruptMode);
52.1971 + return !timedout;
52.1972 + }
52.1973 +
52.1974 + // support for instrumentation
52.1975 +
52.1976 + /**
52.1977 + * Returns true if this condition was created by the given
52.1978 + * synchronization object.
52.1979 + *
52.1980 + * @return {@code true} if owned
52.1981 + */
52.1982 + final boolean isOwnedBy(AbstractQueuedLongSynchronizer sync) {
52.1983 + return sync == AbstractQueuedLongSynchronizer.this;
52.1984 + }
52.1985 +
52.1986 + /**
52.1987 + * Queries whether any threads are waiting on this condition.
52.1988 + * Implements {@link AbstractQueuedLongSynchronizer#hasWaiters}.
52.1989 + *
52.1990 + * @return {@code true} if there are any waiting threads
52.1991 + * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
52.1992 + * returns {@code false}
52.1993 + */
52.1994 + protected final boolean hasWaiters() {
52.1995 + if (!isHeldExclusively())
52.1996 + throw new IllegalMonitorStateException();
52.1997 + for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
52.1998 + if (w.waitStatus == Node.CONDITION)
52.1999 + return true;
52.2000 + }
52.2001 + return false;
52.2002 + }
52.2003 +
52.2004 + /**
52.2005 + * Returns an estimate of the number of threads waiting on
52.2006 + * this condition.
52.2007 + * Implements {@link AbstractQueuedLongSynchronizer#getWaitQueueLength}.
52.2008 + *
52.2009 + * @return the estimated number of waiting threads
52.2010 + * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
52.2011 + * returns {@code false}
52.2012 + */
52.2013 + protected final int getWaitQueueLength() {
52.2014 + if (!isHeldExclusively())
52.2015 + throw new IllegalMonitorStateException();
52.2016 + int n = 0;
52.2017 + for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
52.2018 + if (w.waitStatus == Node.CONDITION)
52.2019 + ++n;
52.2020 + }
52.2021 + return n;
52.2022 + }
52.2023 +
52.2024 + /**
52.2025 + * Returns a collection containing those threads that may be
52.2026 + * waiting on this Condition.
52.2027 + * Implements {@link AbstractQueuedLongSynchronizer#getWaitingThreads}.
52.2028 + *
52.2029 + * @return the collection of threads
52.2030 + * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
52.2031 + * returns {@code false}
52.2032 + */
52.2033 + protected final Collection<Thread> getWaitingThreads() {
52.2034 + if (!isHeldExclusively())
52.2035 + throw new IllegalMonitorStateException();
52.2036 + ArrayList<Thread> list = new ArrayList<Thread>();
52.2037 + for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
52.2038 + if (w.waitStatus == Node.CONDITION) {
52.2039 + Thread t = w.thread;
52.2040 + if (t != null)
52.2041 + list.add(t);
52.2042 + }
52.2043 + }
52.2044 + return list;
52.2045 + }
52.2046 + }
52.2047 +
52.2048 + /**
52.2049 + * Setup to support compareAndSet. We need to natively implement
52.2050 + * this here: For the sake of permitting future enhancements, we
52.2051 + * cannot explicitly subclass AtomicLong, which would be
52.2052 + * efficient and useful otherwise. So, as the lesser of evils, we
52.2053 + * natively implement using hotspot intrinsics API. And while we
52.2054 + * are at it, we do the same for other CASable fields (which could
52.2055 + * otherwise be done with atomic field updaters).
52.2056 + */
52.2057 + private static final Unsafe unsafe = Unsafe.getUnsafe();
52.2058 + private static final long stateOffset;
52.2059 + private static final long headOffset;
52.2060 + private static final long tailOffset;
52.2061 + private static final long waitStatusOffset;
52.2062 + private static final long nextOffset;
52.2063 +
52.2064 + static {
52.2065 + try {
52.2066 + stateOffset = unsafe.objectFieldOffset
52.2067 + (AbstractQueuedLongSynchronizer.class.getDeclaredField("state"));
52.2068 + headOffset = unsafe.objectFieldOffset
52.2069 + (AbstractQueuedLongSynchronizer.class.getDeclaredField("head"));
52.2070 + tailOffset = unsafe.objectFieldOffset
52.2071 + (AbstractQueuedLongSynchronizer.class.getDeclaredField("tail"));
52.2072 + waitStatusOffset = unsafe.objectFieldOffset
52.2073 + (Node.class.getDeclaredField("waitStatus"));
52.2074 + nextOffset = unsafe.objectFieldOffset
52.2075 + (Node.class.getDeclaredField("next"));
52.2076 +
52.2077 + } catch (Exception ex) { throw new Error(ex); }
52.2078 + }
52.2079 +
52.2080 + /**
52.2081 + * CAS head field. Used only by enq.
52.2082 + */
52.2083 + private final boolean compareAndSetHead(Node update) {
52.2084 + return unsafe.compareAndSwapObject(this, headOffset, null, update);
52.2085 + }
52.2086 +
52.2087 + /**
52.2088 + * CAS tail field. Used only by enq.
52.2089 + */
52.2090 + private final boolean compareAndSetTail(Node expect, Node update) {
52.2091 + return unsafe.compareAndSwapObject(this, tailOffset, expect, update);
52.2092 + }
52.2093 +
52.2094 + /**
52.2095 + * CAS waitStatus field of a node.
52.2096 + */
52.2097 + private static final boolean compareAndSetWaitStatus(Node node,
52.2098 + int expect,
52.2099 + int update) {
52.2100 + return unsafe.compareAndSwapInt(node, waitStatusOffset,
52.2101 + expect, update);
52.2102 + }
52.2103 +
52.2104 + /**
52.2105 + * CAS next field of a node.
52.2106 + */
52.2107 + private static final boolean compareAndSetNext(Node node,
52.2108 + Node expect,
52.2109 + Node update) {
52.2110 + return unsafe.compareAndSwapObject(node, nextOffset, expect, update);
52.2111 + }
52.2112 +}
53.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
53.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java Sat Mar 19 10:48:29 2016 +0100
53.3 @@ -0,0 +1,2330 @@
53.4 +/*
53.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
53.6 + *
53.7 + * This code is free software; you can redistribute it and/or modify it
53.8 + * under the terms of the GNU General Public License version 2 only, as
53.9 + * published by the Free Software Foundation. Oracle designates this
53.10 + * particular file as subject to the "Classpath" exception as provided
53.11 + * by Oracle in the LICENSE file that accompanied this code.
53.12 + *
53.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
53.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
53.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
53.16 + * version 2 for more details (a copy is included in the LICENSE file that
53.17 + * accompanied this code).
53.18 + *
53.19 + * You should have received a copy of the GNU General Public License version
53.20 + * 2 along with this work; if not, write to the Free Software Foundation,
53.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
53.22 + *
53.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
53.24 + * or visit www.oracle.com if you need additional information or have any
53.25 + * questions.
53.26 + */
53.27 +
53.28 +/*
53.29 + * This file is available under and governed by the GNU General Public
53.30 + * License version 2 only, as published by the Free Software Foundation.
53.31 + * However, the following notice accompanied the original version of this
53.32 + * file:
53.33 + *
53.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
53.35 + * Expert Group and released to the public domain, as explained at
53.36 + * http://creativecommons.org/publicdomain/zero/1.0/
53.37 + */
53.38 +
53.39 +package java.util.concurrent.locks;
53.40 +import java.util.*;
53.41 +import java.util.concurrent.*;
53.42 +import java.util.concurrent.atomic.*;
53.43 +import sun.misc.Unsafe;
53.44 +
53.45 +/**
53.46 + * Provides a framework for implementing blocking locks and related
53.47 + * synchronizers (semaphores, events, etc) that rely on
53.48 + * first-in-first-out (FIFO) wait queues. This class is designed to
53.49 + * be a useful basis for most kinds of synchronizers that rely on a
53.50 + * single atomic <tt>int</tt> value to represent state. Subclasses
53.51 + * must define the protected methods that change this state, and which
53.52 + * define what that state means in terms of this object being acquired
53.53 + * or released. Given these, the other methods in this class carry
53.54 + * out all queuing and blocking mechanics. Subclasses can maintain
53.55 + * other state fields, but only the atomically updated <tt>int</tt>
53.56 + * value manipulated using methods {@link #getState}, {@link
53.57 + * #setState} and {@link #compareAndSetState} is tracked with respect
53.58 + * to synchronization.
53.59 + *
53.60 + * <p>Subclasses should be defined as non-public internal helper
53.61 + * classes that are used to implement the synchronization properties
53.62 + * of their enclosing class. Class
53.63 + * <tt>AbstractQueuedSynchronizer</tt> does not implement any
53.64 + * synchronization interface. Instead it defines methods such as
53.65 + * {@link #acquireInterruptibly} that can be invoked as
53.66 + * appropriate by concrete locks and related synchronizers to
53.67 + * implement their public methods.
53.68 + *
53.69 + * <p>This class supports either or both a default <em>exclusive</em>
53.70 + * mode and a <em>shared</em> mode. When acquired in exclusive mode,
53.71 + * attempted acquires by other threads cannot succeed. Shared mode
53.72 + * acquires by multiple threads may (but need not) succeed. This class
53.73 + * does not "understand" these differences except in the
53.74 + * mechanical sense that when a shared mode acquire succeeds, the next
53.75 + * waiting thread (if one exists) must also determine whether it can
53.76 + * acquire as well. Threads waiting in the different modes share the
53.77 + * same FIFO queue. Usually, implementation subclasses support only
53.78 + * one of these modes, but both can come into play for example in a
53.79 + * {@link ReadWriteLock}. Subclasses that support only exclusive or
53.80 + * only shared modes need not define the methods supporting the unused mode.
53.81 + *
53.82 + * <p>This class defines a nested {@link ConditionObject} class that
53.83 + * can be used as a {@link Condition} implementation by subclasses
53.84 + * supporting exclusive mode for which method {@link
53.85 + * #isHeldExclusively} reports whether synchronization is exclusively
53.86 + * held with respect to the current thread, method {@link #release}
53.87 + * invoked with the current {@link #getState} value fully releases
53.88 + * this object, and {@link #acquire}, given this saved state value,
53.89 + * eventually restores this object to its previous acquired state. No
53.90 + * <tt>AbstractQueuedSynchronizer</tt> method otherwise creates such a
53.91 + * condition, so if this constraint cannot be met, do not use it. The
53.92 + * behavior of {@link ConditionObject} depends of course on the
53.93 + * semantics of its synchronizer implementation.
53.94 + *
53.95 + * <p>This class provides inspection, instrumentation, and monitoring
53.96 + * methods for the internal queue, as well as similar methods for
53.97 + * condition objects. These can be exported as desired into classes
53.98 + * using an <tt>AbstractQueuedSynchronizer</tt> for their
53.99 + * synchronization mechanics.
53.100 + *
53.101 + * <p>Serialization of this class stores only the underlying atomic
53.102 + * integer maintaining state, so deserialized objects have empty
53.103 + * thread queues. Typical subclasses requiring serializability will
53.104 + * define a <tt>readObject</tt> method that restores this to a known
53.105 + * initial state upon deserialization.
53.106 + *
53.107 + * <h3>Usage</h3>
53.108 + *
53.109 + * <p>To use this class as the basis of a synchronizer, redefine the
53.110 + * following methods, as applicable, by inspecting and/or modifying
53.111 + * the synchronization state using {@link #getState}, {@link
53.112 + * #setState} and/or {@link #compareAndSetState}:
53.113 + *
53.114 + * <ul>
53.115 + * <li> {@link #tryAcquire}
53.116 + * <li> {@link #tryRelease}
53.117 + * <li> {@link #tryAcquireShared}
53.118 + * <li> {@link #tryReleaseShared}
53.119 + * <li> {@link #isHeldExclusively}
53.120 + *</ul>
53.121 + *
53.122 + * Each of these methods by default throws {@link
53.123 + * UnsupportedOperationException}. Implementations of these methods
53.124 + * must be internally thread-safe, and should in general be short and
53.125 + * not block. Defining these methods is the <em>only</em> supported
53.126 + * means of using this class. All other methods are declared
53.127 + * <tt>final</tt> because they cannot be independently varied.
53.128 + *
53.129 + * <p>You may also find the inherited methods from {@link
53.130 + * AbstractOwnableSynchronizer} useful to keep track of the thread
53.131 + * owning an exclusive synchronizer. You are encouraged to use them
53.132 + * -- this enables monitoring and diagnostic tools to assist users in
53.133 + * determining which threads hold locks.
53.134 + *
53.135 + * <p>Even though this class is based on an internal FIFO queue, it
53.136 + * does not automatically enforce FIFO acquisition policies. The core
53.137 + * of exclusive synchronization takes the form:
53.138 + *
53.139 + * <pre>
53.140 + * Acquire:
53.141 + * while (!tryAcquire(arg)) {
53.142 + * <em>enqueue thread if it is not already queued</em>;
53.143 + * <em>possibly block current thread</em>;
53.144 + * }
53.145 + *
53.146 + * Release:
53.147 + * if (tryRelease(arg))
53.148 + * <em>unblock the first queued thread</em>;
53.149 + * </pre>
53.150 + *
53.151 + * (Shared mode is similar but may involve cascading signals.)
53.152 + *
53.153 + * <p><a name="barging">Because checks in acquire are invoked before
53.154 + * enqueuing, a newly acquiring thread may <em>barge</em> ahead of
53.155 + * others that are blocked and queued. However, you can, if desired,
53.156 + * define <tt>tryAcquire</tt> and/or <tt>tryAcquireShared</tt> to
53.157 + * disable barging by internally invoking one or more of the inspection
53.158 + * methods, thereby providing a <em>fair</em> FIFO acquisition order.
53.159 + * In particular, most fair synchronizers can define <tt>tryAcquire</tt>
53.160 + * to return <tt>false</tt> if {@link #hasQueuedPredecessors} (a method
53.161 + * specifically designed to be used by fair synchronizers) returns
53.162 + * <tt>true</tt>. Other variations are possible.
53.163 + *
53.164 + * <p>Throughput and scalability are generally highest for the
53.165 + * default barging (also known as <em>greedy</em>,
53.166 + * <em>renouncement</em>, and <em>convoy-avoidance</em>) strategy.
53.167 + * While this is not guaranteed to be fair or starvation-free, earlier
53.168 + * queued threads are allowed to recontend before later queued
53.169 + * threads, and each recontention has an unbiased chance to succeed
53.170 + * against incoming threads. Also, while acquires do not
53.171 + * "spin" in the usual sense, they may perform multiple
53.172 + * invocations of <tt>tryAcquire</tt> interspersed with other
53.173 + * computations before blocking. This gives most of the benefits of
53.174 + * spins when exclusive synchronization is only briefly held, without
53.175 + * most of the liabilities when it isn't. If so desired, you can
53.176 + * augment this by preceding calls to acquire methods with
53.177 + * "fast-path" checks, possibly prechecking {@link #hasContended}
53.178 + * and/or {@link #hasQueuedThreads} to only do so if the synchronizer
53.179 + * is likely not to be contended.
53.180 + *
53.181 + * <p>This class provides an efficient and scalable basis for
53.182 + * synchronization in part by specializing its range of use to
53.183 + * synchronizers that can rely on <tt>int</tt> state, acquire, and
53.184 + * release parameters, and an internal FIFO wait queue. When this does
53.185 + * not suffice, you can build synchronizers from a lower level using
53.186 + * {@link java.util.concurrent.atomic atomic} classes, your own custom
53.187 + * {@link java.util.Queue} classes, and {@link LockSupport} blocking
53.188 + * support.
53.189 + *
53.190 + * <h3>Usage Examples</h3>
53.191 + *
53.192 + * <p>Here is a non-reentrant mutual exclusion lock class that uses
53.193 + * the value zero to represent the unlocked state, and one to
53.194 + * represent the locked state. While a non-reentrant lock
53.195 + * does not strictly require recording of the current owner
53.196 + * thread, this class does so anyway to make usage easier to monitor.
53.197 + * It also supports conditions and exposes
53.198 + * one of the instrumentation methods:
53.199 + *
53.200 + * <pre>
53.201 + * class Mutex implements Lock, java.io.Serializable {
53.202 + *
53.203 + * // Our internal helper class
53.204 + * private static class Sync extends AbstractQueuedSynchronizer {
53.205 + * // Report whether in locked state
53.206 + * protected boolean isHeldExclusively() {
53.207 + * return getState() == 1;
53.208 + * }
53.209 + *
53.210 + * // Acquire the lock if state is zero
53.211 + * public boolean tryAcquire(int acquires) {
53.212 + * assert acquires == 1; // Otherwise unused
53.213 + * if (compareAndSetState(0, 1)) {
53.214 + * setExclusiveOwnerThread(Thread.currentThread());
53.215 + * return true;
53.216 + * }
53.217 + * return false;
53.218 + * }
53.219 + *
53.220 + * // Release the lock by setting state to zero
53.221 + * protected boolean tryRelease(int releases) {
53.222 + * assert releases == 1; // Otherwise unused
53.223 + * if (getState() == 0) throw new IllegalMonitorStateException();
53.224 + * setExclusiveOwnerThread(null);
53.225 + * setState(0);
53.226 + * return true;
53.227 + * }
53.228 + *
53.229 + * // Provide a Condition
53.230 + * Condition newCondition() { return new ConditionObject(); }
53.231 + *
53.232 + * // Deserialize properly
53.233 + * private void readObject(ObjectInputStream s)
53.234 + * throws IOException, ClassNotFoundException {
53.235 + * s.defaultReadObject();
53.236 + * setState(0); // reset to unlocked state
53.237 + * }
53.238 + * }
53.239 + *
53.240 + * // The sync object does all the hard work. We just forward to it.
53.241 + * private final Sync sync = new Sync();
53.242 + *
53.243 + * public void lock() { sync.acquire(1); }
53.244 + * public boolean tryLock() { return sync.tryAcquire(1); }
53.245 + * public void unlock() { sync.release(1); }
53.246 + * public Condition newCondition() { return sync.newCondition(); }
53.247 + * public boolean isLocked() { return sync.isHeldExclusively(); }
53.248 + * public boolean hasQueuedThreads() { return sync.hasQueuedThreads(); }
53.249 + * public void lockInterruptibly() throws InterruptedException {
53.250 + * sync.acquireInterruptibly(1);
53.251 + * }
53.252 + * public boolean tryLock(long timeout, TimeUnit unit)
53.253 + * throws InterruptedException {
53.254 + * return sync.tryAcquireNanos(1, unit.toNanos(timeout));
53.255 + * }
53.256 + * }
53.257 + * </pre>
53.258 + *
53.259 + * <p>Here is a latch class that is like a {@link CountDownLatch}
53.260 + * except that it only requires a single <tt>signal</tt> to
53.261 + * fire. Because a latch is non-exclusive, it uses the <tt>shared</tt>
53.262 + * acquire and release methods.
53.263 + *
53.264 + * <pre>
53.265 + * class BooleanLatch {
53.266 + *
53.267 + * private static class Sync extends AbstractQueuedSynchronizer {
53.268 + * boolean isSignalled() { return getState() != 0; }
53.269 + *
53.270 + * protected int tryAcquireShared(int ignore) {
53.271 + * return isSignalled() ? 1 : -1;
53.272 + * }
53.273 + *
53.274 + * protected boolean tryReleaseShared(int ignore) {
53.275 + * setState(1);
53.276 + * return true;
53.277 + * }
53.278 + * }
53.279 + *
53.280 + * private final Sync sync = new Sync();
53.281 + * public boolean isSignalled() { return sync.isSignalled(); }
53.282 + * public void signal() { sync.releaseShared(1); }
53.283 + * public void await() throws InterruptedException {
53.284 + * sync.acquireSharedInterruptibly(1);
53.285 + * }
53.286 + * }
53.287 + * </pre>
53.288 + *
53.289 + * @since 1.5
53.290 + * @author Doug Lea
53.291 + */
53.292 +public abstract class AbstractQueuedSynchronizer
53.293 + extends AbstractOwnableSynchronizer
53.294 + implements java.io.Serializable {
53.295 +
53.296 + private static final long serialVersionUID = 7373984972572414691L;
53.297 +
53.298 + /**
53.299 + * Creates a new <tt>AbstractQueuedSynchronizer</tt> instance
53.300 + * with initial synchronization state of zero.
53.301 + */
53.302 + protected AbstractQueuedSynchronizer() { }
53.303 +
53.304 + /**
53.305 + * Wait queue node class.
53.306 + *
53.307 + * <p>The wait queue is a variant of a "CLH" (Craig, Landin, and
53.308 + * Hagersten) lock queue. CLH locks are normally used for
53.309 + * spinlocks. We instead use them for blocking synchronizers, but
53.310 + * use the same basic tactic of holding some of the control
53.311 + * information about a thread in the predecessor of its node. A
53.312 + * "status" field in each node keeps track of whether a thread
53.313 + * should block. A node is signalled when its predecessor
53.314 + * releases. Each node of the queue otherwise serves as a
53.315 + * specific-notification-style monitor holding a single waiting
53.316 + * thread. The status field does NOT control whether threads are
53.317 + * granted locks etc though. A thread may try to acquire if it is
53.318 + * first in the queue. But being first does not guarantee success;
53.319 + * it only gives the right to contend. So the currently released
53.320 + * contender thread may need to rewait.
53.321 + *
53.322 + * <p>To enqueue into a CLH lock, you atomically splice it in as new
53.323 + * tail. To dequeue, you just set the head field.
53.324 + * <pre>
53.325 + * +------+ prev +-----+ +-----+
53.326 + * head | | <---- | | <---- | | tail
53.327 + * +------+ +-----+ +-----+
53.328 + * </pre>
53.329 + *
53.330 + * <p>Insertion into a CLH queue requires only a single atomic
53.331 + * operation on "tail", so there is a simple atomic point of
53.332 + * demarcation from unqueued to queued. Similarly, dequeing
53.333 + * involves only updating the "head". However, it takes a bit
53.334 + * more work for nodes to determine who their successors are,
53.335 + * in part to deal with possible cancellation due to timeouts
53.336 + * and interrupts.
53.337 + *
53.338 + * <p>The "prev" links (not used in original CLH locks), are mainly
53.339 + * needed to handle cancellation. If a node is cancelled, its
53.340 + * successor is (normally) relinked to a non-cancelled
53.341 + * predecessor. For explanation of similar mechanics in the case
53.342 + * of spin locks, see the papers by Scott and Scherer at
53.343 + * http://www.cs.rochester.edu/u/scott/synchronization/
53.344 + *
53.345 + * <p>We also use "next" links to implement blocking mechanics.
53.346 + * The thread id for each node is kept in its own node, so a
53.347 + * predecessor signals the next node to wake up by traversing
53.348 + * next link to determine which thread it is. Determination of
53.349 + * successor must avoid races with newly queued nodes to set
53.350 + * the "next" fields of their predecessors. This is solved
53.351 + * when necessary by checking backwards from the atomically
53.352 + * updated "tail" when a node's successor appears to be null.
53.353 + * (Or, said differently, the next-links are an optimization
53.354 + * so that we don't usually need a backward scan.)
53.355 + *
53.356 + * <p>Cancellation introduces some conservatism to the basic
53.357 + * algorithms. Since we must poll for cancellation of other
53.358 + * nodes, we can miss noticing whether a cancelled node is
53.359 + * ahead or behind us. This is dealt with by always unparking
53.360 + * successors upon cancellation, allowing them to stabilize on
53.361 + * a new predecessor, unless we can identify an uncancelled
53.362 + * predecessor who will carry this responsibility.
53.363 + *
53.364 + * <p>CLH queues need a dummy header node to get started. But
53.365 + * we don't create them on construction, because it would be wasted
53.366 + * effort if there is never contention. Instead, the node
53.367 + * is constructed and head and tail pointers are set upon first
53.368 + * contention.
53.369 + *
53.370 + * <p>Threads waiting on Conditions use the same nodes, but
53.371 + * use an additional link. Conditions only need to link nodes
53.372 + * in simple (non-concurrent) linked queues because they are
53.373 + * only accessed when exclusively held. Upon await, a node is
53.374 + * inserted into a condition queue. Upon signal, the node is
53.375 + * transferred to the main queue. A special value of status
53.376 + * field is used to mark which queue a node is on.
53.377 + *
53.378 + * <p>Thanks go to Dave Dice, Mark Moir, Victor Luchangco, Bill
53.379 + * Scherer and Michael Scott, along with members of JSR-166
53.380 + * expert group, for helpful ideas, discussions, and critiques
53.381 + * on the design of this class.
53.382 + */
53.383 + static final class Node {
53.384 + /** Marker to indicate a node is waiting in shared mode */
53.385 + static final Node SHARED = new Node();
53.386 + /** Marker to indicate a node is waiting in exclusive mode */
53.387 + static final Node EXCLUSIVE = null;
53.388 +
53.389 + /** waitStatus value to indicate thread has cancelled */
53.390 + static final int CANCELLED = 1;
53.391 + /** waitStatus value to indicate successor's thread needs unparking */
53.392 + static final int SIGNAL = -1;
53.393 + /** waitStatus value to indicate thread is waiting on condition */
53.394 + static final int CONDITION = -2;
53.395 + /**
53.396 + * waitStatus value to indicate the next acquireShared should
53.397 + * unconditionally propagate
53.398 + */
53.399 + static final int PROPAGATE = -3;
53.400 +
53.401 + /**
53.402 + * Status field, taking on only the values:
53.403 + * SIGNAL: The successor of this node is (or will soon be)
53.404 + * blocked (via park), so the current node must
53.405 + * unpark its successor when it releases or
53.406 + * cancels. To avoid races, acquire methods must
53.407 + * first indicate they need a signal,
53.408 + * then retry the atomic acquire, and then,
53.409 + * on failure, block.
53.410 + * CANCELLED: This node is cancelled due to timeout or interrupt.
53.411 + * Nodes never leave this state. In particular,
53.412 + * a thread with cancelled node never again blocks.
53.413 + * CONDITION: This node is currently on a condition queue.
53.414 + * It will not be used as a sync queue node
53.415 + * until transferred, at which time the status
53.416 + * will be set to 0. (Use of this value here has
53.417 + * nothing to do with the other uses of the
53.418 + * field, but simplifies mechanics.)
53.419 + * PROPAGATE: A releaseShared should be propagated to other
53.420 + * nodes. This is set (for head node only) in
53.421 + * doReleaseShared to ensure propagation
53.422 + * continues, even if other operations have
53.423 + * since intervened.
53.424 + * 0: None of the above
53.425 + *
53.426 + * The values are arranged numerically to simplify use.
53.427 + * Non-negative values mean that a node doesn't need to
53.428 + * signal. So, most code doesn't need to check for particular
53.429 + * values, just for sign.
53.430 + *
53.431 + * The field is initialized to 0 for normal sync nodes, and
53.432 + * CONDITION for condition nodes. It is modified using CAS
53.433 + * (or when possible, unconditional volatile writes).
53.434 + */
53.435 + volatile int waitStatus;
53.436 +
53.437 + /**
53.438 + * Link to predecessor node that current node/thread relies on
53.439 + * for checking waitStatus. Assigned during enqueing, and nulled
53.440 + * out (for sake of GC) only upon dequeuing. Also, upon
53.441 + * cancellation of a predecessor, we short-circuit while
53.442 + * finding a non-cancelled one, which will always exist
53.443 + * because the head node is never cancelled: A node becomes
53.444 + * head only as a result of successful acquire. A
53.445 + * cancelled thread never succeeds in acquiring, and a thread only
53.446 + * cancels itself, not any other node.
53.447 + */
53.448 + volatile Node prev;
53.449 +
53.450 + /**
53.451 + * Link to the successor node that the current node/thread
53.452 + * unparks upon release. Assigned during enqueuing, adjusted
53.453 + * when bypassing cancelled predecessors, and nulled out (for
53.454 + * sake of GC) when dequeued. The enq operation does not
53.455 + * assign next field of a predecessor until after attachment,
53.456 + * so seeing a null next field does not necessarily mean that
53.457 + * node is at end of queue. However, if a next field appears
53.458 + * to be null, we can scan prev's from the tail to
53.459 + * double-check. The next field of cancelled nodes is set to
53.460 + * point to the node itself instead of null, to make life
53.461 + * easier for isOnSyncQueue.
53.462 + */
53.463 + volatile Node next;
53.464 +
53.465 + /**
53.466 + * The thread that enqueued this node. Initialized on
53.467 + * construction and nulled out after use.
53.468 + */
53.469 + volatile Thread thread;
53.470 +
53.471 + /**
53.472 + * Link to next node waiting on condition, or the special
53.473 + * value SHARED. Because condition queues are accessed only
53.474 + * when holding in exclusive mode, we just need a simple
53.475 + * linked queue to hold nodes while they are waiting on
53.476 + * conditions. They are then transferred to the queue to
53.477 + * re-acquire. And because conditions can only be exclusive,
53.478 + * we save a field by using special value to indicate shared
53.479 + * mode.
53.480 + */
53.481 + Node nextWaiter;
53.482 +
53.483 + /**
53.484 + * Returns true if node is waiting in shared mode
53.485 + */
53.486 + final boolean isShared() {
53.487 + return nextWaiter == SHARED;
53.488 + }
53.489 +
53.490 + /**
53.491 + * Returns previous node, or throws NullPointerException if null.
53.492 + * Use when predecessor cannot be null. The null check could
53.493 + * be elided, but is present to help the VM.
53.494 + *
53.495 + * @return the predecessor of this node
53.496 + */
53.497 + final Node predecessor() throws NullPointerException {
53.498 + Node p = prev;
53.499 + if (p == null)
53.500 + throw new NullPointerException();
53.501 + else
53.502 + return p;
53.503 + }
53.504 +
53.505 + Node() { // Used to establish initial head or SHARED marker
53.506 + }
53.507 +
53.508 + Node(Thread thread, Node mode) { // Used by addWaiter
53.509 + this.nextWaiter = mode;
53.510 + this.thread = thread;
53.511 + }
53.512 +
53.513 + Node(Thread thread, int waitStatus) { // Used by Condition
53.514 + this.waitStatus = waitStatus;
53.515 + this.thread = thread;
53.516 + }
53.517 + }
53.518 +
53.519 + /**
53.520 + * Head of the wait queue, lazily initialized. Except for
53.521 + * initialization, it is modified only via method setHead. Note:
53.522 + * If head exists, its waitStatus is guaranteed not to be
53.523 + * CANCELLED.
53.524 + */
53.525 + private transient volatile Node head;
53.526 +
53.527 + /**
53.528 + * Tail of the wait queue, lazily initialized. Modified only via
53.529 + * method enq to add new wait node.
53.530 + */
53.531 + private transient volatile Node tail;
53.532 +
53.533 + /**
53.534 + * The synchronization state.
53.535 + */
53.536 + private volatile int state;
53.537 +
53.538 + /**
53.539 + * Returns the current value of synchronization state.
53.540 + * This operation has memory semantics of a <tt>volatile</tt> read.
53.541 + * @return current state value
53.542 + */
53.543 + protected final int getState() {
53.544 + return state;
53.545 + }
53.546 +
53.547 + /**
53.548 + * Sets the value of synchronization state.
53.549 + * This operation has memory semantics of a <tt>volatile</tt> write.
53.550 + * @param newState the new state value
53.551 + */
53.552 + protected final void setState(int newState) {
53.553 + state = newState;
53.554 + }
53.555 +
53.556 + /**
53.557 + * Atomically sets synchronization state to the given updated
53.558 + * value if the current state value equals the expected value.
53.559 + * This operation has memory semantics of a <tt>volatile</tt> read
53.560 + * and write.
53.561 + *
53.562 + * @param expect the expected value
53.563 + * @param update the new value
53.564 + * @return true if successful. False return indicates that the actual
53.565 + * value was not equal to the expected value.
53.566 + */
53.567 + protected final boolean compareAndSetState(int expect, int update) {
53.568 + // See below for intrinsics setup to support this
53.569 + return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
53.570 + }
53.571 +
53.572 + // Queuing utilities
53.573 +
53.574 + /**
53.575 + * The number of nanoseconds for which it is faster to spin
53.576 + * rather than to use timed park. A rough estimate suffices
53.577 + * to improve responsiveness with very short timeouts.
53.578 + */
53.579 + static final long spinForTimeoutThreshold = 1000L;
53.580 +
53.581 + /**
53.582 + * Inserts node into queue, initializing if necessary. See picture above.
53.583 + * @param node the node to insert
53.584 + * @return node's predecessor
53.585 + */
53.586 + private Node enq(final Node node) {
53.587 + for (;;) {
53.588 + Node t = tail;
53.589 + if (t == null) { // Must initialize
53.590 + if (compareAndSetHead(new Node()))
53.591 + tail = head;
53.592 + } else {
53.593 + node.prev = t;
53.594 + if (compareAndSetTail(t, node)) {
53.595 + t.next = node;
53.596 + return t;
53.597 + }
53.598 + }
53.599 + }
53.600 + }
53.601 +
53.602 + /**
53.603 + * Creates and enqueues node for current thread and given mode.
53.604 + *
53.605 + * @param mode Node.EXCLUSIVE for exclusive, Node.SHARED for shared
53.606 + * @return the new node
53.607 + */
53.608 + private Node addWaiter(Node mode) {
53.609 + Node node = new Node(Thread.currentThread(), mode);
53.610 + // Try the fast path of enq; backup to full enq on failure
53.611 + Node pred = tail;
53.612 + if (pred != null) {
53.613 + node.prev = pred;
53.614 + if (compareAndSetTail(pred, node)) {
53.615 + pred.next = node;
53.616 + return node;
53.617 + }
53.618 + }
53.619 + enq(node);
53.620 + return node;
53.621 + }
53.622 +
53.623 + /**
53.624 + * Sets head of queue to be node, thus dequeuing. Called only by
53.625 + * acquire methods. Also nulls out unused fields for sake of GC
53.626 + * and to suppress unnecessary signals and traversals.
53.627 + *
53.628 + * @param node the node
53.629 + */
53.630 + private void setHead(Node node) {
53.631 + head = node;
53.632 + node.thread = null;
53.633 + node.prev = null;
53.634 + }
53.635 +
53.636 + /**
53.637 + * Wakes up node's successor, if one exists.
53.638 + *
53.639 + * @param node the node
53.640 + */
53.641 + private void unparkSuccessor(Node node) {
53.642 + /*
53.643 + * If status is negative (i.e., possibly needing signal) try
53.644 + * to clear in anticipation of signalling. It is OK if this
53.645 + * fails or if status is changed by waiting thread.
53.646 + */
53.647 + int ws = node.waitStatus;
53.648 + if (ws < 0)
53.649 + compareAndSetWaitStatus(node, ws, 0);
53.650 +
53.651 + /*
53.652 + * Thread to unpark is held in successor, which is normally
53.653 + * just the next node. But if cancelled or apparently null,
53.654 + * traverse backwards from tail to find the actual
53.655 + * non-cancelled successor.
53.656 + */
53.657 + Node s = node.next;
53.658 + if (s == null || s.waitStatus > 0) {
53.659 + s = null;
53.660 + for (Node t = tail; t != null && t != node; t = t.prev)
53.661 + if (t.waitStatus <= 0)
53.662 + s = t;
53.663 + }
53.664 + if (s != null)
53.665 + LockSupport.unpark(s.thread);
53.666 + }
53.667 +
53.668 + /**
53.669 + * Release action for shared mode -- signal successor and ensure
53.670 + * propagation. (Note: For exclusive mode, release just amounts
53.671 + * to calling unparkSuccessor of head if it needs signal.)
53.672 + */
53.673 + private void doReleaseShared() {
53.674 + /*
53.675 + * Ensure that a release propagates, even if there are other
53.676 + * in-progress acquires/releases. This proceeds in the usual
53.677 + * way of trying to unparkSuccessor of head if it needs
53.678 + * signal. But if it does not, status is set to PROPAGATE to
53.679 + * ensure that upon release, propagation continues.
53.680 + * Additionally, we must loop in case a new node is added
53.681 + * while we are doing this. Also, unlike other uses of
53.682 + * unparkSuccessor, we need to know if CAS to reset status
53.683 + * fails, if so rechecking.
53.684 + */
53.685 + for (;;) {
53.686 + Node h = head;
53.687 + if (h != null && h != tail) {
53.688 + int ws = h.waitStatus;
53.689 + if (ws == Node.SIGNAL) {
53.690 + if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))
53.691 + continue; // loop to recheck cases
53.692 + unparkSuccessor(h);
53.693 + }
53.694 + else if (ws == 0 &&
53.695 + !compareAndSetWaitStatus(h, 0, Node.PROPAGATE))
53.696 + continue; // loop on failed CAS
53.697 + }
53.698 + if (h == head) // loop if head changed
53.699 + break;
53.700 + }
53.701 + }
53.702 +
53.703 + /**
53.704 + * Sets head of queue, and checks if successor may be waiting
53.705 + * in shared mode, if so propagating if either propagate > 0 or
53.706 + * PROPAGATE status was set.
53.707 + *
53.708 + * @param node the node
53.709 + * @param propagate the return value from a tryAcquireShared
53.710 + */
53.711 + private void setHeadAndPropagate(Node node, int propagate) {
53.712 + Node h = head; // Record old head for check below
53.713 + setHead(node);
53.714 + /*
53.715 + * Try to signal next queued node if:
53.716 + * Propagation was indicated by caller,
53.717 + * or was recorded (as h.waitStatus) by a previous operation
53.718 + * (note: this uses sign-check of waitStatus because
53.719 + * PROPAGATE status may transition to SIGNAL.)
53.720 + * and
53.721 + * The next node is waiting in shared mode,
53.722 + * or we don't know, because it appears null
53.723 + *
53.724 + * The conservatism in both of these checks may cause
53.725 + * unnecessary wake-ups, but only when there are multiple
53.726 + * racing acquires/releases, so most need signals now or soon
53.727 + * anyway.
53.728 + */
53.729 + if (propagate > 0 || h == null || h.waitStatus < 0) {
53.730 + Node s = node.next;
53.731 + if (s == null || s.isShared())
53.732 + doReleaseShared();
53.733 + }
53.734 + }
53.735 +
53.736 + // Utilities for various versions of acquire
53.737 +
53.738 + /**
53.739 + * Cancels an ongoing attempt to acquire.
53.740 + *
53.741 + * @param node the node
53.742 + */
53.743 + private void cancelAcquire(Node node) {
53.744 + // Ignore if node doesn't exist
53.745 + if (node == null)
53.746 + return;
53.747 +
53.748 + node.thread = null;
53.749 +
53.750 + // Skip cancelled predecessors
53.751 + Node pred = node.prev;
53.752 + while (pred.waitStatus > 0)
53.753 + node.prev = pred = pred.prev;
53.754 +
53.755 + // predNext is the apparent node to unsplice. CASes below will
53.756 + // fail if not, in which case, we lost race vs another cancel
53.757 + // or signal, so no further action is necessary.
53.758 + Node predNext = pred.next;
53.759 +
53.760 + // Can use unconditional write instead of CAS here.
53.761 + // After this atomic step, other Nodes can skip past us.
53.762 + // Before, we are free of interference from other threads.
53.763 + node.waitStatus = Node.CANCELLED;
53.764 +
53.765 + // If we are the tail, remove ourselves.
53.766 + if (node == tail && compareAndSetTail(node, pred)) {
53.767 + compareAndSetNext(pred, predNext, null);
53.768 + } else {
53.769 + // If successor needs signal, try to set pred's next-link
53.770 + // so it will get one. Otherwise wake it up to propagate.
53.771 + int ws;
53.772 + if (pred != head &&
53.773 + ((ws = pred.waitStatus) == Node.SIGNAL ||
53.774 + (ws <= 0 && compareAndSetWaitStatus(pred, ws, Node.SIGNAL))) &&
53.775 + pred.thread != null) {
53.776 + Node next = node.next;
53.777 + if (next != null && next.waitStatus <= 0)
53.778 + compareAndSetNext(pred, predNext, next);
53.779 + } else {
53.780 + unparkSuccessor(node);
53.781 + }
53.782 +
53.783 + node.next = node; // help GC
53.784 + }
53.785 + }
53.786 +
53.787 + /**
53.788 + * Checks and updates status for a node that failed to acquire.
53.789 + * Returns true if thread should block. This is the main signal
53.790 + * control in all acquire loops. Requires that pred == node.prev
53.791 + *
53.792 + * @param pred node's predecessor holding status
53.793 + * @param node the node
53.794 + * @return {@code true} if thread should block
53.795 + */
53.796 + private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
53.797 + int ws = pred.waitStatus;
53.798 + if (ws == Node.SIGNAL)
53.799 + /*
53.800 + * This node has already set status asking a release
53.801 + * to signal it, so it can safely park.
53.802 + */
53.803 + return true;
53.804 + if (ws > 0) {
53.805 + /*
53.806 + * Predecessor was cancelled. Skip over predecessors and
53.807 + * indicate retry.
53.808 + */
53.809 + do {
53.810 + node.prev = pred = pred.prev;
53.811 + } while (pred.waitStatus > 0);
53.812 + pred.next = node;
53.813 + } else {
53.814 + /*
53.815 + * waitStatus must be 0 or PROPAGATE. Indicate that we
53.816 + * need a signal, but don't park yet. Caller will need to
53.817 + * retry to make sure it cannot acquire before parking.
53.818 + */
53.819 + compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
53.820 + }
53.821 + return false;
53.822 + }
53.823 +
53.824 + /**
53.825 + * Convenience method to interrupt current thread.
53.826 + */
53.827 + private static void selfInterrupt() {
53.828 + Thread.currentThread().interrupt();
53.829 + }
53.830 +
53.831 + /**
53.832 + * Convenience method to park and then check if interrupted
53.833 + *
53.834 + * @return {@code true} if interrupted
53.835 + */
53.836 + private final boolean parkAndCheckInterrupt() {
53.837 + LockSupport.park(this);
53.838 + return Thread.interrupted();
53.839 + }
53.840 +
53.841 + /*
53.842 + * Various flavors of acquire, varying in exclusive/shared and
53.843 + * control modes. Each is mostly the same, but annoyingly
53.844 + * different. Only a little bit of factoring is possible due to
53.845 + * interactions of exception mechanics (including ensuring that we
53.846 + * cancel if tryAcquire throws exception) and other control, at
53.847 + * least not without hurting performance too much.
53.848 + */
53.849 +
53.850 + /**
53.851 + * Acquires in exclusive uninterruptible mode for thread already in
53.852 + * queue. Used by condition wait methods as well as acquire.
53.853 + *
53.854 + * @param node the node
53.855 + * @param arg the acquire argument
53.856 + * @return {@code true} if interrupted while waiting
53.857 + */
53.858 + final boolean acquireQueued(final Node node, int arg) {
53.859 + boolean failed = true;
53.860 + try {
53.861 + boolean interrupted = false;
53.862 + for (;;) {
53.863 + final Node p = node.predecessor();
53.864 + if (p == head && tryAcquire(arg)) {
53.865 + setHead(node);
53.866 + p.next = null; // help GC
53.867 + failed = false;
53.868 + return interrupted;
53.869 + }
53.870 + if (shouldParkAfterFailedAcquire(p, node) &&
53.871 + parkAndCheckInterrupt())
53.872 + interrupted = true;
53.873 + }
53.874 + } finally {
53.875 + if (failed)
53.876 + cancelAcquire(node);
53.877 + }
53.878 + }
53.879 +
53.880 + /**
53.881 + * Acquires in exclusive interruptible mode.
53.882 + * @param arg the acquire argument
53.883 + */
53.884 + private void doAcquireInterruptibly(int arg)
53.885 + throws InterruptedException {
53.886 + final Node node = addWaiter(Node.EXCLUSIVE);
53.887 + boolean failed = true;
53.888 + try {
53.889 + for (;;) {
53.890 + final Node p = node.predecessor();
53.891 + if (p == head && tryAcquire(arg)) {
53.892 + setHead(node);
53.893 + p.next = null; // help GC
53.894 + failed = false;
53.895 + return;
53.896 + }
53.897 + if (shouldParkAfterFailedAcquire(p, node) &&
53.898 + parkAndCheckInterrupt())
53.899 + throw new InterruptedException();
53.900 + }
53.901 + } finally {
53.902 + if (failed)
53.903 + cancelAcquire(node);
53.904 + }
53.905 + }
53.906 +
53.907 + /**
53.908 + * Acquires in exclusive timed mode.
53.909 + *
53.910 + * @param arg the acquire argument
53.911 + * @param nanosTimeout max wait time
53.912 + * @return {@code true} if acquired
53.913 + */
53.914 + private boolean doAcquireNanos(int arg, long nanosTimeout)
53.915 + throws InterruptedException {
53.916 + long lastTime = System.nanoTime();
53.917 + final Node node = addWaiter(Node.EXCLUSIVE);
53.918 + boolean failed = true;
53.919 + try {
53.920 + for (;;) {
53.921 + final Node p = node.predecessor();
53.922 + if (p == head && tryAcquire(arg)) {
53.923 + setHead(node);
53.924 + p.next = null; // help GC
53.925 + failed = false;
53.926 + return true;
53.927 + }
53.928 + if (nanosTimeout <= 0)
53.929 + return false;
53.930 + if (shouldParkAfterFailedAcquire(p, node) &&
53.931 + nanosTimeout > spinForTimeoutThreshold)
53.932 + LockSupport.parkNanos(this, nanosTimeout);
53.933 + long now = System.nanoTime();
53.934 + nanosTimeout -= now - lastTime;
53.935 + lastTime = now;
53.936 + if (Thread.interrupted())
53.937 + throw new InterruptedException();
53.938 + }
53.939 + } finally {
53.940 + if (failed)
53.941 + cancelAcquire(node);
53.942 + }
53.943 + }
53.944 +
53.945 + /**
53.946 + * Acquires in shared uninterruptible mode.
53.947 + * @param arg the acquire argument
53.948 + */
53.949 + private void doAcquireShared(int arg) {
53.950 + final Node node = addWaiter(Node.SHARED);
53.951 + boolean failed = true;
53.952 + try {
53.953 + boolean interrupted = false;
53.954 + for (;;) {
53.955 + final Node p = node.predecessor();
53.956 + if (p == head) {
53.957 + int r = tryAcquireShared(arg);
53.958 + if (r >= 0) {
53.959 + setHeadAndPropagate(node, r);
53.960 + p.next = null; // help GC
53.961 + if (interrupted)
53.962 + selfInterrupt();
53.963 + failed = false;
53.964 + return;
53.965 + }
53.966 + }
53.967 + if (shouldParkAfterFailedAcquire(p, node) &&
53.968 + parkAndCheckInterrupt())
53.969 + interrupted = true;
53.970 + }
53.971 + } finally {
53.972 + if (failed)
53.973 + cancelAcquire(node);
53.974 + }
53.975 + }
53.976 +
53.977 + /**
53.978 + * Acquires in shared interruptible mode.
53.979 + * @param arg the acquire argument
53.980 + */
53.981 + private void doAcquireSharedInterruptibly(int arg)
53.982 + throws InterruptedException {
53.983 + final Node node = addWaiter(Node.SHARED);
53.984 + boolean failed = true;
53.985 + try {
53.986 + for (;;) {
53.987 + final Node p = node.predecessor();
53.988 + if (p == head) {
53.989 + int r = tryAcquireShared(arg);
53.990 + if (r >= 0) {
53.991 + setHeadAndPropagate(node, r);
53.992 + p.next = null; // help GC
53.993 + failed = false;
53.994 + return;
53.995 + }
53.996 + }
53.997 + if (shouldParkAfterFailedAcquire(p, node) &&
53.998 + parkAndCheckInterrupt())
53.999 + throw new InterruptedException();
53.1000 + }
53.1001 + } finally {
53.1002 + if (failed)
53.1003 + cancelAcquire(node);
53.1004 + }
53.1005 + }
53.1006 +
53.1007 + /**
53.1008 + * Acquires in shared timed mode.
53.1009 + *
53.1010 + * @param arg the acquire argument
53.1011 + * @param nanosTimeout max wait time
53.1012 + * @return {@code true} if acquired
53.1013 + */
53.1014 + private boolean doAcquireSharedNanos(int arg, long nanosTimeout)
53.1015 + throws InterruptedException {
53.1016 +
53.1017 + long lastTime = System.nanoTime();
53.1018 + final Node node = addWaiter(Node.SHARED);
53.1019 + boolean failed = true;
53.1020 + try {
53.1021 + for (;;) {
53.1022 + final Node p = node.predecessor();
53.1023 + if (p == head) {
53.1024 + int r = tryAcquireShared(arg);
53.1025 + if (r >= 0) {
53.1026 + setHeadAndPropagate(node, r);
53.1027 + p.next = null; // help GC
53.1028 + failed = false;
53.1029 + return true;
53.1030 + }
53.1031 + }
53.1032 + if (nanosTimeout <= 0)
53.1033 + return false;
53.1034 + if (shouldParkAfterFailedAcquire(p, node) &&
53.1035 + nanosTimeout > spinForTimeoutThreshold)
53.1036 + LockSupport.parkNanos(this, nanosTimeout);
53.1037 + long now = System.nanoTime();
53.1038 + nanosTimeout -= now - lastTime;
53.1039 + lastTime = now;
53.1040 + if (Thread.interrupted())
53.1041 + throw new InterruptedException();
53.1042 + }
53.1043 + } finally {
53.1044 + if (failed)
53.1045 + cancelAcquire(node);
53.1046 + }
53.1047 + }
53.1048 +
53.1049 + // Main exported methods
53.1050 +
53.1051 + /**
53.1052 + * Attempts to acquire in exclusive mode. This method should query
53.1053 + * if the state of the object permits it to be acquired in the
53.1054 + * exclusive mode, and if so to acquire it.
53.1055 + *
53.1056 + * <p>This method is always invoked by the thread performing
53.1057 + * acquire. If this method reports failure, the acquire method
53.1058 + * may queue the thread, if it is not already queued, until it is
53.1059 + * signalled by a release from some other thread. This can be used
53.1060 + * to implement method {@link Lock#tryLock()}.
53.1061 + *
53.1062 + * <p>The default
53.1063 + * implementation throws {@link UnsupportedOperationException}.
53.1064 + *
53.1065 + * @param arg the acquire argument. This value is always the one
53.1066 + * passed to an acquire method, or is the value saved on entry
53.1067 + * to a condition wait. The value is otherwise uninterpreted
53.1068 + * and can represent anything you like.
53.1069 + * @return {@code true} if successful. Upon success, this object has
53.1070 + * been acquired.
53.1071 + * @throws IllegalMonitorStateException if acquiring would place this
53.1072 + * synchronizer in an illegal state. This exception must be
53.1073 + * thrown in a consistent fashion for synchronization to work
53.1074 + * correctly.
53.1075 + * @throws UnsupportedOperationException if exclusive mode is not supported
53.1076 + */
53.1077 + protected boolean tryAcquire(int arg) {
53.1078 + throw new UnsupportedOperationException();
53.1079 + }
53.1080 +
53.1081 + /**
53.1082 + * Attempts to set the state to reflect a release in exclusive
53.1083 + * mode.
53.1084 + *
53.1085 + * <p>This method is always invoked by the thread performing release.
53.1086 + *
53.1087 + * <p>The default implementation throws
53.1088 + * {@link UnsupportedOperationException}.
53.1089 + *
53.1090 + * @param arg the release argument. This value is always the one
53.1091 + * passed to a release method, or the current state value upon
53.1092 + * entry to a condition wait. The value is otherwise
53.1093 + * uninterpreted and can represent anything you like.
53.1094 + * @return {@code true} if this object is now in a fully released
53.1095 + * state, so that any waiting threads may attempt to acquire;
53.1096 + * and {@code false} otherwise.
53.1097 + * @throws IllegalMonitorStateException if releasing would place this
53.1098 + * synchronizer in an illegal state. This exception must be
53.1099 + * thrown in a consistent fashion for synchronization to work
53.1100 + * correctly.
53.1101 + * @throws UnsupportedOperationException if exclusive mode is not supported
53.1102 + */
53.1103 + protected boolean tryRelease(int arg) {
53.1104 + throw new UnsupportedOperationException();
53.1105 + }
53.1106 +
53.1107 + /**
53.1108 + * Attempts to acquire in shared mode. This method should query if
53.1109 + * the state of the object permits it to be acquired in the shared
53.1110 + * mode, and if so to acquire it.
53.1111 + *
53.1112 + * <p>This method is always invoked by the thread performing
53.1113 + * acquire. If this method reports failure, the acquire method
53.1114 + * may queue the thread, if it is not already queued, until it is
53.1115 + * signalled by a release from some other thread.
53.1116 + *
53.1117 + * <p>The default implementation throws {@link
53.1118 + * UnsupportedOperationException}.
53.1119 + *
53.1120 + * @param arg the acquire argument. This value is always the one
53.1121 + * passed to an acquire method, or is the value saved on entry
53.1122 + * to a condition wait. The value is otherwise uninterpreted
53.1123 + * and can represent anything you like.
53.1124 + * @return a negative value on failure; zero if acquisition in shared
53.1125 + * mode succeeded but no subsequent shared-mode acquire can
53.1126 + * succeed; and a positive value if acquisition in shared
53.1127 + * mode succeeded and subsequent shared-mode acquires might
53.1128 + * also succeed, in which case a subsequent waiting thread
53.1129 + * must check availability. (Support for three different
53.1130 + * return values enables this method to be used in contexts
53.1131 + * where acquires only sometimes act exclusively.) Upon
53.1132 + * success, this object has been acquired.
53.1133 + * @throws IllegalMonitorStateException if acquiring would place this
53.1134 + * synchronizer in an illegal state. This exception must be
53.1135 + * thrown in a consistent fashion for synchronization to work
53.1136 + * correctly.
53.1137 + * @throws UnsupportedOperationException if shared mode is not supported
53.1138 + */
53.1139 + protected int tryAcquireShared(int arg) {
53.1140 + throw new UnsupportedOperationException();
53.1141 + }
53.1142 +
53.1143 + /**
53.1144 + * Attempts to set the state to reflect a release in shared mode.
53.1145 + *
53.1146 + * <p>This method is always invoked by the thread performing release.
53.1147 + *
53.1148 + * <p>The default implementation throws
53.1149 + * {@link UnsupportedOperationException}.
53.1150 + *
53.1151 + * @param arg the release argument. This value is always the one
53.1152 + * passed to a release method, or the current state value upon
53.1153 + * entry to a condition wait. The value is otherwise
53.1154 + * uninterpreted and can represent anything you like.
53.1155 + * @return {@code true} if this release of shared mode may permit a
53.1156 + * waiting acquire (shared or exclusive) to succeed; and
53.1157 + * {@code false} otherwise
53.1158 + * @throws IllegalMonitorStateException if releasing would place this
53.1159 + * synchronizer in an illegal state. This exception must be
53.1160 + * thrown in a consistent fashion for synchronization to work
53.1161 + * correctly.
53.1162 + * @throws UnsupportedOperationException if shared mode is not supported
53.1163 + */
53.1164 + protected boolean tryReleaseShared(int arg) {
53.1165 + throw new UnsupportedOperationException();
53.1166 + }
53.1167 +
53.1168 + /**
53.1169 + * Returns {@code true} if synchronization is held exclusively with
53.1170 + * respect to the current (calling) thread. This method is invoked
53.1171 + * upon each call to a non-waiting {@link ConditionObject} method.
53.1172 + * (Waiting methods instead invoke {@link #release}.)
53.1173 + *
53.1174 + * <p>The default implementation throws {@link
53.1175 + * UnsupportedOperationException}. This method is invoked
53.1176 + * internally only within {@link ConditionObject} methods, so need
53.1177 + * not be defined if conditions are not used.
53.1178 + *
53.1179 + * @return {@code true} if synchronization is held exclusively;
53.1180 + * {@code false} otherwise
53.1181 + * @throws UnsupportedOperationException if conditions are not supported
53.1182 + */
53.1183 + protected boolean isHeldExclusively() {
53.1184 + throw new UnsupportedOperationException();
53.1185 + }
53.1186 +
53.1187 + /**
53.1188 + * Acquires in exclusive mode, ignoring interrupts. Implemented
53.1189 + * by invoking at least once {@link #tryAcquire},
53.1190 + * returning on success. Otherwise the thread is queued, possibly
53.1191 + * repeatedly blocking and unblocking, invoking {@link
53.1192 + * #tryAcquire} until success. This method can be used
53.1193 + * to implement method {@link Lock#lock}.
53.1194 + *
53.1195 + * @param arg the acquire argument. This value is conveyed to
53.1196 + * {@link #tryAcquire} but is otherwise uninterpreted and
53.1197 + * can represent anything you like.
53.1198 + */
53.1199 + public final void acquire(int arg) {
53.1200 + if (!tryAcquire(arg) &&
53.1201 + acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
53.1202 + selfInterrupt();
53.1203 + }
53.1204 +
53.1205 + /**
53.1206 + * Acquires in exclusive mode, aborting if interrupted.
53.1207 + * Implemented by first checking interrupt status, then invoking
53.1208 + * at least once {@link #tryAcquire}, returning on
53.1209 + * success. Otherwise the thread is queued, possibly repeatedly
53.1210 + * blocking and unblocking, invoking {@link #tryAcquire}
53.1211 + * until success or the thread is interrupted. This method can be
53.1212 + * used to implement method {@link Lock#lockInterruptibly}.
53.1213 + *
53.1214 + * @param arg the acquire argument. This value is conveyed to
53.1215 + * {@link #tryAcquire} but is otherwise uninterpreted and
53.1216 + * can represent anything you like.
53.1217 + * @throws InterruptedException if the current thread is interrupted
53.1218 + */
53.1219 + public final void acquireInterruptibly(int arg)
53.1220 + throws InterruptedException {
53.1221 + if (Thread.interrupted())
53.1222 + throw new InterruptedException();
53.1223 + if (!tryAcquire(arg))
53.1224 + doAcquireInterruptibly(arg);
53.1225 + }
53.1226 +
53.1227 + /**
53.1228 + * Attempts to acquire in exclusive mode, aborting if interrupted,
53.1229 + * and failing if the given timeout elapses. Implemented by first
53.1230 + * checking interrupt status, then invoking at least once {@link
53.1231 + * #tryAcquire}, returning on success. Otherwise, the thread is
53.1232 + * queued, possibly repeatedly blocking and unblocking, invoking
53.1233 + * {@link #tryAcquire} until success or the thread is interrupted
53.1234 + * or the timeout elapses. This method can be used to implement
53.1235 + * method {@link Lock#tryLock(long, TimeUnit)}.
53.1236 + *
53.1237 + * @param arg the acquire argument. This value is conveyed to
53.1238 + * {@link #tryAcquire} but is otherwise uninterpreted and
53.1239 + * can represent anything you like.
53.1240 + * @param nanosTimeout the maximum number of nanoseconds to wait
53.1241 + * @return {@code true} if acquired; {@code false} if timed out
53.1242 + * @throws InterruptedException if the current thread is interrupted
53.1243 + */
53.1244 + public final boolean tryAcquireNanos(int arg, long nanosTimeout)
53.1245 + throws InterruptedException {
53.1246 + if (Thread.interrupted())
53.1247 + throw new InterruptedException();
53.1248 + return tryAcquire(arg) ||
53.1249 + doAcquireNanos(arg, nanosTimeout);
53.1250 + }
53.1251 +
53.1252 + /**
53.1253 + * Releases in exclusive mode. Implemented by unblocking one or
53.1254 + * more threads if {@link #tryRelease} returns true.
53.1255 + * This method can be used to implement method {@link Lock#unlock}.
53.1256 + *
53.1257 + * @param arg the release argument. This value is conveyed to
53.1258 + * {@link #tryRelease} but is otherwise uninterpreted and
53.1259 + * can represent anything you like.
53.1260 + * @return the value returned from {@link #tryRelease}
53.1261 + */
53.1262 + public final boolean release(int arg) {
53.1263 + if (tryRelease(arg)) {
53.1264 + Node h = head;
53.1265 + if (h != null && h.waitStatus != 0)
53.1266 + unparkSuccessor(h);
53.1267 + return true;
53.1268 + }
53.1269 + return false;
53.1270 + }
53.1271 +
53.1272 + /**
53.1273 + * Acquires in shared mode, ignoring interrupts. Implemented by
53.1274 + * first invoking at least once {@link #tryAcquireShared},
53.1275 + * returning on success. Otherwise the thread is queued, possibly
53.1276 + * repeatedly blocking and unblocking, invoking {@link
53.1277 + * #tryAcquireShared} until success.
53.1278 + *
53.1279 + * @param arg the acquire argument. This value is conveyed to
53.1280 + * {@link #tryAcquireShared} but is otherwise uninterpreted
53.1281 + * and can represent anything you like.
53.1282 + */
53.1283 + public final void acquireShared(int arg) {
53.1284 + if (tryAcquireShared(arg) < 0)
53.1285 + doAcquireShared(arg);
53.1286 + }
53.1287 +
53.1288 + /**
53.1289 + * Acquires in shared mode, aborting if interrupted. Implemented
53.1290 + * by first checking interrupt status, then invoking at least once
53.1291 + * {@link #tryAcquireShared}, returning on success. Otherwise the
53.1292 + * thread is queued, possibly repeatedly blocking and unblocking,
53.1293 + * invoking {@link #tryAcquireShared} until success or the thread
53.1294 + * is interrupted.
53.1295 + * @param arg the acquire argument
53.1296 + * This value is conveyed to {@link #tryAcquireShared} but is
53.1297 + * otherwise uninterpreted and can represent anything
53.1298 + * you like.
53.1299 + * @throws InterruptedException if the current thread is interrupted
53.1300 + */
53.1301 + public final void acquireSharedInterruptibly(int arg)
53.1302 + throws InterruptedException {
53.1303 + if (Thread.interrupted())
53.1304 + throw new InterruptedException();
53.1305 + if (tryAcquireShared(arg) < 0)
53.1306 + doAcquireSharedInterruptibly(arg);
53.1307 + }
53.1308 +
53.1309 + /**
53.1310 + * Attempts to acquire in shared mode, aborting if interrupted, and
53.1311 + * failing if the given timeout elapses. Implemented by first
53.1312 + * checking interrupt status, then invoking at least once {@link
53.1313 + * #tryAcquireShared}, returning on success. Otherwise, the
53.1314 + * thread is queued, possibly repeatedly blocking and unblocking,
53.1315 + * invoking {@link #tryAcquireShared} until success or the thread
53.1316 + * is interrupted or the timeout elapses.
53.1317 + *
53.1318 + * @param arg the acquire argument. This value is conveyed to
53.1319 + * {@link #tryAcquireShared} but is otherwise uninterpreted
53.1320 + * and can represent anything you like.
53.1321 + * @param nanosTimeout the maximum number of nanoseconds to wait
53.1322 + * @return {@code true} if acquired; {@code false} if timed out
53.1323 + * @throws InterruptedException if the current thread is interrupted
53.1324 + */
53.1325 + public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout)
53.1326 + throws InterruptedException {
53.1327 + if (Thread.interrupted())
53.1328 + throw new InterruptedException();
53.1329 + return tryAcquireShared(arg) >= 0 ||
53.1330 + doAcquireSharedNanos(arg, nanosTimeout);
53.1331 + }
53.1332 +
53.1333 + /**
53.1334 + * Releases in shared mode. Implemented by unblocking one or more
53.1335 + * threads if {@link #tryReleaseShared} returns true.
53.1336 + *
53.1337 + * @param arg the release argument. This value is conveyed to
53.1338 + * {@link #tryReleaseShared} but is otherwise uninterpreted
53.1339 + * and can represent anything you like.
53.1340 + * @return the value returned from {@link #tryReleaseShared}
53.1341 + */
53.1342 + public final boolean releaseShared(int arg) {
53.1343 + if (tryReleaseShared(arg)) {
53.1344 + doReleaseShared();
53.1345 + return true;
53.1346 + }
53.1347 + return false;
53.1348 + }
53.1349 +
53.1350 + // Queue inspection methods
53.1351 +
53.1352 + /**
53.1353 + * Queries whether any threads are waiting to acquire. Note that
53.1354 + * because cancellations due to interrupts and timeouts may occur
53.1355 + * at any time, a {@code true} return does not guarantee that any
53.1356 + * other thread will ever acquire.
53.1357 + *
53.1358 + * <p>In this implementation, this operation returns in
53.1359 + * constant time.
53.1360 + *
53.1361 + * @return {@code true} if there may be other threads waiting to acquire
53.1362 + */
53.1363 + public final boolean hasQueuedThreads() {
53.1364 + return head != tail;
53.1365 + }
53.1366 +
53.1367 + /**
53.1368 + * Queries whether any threads have ever contended to acquire this
53.1369 + * synchronizer; that is if an acquire method has ever blocked.
53.1370 + *
53.1371 + * <p>In this implementation, this operation returns in
53.1372 + * constant time.
53.1373 + *
53.1374 + * @return {@code true} if there has ever been contention
53.1375 + */
53.1376 + public final boolean hasContended() {
53.1377 + return head != null;
53.1378 + }
53.1379 +
53.1380 + /**
53.1381 + * Returns the first (longest-waiting) thread in the queue, or
53.1382 + * {@code null} if no threads are currently queued.
53.1383 + *
53.1384 + * <p>In this implementation, this operation normally returns in
53.1385 + * constant time, but may iterate upon contention if other threads are
53.1386 + * concurrently modifying the queue.
53.1387 + *
53.1388 + * @return the first (longest-waiting) thread in the queue, or
53.1389 + * {@code null} if no threads are currently queued
53.1390 + */
53.1391 + public final Thread getFirstQueuedThread() {
53.1392 + // handle only fast path, else relay
53.1393 + return (head == tail) ? null : fullGetFirstQueuedThread();
53.1394 + }
53.1395 +
53.1396 + /**
53.1397 + * Version of getFirstQueuedThread called when fastpath fails
53.1398 + */
53.1399 + private Thread fullGetFirstQueuedThread() {
53.1400 + /*
53.1401 + * The first node is normally head.next. Try to get its
53.1402 + * thread field, ensuring consistent reads: If thread
53.1403 + * field is nulled out or s.prev is no longer head, then
53.1404 + * some other thread(s) concurrently performed setHead in
53.1405 + * between some of our reads. We try this twice before
53.1406 + * resorting to traversal.
53.1407 + */
53.1408 + Node h, s;
53.1409 + Thread st;
53.1410 + if (((h = head) != null && (s = h.next) != null &&
53.1411 + s.prev == head && (st = s.thread) != null) ||
53.1412 + ((h = head) != null && (s = h.next) != null &&
53.1413 + s.prev == head && (st = s.thread) != null))
53.1414 + return st;
53.1415 +
53.1416 + /*
53.1417 + * Head's next field might not have been set yet, or may have
53.1418 + * been unset after setHead. So we must check to see if tail
53.1419 + * is actually first node. If not, we continue on, safely
53.1420 + * traversing from tail back to head to find first,
53.1421 + * guaranteeing termination.
53.1422 + */
53.1423 +
53.1424 + Node t = tail;
53.1425 + Thread firstThread = null;
53.1426 + while (t != null && t != head) {
53.1427 + Thread tt = t.thread;
53.1428 + if (tt != null)
53.1429 + firstThread = tt;
53.1430 + t = t.prev;
53.1431 + }
53.1432 + return firstThread;
53.1433 + }
53.1434 +
53.1435 + /**
53.1436 + * Returns true if the given thread is currently queued.
53.1437 + *
53.1438 + * <p>This implementation traverses the queue to determine
53.1439 + * presence of the given thread.
53.1440 + *
53.1441 + * @param thread the thread
53.1442 + * @return {@code true} if the given thread is on the queue
53.1443 + * @throws NullPointerException if the thread is null
53.1444 + */
53.1445 + public final boolean isQueued(Thread thread) {
53.1446 + if (thread == null)
53.1447 + throw new NullPointerException();
53.1448 + for (Node p = tail; p != null; p = p.prev)
53.1449 + if (p.thread == thread)
53.1450 + return true;
53.1451 + return false;
53.1452 + }
53.1453 +
53.1454 + /**
53.1455 + * Returns {@code true} if the apparent first queued thread, if one
53.1456 + * exists, is waiting in exclusive mode. If this method returns
53.1457 + * {@code true}, and the current thread is attempting to acquire in
53.1458 + * shared mode (that is, this method is invoked from {@link
53.1459 + * #tryAcquireShared}) then it is guaranteed that the current thread
53.1460 + * is not the first queued thread. Used only as a heuristic in
53.1461 + * ReentrantReadWriteLock.
53.1462 + */
53.1463 + final boolean apparentlyFirstQueuedIsExclusive() {
53.1464 + Node h, s;
53.1465 + return (h = head) != null &&
53.1466 + (s = h.next) != null &&
53.1467 + !s.isShared() &&
53.1468 + s.thread != null;
53.1469 + }
53.1470 +
53.1471 + /**
53.1472 + * Queries whether any threads have been waiting to acquire longer
53.1473 + * than the current thread.
53.1474 + *
53.1475 + * <p>An invocation of this method is equivalent to (but may be
53.1476 + * more efficient than):
53.1477 + * <pre> {@code
53.1478 + * getFirstQueuedThread() != Thread.currentThread() &&
53.1479 + * hasQueuedThreads()}</pre>
53.1480 + *
53.1481 + * <p>Note that because cancellations due to interrupts and
53.1482 + * timeouts may occur at any time, a {@code true} return does not
53.1483 + * guarantee that some other thread will acquire before the current
53.1484 + * thread. Likewise, it is possible for another thread to win a
53.1485 + * race to enqueue after this method has returned {@code false},
53.1486 + * due to the queue being empty.
53.1487 + *
53.1488 + * <p>This method is designed to be used by a fair synchronizer to
53.1489 + * avoid <a href="AbstractQueuedSynchronizer#barging">barging</a>.
53.1490 + * Such a synchronizer's {@link #tryAcquire} method should return
53.1491 + * {@code false}, and its {@link #tryAcquireShared} method should
53.1492 + * return a negative value, if this method returns {@code true}
53.1493 + * (unless this is a reentrant acquire). For example, the {@code
53.1494 + * tryAcquire} method for a fair, reentrant, exclusive mode
53.1495 + * synchronizer might look like this:
53.1496 + *
53.1497 + * <pre> {@code
53.1498 + * protected boolean tryAcquire(int arg) {
53.1499 + * if (isHeldExclusively()) {
53.1500 + * // A reentrant acquire; increment hold count
53.1501 + * return true;
53.1502 + * } else if (hasQueuedPredecessors()) {
53.1503 + * return false;
53.1504 + * } else {
53.1505 + * // try to acquire normally
53.1506 + * }
53.1507 + * }}</pre>
53.1508 + *
53.1509 + * @return {@code true} if there is a queued thread preceding the
53.1510 + * current thread, and {@code false} if the current thread
53.1511 + * is at the head of the queue or the queue is empty
53.1512 + * @since 1.7
53.1513 + */
53.1514 + public final boolean hasQueuedPredecessors() {
53.1515 + // The correctness of this depends on head being initialized
53.1516 + // before tail and on head.next being accurate if the current
53.1517 + // thread is first in queue.
53.1518 + Node t = tail; // Read fields in reverse initialization order
53.1519 + Node h = head;
53.1520 + Node s;
53.1521 + return h != t &&
53.1522 + ((s = h.next) == null || s.thread != Thread.currentThread());
53.1523 + }
53.1524 +
53.1525 +
53.1526 + // Instrumentation and monitoring methods
53.1527 +
53.1528 + /**
53.1529 + * Returns an estimate of the number of threads waiting to
53.1530 + * acquire. The value is only an estimate because the number of
53.1531 + * threads may change dynamically while this method traverses
53.1532 + * internal data structures. This method is designed for use in
53.1533 + * monitoring system state, not for synchronization
53.1534 + * control.
53.1535 + *
53.1536 + * @return the estimated number of threads waiting to acquire
53.1537 + */
53.1538 + public final int getQueueLength() {
53.1539 + int n = 0;
53.1540 + for (Node p = tail; p != null; p = p.prev) {
53.1541 + if (p.thread != null)
53.1542 + ++n;
53.1543 + }
53.1544 + return n;
53.1545 + }
53.1546 +
53.1547 + /**
53.1548 + * Returns a collection containing threads that may be waiting to
53.1549 + * acquire. Because the actual set of threads may change
53.1550 + * dynamically while constructing this result, the returned
53.1551 + * collection is only a best-effort estimate. The elements of the
53.1552 + * returned collection are in no particular order. This method is
53.1553 + * designed to facilitate construction of subclasses that provide
53.1554 + * more extensive monitoring facilities.
53.1555 + *
53.1556 + * @return the collection of threads
53.1557 + */
53.1558 + public final Collection<Thread> getQueuedThreads() {
53.1559 + ArrayList<Thread> list = new ArrayList<Thread>();
53.1560 + for (Node p = tail; p != null; p = p.prev) {
53.1561 + Thread t = p.thread;
53.1562 + if (t != null)
53.1563 + list.add(t);
53.1564 + }
53.1565 + return list;
53.1566 + }
53.1567 +
53.1568 + /**
53.1569 + * Returns a collection containing threads that may be waiting to
53.1570 + * acquire in exclusive mode. This has the same properties
53.1571 + * as {@link #getQueuedThreads} except that it only returns
53.1572 + * those threads waiting due to an exclusive acquire.
53.1573 + *
53.1574 + * @return the collection of threads
53.1575 + */
53.1576 + public final Collection<Thread> getExclusiveQueuedThreads() {
53.1577 + ArrayList<Thread> list = new ArrayList<Thread>();
53.1578 + for (Node p = tail; p != null; p = p.prev) {
53.1579 + if (!p.isShared()) {
53.1580 + Thread t = p.thread;
53.1581 + if (t != null)
53.1582 + list.add(t);
53.1583 + }
53.1584 + }
53.1585 + return list;
53.1586 + }
53.1587 +
53.1588 + /**
53.1589 + * Returns a collection containing threads that may be waiting to
53.1590 + * acquire in shared mode. This has the same properties
53.1591 + * as {@link #getQueuedThreads} except that it only returns
53.1592 + * those threads waiting due to a shared acquire.
53.1593 + *
53.1594 + * @return the collection of threads
53.1595 + */
53.1596 + public final Collection<Thread> getSharedQueuedThreads() {
53.1597 + ArrayList<Thread> list = new ArrayList<Thread>();
53.1598 + for (Node p = tail; p != null; p = p.prev) {
53.1599 + if (p.isShared()) {
53.1600 + Thread t = p.thread;
53.1601 + if (t != null)
53.1602 + list.add(t);
53.1603 + }
53.1604 + }
53.1605 + return list;
53.1606 + }
53.1607 +
53.1608 + /**
53.1609 + * Returns a string identifying this synchronizer, as well as its state.
53.1610 + * The state, in brackets, includes the String {@code "State ="}
53.1611 + * followed by the current value of {@link #getState}, and either
53.1612 + * {@code "nonempty"} or {@code "empty"} depending on whether the
53.1613 + * queue is empty.
53.1614 + *
53.1615 + * @return a string identifying this synchronizer, as well as its state
53.1616 + */
53.1617 + public String toString() {
53.1618 + int s = getState();
53.1619 + String q = hasQueuedThreads() ? "non" : "";
53.1620 + return super.toString() +
53.1621 + "[State = " + s + ", " + q + "empty queue]";
53.1622 + }
53.1623 +
53.1624 +
53.1625 + // Internal support methods for Conditions
53.1626 +
53.1627 + /**
53.1628 + * Returns true if a node, always one that was initially placed on
53.1629 + * a condition queue, is now waiting to reacquire on sync queue.
53.1630 + * @param node the node
53.1631 + * @return true if is reacquiring
53.1632 + */
53.1633 + final boolean isOnSyncQueue(Node node) {
53.1634 + if (node.waitStatus == Node.CONDITION || node.prev == null)
53.1635 + return false;
53.1636 + if (node.next != null) // If has successor, it must be on queue
53.1637 + return true;
53.1638 + /*
53.1639 + * node.prev can be non-null, but not yet on queue because
53.1640 + * the CAS to place it on queue can fail. So we have to
53.1641 + * traverse from tail to make sure it actually made it. It
53.1642 + * will always be near the tail in calls to this method, and
53.1643 + * unless the CAS failed (which is unlikely), it will be
53.1644 + * there, so we hardly ever traverse much.
53.1645 + */
53.1646 + return findNodeFromTail(node);
53.1647 + }
53.1648 +
53.1649 + /**
53.1650 + * Returns true if node is on sync queue by searching backwards from tail.
53.1651 + * Called only when needed by isOnSyncQueue.
53.1652 + * @return true if present
53.1653 + */
53.1654 + private boolean findNodeFromTail(Node node) {
53.1655 + Node t = tail;
53.1656 + for (;;) {
53.1657 + if (t == node)
53.1658 + return true;
53.1659 + if (t == null)
53.1660 + return false;
53.1661 + t = t.prev;
53.1662 + }
53.1663 + }
53.1664 +
53.1665 + /**
53.1666 + * Transfers a node from a condition queue onto sync queue.
53.1667 + * Returns true if successful.
53.1668 + * @param node the node
53.1669 + * @return true if successfully transferred (else the node was
53.1670 + * cancelled before signal).
53.1671 + */
53.1672 + final boolean transferForSignal(Node node) {
53.1673 + /*
53.1674 + * If cannot change waitStatus, the node has been cancelled.
53.1675 + */
53.1676 + if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))
53.1677 + return false;
53.1678 +
53.1679 + /*
53.1680 + * Splice onto queue and try to set waitStatus of predecessor to
53.1681 + * indicate that thread is (probably) waiting. If cancelled or
53.1682 + * attempt to set waitStatus fails, wake up to resync (in which
53.1683 + * case the waitStatus can be transiently and harmlessly wrong).
53.1684 + */
53.1685 + Node p = enq(node);
53.1686 + int ws = p.waitStatus;
53.1687 + if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))
53.1688 + LockSupport.unpark(node.thread);
53.1689 + return true;
53.1690 + }
53.1691 +
53.1692 + /**
53.1693 + * Transfers node, if necessary, to sync queue after a cancelled
53.1694 + * wait. Returns true if thread was cancelled before being
53.1695 + * signalled.
53.1696 + * @param current the waiting thread
53.1697 + * @param node its node
53.1698 + * @return true if cancelled before the node was signalled
53.1699 + */
53.1700 + final boolean transferAfterCancelledWait(Node node) {
53.1701 + if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) {
53.1702 + enq(node);
53.1703 + return true;
53.1704 + }
53.1705 + /*
53.1706 + * If we lost out to a signal(), then we can't proceed
53.1707 + * until it finishes its enq(). Cancelling during an
53.1708 + * incomplete transfer is both rare and transient, so just
53.1709 + * spin.
53.1710 + */
53.1711 + while (!isOnSyncQueue(node))
53.1712 + Thread.yield();
53.1713 + return false;
53.1714 + }
53.1715 +
53.1716 + /**
53.1717 + * Invokes release with current state value; returns saved state.
53.1718 + * Cancels node and throws exception on failure.
53.1719 + * @param node the condition node for this wait
53.1720 + * @return previous sync state
53.1721 + */
53.1722 + final int fullyRelease(Node node) {
53.1723 + boolean failed = true;
53.1724 + try {
53.1725 + int savedState = getState();
53.1726 + if (release(savedState)) {
53.1727 + failed = false;
53.1728 + return savedState;
53.1729 + } else {
53.1730 + throw new IllegalMonitorStateException();
53.1731 + }
53.1732 + } finally {
53.1733 + if (failed)
53.1734 + node.waitStatus = Node.CANCELLED;
53.1735 + }
53.1736 + }
53.1737 +
53.1738 + // Instrumentation methods for conditions
53.1739 +
53.1740 + /**
53.1741 + * Queries whether the given ConditionObject
53.1742 + * uses this synchronizer as its lock.
53.1743 + *
53.1744 + * @param condition the condition
53.1745 + * @return <tt>true</tt> if owned
53.1746 + * @throws NullPointerException if the condition is null
53.1747 + */
53.1748 + public final boolean owns(ConditionObject condition) {
53.1749 + if (condition == null)
53.1750 + throw new NullPointerException();
53.1751 + return condition.isOwnedBy(this);
53.1752 + }
53.1753 +
53.1754 + /**
53.1755 + * Queries whether any threads are waiting on the given condition
53.1756 + * associated with this synchronizer. Note that because timeouts
53.1757 + * and interrupts may occur at any time, a <tt>true</tt> return
53.1758 + * does not guarantee that a future <tt>signal</tt> will awaken
53.1759 + * any threads. This method is designed primarily for use in
53.1760 + * monitoring of the system state.
53.1761 + *
53.1762 + * @param condition the condition
53.1763 + * @return <tt>true</tt> if there are any waiting threads
53.1764 + * @throws IllegalMonitorStateException if exclusive synchronization
53.1765 + * is not held
53.1766 + * @throws IllegalArgumentException if the given condition is
53.1767 + * not associated with this synchronizer
53.1768 + * @throws NullPointerException if the condition is null
53.1769 + */
53.1770 + public final boolean hasWaiters(ConditionObject condition) {
53.1771 + if (!owns(condition))
53.1772 + throw new IllegalArgumentException("Not owner");
53.1773 + return condition.hasWaiters();
53.1774 + }
53.1775 +
53.1776 + /**
53.1777 + * Returns an estimate of the number of threads waiting on the
53.1778 + * given condition associated with this synchronizer. Note that
53.1779 + * because timeouts and interrupts may occur at any time, the
53.1780 + * estimate serves only as an upper bound on the actual number of
53.1781 + * waiters. This method is designed for use in monitoring of the
53.1782 + * system state, not for synchronization control.
53.1783 + *
53.1784 + * @param condition the condition
53.1785 + * @return the estimated number of waiting threads
53.1786 + * @throws IllegalMonitorStateException if exclusive synchronization
53.1787 + * is not held
53.1788 + * @throws IllegalArgumentException if the given condition is
53.1789 + * not associated with this synchronizer
53.1790 + * @throws NullPointerException if the condition is null
53.1791 + */
53.1792 + public final int getWaitQueueLength(ConditionObject condition) {
53.1793 + if (!owns(condition))
53.1794 + throw new IllegalArgumentException("Not owner");
53.1795 + return condition.getWaitQueueLength();
53.1796 + }
53.1797 +
53.1798 + /**
53.1799 + * Returns a collection containing those threads that may be
53.1800 + * waiting on the given condition associated with this
53.1801 + * synchronizer. Because the actual set of threads may change
53.1802 + * dynamically while constructing this result, the returned
53.1803 + * collection is only a best-effort estimate. The elements of the
53.1804 + * returned collection are in no particular order.
53.1805 + *
53.1806 + * @param condition the condition
53.1807 + * @return the collection of threads
53.1808 + * @throws IllegalMonitorStateException if exclusive synchronization
53.1809 + * is not held
53.1810 + * @throws IllegalArgumentException if the given condition is
53.1811 + * not associated with this synchronizer
53.1812 + * @throws NullPointerException if the condition is null
53.1813 + */
53.1814 + public final Collection<Thread> getWaitingThreads(ConditionObject condition) {
53.1815 + if (!owns(condition))
53.1816 + throw new IllegalArgumentException("Not owner");
53.1817 + return condition.getWaitingThreads();
53.1818 + }
53.1819 +
53.1820 + /**
53.1821 + * Condition implementation for a {@link
53.1822 + * AbstractQueuedSynchronizer} serving as the basis of a {@link
53.1823 + * Lock} implementation.
53.1824 + *
53.1825 + * <p>Method documentation for this class describes mechanics,
53.1826 + * not behavioral specifications from the point of view of Lock
53.1827 + * and Condition users. Exported versions of this class will in
53.1828 + * general need to be accompanied by documentation describing
53.1829 + * condition semantics that rely on those of the associated
53.1830 + * <tt>AbstractQueuedSynchronizer</tt>.
53.1831 + *
53.1832 + * <p>This class is Serializable, but all fields are transient,
53.1833 + * so deserialized conditions have no waiters.
53.1834 + */
53.1835 + public class ConditionObject implements Condition, java.io.Serializable {
53.1836 + private static final long serialVersionUID = 1173984872572414699L;
53.1837 + /** First node of condition queue. */
53.1838 + private transient Node firstWaiter;
53.1839 + /** Last node of condition queue. */
53.1840 + private transient Node lastWaiter;
53.1841 +
53.1842 + /**
53.1843 + * Creates a new <tt>ConditionObject</tt> instance.
53.1844 + */
53.1845 + public ConditionObject() { }
53.1846 +
53.1847 + // Internal methods
53.1848 +
53.1849 + /**
53.1850 + * Adds a new waiter to wait queue.
53.1851 + * @return its new wait node
53.1852 + */
53.1853 + private Node addConditionWaiter() {
53.1854 + Node t = lastWaiter;
53.1855 + // If lastWaiter is cancelled, clean out.
53.1856 + if (t != null && t.waitStatus != Node.CONDITION) {
53.1857 + unlinkCancelledWaiters();
53.1858 + t = lastWaiter;
53.1859 + }
53.1860 + Node node = new Node(Thread.currentThread(), Node.CONDITION);
53.1861 + if (t == null)
53.1862 + firstWaiter = node;
53.1863 + else
53.1864 + t.nextWaiter = node;
53.1865 + lastWaiter = node;
53.1866 + return node;
53.1867 + }
53.1868 +
53.1869 + /**
53.1870 + * Removes and transfers nodes until hit non-cancelled one or
53.1871 + * null. Split out from signal in part to encourage compilers
53.1872 + * to inline the case of no waiters.
53.1873 + * @param first (non-null) the first node on condition queue
53.1874 + */
53.1875 + private void doSignal(Node first) {
53.1876 + do {
53.1877 + if ( (firstWaiter = first.nextWaiter) == null)
53.1878 + lastWaiter = null;
53.1879 + first.nextWaiter = null;
53.1880 + } while (!transferForSignal(first) &&
53.1881 + (first = firstWaiter) != null);
53.1882 + }
53.1883 +
53.1884 + /**
53.1885 + * Removes and transfers all nodes.
53.1886 + * @param first (non-null) the first node on condition queue
53.1887 + */
53.1888 + private void doSignalAll(Node first) {
53.1889 + lastWaiter = firstWaiter = null;
53.1890 + do {
53.1891 + Node next = first.nextWaiter;
53.1892 + first.nextWaiter = null;
53.1893 + transferForSignal(first);
53.1894 + first = next;
53.1895 + } while (first != null);
53.1896 + }
53.1897 +
53.1898 + /**
53.1899 + * Unlinks cancelled waiter nodes from condition queue.
53.1900 + * Called only while holding lock. This is called when
53.1901 + * cancellation occurred during condition wait, and upon
53.1902 + * insertion of a new waiter when lastWaiter is seen to have
53.1903 + * been cancelled. This method is needed to avoid garbage
53.1904 + * retention in the absence of signals. So even though it may
53.1905 + * require a full traversal, it comes into play only when
53.1906 + * timeouts or cancellations occur in the absence of
53.1907 + * signals. It traverses all nodes rather than stopping at a
53.1908 + * particular target to unlink all pointers to garbage nodes
53.1909 + * without requiring many re-traversals during cancellation
53.1910 + * storms.
53.1911 + */
53.1912 + private void unlinkCancelledWaiters() {
53.1913 + Node t = firstWaiter;
53.1914 + Node trail = null;
53.1915 + while (t != null) {
53.1916 + Node next = t.nextWaiter;
53.1917 + if (t.waitStatus != Node.CONDITION) {
53.1918 + t.nextWaiter = null;
53.1919 + if (trail == null)
53.1920 + firstWaiter = next;
53.1921 + else
53.1922 + trail.nextWaiter = next;
53.1923 + if (next == null)
53.1924 + lastWaiter = trail;
53.1925 + }
53.1926 + else
53.1927 + trail = t;
53.1928 + t = next;
53.1929 + }
53.1930 + }
53.1931 +
53.1932 + // public methods
53.1933 +
53.1934 + /**
53.1935 + * Moves the longest-waiting thread, if one exists, from the
53.1936 + * wait queue for this condition to the wait queue for the
53.1937 + * owning lock.
53.1938 + *
53.1939 + * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
53.1940 + * returns {@code false}
53.1941 + */
53.1942 + public final void signal() {
53.1943 + if (!isHeldExclusively())
53.1944 + throw new IllegalMonitorStateException();
53.1945 + Node first = firstWaiter;
53.1946 + if (first != null)
53.1947 + doSignal(first);
53.1948 + }
53.1949 +
53.1950 + /**
53.1951 + * Moves all threads from the wait queue for this condition to
53.1952 + * the wait queue for the owning lock.
53.1953 + *
53.1954 + * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
53.1955 + * returns {@code false}
53.1956 + */
53.1957 + public final void signalAll() {
53.1958 + if (!isHeldExclusively())
53.1959 + throw new IllegalMonitorStateException();
53.1960 + Node first = firstWaiter;
53.1961 + if (first != null)
53.1962 + doSignalAll(first);
53.1963 + }
53.1964 +
53.1965 + /**
53.1966 + * Implements uninterruptible condition wait.
53.1967 + * <ol>
53.1968 + * <li> Save lock state returned by {@link #getState}.
53.1969 + * <li> Invoke {@link #release} with
53.1970 + * saved state as argument, throwing
53.1971 + * IllegalMonitorStateException if it fails.
53.1972 + * <li> Block until signalled.
53.1973 + * <li> Reacquire by invoking specialized version of
53.1974 + * {@link #acquire} with saved state as argument.
53.1975 + * </ol>
53.1976 + */
53.1977 + public final void awaitUninterruptibly() {
53.1978 + Node node = addConditionWaiter();
53.1979 + int savedState = fullyRelease(node);
53.1980 + boolean interrupted = false;
53.1981 + while (!isOnSyncQueue(node)) {
53.1982 + LockSupport.park(this);
53.1983 + if (Thread.interrupted())
53.1984 + interrupted = true;
53.1985 + }
53.1986 + if (acquireQueued(node, savedState) || interrupted)
53.1987 + selfInterrupt();
53.1988 + }
53.1989 +
53.1990 + /*
53.1991 + * For interruptible waits, we need to track whether to throw
53.1992 + * InterruptedException, if interrupted while blocked on
53.1993 + * condition, versus reinterrupt current thread, if
53.1994 + * interrupted while blocked waiting to re-acquire.
53.1995 + */
53.1996 +
53.1997 + /** Mode meaning to reinterrupt on exit from wait */
53.1998 + private static final int REINTERRUPT = 1;
53.1999 + /** Mode meaning to throw InterruptedException on exit from wait */
53.2000 + private static final int THROW_IE = -1;
53.2001 +
53.2002 + /**
53.2003 + * Checks for interrupt, returning THROW_IE if interrupted
53.2004 + * before signalled, REINTERRUPT if after signalled, or
53.2005 + * 0 if not interrupted.
53.2006 + */
53.2007 + private int checkInterruptWhileWaiting(Node node) {
53.2008 + return Thread.interrupted() ?
53.2009 + (transferAfterCancelledWait(node) ? THROW_IE : REINTERRUPT) :
53.2010 + 0;
53.2011 + }
53.2012 +
53.2013 + /**
53.2014 + * Throws InterruptedException, reinterrupts current thread, or
53.2015 + * does nothing, depending on mode.
53.2016 + */
53.2017 + private void reportInterruptAfterWait(int interruptMode)
53.2018 + throws InterruptedException {
53.2019 + if (interruptMode == THROW_IE)
53.2020 + throw new InterruptedException();
53.2021 + else if (interruptMode == REINTERRUPT)
53.2022 + selfInterrupt();
53.2023 + }
53.2024 +
53.2025 + /**
53.2026 + * Implements interruptible condition wait.
53.2027 + * <ol>
53.2028 + * <li> If current thread is interrupted, throw InterruptedException.
53.2029 + * <li> Save lock state returned by {@link #getState}.
53.2030 + * <li> Invoke {@link #release} with
53.2031 + * saved state as argument, throwing
53.2032 + * IllegalMonitorStateException if it fails.
53.2033 + * <li> Block until signalled or interrupted.
53.2034 + * <li> Reacquire by invoking specialized version of
53.2035 + * {@link #acquire} with saved state as argument.
53.2036 + * <li> If interrupted while blocked in step 4, throw InterruptedException.
53.2037 + * </ol>
53.2038 + */
53.2039 + public final void await() throws InterruptedException {
53.2040 + if (Thread.interrupted())
53.2041 + throw new InterruptedException();
53.2042 + Node node = addConditionWaiter();
53.2043 + int savedState = fullyRelease(node);
53.2044 + int interruptMode = 0;
53.2045 + while (!isOnSyncQueue(node)) {
53.2046 + LockSupport.park(this);
53.2047 + if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
53.2048 + break;
53.2049 + }
53.2050 + if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
53.2051 + interruptMode = REINTERRUPT;
53.2052 + if (node.nextWaiter != null) // clean up if cancelled
53.2053 + unlinkCancelledWaiters();
53.2054 + if (interruptMode != 0)
53.2055 + reportInterruptAfterWait(interruptMode);
53.2056 + }
53.2057 +
53.2058 + /**
53.2059 + * Implements timed condition wait.
53.2060 + * <ol>
53.2061 + * <li> If current thread is interrupted, throw InterruptedException.
53.2062 + * <li> Save lock state returned by {@link #getState}.
53.2063 + * <li> Invoke {@link #release} with
53.2064 + * saved state as argument, throwing
53.2065 + * IllegalMonitorStateException if it fails.
53.2066 + * <li> Block until signalled, interrupted, or timed out.
53.2067 + * <li> Reacquire by invoking specialized version of
53.2068 + * {@link #acquire} with saved state as argument.
53.2069 + * <li> If interrupted while blocked in step 4, throw InterruptedException.
53.2070 + * </ol>
53.2071 + */
53.2072 + public final long awaitNanos(long nanosTimeout)
53.2073 + throws InterruptedException {
53.2074 + if (Thread.interrupted())
53.2075 + throw new InterruptedException();
53.2076 + Node node = addConditionWaiter();
53.2077 + int savedState = fullyRelease(node);
53.2078 + long lastTime = System.nanoTime();
53.2079 + int interruptMode = 0;
53.2080 + while (!isOnSyncQueue(node)) {
53.2081 + if (nanosTimeout <= 0L) {
53.2082 + transferAfterCancelledWait(node);
53.2083 + break;
53.2084 + }
53.2085 + LockSupport.parkNanos(this, nanosTimeout);
53.2086 + if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
53.2087 + break;
53.2088 +
53.2089 + long now = System.nanoTime();
53.2090 + nanosTimeout -= now - lastTime;
53.2091 + lastTime = now;
53.2092 + }
53.2093 + if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
53.2094 + interruptMode = REINTERRUPT;
53.2095 + if (node.nextWaiter != null)
53.2096 + unlinkCancelledWaiters();
53.2097 + if (interruptMode != 0)
53.2098 + reportInterruptAfterWait(interruptMode);
53.2099 + return nanosTimeout - (System.nanoTime() - lastTime);
53.2100 + }
53.2101 +
53.2102 + /**
53.2103 + * Implements absolute timed condition wait.
53.2104 + * <ol>
53.2105 + * <li> If current thread is interrupted, throw InterruptedException.
53.2106 + * <li> Save lock state returned by {@link #getState}.
53.2107 + * <li> Invoke {@link #release} with
53.2108 + * saved state as argument, throwing
53.2109 + * IllegalMonitorStateException if it fails.
53.2110 + * <li> Block until signalled, interrupted, or timed out.
53.2111 + * <li> Reacquire by invoking specialized version of
53.2112 + * {@link #acquire} with saved state as argument.
53.2113 + * <li> If interrupted while blocked in step 4, throw InterruptedException.
53.2114 + * <li> If timed out while blocked in step 4, return false, else true.
53.2115 + * </ol>
53.2116 + */
53.2117 + public final boolean awaitUntil(Date deadline)
53.2118 + throws InterruptedException {
53.2119 + if (deadline == null)
53.2120 + throw new NullPointerException();
53.2121 + long abstime = deadline.getTime();
53.2122 + if (Thread.interrupted())
53.2123 + throw new InterruptedException();
53.2124 + Node node = addConditionWaiter();
53.2125 + int savedState = fullyRelease(node);
53.2126 + boolean timedout = false;
53.2127 + int interruptMode = 0;
53.2128 + while (!isOnSyncQueue(node)) {
53.2129 + if (System.currentTimeMillis() > abstime) {
53.2130 + timedout = transferAfterCancelledWait(node);
53.2131 + break;
53.2132 + }
53.2133 + LockSupport.parkUntil(this, abstime);
53.2134 + if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
53.2135 + break;
53.2136 + }
53.2137 + if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
53.2138 + interruptMode = REINTERRUPT;
53.2139 + if (node.nextWaiter != null)
53.2140 + unlinkCancelledWaiters();
53.2141 + if (interruptMode != 0)
53.2142 + reportInterruptAfterWait(interruptMode);
53.2143 + return !timedout;
53.2144 + }
53.2145 +
53.2146 + /**
53.2147 + * Implements timed condition wait.
53.2148 + * <ol>
53.2149 + * <li> If current thread is interrupted, throw InterruptedException.
53.2150 + * <li> Save lock state returned by {@link #getState}.
53.2151 + * <li> Invoke {@link #release} with
53.2152 + * saved state as argument, throwing
53.2153 + * IllegalMonitorStateException if it fails.
53.2154 + * <li> Block until signalled, interrupted, or timed out.
53.2155 + * <li> Reacquire by invoking specialized version of
53.2156 + * {@link #acquire} with saved state as argument.
53.2157 + * <li> If interrupted while blocked in step 4, throw InterruptedException.
53.2158 + * <li> If timed out while blocked in step 4, return false, else true.
53.2159 + * </ol>
53.2160 + */
53.2161 + public final boolean await(long time, TimeUnit unit)
53.2162 + throws InterruptedException {
53.2163 + if (unit == null)
53.2164 + throw new NullPointerException();
53.2165 + long nanosTimeout = unit.toNanos(time);
53.2166 + if (Thread.interrupted())
53.2167 + throw new InterruptedException();
53.2168 + Node node = addConditionWaiter();
53.2169 + int savedState = fullyRelease(node);
53.2170 + long lastTime = System.nanoTime();
53.2171 + boolean timedout = false;
53.2172 + int interruptMode = 0;
53.2173 + while (!isOnSyncQueue(node)) {
53.2174 + if (nanosTimeout <= 0L) {
53.2175 + timedout = transferAfterCancelledWait(node);
53.2176 + break;
53.2177 + }
53.2178 + if (nanosTimeout >= spinForTimeoutThreshold)
53.2179 + LockSupport.parkNanos(this, nanosTimeout);
53.2180 + if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
53.2181 + break;
53.2182 + long now = System.nanoTime();
53.2183 + nanosTimeout -= now - lastTime;
53.2184 + lastTime = now;
53.2185 + }
53.2186 + if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
53.2187 + interruptMode = REINTERRUPT;
53.2188 + if (node.nextWaiter != null)
53.2189 + unlinkCancelledWaiters();
53.2190 + if (interruptMode != 0)
53.2191 + reportInterruptAfterWait(interruptMode);
53.2192 + return !timedout;
53.2193 + }
53.2194 +
53.2195 + // support for instrumentation
53.2196 +
53.2197 + /**
53.2198 + * Returns true if this condition was created by the given
53.2199 + * synchronization object.
53.2200 + *
53.2201 + * @return {@code true} if owned
53.2202 + */
53.2203 + final boolean isOwnedBy(AbstractQueuedSynchronizer sync) {
53.2204 + return sync == AbstractQueuedSynchronizer.this;
53.2205 + }
53.2206 +
53.2207 + /**
53.2208 + * Queries whether any threads are waiting on this condition.
53.2209 + * Implements {@link AbstractQueuedSynchronizer#hasWaiters}.
53.2210 + *
53.2211 + * @return {@code true} if there are any waiting threads
53.2212 + * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
53.2213 + * returns {@code false}
53.2214 + */
53.2215 + protected final boolean hasWaiters() {
53.2216 + if (!isHeldExclusively())
53.2217 + throw new IllegalMonitorStateException();
53.2218 + for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
53.2219 + if (w.waitStatus == Node.CONDITION)
53.2220 + return true;
53.2221 + }
53.2222 + return false;
53.2223 + }
53.2224 +
53.2225 + /**
53.2226 + * Returns an estimate of the number of threads waiting on
53.2227 + * this condition.
53.2228 + * Implements {@link AbstractQueuedSynchronizer#getWaitQueueLength}.
53.2229 + *
53.2230 + * @return the estimated number of waiting threads
53.2231 + * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
53.2232 + * returns {@code false}
53.2233 + */
53.2234 + protected final int getWaitQueueLength() {
53.2235 + if (!isHeldExclusively())
53.2236 + throw new IllegalMonitorStateException();
53.2237 + int n = 0;
53.2238 + for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
53.2239 + if (w.waitStatus == Node.CONDITION)
53.2240 + ++n;
53.2241 + }
53.2242 + return n;
53.2243 + }
53.2244 +
53.2245 + /**
53.2246 + * Returns a collection containing those threads that may be
53.2247 + * waiting on this Condition.
53.2248 + * Implements {@link AbstractQueuedSynchronizer#getWaitingThreads}.
53.2249 + *
53.2250 + * @return the collection of threads
53.2251 + * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
53.2252 + * returns {@code false}
53.2253 + */
53.2254 + protected final Collection<Thread> getWaitingThreads() {
53.2255 + if (!isHeldExclusively())
53.2256 + throw new IllegalMonitorStateException();
53.2257 + ArrayList<Thread> list = new ArrayList<Thread>();
53.2258 + for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
53.2259 + if (w.waitStatus == Node.CONDITION) {
53.2260 + Thread t = w.thread;
53.2261 + if (t != null)
53.2262 + list.add(t);
53.2263 + }
53.2264 + }
53.2265 + return list;
53.2266 + }
53.2267 + }
53.2268 +
53.2269 + /**
53.2270 + * Setup to support compareAndSet. We need to natively implement
53.2271 + * this here: For the sake of permitting future enhancements, we
53.2272 + * cannot explicitly subclass AtomicInteger, which would be
53.2273 + * efficient and useful otherwise. So, as the lesser of evils, we
53.2274 + * natively implement using hotspot intrinsics API. And while we
53.2275 + * are at it, we do the same for other CASable fields (which could
53.2276 + * otherwise be done with atomic field updaters).
53.2277 + */
53.2278 + private static final Unsafe unsafe = Unsafe.getUnsafe();
53.2279 + private static final long stateOffset;
53.2280 + private static final long headOffset;
53.2281 + private static final long tailOffset;
53.2282 + private static final long waitStatusOffset;
53.2283 + private static final long nextOffset;
53.2284 +
53.2285 + static {
53.2286 + try {
53.2287 + stateOffset = unsafe.objectFieldOffset
53.2288 + (AbstractQueuedSynchronizer.class.getDeclaredField("state"));
53.2289 + headOffset = unsafe.objectFieldOffset
53.2290 + (AbstractQueuedSynchronizer.class.getDeclaredField("head"));
53.2291 + tailOffset = unsafe.objectFieldOffset
53.2292 + (AbstractQueuedSynchronizer.class.getDeclaredField("tail"));
53.2293 + waitStatusOffset = unsafe.objectFieldOffset
53.2294 + (Node.class.getDeclaredField("waitStatus"));
53.2295 + nextOffset = unsafe.objectFieldOffset
53.2296 + (Node.class.getDeclaredField("next"));
53.2297 +
53.2298 + } catch (Exception ex) { throw new Error(ex); }
53.2299 + }
53.2300 +
53.2301 + /**
53.2302 + * CAS head field. Used only by enq.
53.2303 + */
53.2304 + private final boolean compareAndSetHead(Node update) {
53.2305 + return unsafe.compareAndSwapObject(this, headOffset, null, update);
53.2306 + }
53.2307 +
53.2308 + /**
53.2309 + * CAS tail field. Used only by enq.
53.2310 + */
53.2311 + private final boolean compareAndSetTail(Node expect, Node update) {
53.2312 + return unsafe.compareAndSwapObject(this, tailOffset, expect, update);
53.2313 + }
53.2314 +
53.2315 + /**
53.2316 + * CAS waitStatus field of a node.
53.2317 + */
53.2318 + private static final boolean compareAndSetWaitStatus(Node node,
53.2319 + int expect,
53.2320 + int update) {
53.2321 + return unsafe.compareAndSwapInt(node, waitStatusOffset,
53.2322 + expect, update);
53.2323 + }
53.2324 +
53.2325 + /**
53.2326 + * CAS next field of a node.
53.2327 + */
53.2328 + private static final boolean compareAndSetNext(Node node,
53.2329 + Node expect,
53.2330 + Node update) {
53.2331 + return unsafe.compareAndSwapObject(node, nextOffset, expect, update);
53.2332 + }
53.2333 +}
54.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
54.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/locks/Condition.java Sat Mar 19 10:48:29 2016 +0100
54.3 @@ -0,0 +1,488 @@
54.4 +/*
54.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
54.6 + *
54.7 + * This code is free software; you can redistribute it and/or modify it
54.8 + * under the terms of the GNU General Public License version 2 only, as
54.9 + * published by the Free Software Foundation. Oracle designates this
54.10 + * particular file as subject to the "Classpath" exception as provided
54.11 + * by Oracle in the LICENSE file that accompanied this code.
54.12 + *
54.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
54.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
54.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
54.16 + * version 2 for more details (a copy is included in the LICENSE file that
54.17 + * accompanied this code).
54.18 + *
54.19 + * You should have received a copy of the GNU General Public License version
54.20 + * 2 along with this work; if not, write to the Free Software Foundation,
54.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
54.22 + *
54.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
54.24 + * or visit www.oracle.com if you need additional information or have any
54.25 + * questions.
54.26 + */
54.27 +
54.28 +/*
54.29 + * This file is available under and governed by the GNU General Public
54.30 + * License version 2 only, as published by the Free Software Foundation.
54.31 + * However, the following notice accompanied the original version of this
54.32 + * file:
54.33 + *
54.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
54.35 + * Expert Group and released to the public domain, as explained at
54.36 + * http://creativecommons.org/publicdomain/zero/1.0/
54.37 + */
54.38 +
54.39 +package java.util.concurrent.locks;
54.40 +import java.util.concurrent.*;
54.41 +import java.util.Date;
54.42 +
54.43 +/**
54.44 + * {@code Condition} factors out the {@code Object} monitor
54.45 + * methods ({@link Object#wait() wait}, {@link Object#notify notify}
54.46 + * and {@link Object#notifyAll notifyAll}) into distinct objects to
54.47 + * give the effect of having multiple wait-sets per object, by
54.48 + * combining them with the use of arbitrary {@link Lock} implementations.
54.49 + * Where a {@code Lock} replaces the use of {@code synchronized} methods
54.50 + * and statements, a {@code Condition} replaces the use of the Object
54.51 + * monitor methods.
54.52 + *
54.53 + * <p>Conditions (also known as <em>condition queues</em> or
54.54 + * <em>condition variables</em>) provide a means for one thread to
54.55 + * suspend execution (to "wait") until notified by another
54.56 + * thread that some state condition may now be true. Because access
54.57 + * to this shared state information occurs in different threads, it
54.58 + * must be protected, so a lock of some form is associated with the
54.59 + * condition. The key property that waiting for a condition provides
54.60 + * is that it <em>atomically</em> releases the associated lock and
54.61 + * suspends the current thread, just like {@code Object.wait}.
54.62 + *
54.63 + * <p>A {@code Condition} instance is intrinsically bound to a lock.
54.64 + * To obtain a {@code Condition} instance for a particular {@link Lock}
54.65 + * instance use its {@link Lock#newCondition newCondition()} method.
54.66 + *
54.67 + * <p>As an example, suppose we have a bounded buffer which supports
54.68 + * {@code put} and {@code take} methods. If a
54.69 + * {@code take} is attempted on an empty buffer, then the thread will block
54.70 + * until an item becomes available; if a {@code put} is attempted on a
54.71 + * full buffer, then the thread will block until a space becomes available.
54.72 + * We would like to keep waiting {@code put} threads and {@code take}
54.73 + * threads in separate wait-sets so that we can use the optimization of
54.74 + * only notifying a single thread at a time when items or spaces become
54.75 + * available in the buffer. This can be achieved using two
54.76 + * {@link Condition} instances.
54.77 + * <pre>
54.78 + * class BoundedBuffer {
54.79 + * <b>final Lock lock = new ReentrantLock();</b>
54.80 + * final Condition notFull = <b>lock.newCondition(); </b>
54.81 + * final Condition notEmpty = <b>lock.newCondition(); </b>
54.82 + *
54.83 + * final Object[] items = new Object[100];
54.84 + * int putptr, takeptr, count;
54.85 + *
54.86 + * public void put(Object x) throws InterruptedException {
54.87 + * <b>lock.lock();
54.88 + * try {</b>
54.89 + * while (count == items.length)
54.90 + * <b>notFull.await();</b>
54.91 + * items[putptr] = x;
54.92 + * if (++putptr == items.length) putptr = 0;
54.93 + * ++count;
54.94 + * <b>notEmpty.signal();</b>
54.95 + * <b>} finally {
54.96 + * lock.unlock();
54.97 + * }</b>
54.98 + * }
54.99 + *
54.100 + * public Object take() throws InterruptedException {
54.101 + * <b>lock.lock();
54.102 + * try {</b>
54.103 + * while (count == 0)
54.104 + * <b>notEmpty.await();</b>
54.105 + * Object x = items[takeptr];
54.106 + * if (++takeptr == items.length) takeptr = 0;
54.107 + * --count;
54.108 + * <b>notFull.signal();</b>
54.109 + * return x;
54.110 + * <b>} finally {
54.111 + * lock.unlock();
54.112 + * }</b>
54.113 + * }
54.114 + * }
54.115 + * </pre>
54.116 + *
54.117 + * (The {@link java.util.concurrent.ArrayBlockingQueue} class provides
54.118 + * this functionality, so there is no reason to implement this
54.119 + * sample usage class.)
54.120 + *
54.121 + * <p>A {@code Condition} implementation can provide behavior and semantics
54.122 + * that is
54.123 + * different from that of the {@code Object} monitor methods, such as
54.124 + * guaranteed ordering for notifications, or not requiring a lock to be held
54.125 + * when performing notifications.
54.126 + * If an implementation provides such specialized semantics then the
54.127 + * implementation must document those semantics.
54.128 + *
54.129 + * <p>Note that {@code Condition} instances are just normal objects and can
54.130 + * themselves be used as the target in a {@code synchronized} statement,
54.131 + * and can have their own monitor {@link Object#wait wait} and
54.132 + * {@link Object#notify notification} methods invoked.
54.133 + * Acquiring the monitor lock of a {@code Condition} instance, or using its
54.134 + * monitor methods, has no specified relationship with acquiring the
54.135 + * {@link Lock} associated with that {@code Condition} or the use of its
54.136 + * {@linkplain #await waiting} and {@linkplain #signal signalling} methods.
54.137 + * It is recommended that to avoid confusion you never use {@code Condition}
54.138 + * instances in this way, except perhaps within their own implementation.
54.139 + *
54.140 + * <p>Except where noted, passing a {@code null} value for any parameter
54.141 + * will result in a {@link NullPointerException} being thrown.
54.142 + *
54.143 + * <h3>Implementation Considerations</h3>
54.144 + *
54.145 + * <p>When waiting upon a {@code Condition}, a "<em>spurious
54.146 + * wakeup</em>" is permitted to occur, in
54.147 + * general, as a concession to the underlying platform semantics.
54.148 + * This has little practical impact on most application programs as a
54.149 + * {@code Condition} should always be waited upon in a loop, testing
54.150 + * the state predicate that is being waited for. An implementation is
54.151 + * free to remove the possibility of spurious wakeups but it is
54.152 + * recommended that applications programmers always assume that they can
54.153 + * occur and so always wait in a loop.
54.154 + *
54.155 + * <p>The three forms of condition waiting
54.156 + * (interruptible, non-interruptible, and timed) may differ in their ease of
54.157 + * implementation on some platforms and in their performance characteristics.
54.158 + * In particular, it may be difficult to provide these features and maintain
54.159 + * specific semantics such as ordering guarantees.
54.160 + * Further, the ability to interrupt the actual suspension of the thread may
54.161 + * not always be feasible to implement on all platforms.
54.162 + *
54.163 + * <p>Consequently, an implementation is not required to define exactly the
54.164 + * same guarantees or semantics for all three forms of waiting, nor is it
54.165 + * required to support interruption of the actual suspension of the thread.
54.166 + *
54.167 + * <p>An implementation is required to
54.168 + * clearly document the semantics and guarantees provided by each of the
54.169 + * waiting methods, and when an implementation does support interruption of
54.170 + * thread suspension then it must obey the interruption semantics as defined
54.171 + * in this interface.
54.172 + *
54.173 + * <p>As interruption generally implies cancellation, and checks for
54.174 + * interruption are often infrequent, an implementation can favor responding
54.175 + * to an interrupt over normal method return. This is true even if it can be
54.176 + * shown that the interrupt occurred after another action that may have
54.177 + * unblocked the thread. An implementation should document this behavior.
54.178 + *
54.179 + * @since 1.5
54.180 + * @author Doug Lea
54.181 + */
54.182 +public interface Condition {
54.183 +
54.184 + /**
54.185 + * Causes the current thread to wait until it is signalled or
54.186 + * {@linkplain Thread#interrupt interrupted}.
54.187 + *
54.188 + * <p>The lock associated with this {@code Condition} is atomically
54.189 + * released and the current thread becomes disabled for thread scheduling
54.190 + * purposes and lies dormant until <em>one</em> of four things happens:
54.191 + * <ul>
54.192 + * <li>Some other thread invokes the {@link #signal} method for this
54.193 + * {@code Condition} and the current thread happens to be chosen as the
54.194 + * thread to be awakened; or
54.195 + * <li>Some other thread invokes the {@link #signalAll} method for this
54.196 + * {@code Condition}; or
54.197 + * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
54.198 + * current thread, and interruption of thread suspension is supported; or
54.199 + * <li>A "<em>spurious wakeup</em>" occurs.
54.200 + * </ul>
54.201 + *
54.202 + * <p>In all cases, before this method can return the current thread must
54.203 + * re-acquire the lock associated with this condition. When the
54.204 + * thread returns it is <em>guaranteed</em> to hold this lock.
54.205 + *
54.206 + * <p>If the current thread:
54.207 + * <ul>
54.208 + * <li>has its interrupted status set on entry to this method; or
54.209 + * <li>is {@linkplain Thread#interrupt interrupted} while waiting
54.210 + * and interruption of thread suspension is supported,
54.211 + * </ul>
54.212 + * then {@link InterruptedException} is thrown and the current thread's
54.213 + * interrupted status is cleared. It is not specified, in the first
54.214 + * case, whether or not the test for interruption occurs before the lock
54.215 + * is released.
54.216 + *
54.217 + * <p><b>Implementation Considerations</b>
54.218 + *
54.219 + * <p>The current thread is assumed to hold the lock associated with this
54.220 + * {@code Condition} when this method is called.
54.221 + * It is up to the implementation to determine if this is
54.222 + * the case and if not, how to respond. Typically, an exception will be
54.223 + * thrown (such as {@link IllegalMonitorStateException}) and the
54.224 + * implementation must document that fact.
54.225 + *
54.226 + * <p>An implementation can favor responding to an interrupt over normal
54.227 + * method return in response to a signal. In that case the implementation
54.228 + * must ensure that the signal is redirected to another waiting thread, if
54.229 + * there is one.
54.230 + *
54.231 + * @throws InterruptedException if the current thread is interrupted
54.232 + * (and interruption of thread suspension is supported)
54.233 + */
54.234 + void await() throws InterruptedException;
54.235 +
54.236 + /**
54.237 + * Causes the current thread to wait until it is signalled.
54.238 + *
54.239 + * <p>The lock associated with this condition is atomically
54.240 + * released and the current thread becomes disabled for thread scheduling
54.241 + * purposes and lies dormant until <em>one</em> of three things happens:
54.242 + * <ul>
54.243 + * <li>Some other thread invokes the {@link #signal} method for this
54.244 + * {@code Condition} and the current thread happens to be chosen as the
54.245 + * thread to be awakened; or
54.246 + * <li>Some other thread invokes the {@link #signalAll} method for this
54.247 + * {@code Condition}; or
54.248 + * <li>A "<em>spurious wakeup</em>" occurs.
54.249 + * </ul>
54.250 + *
54.251 + * <p>In all cases, before this method can return the current thread must
54.252 + * re-acquire the lock associated with this condition. When the
54.253 + * thread returns it is <em>guaranteed</em> to hold this lock.
54.254 + *
54.255 + * <p>If the current thread's interrupted status is set when it enters
54.256 + * this method, or it is {@linkplain Thread#interrupt interrupted}
54.257 + * while waiting, it will continue to wait until signalled. When it finally
54.258 + * returns from this method its interrupted status will still
54.259 + * be set.
54.260 + *
54.261 + * <p><b>Implementation Considerations</b>
54.262 + *
54.263 + * <p>The current thread is assumed to hold the lock associated with this
54.264 + * {@code Condition} when this method is called.
54.265 + * It is up to the implementation to determine if this is
54.266 + * the case and if not, how to respond. Typically, an exception will be
54.267 + * thrown (such as {@link IllegalMonitorStateException}) and the
54.268 + * implementation must document that fact.
54.269 + */
54.270 + void awaitUninterruptibly();
54.271 +
54.272 + /**
54.273 + * Causes the current thread to wait until it is signalled or interrupted,
54.274 + * or the specified waiting time elapses.
54.275 + *
54.276 + * <p>The lock associated with this condition is atomically
54.277 + * released and the current thread becomes disabled for thread scheduling
54.278 + * purposes and lies dormant until <em>one</em> of five things happens:
54.279 + * <ul>
54.280 + * <li>Some other thread invokes the {@link #signal} method for this
54.281 + * {@code Condition} and the current thread happens to be chosen as the
54.282 + * thread to be awakened; or
54.283 + * <li>Some other thread invokes the {@link #signalAll} method for this
54.284 + * {@code Condition}; or
54.285 + * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
54.286 + * current thread, and interruption of thread suspension is supported; or
54.287 + * <li>The specified waiting time elapses; or
54.288 + * <li>A "<em>spurious wakeup</em>" occurs.
54.289 + * </ul>
54.290 + *
54.291 + * <p>In all cases, before this method can return the current thread must
54.292 + * re-acquire the lock associated with this condition. When the
54.293 + * thread returns it is <em>guaranteed</em> to hold this lock.
54.294 + *
54.295 + * <p>If the current thread:
54.296 + * <ul>
54.297 + * <li>has its interrupted status set on entry to this method; or
54.298 + * <li>is {@linkplain Thread#interrupt interrupted} while waiting
54.299 + * and interruption of thread suspension is supported,
54.300 + * </ul>
54.301 + * then {@link InterruptedException} is thrown and the current thread's
54.302 + * interrupted status is cleared. It is not specified, in the first
54.303 + * case, whether or not the test for interruption occurs before the lock
54.304 + * is released.
54.305 + *
54.306 + * <p>The method returns an estimate of the number of nanoseconds
54.307 + * remaining to wait given the supplied {@code nanosTimeout}
54.308 + * value upon return, or a value less than or equal to zero if it
54.309 + * timed out. This value can be used to determine whether and how
54.310 + * long to re-wait in cases where the wait returns but an awaited
54.311 + * condition still does not hold. Typical uses of this method take
54.312 + * the following form:
54.313 + *
54.314 + * <pre> {@code
54.315 + * boolean aMethod(long timeout, TimeUnit unit) {
54.316 + * long nanos = unit.toNanos(timeout);
54.317 + * lock.lock();
54.318 + * try {
54.319 + * while (!conditionBeingWaitedFor()) {
54.320 + * if (nanos <= 0L)
54.321 + * return false;
54.322 + * nanos = theCondition.awaitNanos(nanos);
54.323 + * }
54.324 + * // ...
54.325 + * } finally {
54.326 + * lock.unlock();
54.327 + * }
54.328 + * }}</pre>
54.329 + *
54.330 + * <p> Design note: This method requires a nanosecond argument so
54.331 + * as to avoid truncation errors in reporting remaining times.
54.332 + * Such precision loss would make it difficult for programmers to
54.333 + * ensure that total waiting times are not systematically shorter
54.334 + * than specified when re-waits occur.
54.335 + *
54.336 + * <p><b>Implementation Considerations</b>
54.337 + *
54.338 + * <p>The current thread is assumed to hold the lock associated with this
54.339 + * {@code Condition} when this method is called.
54.340 + * It is up to the implementation to determine if this is
54.341 + * the case and if not, how to respond. Typically, an exception will be
54.342 + * thrown (such as {@link IllegalMonitorStateException}) and the
54.343 + * implementation must document that fact.
54.344 + *
54.345 + * <p>An implementation can favor responding to an interrupt over normal
54.346 + * method return in response to a signal, or over indicating the elapse
54.347 + * of the specified waiting time. In either case the implementation
54.348 + * must ensure that the signal is redirected to another waiting thread, if
54.349 + * there is one.
54.350 + *
54.351 + * @param nanosTimeout the maximum time to wait, in nanoseconds
54.352 + * @return an estimate of the {@code nanosTimeout} value minus
54.353 + * the time spent waiting upon return from this method.
54.354 + * A positive value may be used as the argument to a
54.355 + * subsequent call to this method to finish waiting out
54.356 + * the desired time. A value less than or equal to zero
54.357 + * indicates that no time remains.
54.358 + * @throws InterruptedException if the current thread is interrupted
54.359 + * (and interruption of thread suspension is supported)
54.360 + */
54.361 + long awaitNanos(long nanosTimeout) throws InterruptedException;
54.362 +
54.363 + /**
54.364 + * Causes the current thread to wait until it is signalled or interrupted,
54.365 + * or the specified waiting time elapses. This method is behaviorally
54.366 + * equivalent to:<br>
54.367 + * <pre>
54.368 + * awaitNanos(unit.toNanos(time)) > 0
54.369 + * </pre>
54.370 + * @param time the maximum time to wait
54.371 + * @param unit the time unit of the {@code time} argument
54.372 + * @return {@code false} if the waiting time detectably elapsed
54.373 + * before return from the method, else {@code true}
54.374 + * @throws InterruptedException if the current thread is interrupted
54.375 + * (and interruption of thread suspension is supported)
54.376 + */
54.377 + boolean await(long time, TimeUnit unit) throws InterruptedException;
54.378 +
54.379 + /**
54.380 + * Causes the current thread to wait until it is signalled or interrupted,
54.381 + * or the specified deadline elapses.
54.382 + *
54.383 + * <p>The lock associated with this condition is atomically
54.384 + * released and the current thread becomes disabled for thread scheduling
54.385 + * purposes and lies dormant until <em>one</em> of five things happens:
54.386 + * <ul>
54.387 + * <li>Some other thread invokes the {@link #signal} method for this
54.388 + * {@code Condition} and the current thread happens to be chosen as the
54.389 + * thread to be awakened; or
54.390 + * <li>Some other thread invokes the {@link #signalAll} method for this
54.391 + * {@code Condition}; or
54.392 + * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
54.393 + * current thread, and interruption of thread suspension is supported; or
54.394 + * <li>The specified deadline elapses; or
54.395 + * <li>A "<em>spurious wakeup</em>" occurs.
54.396 + * </ul>
54.397 + *
54.398 + * <p>In all cases, before this method can return the current thread must
54.399 + * re-acquire the lock associated with this condition. When the
54.400 + * thread returns it is <em>guaranteed</em> to hold this lock.
54.401 + *
54.402 + *
54.403 + * <p>If the current thread:
54.404 + * <ul>
54.405 + * <li>has its interrupted status set on entry to this method; or
54.406 + * <li>is {@linkplain Thread#interrupt interrupted} while waiting
54.407 + * and interruption of thread suspension is supported,
54.408 + * </ul>
54.409 + * then {@link InterruptedException} is thrown and the current thread's
54.410 + * interrupted status is cleared. It is not specified, in the first
54.411 + * case, whether or not the test for interruption occurs before the lock
54.412 + * is released.
54.413 + *
54.414 + *
54.415 + * <p>The return value indicates whether the deadline has elapsed,
54.416 + * which can be used as follows:
54.417 + * <pre> {@code
54.418 + * boolean aMethod(Date deadline) {
54.419 + * boolean stillWaiting = true;
54.420 + * lock.lock();
54.421 + * try {
54.422 + * while (!conditionBeingWaitedFor()) {
54.423 + * if (!stillWaiting)
54.424 + * return false;
54.425 + * stillWaiting = theCondition.awaitUntil(deadline);
54.426 + * }
54.427 + * // ...
54.428 + * } finally {
54.429 + * lock.unlock();
54.430 + * }
54.431 + * }}</pre>
54.432 + *
54.433 + * <p><b>Implementation Considerations</b>
54.434 + *
54.435 + * <p>The current thread is assumed to hold the lock associated with this
54.436 + * {@code Condition} when this method is called.
54.437 + * It is up to the implementation to determine if this is
54.438 + * the case and if not, how to respond. Typically, an exception will be
54.439 + * thrown (such as {@link IllegalMonitorStateException}) and the
54.440 + * implementation must document that fact.
54.441 + *
54.442 + * <p>An implementation can favor responding to an interrupt over normal
54.443 + * method return in response to a signal, or over indicating the passing
54.444 + * of the specified deadline. In either case the implementation
54.445 + * must ensure that the signal is redirected to another waiting thread, if
54.446 + * there is one.
54.447 + *
54.448 + * @param deadline the absolute time to wait until
54.449 + * @return {@code false} if the deadline has elapsed upon return, else
54.450 + * {@code true}
54.451 + * @throws InterruptedException if the current thread is interrupted
54.452 + * (and interruption of thread suspension is supported)
54.453 + */
54.454 + boolean awaitUntil(Date deadline) throws InterruptedException;
54.455 +
54.456 + /**
54.457 + * Wakes up one waiting thread.
54.458 + *
54.459 + * <p>If any threads are waiting on this condition then one
54.460 + * is selected for waking up. That thread must then re-acquire the
54.461 + * lock before returning from {@code await}.
54.462 + *
54.463 + * <p><b>Implementation Considerations</b>
54.464 + *
54.465 + * <p>An implementation may (and typically does) require that the
54.466 + * current thread hold the lock associated with this {@code
54.467 + * Condition} when this method is called. Implementations must
54.468 + * document this precondition and any actions taken if the lock is
54.469 + * not held. Typically, an exception such as {@link
54.470 + * IllegalMonitorStateException} will be thrown.
54.471 + */
54.472 + void signal();
54.473 +
54.474 + /**
54.475 + * Wakes up all waiting threads.
54.476 + *
54.477 + * <p>If any threads are waiting on this condition then they are
54.478 + * all woken up. Each thread must re-acquire the lock before it can
54.479 + * return from {@code await}.
54.480 + *
54.481 + * <p><b>Implementation Considerations</b>
54.482 + *
54.483 + * <p>An implementation may (and typically does) require that the
54.484 + * current thread hold the lock associated with this {@code
54.485 + * Condition} when this method is called. Implementations must
54.486 + * document this precondition and any actions taken if the lock is
54.487 + * not held. Typically, an exception such as {@link
54.488 + * IllegalMonitorStateException} will be thrown.
54.489 + */
54.490 + void signalAll();
54.491 +}
55.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
55.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/locks/Lock.java Sat Mar 19 10:48:29 2016 +0100
55.3 @@ -0,0 +1,356 @@
55.4 +/*
55.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55.6 + *
55.7 + * This code is free software; you can redistribute it and/or modify it
55.8 + * under the terms of the GNU General Public License version 2 only, as
55.9 + * published by the Free Software Foundation. Oracle designates this
55.10 + * particular file as subject to the "Classpath" exception as provided
55.11 + * by Oracle in the LICENSE file that accompanied this code.
55.12 + *
55.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
55.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
55.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
55.16 + * version 2 for more details (a copy is included in the LICENSE file that
55.17 + * accompanied this code).
55.18 + *
55.19 + * You should have received a copy of the GNU General Public License version
55.20 + * 2 along with this work; if not, write to the Free Software Foundation,
55.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
55.22 + *
55.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
55.24 + * or visit www.oracle.com if you need additional information or have any
55.25 + * questions.
55.26 + */
55.27 +
55.28 +/*
55.29 + * This file is available under and governed by the GNU General Public
55.30 + * License version 2 only, as published by the Free Software Foundation.
55.31 + * However, the following notice accompanied the original version of this
55.32 + * file:
55.33 + *
55.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
55.35 + * Expert Group and released to the public domain, as explained at
55.36 + * http://creativecommons.org/publicdomain/zero/1.0/
55.37 + */
55.38 +
55.39 +package java.util.concurrent.locks;
55.40 +import java.util.concurrent.TimeUnit;
55.41 +
55.42 +/**
55.43 + * {@code Lock} implementations provide more extensive locking
55.44 + * operations than can be obtained using {@code synchronized} methods
55.45 + * and statements. They allow more flexible structuring, may have
55.46 + * quite different properties, and may support multiple associated
55.47 + * {@link Condition} objects.
55.48 + *
55.49 + * <p>A lock is a tool for controlling access to a shared resource by
55.50 + * multiple threads. Commonly, a lock provides exclusive access to a
55.51 + * shared resource: only one thread at a time can acquire the lock and
55.52 + * all access to the shared resource requires that the lock be
55.53 + * acquired first. However, some locks may allow concurrent access to
55.54 + * a shared resource, such as the read lock of a {@link ReadWriteLock}.
55.55 + *
55.56 + * <p>The use of {@code synchronized} methods or statements provides
55.57 + * access to the implicit monitor lock associated with every object, but
55.58 + * forces all lock acquisition and release to occur in a block-structured way:
55.59 + * when multiple locks are acquired they must be released in the opposite
55.60 + * order, and all locks must be released in the same lexical scope in which
55.61 + * they were acquired.
55.62 + *
55.63 + * <p>While the scoping mechanism for {@code synchronized} methods
55.64 + * and statements makes it much easier to program with monitor locks,
55.65 + * and helps avoid many common programming errors involving locks,
55.66 + * there are occasions where you need to work with locks in a more
55.67 + * flexible way. For example, some algorithms for traversing
55.68 + * concurrently accessed data structures require the use of
55.69 + * "hand-over-hand" or "chain locking": you
55.70 + * acquire the lock of node A, then node B, then release A and acquire
55.71 + * C, then release B and acquire D and so on. Implementations of the
55.72 + * {@code Lock} interface enable the use of such techniques by
55.73 + * allowing a lock to be acquired and released in different scopes,
55.74 + * and allowing multiple locks to be acquired and released in any
55.75 + * order.
55.76 + *
55.77 + * <p>With this increased flexibility comes additional
55.78 + * responsibility. The absence of block-structured locking removes the
55.79 + * automatic release of locks that occurs with {@code synchronized}
55.80 + * methods and statements. In most cases, the following idiom
55.81 + * should be used:
55.82 + *
55.83 + * <pre><tt> Lock l = ...;
55.84 + * l.lock();
55.85 + * try {
55.86 + * // access the resource protected by this lock
55.87 + * } finally {
55.88 + * l.unlock();
55.89 + * }
55.90 + * </tt></pre>
55.91 + *
55.92 + * When locking and unlocking occur in different scopes, care must be
55.93 + * taken to ensure that all code that is executed while the lock is
55.94 + * held is protected by try-finally or try-catch to ensure that the
55.95 + * lock is released when necessary.
55.96 + *
55.97 + * <p>{@code Lock} implementations provide additional functionality
55.98 + * over the use of {@code synchronized} methods and statements by
55.99 + * providing a non-blocking attempt to acquire a lock ({@link
55.100 + * #tryLock()}), an attempt to acquire the lock that can be
55.101 + * interrupted ({@link #lockInterruptibly}, and an attempt to acquire
55.102 + * the lock that can timeout ({@link #tryLock(long, TimeUnit)}).
55.103 + *
55.104 + * <p>A {@code Lock} class can also provide behavior and semantics
55.105 + * that is quite different from that of the implicit monitor lock,
55.106 + * such as guaranteed ordering, non-reentrant usage, or deadlock
55.107 + * detection. If an implementation provides such specialized semantics
55.108 + * then the implementation must document those semantics.
55.109 + *
55.110 + * <p>Note that {@code Lock} instances are just normal objects and can
55.111 + * themselves be used as the target in a {@code synchronized} statement.
55.112 + * Acquiring the
55.113 + * monitor lock of a {@code Lock} instance has no specified relationship
55.114 + * with invoking any of the {@link #lock} methods of that instance.
55.115 + * It is recommended that to avoid confusion you never use {@code Lock}
55.116 + * instances in this way, except within their own implementation.
55.117 + *
55.118 + * <p>Except where noted, passing a {@code null} value for any
55.119 + * parameter will result in a {@link NullPointerException} being
55.120 + * thrown.
55.121 + *
55.122 + * <h3>Memory Synchronization</h3>
55.123 + *
55.124 + * <p>All {@code Lock} implementations <em>must</em> enforce the same
55.125 + * memory synchronization semantics as provided by the built-in monitor
55.126 + * lock, as described in section 17.4 of
55.127 + * <cite>The Java™ Language Specification</cite>:
55.128 + * <ul>
55.129 + * <li>A successful {@code lock} operation has the same memory
55.130 + * synchronization effects as a successful <em>Lock</em> action.
55.131 + * <li>A successful {@code unlock} operation has the same
55.132 + * memory synchronization effects as a successful <em>Unlock</em> action.
55.133 + * </ul>
55.134 + *
55.135 + * Unsuccessful locking and unlocking operations, and reentrant
55.136 + * locking/unlocking operations, do not require any memory
55.137 + * synchronization effects.
55.138 + *
55.139 + * <h3>Implementation Considerations</h3>
55.140 + *
55.141 + * <p> The three forms of lock acquisition (interruptible,
55.142 + * non-interruptible, and timed) may differ in their performance
55.143 + * characteristics, ordering guarantees, or other implementation
55.144 + * qualities. Further, the ability to interrupt the <em>ongoing</em>
55.145 + * acquisition of a lock may not be available in a given {@code Lock}
55.146 + * class. Consequently, an implementation is not required to define
55.147 + * exactly the same guarantees or semantics for all three forms of
55.148 + * lock acquisition, nor is it required to support interruption of an
55.149 + * ongoing lock acquisition. An implementation is required to clearly
55.150 + * document the semantics and guarantees provided by each of the
55.151 + * locking methods. It must also obey the interruption semantics as
55.152 + * defined in this interface, to the extent that interruption of lock
55.153 + * acquisition is supported: which is either totally, or only on
55.154 + * method entry.
55.155 + *
55.156 + * <p>As interruption generally implies cancellation, and checks for
55.157 + * interruption are often infrequent, an implementation can favor responding
55.158 + * to an interrupt over normal method return. This is true even if it can be
55.159 + * shown that the interrupt occurred after another action may have unblocked
55.160 + * the thread. An implementation should document this behavior.
55.161 + *
55.162 + * @see ReentrantLock
55.163 + * @see Condition
55.164 + * @see ReadWriteLock
55.165 + *
55.166 + * @since 1.5
55.167 + * @author Doug Lea
55.168 + */
55.169 +public interface Lock {
55.170 +
55.171 + /**
55.172 + * Acquires the lock.
55.173 + *
55.174 + * <p>If the lock is not available then the current thread becomes
55.175 + * disabled for thread scheduling purposes and lies dormant until the
55.176 + * lock has been acquired.
55.177 + *
55.178 + * <p><b>Implementation Considerations</b>
55.179 + *
55.180 + * <p>A {@code Lock} implementation may be able to detect erroneous use
55.181 + * of the lock, such as an invocation that would cause deadlock, and
55.182 + * may throw an (unchecked) exception in such circumstances. The
55.183 + * circumstances and the exception type must be documented by that
55.184 + * {@code Lock} implementation.
55.185 + */
55.186 + void lock();
55.187 +
55.188 + /**
55.189 + * Acquires the lock unless the current thread is
55.190 + * {@linkplain Thread#interrupt interrupted}.
55.191 + *
55.192 + * <p>Acquires the lock if it is available and returns immediately.
55.193 + *
55.194 + * <p>If the lock is not available then the current thread becomes
55.195 + * disabled for thread scheduling purposes and lies dormant until
55.196 + * one of two things happens:
55.197 + *
55.198 + * <ul>
55.199 + * <li>The lock is acquired by the current thread; or
55.200 + * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
55.201 + * current thread, and interruption of lock acquisition is supported.
55.202 + * </ul>
55.203 + *
55.204 + * <p>If the current thread:
55.205 + * <ul>
55.206 + * <li>has its interrupted status set on entry to this method; or
55.207 + * <li>is {@linkplain Thread#interrupt interrupted} while acquiring the
55.208 + * lock, and interruption of lock acquisition is supported,
55.209 + * </ul>
55.210 + * then {@link InterruptedException} is thrown and the current thread's
55.211 + * interrupted status is cleared.
55.212 + *
55.213 + * <p><b>Implementation Considerations</b>
55.214 + *
55.215 + * <p>The ability to interrupt a lock acquisition in some
55.216 + * implementations may not be possible, and if possible may be an
55.217 + * expensive operation. The programmer should be aware that this
55.218 + * may be the case. An implementation should document when this is
55.219 + * the case.
55.220 + *
55.221 + * <p>An implementation can favor responding to an interrupt over
55.222 + * normal method return.
55.223 + *
55.224 + * <p>A {@code Lock} implementation may be able to detect
55.225 + * erroneous use of the lock, such as an invocation that would
55.226 + * cause deadlock, and may throw an (unchecked) exception in such
55.227 + * circumstances. The circumstances and the exception type must
55.228 + * be documented by that {@code Lock} implementation.
55.229 + *
55.230 + * @throws InterruptedException if the current thread is
55.231 + * interrupted while acquiring the lock (and interruption
55.232 + * of lock acquisition is supported).
55.233 + */
55.234 + void lockInterruptibly() throws InterruptedException;
55.235 +
55.236 + /**
55.237 + * Acquires the lock only if it is free at the time of invocation.
55.238 + *
55.239 + * <p>Acquires the lock if it is available and returns immediately
55.240 + * with the value {@code true}.
55.241 + * If the lock is not available then this method will return
55.242 + * immediately with the value {@code false}.
55.243 + *
55.244 + * <p>A typical usage idiom for this method would be:
55.245 + * <pre>
55.246 + * Lock lock = ...;
55.247 + * if (lock.tryLock()) {
55.248 + * try {
55.249 + * // manipulate protected state
55.250 + * } finally {
55.251 + * lock.unlock();
55.252 + * }
55.253 + * } else {
55.254 + * // perform alternative actions
55.255 + * }
55.256 + * </pre>
55.257 + * This usage ensures that the lock is unlocked if it was acquired, and
55.258 + * doesn't try to unlock if the lock was not acquired.
55.259 + *
55.260 + * @return {@code true} if the lock was acquired and
55.261 + * {@code false} otherwise
55.262 + */
55.263 + boolean tryLock();
55.264 +
55.265 + /**
55.266 + * Acquires the lock if it is free within the given waiting time and the
55.267 + * current thread has not been {@linkplain Thread#interrupt interrupted}.
55.268 + *
55.269 + * <p>If the lock is available this method returns immediately
55.270 + * with the value {@code true}.
55.271 + * If the lock is not available then
55.272 + * the current thread becomes disabled for thread scheduling
55.273 + * purposes and lies dormant until one of three things happens:
55.274 + * <ul>
55.275 + * <li>The lock is acquired by the current thread; or
55.276 + * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
55.277 + * current thread, and interruption of lock acquisition is supported; or
55.278 + * <li>The specified waiting time elapses
55.279 + * </ul>
55.280 + *
55.281 + * <p>If the lock is acquired then the value {@code true} is returned.
55.282 + *
55.283 + * <p>If the current thread:
55.284 + * <ul>
55.285 + * <li>has its interrupted status set on entry to this method; or
55.286 + * <li>is {@linkplain Thread#interrupt interrupted} while acquiring
55.287 + * the lock, and interruption of lock acquisition is supported,
55.288 + * </ul>
55.289 + * then {@link InterruptedException} is thrown and the current thread's
55.290 + * interrupted status is cleared.
55.291 + *
55.292 + * <p>If the specified waiting time elapses then the value {@code false}
55.293 + * is returned.
55.294 + * If the time is
55.295 + * less than or equal to zero, the method will not wait at all.
55.296 + *
55.297 + * <p><b>Implementation Considerations</b>
55.298 + *
55.299 + * <p>The ability to interrupt a lock acquisition in some implementations
55.300 + * may not be possible, and if possible may
55.301 + * be an expensive operation.
55.302 + * The programmer should be aware that this may be the case. An
55.303 + * implementation should document when this is the case.
55.304 + *
55.305 + * <p>An implementation can favor responding to an interrupt over normal
55.306 + * method return, or reporting a timeout.
55.307 + *
55.308 + * <p>A {@code Lock} implementation may be able to detect
55.309 + * erroneous use of the lock, such as an invocation that would cause
55.310 + * deadlock, and may throw an (unchecked) exception in such circumstances.
55.311 + * The circumstances and the exception type must be documented by that
55.312 + * {@code Lock} implementation.
55.313 + *
55.314 + * @param time the maximum time to wait for the lock
55.315 + * @param unit the time unit of the {@code time} argument
55.316 + * @return {@code true} if the lock was acquired and {@code false}
55.317 + * if the waiting time elapsed before the lock was acquired
55.318 + *
55.319 + * @throws InterruptedException if the current thread is interrupted
55.320 + * while acquiring the lock (and interruption of lock
55.321 + * acquisition is supported)
55.322 + */
55.323 + boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
55.324 +
55.325 + /**
55.326 + * Releases the lock.
55.327 + *
55.328 + * <p><b>Implementation Considerations</b>
55.329 + *
55.330 + * <p>A {@code Lock} implementation will usually impose
55.331 + * restrictions on which thread can release a lock (typically only the
55.332 + * holder of the lock can release it) and may throw
55.333 + * an (unchecked) exception if the restriction is violated.
55.334 + * Any restrictions and the exception
55.335 + * type must be documented by that {@code Lock} implementation.
55.336 + */
55.337 + void unlock();
55.338 +
55.339 + /**
55.340 + * Returns a new {@link Condition} instance that is bound to this
55.341 + * {@code Lock} instance.
55.342 + *
55.343 + * <p>Before waiting on the condition the lock must be held by the
55.344 + * current thread.
55.345 + * A call to {@link Condition#await()} will atomically release the lock
55.346 + * before waiting and re-acquire the lock before the wait returns.
55.347 + *
55.348 + * <p><b>Implementation Considerations</b>
55.349 + *
55.350 + * <p>The exact operation of the {@link Condition} instance depends on
55.351 + * the {@code Lock} implementation and must be documented by that
55.352 + * implementation.
55.353 + *
55.354 + * @return A new {@link Condition} instance for this {@code Lock} instance
55.355 + * @throws UnsupportedOperationException if this {@code Lock}
55.356 + * implementation does not support conditions
55.357 + */
55.358 + Condition newCondition();
55.359 +}
56.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
56.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/locks/LockSupport.java Sat Mar 19 10:48:29 2016 +0100
56.3 @@ -0,0 +1,385 @@
56.4 +/*
56.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
56.6 + *
56.7 + * This code is free software; you can redistribute it and/or modify it
56.8 + * under the terms of the GNU General Public License version 2 only, as
56.9 + * published by the Free Software Foundation. Oracle designates this
56.10 + * particular file as subject to the "Classpath" exception as provided
56.11 + * by Oracle in the LICENSE file that accompanied this code.
56.12 + *
56.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
56.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
56.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
56.16 + * version 2 for more details (a copy is included in the LICENSE file that
56.17 + * accompanied this code).
56.18 + *
56.19 + * You should have received a copy of the GNU General Public License version
56.20 + * 2 along with this work; if not, write to the Free Software Foundation,
56.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
56.22 + *
56.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
56.24 + * or visit www.oracle.com if you need additional information or have any
56.25 + * questions.
56.26 + */
56.27 +
56.28 +/*
56.29 + * This file is available under and governed by the GNU General Public
56.30 + * License version 2 only, as published by the Free Software Foundation.
56.31 + * However, the following notice accompanied the original version of this
56.32 + * file:
56.33 + *
56.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
56.35 + * Expert Group and released to the public domain, as explained at
56.36 + * http://creativecommons.org/publicdomain/zero/1.0/
56.37 + */
56.38 +
56.39 +package java.util.concurrent.locks;
56.40 +import java.util.concurrent.*;
56.41 +import sun.misc.Unsafe;
56.42 +
56.43 +
56.44 +/**
56.45 + * Basic thread blocking primitives for creating locks and other
56.46 + * synchronization classes.
56.47 + *
56.48 + * <p>This class associates, with each thread that uses it, a permit
56.49 + * (in the sense of the {@link java.util.concurrent.Semaphore
56.50 + * Semaphore} class). A call to {@code park} will return immediately
56.51 + * if the permit is available, consuming it in the process; otherwise
56.52 + * it <em>may</em> block. A call to {@code unpark} makes the permit
56.53 + * available, if it was not already available. (Unlike with Semaphores
56.54 + * though, permits do not accumulate. There is at most one.)
56.55 + *
56.56 + * <p>Methods {@code park} and {@code unpark} provide efficient
56.57 + * means of blocking and unblocking threads that do not encounter the
56.58 + * problems that cause the deprecated methods {@code Thread.suspend}
56.59 + * and {@code Thread.resume} to be unusable for such purposes: Races
56.60 + * between one thread invoking {@code park} and another thread trying
56.61 + * to {@code unpark} it will preserve liveness, due to the
56.62 + * permit. Additionally, {@code park} will return if the caller's
56.63 + * thread was interrupted, and timeout versions are supported. The
56.64 + * {@code park} method may also return at any other time, for "no
56.65 + * reason", so in general must be invoked within a loop that rechecks
56.66 + * conditions upon return. In this sense {@code park} serves as an
56.67 + * optimization of a "busy wait" that does not waste as much time
56.68 + * spinning, but must be paired with an {@code unpark} to be
56.69 + * effective.
56.70 + *
56.71 + * <p>The three forms of {@code park} each also support a
56.72 + * {@code blocker} object parameter. This object is recorded while
56.73 + * the thread is blocked to permit monitoring and diagnostic tools to
56.74 + * identify the reasons that threads are blocked. (Such tools may
56.75 + * access blockers using method {@link #getBlocker}.) The use of these
56.76 + * forms rather than the original forms without this parameter is
56.77 + * strongly encouraged. The normal argument to supply as a
56.78 + * {@code blocker} within a lock implementation is {@code this}.
56.79 + *
56.80 + * <p>These methods are designed to be used as tools for creating
56.81 + * higher-level synchronization utilities, and are not in themselves
56.82 + * useful for most concurrency control applications. The {@code park}
56.83 + * method is designed for use only in constructions of the form:
56.84 + * <pre>while (!canProceed()) { ... LockSupport.park(this); }</pre>
56.85 + * where neither {@code canProceed} nor any other actions prior to the
56.86 + * call to {@code park} entail locking or blocking. Because only one
56.87 + * permit is associated with each thread, any intermediary uses of
56.88 + * {@code park} could interfere with its intended effects.
56.89 + *
56.90 + * <p><b>Sample Usage.</b> Here is a sketch of a first-in-first-out
56.91 + * non-reentrant lock class:
56.92 + * <pre>{@code
56.93 + * class FIFOMutex {
56.94 + * private final AtomicBoolean locked = new AtomicBoolean(false);
56.95 + * private final Queue<Thread> waiters
56.96 + * = new ConcurrentLinkedQueue<Thread>();
56.97 + *
56.98 + * public void lock() {
56.99 + * boolean wasInterrupted = false;
56.100 + * Thread current = Thread.currentThread();
56.101 + * waiters.add(current);
56.102 + *
56.103 + * // Block while not first in queue or cannot acquire lock
56.104 + * while (waiters.peek() != current ||
56.105 + * !locked.compareAndSet(false, true)) {
56.106 + * LockSupport.park(this);
56.107 + * if (Thread.interrupted()) // ignore interrupts while waiting
56.108 + * wasInterrupted = true;
56.109 + * }
56.110 + *
56.111 + * waiters.remove();
56.112 + * if (wasInterrupted) // reassert interrupt status on exit
56.113 + * current.interrupt();
56.114 + * }
56.115 + *
56.116 + * public void unlock() {
56.117 + * locked.set(false);
56.118 + * LockSupport.unpark(waiters.peek());
56.119 + * }
56.120 + * }}</pre>
56.121 + */
56.122 +
56.123 +public class LockSupport {
56.124 + private LockSupport() {} // Cannot be instantiated.
56.125 +
56.126 + // Hotspot implementation via intrinsics API
56.127 + private static final Unsafe unsafe = Unsafe.getUnsafe();
56.128 + private static final long parkBlockerOffset;
56.129 +
56.130 + static {
56.131 + try {
56.132 + parkBlockerOffset = unsafe.objectFieldOffset
56.133 + (java.lang.Thread.class.getDeclaredField("parkBlocker"));
56.134 + } catch (Exception ex) { throw new Error(ex); }
56.135 + }
56.136 +
56.137 + private static void setBlocker(Thread t, Object arg) {
56.138 + // Even though volatile, hotspot doesn't need a write barrier here.
56.139 + unsafe.putObject(t, parkBlockerOffset, arg);
56.140 + }
56.141 +
56.142 + /**
56.143 + * Makes available the permit for the given thread, if it
56.144 + * was not already available. If the thread was blocked on
56.145 + * {@code park} then it will unblock. Otherwise, its next call
56.146 + * to {@code park} is guaranteed not to block. This operation
56.147 + * is not guaranteed to have any effect at all if the given
56.148 + * thread has not been started.
56.149 + *
56.150 + * @param thread the thread to unpark, or {@code null}, in which case
56.151 + * this operation has no effect
56.152 + */
56.153 + public static void unpark(Thread thread) {
56.154 + if (thread != null)
56.155 + unsafe.unpark(thread);
56.156 + }
56.157 +
56.158 + /**
56.159 + * Disables the current thread for thread scheduling purposes unless the
56.160 + * permit is available.
56.161 + *
56.162 + * <p>If the permit is available then it is consumed and the call returns
56.163 + * immediately; otherwise
56.164 + * the current thread becomes disabled for thread scheduling
56.165 + * purposes and lies dormant until one of three things happens:
56.166 + *
56.167 + * <ul>
56.168 + * <li>Some other thread invokes {@link #unpark unpark} with the
56.169 + * current thread as the target; or
56.170 + *
56.171 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
56.172 + * the current thread; or
56.173 + *
56.174 + * <li>The call spuriously (that is, for no reason) returns.
56.175 + * </ul>
56.176 + *
56.177 + * <p>This method does <em>not</em> report which of these caused the
56.178 + * method to return. Callers should re-check the conditions which caused
56.179 + * the thread to park in the first place. Callers may also determine,
56.180 + * for example, the interrupt status of the thread upon return.
56.181 + *
56.182 + * @param blocker the synchronization object responsible for this
56.183 + * thread parking
56.184 + * @since 1.6
56.185 + */
56.186 + public static void park(Object blocker) {
56.187 + Thread t = Thread.currentThread();
56.188 + setBlocker(t, blocker);
56.189 + unsafe.park(false, 0L);
56.190 + setBlocker(t, null);
56.191 + }
56.192 +
56.193 + /**
56.194 + * Disables the current thread for thread scheduling purposes, for up to
56.195 + * the specified waiting time, unless the permit is available.
56.196 + *
56.197 + * <p>If the permit is available then it is consumed and the call
56.198 + * returns immediately; otherwise the current thread becomes disabled
56.199 + * for thread scheduling purposes and lies dormant until one of four
56.200 + * things happens:
56.201 + *
56.202 + * <ul>
56.203 + * <li>Some other thread invokes {@link #unpark unpark} with the
56.204 + * current thread as the target; or
56.205 + *
56.206 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
56.207 + * the current thread; or
56.208 + *
56.209 + * <li>The specified waiting time elapses; or
56.210 + *
56.211 + * <li>The call spuriously (that is, for no reason) returns.
56.212 + * </ul>
56.213 + *
56.214 + * <p>This method does <em>not</em> report which of these caused the
56.215 + * method to return. Callers should re-check the conditions which caused
56.216 + * the thread to park in the first place. Callers may also determine,
56.217 + * for example, the interrupt status of the thread, or the elapsed time
56.218 + * upon return.
56.219 + *
56.220 + * @param blocker the synchronization object responsible for this
56.221 + * thread parking
56.222 + * @param nanos the maximum number of nanoseconds to wait
56.223 + * @since 1.6
56.224 + */
56.225 + public static void parkNanos(Object blocker, long nanos) {
56.226 + if (nanos > 0) {
56.227 + Thread t = Thread.currentThread();
56.228 + setBlocker(t, blocker);
56.229 + unsafe.park(false, nanos);
56.230 + setBlocker(t, null);
56.231 + }
56.232 + }
56.233 +
56.234 + /**
56.235 + * Disables the current thread for thread scheduling purposes, until
56.236 + * the specified deadline, unless the permit is available.
56.237 + *
56.238 + * <p>If the permit is available then it is consumed and the call
56.239 + * returns immediately; otherwise the current thread becomes disabled
56.240 + * for thread scheduling purposes and lies dormant until one of four
56.241 + * things happens:
56.242 + *
56.243 + * <ul>
56.244 + * <li>Some other thread invokes {@link #unpark unpark} with the
56.245 + * current thread as the target; or
56.246 + *
56.247 + * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
56.248 + * current thread; or
56.249 + *
56.250 + * <li>The specified deadline passes; or
56.251 + *
56.252 + * <li>The call spuriously (that is, for no reason) returns.
56.253 + * </ul>
56.254 + *
56.255 + * <p>This method does <em>not</em> report which of these caused the
56.256 + * method to return. Callers should re-check the conditions which caused
56.257 + * the thread to park in the first place. Callers may also determine,
56.258 + * for example, the interrupt status of the thread, or the current time
56.259 + * upon return.
56.260 + *
56.261 + * @param blocker the synchronization object responsible for this
56.262 + * thread parking
56.263 + * @param deadline the absolute time, in milliseconds from the Epoch,
56.264 + * to wait until
56.265 + * @since 1.6
56.266 + */
56.267 + public static void parkUntil(Object blocker, long deadline) {
56.268 + Thread t = Thread.currentThread();
56.269 + setBlocker(t, blocker);
56.270 + unsafe.park(true, deadline);
56.271 + setBlocker(t, null);
56.272 + }
56.273 +
56.274 + /**
56.275 + * Returns the blocker object supplied to the most recent
56.276 + * invocation of a park method that has not yet unblocked, or null
56.277 + * if not blocked. The value returned is just a momentary
56.278 + * snapshot -- the thread may have since unblocked or blocked on a
56.279 + * different blocker object.
56.280 + *
56.281 + * @param t the thread
56.282 + * @return the blocker
56.283 + * @throws NullPointerException if argument is null
56.284 + * @since 1.6
56.285 + */
56.286 + public static Object getBlocker(Thread t) {
56.287 + if (t == null)
56.288 + throw new NullPointerException();
56.289 + return unsafe.getObjectVolatile(t, parkBlockerOffset);
56.290 + }
56.291 +
56.292 + /**
56.293 + * Disables the current thread for thread scheduling purposes unless the
56.294 + * permit is available.
56.295 + *
56.296 + * <p>If the permit is available then it is consumed and the call
56.297 + * returns immediately; otherwise the current thread becomes disabled
56.298 + * for thread scheduling purposes and lies dormant until one of three
56.299 + * things happens:
56.300 + *
56.301 + * <ul>
56.302 + *
56.303 + * <li>Some other thread invokes {@link #unpark unpark} with the
56.304 + * current thread as the target; or
56.305 + *
56.306 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
56.307 + * the current thread; or
56.308 + *
56.309 + * <li>The call spuriously (that is, for no reason) returns.
56.310 + * </ul>
56.311 + *
56.312 + * <p>This method does <em>not</em> report which of these caused the
56.313 + * method to return. Callers should re-check the conditions which caused
56.314 + * the thread to park in the first place. Callers may also determine,
56.315 + * for example, the interrupt status of the thread upon return.
56.316 + */
56.317 + public static void park() {
56.318 + unsafe.park(false, 0L);
56.319 + }
56.320 +
56.321 + /**
56.322 + * Disables the current thread for thread scheduling purposes, for up to
56.323 + * the specified waiting time, unless the permit is available.
56.324 + *
56.325 + * <p>If the permit is available then it is consumed and the call
56.326 + * returns immediately; otherwise the current thread becomes disabled
56.327 + * for thread scheduling purposes and lies dormant until one of four
56.328 + * things happens:
56.329 + *
56.330 + * <ul>
56.331 + * <li>Some other thread invokes {@link #unpark unpark} with the
56.332 + * current thread as the target; or
56.333 + *
56.334 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
56.335 + * the current thread; or
56.336 + *
56.337 + * <li>The specified waiting time elapses; or
56.338 + *
56.339 + * <li>The call spuriously (that is, for no reason) returns.
56.340 + * </ul>
56.341 + *
56.342 + * <p>This method does <em>not</em> report which of these caused the
56.343 + * method to return. Callers should re-check the conditions which caused
56.344 + * the thread to park in the first place. Callers may also determine,
56.345 + * for example, the interrupt status of the thread, or the elapsed time
56.346 + * upon return.
56.347 + *
56.348 + * @param nanos the maximum number of nanoseconds to wait
56.349 + */
56.350 + public static void parkNanos(long nanos) {
56.351 + if (nanos > 0)
56.352 + unsafe.park(false, nanos);
56.353 + }
56.354 +
56.355 + /**
56.356 + * Disables the current thread for thread scheduling purposes, until
56.357 + * the specified deadline, unless the permit is available.
56.358 + *
56.359 + * <p>If the permit is available then it is consumed and the call
56.360 + * returns immediately; otherwise the current thread becomes disabled
56.361 + * for thread scheduling purposes and lies dormant until one of four
56.362 + * things happens:
56.363 + *
56.364 + * <ul>
56.365 + * <li>Some other thread invokes {@link #unpark unpark} with the
56.366 + * current thread as the target; or
56.367 + *
56.368 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
56.369 + * the current thread; or
56.370 + *
56.371 + * <li>The specified deadline passes; or
56.372 + *
56.373 + * <li>The call spuriously (that is, for no reason) returns.
56.374 + * </ul>
56.375 + *
56.376 + * <p>This method does <em>not</em> report which of these caused the
56.377 + * method to return. Callers should re-check the conditions which caused
56.378 + * the thread to park in the first place. Callers may also determine,
56.379 + * for example, the interrupt status of the thread, or the current time
56.380 + * upon return.
56.381 + *
56.382 + * @param deadline the absolute time, in milliseconds from the Epoch,
56.383 + * to wait until
56.384 + */
56.385 + public static void parkUntil(long deadline) {
56.386 + unsafe.park(true, deadline);
56.387 + }
56.388 +}
57.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
57.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/locks/ReadWriteLock.java Sat Mar 19 10:48:29 2016 +0100
57.3 @@ -0,0 +1,133 @@
57.4 +/*
57.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
57.6 + *
57.7 + * This code is free software; you can redistribute it and/or modify it
57.8 + * under the terms of the GNU General Public License version 2 only, as
57.9 + * published by the Free Software Foundation. Oracle designates this
57.10 + * particular file as subject to the "Classpath" exception as provided
57.11 + * by Oracle in the LICENSE file that accompanied this code.
57.12 + *
57.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
57.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
57.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
57.16 + * version 2 for more details (a copy is included in the LICENSE file that
57.17 + * accompanied this code).
57.18 + *
57.19 + * You should have received a copy of the GNU General Public License version
57.20 + * 2 along with this work; if not, write to the Free Software Foundation,
57.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
57.22 + *
57.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
57.24 + * or visit www.oracle.com if you need additional information or have any
57.25 + * questions.
57.26 + */
57.27 +
57.28 +/*
57.29 + * This file is available under and governed by the GNU General Public
57.30 + * License version 2 only, as published by the Free Software Foundation.
57.31 + * However, the following notice accompanied the original version of this
57.32 + * file:
57.33 + *
57.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
57.35 + * Expert Group and released to the public domain, as explained at
57.36 + * http://creativecommons.org/publicdomain/zero/1.0/
57.37 + */
57.38 +
57.39 +package java.util.concurrent.locks;
57.40 +
57.41 +/**
57.42 + * A <tt>ReadWriteLock</tt> maintains a pair of associated {@link
57.43 + * Lock locks}, one for read-only operations and one for writing.
57.44 + * The {@link #readLock read lock} may be held simultaneously by
57.45 + * multiple reader threads, so long as there are no writers. The
57.46 + * {@link #writeLock write lock} is exclusive.
57.47 + *
57.48 + * <p>All <tt>ReadWriteLock</tt> implementations must guarantee that
57.49 + * the memory synchronization effects of <tt>writeLock</tt> operations
57.50 + * (as specified in the {@link Lock} interface) also hold with respect
57.51 + * to the associated <tt>readLock</tt>. That is, a thread successfully
57.52 + * acquiring the read lock will see all updates made upon previous
57.53 + * release of the write lock.
57.54 + *
57.55 + * <p>A read-write lock allows for a greater level of concurrency in
57.56 + * accessing shared data than that permitted by a mutual exclusion lock.
57.57 + * It exploits the fact that while only a single thread at a time (a
57.58 + * <em>writer</em> thread) can modify the shared data, in many cases any
57.59 + * number of threads can concurrently read the data (hence <em>reader</em>
57.60 + * threads).
57.61 + * In theory, the increase in concurrency permitted by the use of a read-write
57.62 + * lock will lead to performance improvements over the use of a mutual
57.63 + * exclusion lock. In practice this increase in concurrency will only be fully
57.64 + * realized on a multi-processor, and then only if the access patterns for
57.65 + * the shared data are suitable.
57.66 + *
57.67 + * <p>Whether or not a read-write lock will improve performance over the use
57.68 + * of a mutual exclusion lock depends on the frequency that the data is
57.69 + * read compared to being modified, the duration of the read and write
57.70 + * operations, and the contention for the data - that is, the number of
57.71 + * threads that will try to read or write the data at the same time.
57.72 + * For example, a collection that is initially populated with data and
57.73 + * thereafter infrequently modified, while being frequently searched
57.74 + * (such as a directory of some kind) is an ideal candidate for the use of
57.75 + * a read-write lock. However, if updates become frequent then the data
57.76 + * spends most of its time being exclusively locked and there is little, if any
57.77 + * increase in concurrency. Further, if the read operations are too short
57.78 + * the overhead of the read-write lock implementation (which is inherently
57.79 + * more complex than a mutual exclusion lock) can dominate the execution
57.80 + * cost, particularly as many read-write lock implementations still serialize
57.81 + * all threads through a small section of code. Ultimately, only profiling
57.82 + * and measurement will establish whether the use of a read-write lock is
57.83 + * suitable for your application.
57.84 + *
57.85 + *
57.86 + * <p>Although the basic operation of a read-write lock is straight-forward,
57.87 + * there are many policy decisions that an implementation must make, which
57.88 + * may affect the effectiveness of the read-write lock in a given application.
57.89 + * Examples of these policies include:
57.90 + * <ul>
57.91 + * <li>Determining whether to grant the read lock or the write lock, when
57.92 + * both readers and writers are waiting, at the time that a writer releases
57.93 + * the write lock. Writer preference is common, as writes are expected to be
57.94 + * short and infrequent. Reader preference is less common as it can lead to
57.95 + * lengthy delays for a write if the readers are frequent and long-lived as
57.96 + * expected. Fair, or "in-order" implementations are also possible.
57.97 + *
57.98 + * <li>Determining whether readers that request the read lock while a
57.99 + * reader is active and a writer is waiting, are granted the read lock.
57.100 + * Preference to the reader can delay the writer indefinitely, while
57.101 + * preference to the writer can reduce the potential for concurrency.
57.102 + *
57.103 + * <li>Determining whether the locks are reentrant: can a thread with the
57.104 + * write lock reacquire it? Can it acquire a read lock while holding the
57.105 + * write lock? Is the read lock itself reentrant?
57.106 + *
57.107 + * <li>Can the write lock be downgraded to a read lock without allowing
57.108 + * an intervening writer? Can a read lock be upgraded to a write lock,
57.109 + * in preference to other waiting readers or writers?
57.110 + *
57.111 + * </ul>
57.112 + * You should consider all of these things when evaluating the suitability
57.113 + * of a given implementation for your application.
57.114 + *
57.115 + * @see ReentrantReadWriteLock
57.116 + * @see Lock
57.117 + * @see ReentrantLock
57.118 + *
57.119 + * @since 1.5
57.120 + * @author Doug Lea
57.121 + */
57.122 +public interface ReadWriteLock {
57.123 + /**
57.124 + * Returns the lock used for reading.
57.125 + *
57.126 + * @return the lock used for reading.
57.127 + */
57.128 + Lock readLock();
57.129 +
57.130 + /**
57.131 + * Returns the lock used for writing.
57.132 + *
57.133 + * @return the lock used for writing.
57.134 + */
57.135 + Lock writeLock();
57.136 +}
58.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
58.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/locks/ReentrantLock.java Sat Mar 19 10:48:29 2016 +0100
58.3 @@ -0,0 +1,770 @@
58.4 +/*
58.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
58.6 + *
58.7 + * This code is free software; you can redistribute it and/or modify it
58.8 + * under the terms of the GNU General Public License version 2 only, as
58.9 + * published by the Free Software Foundation. Oracle designates this
58.10 + * particular file as subject to the "Classpath" exception as provided
58.11 + * by Oracle in the LICENSE file that accompanied this code.
58.12 + *
58.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
58.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
58.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
58.16 + * version 2 for more details (a copy is included in the LICENSE file that
58.17 + * accompanied this code).
58.18 + *
58.19 + * You should have received a copy of the GNU General Public License version
58.20 + * 2 along with this work; if not, write to the Free Software Foundation,
58.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
58.22 + *
58.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
58.24 + * or visit www.oracle.com if you need additional information or have any
58.25 + * questions.
58.26 + */
58.27 +
58.28 +/*
58.29 + * This file is available under and governed by the GNU General Public
58.30 + * License version 2 only, as published by the Free Software Foundation.
58.31 + * However, the following notice accompanied the original version of this
58.32 + * file:
58.33 + *
58.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
58.35 + * Expert Group and released to the public domain, as explained at
58.36 + * http://creativecommons.org/publicdomain/zero/1.0/
58.37 + */
58.38 +
58.39 +package java.util.concurrent.locks;
58.40 +import java.util.*;
58.41 +import java.util.concurrent.*;
58.42 +import java.util.concurrent.atomic.*;
58.43 +
58.44 +/**
58.45 + * A reentrant mutual exclusion {@link Lock} with the same basic
58.46 + * behavior and semantics as the implicit monitor lock accessed using
58.47 + * {@code synchronized} methods and statements, but with extended
58.48 + * capabilities.
58.49 + *
58.50 + * <p>A {@code ReentrantLock} is <em>owned</em> by the thread last
58.51 + * successfully locking, but not yet unlocking it. A thread invoking
58.52 + * {@code lock} will return, successfully acquiring the lock, when
58.53 + * the lock is not owned by another thread. The method will return
58.54 + * immediately if the current thread already owns the lock. This can
58.55 + * be checked using methods {@link #isHeldByCurrentThread}, and {@link
58.56 + * #getHoldCount}.
58.57 + *
58.58 + * <p>The constructor for this class accepts an optional
58.59 + * <em>fairness</em> parameter. When set {@code true}, under
58.60 + * contention, locks favor granting access to the longest-waiting
58.61 + * thread. Otherwise this lock does not guarantee any particular
58.62 + * access order. Programs using fair locks accessed by many threads
58.63 + * may display lower overall throughput (i.e., are slower; often much
58.64 + * slower) than those using the default setting, but have smaller
58.65 + * variances in times to obtain locks and guarantee lack of
58.66 + * starvation. Note however, that fairness of locks does not guarantee
58.67 + * fairness of thread scheduling. Thus, one of many threads using a
58.68 + * fair lock may obtain it multiple times in succession while other
58.69 + * active threads are not progressing and not currently holding the
58.70 + * lock.
58.71 + * Also note that the untimed {@link #tryLock() tryLock} method does not
58.72 + * honor the fairness setting. It will succeed if the lock
58.73 + * is available even if other threads are waiting.
58.74 + *
58.75 + * <p>It is recommended practice to <em>always</em> immediately
58.76 + * follow a call to {@code lock} with a {@code try} block, most
58.77 + * typically in a before/after construction such as:
58.78 + *
58.79 + * <pre>
58.80 + * class X {
58.81 + * private final ReentrantLock lock = new ReentrantLock();
58.82 + * // ...
58.83 + *
58.84 + * public void m() {
58.85 + * lock.lock(); // block until condition holds
58.86 + * try {
58.87 + * // ... method body
58.88 + * } finally {
58.89 + * lock.unlock()
58.90 + * }
58.91 + * }
58.92 + * }
58.93 + * </pre>
58.94 + *
58.95 + * <p>In addition to implementing the {@link Lock} interface, this
58.96 + * class defines methods {@code isLocked} and
58.97 + * {@code getLockQueueLength}, as well as some associated
58.98 + * {@code protected} access methods that may be useful for
58.99 + * instrumentation and monitoring.
58.100 + *
58.101 + * <p>Serialization of this class behaves in the same way as built-in
58.102 + * locks: a deserialized lock is in the unlocked state, regardless of
58.103 + * its state when serialized.
58.104 + *
58.105 + * <p>This lock supports a maximum of 2147483647 recursive locks by
58.106 + * the same thread. Attempts to exceed this limit result in
58.107 + * {@link Error} throws from locking methods.
58.108 + *
58.109 + * @since 1.5
58.110 + * @author Doug Lea
58.111 + */
58.112 +public class ReentrantLock implements Lock, java.io.Serializable {
58.113 + private static final long serialVersionUID = 7373984872572414699L;
58.114 + /** Synchronizer providing all implementation mechanics */
58.115 + private final Sync sync;
58.116 +
58.117 + /**
58.118 + * Base of synchronization control for this lock. Subclassed
58.119 + * into fair and nonfair versions below. Uses AQS state to
58.120 + * represent the number of holds on the lock.
58.121 + */
58.122 + abstract static class Sync extends AbstractQueuedSynchronizer {
58.123 + private static final long serialVersionUID = -5179523762034025860L;
58.124 +
58.125 + /**
58.126 + * Performs {@link Lock#lock}. The main reason for subclassing
58.127 + * is to allow fast path for nonfair version.
58.128 + */
58.129 + abstract void lock();
58.130 +
58.131 + /**
58.132 + * Performs non-fair tryLock. tryAcquire is
58.133 + * implemented in subclasses, but both need nonfair
58.134 + * try for trylock method.
58.135 + */
58.136 + final boolean nonfairTryAcquire(int acquires) {
58.137 + final Thread current = Thread.currentThread();
58.138 + int c = getState();
58.139 + if (c == 0) {
58.140 + if (compareAndSetState(0, acquires)) {
58.141 + setExclusiveOwnerThread(current);
58.142 + return true;
58.143 + }
58.144 + }
58.145 + else if (current == getExclusiveOwnerThread()) {
58.146 + int nextc = c + acquires;
58.147 + if (nextc < 0) // overflow
58.148 + throw new Error("Maximum lock count exceeded");
58.149 + setState(nextc);
58.150 + return true;
58.151 + }
58.152 + return false;
58.153 + }
58.154 +
58.155 + protected final boolean tryRelease(int releases) {
58.156 + int c = getState() - releases;
58.157 + if (Thread.currentThread() != getExclusiveOwnerThread())
58.158 + throw new IllegalMonitorStateException();
58.159 + boolean free = false;
58.160 + if (c == 0) {
58.161 + free = true;
58.162 + setExclusiveOwnerThread(null);
58.163 + }
58.164 + setState(c);
58.165 + return free;
58.166 + }
58.167 +
58.168 + protected final boolean isHeldExclusively() {
58.169 + // While we must in general read state before owner,
58.170 + // we don't need to do so to check if current thread is owner
58.171 + return getExclusiveOwnerThread() == Thread.currentThread();
58.172 + }
58.173 +
58.174 + final ConditionObject newCondition() {
58.175 + return new ConditionObject();
58.176 + }
58.177 +
58.178 + // Methods relayed from outer class
58.179 +
58.180 + final Thread getOwner() {
58.181 + return getState() == 0 ? null : getExclusiveOwnerThread();
58.182 + }
58.183 +
58.184 + final int getHoldCount() {
58.185 + return isHeldExclusively() ? getState() : 0;
58.186 + }
58.187 +
58.188 + final boolean isLocked() {
58.189 + return getState() != 0;
58.190 + }
58.191 +
58.192 + /**
58.193 + * Reconstitutes this lock instance from a stream.
58.194 + * @param s the stream
58.195 + */
58.196 + private void readObject(java.io.ObjectInputStream s)
58.197 + throws java.io.IOException, ClassNotFoundException {
58.198 + s.defaultReadObject();
58.199 + setState(0); // reset to unlocked state
58.200 + }
58.201 + }
58.202 +
58.203 + /**
58.204 + * Sync object for non-fair locks
58.205 + */
58.206 + static final class NonfairSync extends Sync {
58.207 + private static final long serialVersionUID = 7316153563782823691L;
58.208 +
58.209 + /**
58.210 + * Performs lock. Try immediate barge, backing up to normal
58.211 + * acquire on failure.
58.212 + */
58.213 + final void lock() {
58.214 + if (compareAndSetState(0, 1))
58.215 + setExclusiveOwnerThread(Thread.currentThread());
58.216 + else
58.217 + acquire(1);
58.218 + }
58.219 +
58.220 + protected final boolean tryAcquire(int acquires) {
58.221 + return nonfairTryAcquire(acquires);
58.222 + }
58.223 + }
58.224 +
58.225 + /**
58.226 + * Sync object for fair locks
58.227 + */
58.228 + static final class FairSync extends Sync {
58.229 + private static final long serialVersionUID = -3000897897090466540L;
58.230 +
58.231 + final void lock() {
58.232 + acquire(1);
58.233 + }
58.234 +
58.235 + /**
58.236 + * Fair version of tryAcquire. Don't grant access unless
58.237 + * recursive call or no waiters or is first.
58.238 + */
58.239 + protected final boolean tryAcquire(int acquires) {
58.240 + final Thread current = Thread.currentThread();
58.241 + int c = getState();
58.242 + if (c == 0) {
58.243 + if (!hasQueuedPredecessors() &&
58.244 + compareAndSetState(0, acquires)) {
58.245 + setExclusiveOwnerThread(current);
58.246 + return true;
58.247 + }
58.248 + }
58.249 + else if (current == getExclusiveOwnerThread()) {
58.250 + int nextc = c + acquires;
58.251 + if (nextc < 0)
58.252 + throw new Error("Maximum lock count exceeded");
58.253 + setState(nextc);
58.254 + return true;
58.255 + }
58.256 + return false;
58.257 + }
58.258 + }
58.259 +
58.260 + /**
58.261 + * Creates an instance of {@code ReentrantLock}.
58.262 + * This is equivalent to using {@code ReentrantLock(false)}.
58.263 + */
58.264 + public ReentrantLock() {
58.265 + sync = new NonfairSync();
58.266 + }
58.267 +
58.268 + /**
58.269 + * Creates an instance of {@code ReentrantLock} with the
58.270 + * given fairness policy.
58.271 + *
58.272 + * @param fair {@code true} if this lock should use a fair ordering policy
58.273 + */
58.274 + public ReentrantLock(boolean fair) {
58.275 + sync = fair ? new FairSync() : new NonfairSync();
58.276 + }
58.277 +
58.278 + /**
58.279 + * Acquires the lock.
58.280 + *
58.281 + * <p>Acquires the lock if it is not held by another thread and returns
58.282 + * immediately, setting the lock hold count to one.
58.283 + *
58.284 + * <p>If the current thread already holds the lock then the hold
58.285 + * count is incremented by one and the method returns immediately.
58.286 + *
58.287 + * <p>If the lock is held by another thread then the
58.288 + * current thread becomes disabled for thread scheduling
58.289 + * purposes and lies dormant until the lock has been acquired,
58.290 + * at which time the lock hold count is set to one.
58.291 + */
58.292 + public void lock() {
58.293 + sync.lock();
58.294 + }
58.295 +
58.296 + /**
58.297 + * Acquires the lock unless the current thread is
58.298 + * {@linkplain Thread#interrupt interrupted}.
58.299 + *
58.300 + * <p>Acquires the lock if it is not held by another thread and returns
58.301 + * immediately, setting the lock hold count to one.
58.302 + *
58.303 + * <p>If the current thread already holds this lock then the hold count
58.304 + * is incremented by one and the method returns immediately.
58.305 + *
58.306 + * <p>If the lock is held by another thread then the
58.307 + * current thread becomes disabled for thread scheduling
58.308 + * purposes and lies dormant until one of two things happens:
58.309 + *
58.310 + * <ul>
58.311 + *
58.312 + * <li>The lock is acquired by the current thread; or
58.313 + *
58.314 + * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
58.315 + * current thread.
58.316 + *
58.317 + * </ul>
58.318 + *
58.319 + * <p>If the lock is acquired by the current thread then the lock hold
58.320 + * count is set to one.
58.321 + *
58.322 + * <p>If the current thread:
58.323 + *
58.324 + * <ul>
58.325 + *
58.326 + * <li>has its interrupted status set on entry to this method; or
58.327 + *
58.328 + * <li>is {@linkplain Thread#interrupt interrupted} while acquiring
58.329 + * the lock,
58.330 + *
58.331 + * </ul>
58.332 + *
58.333 + * then {@link InterruptedException} is thrown and the current thread's
58.334 + * interrupted status is cleared.
58.335 + *
58.336 + * <p>In this implementation, as this method is an explicit
58.337 + * interruption point, preference is given to responding to the
58.338 + * interrupt over normal or reentrant acquisition of the lock.
58.339 + *
58.340 + * @throws InterruptedException if the current thread is interrupted
58.341 + */
58.342 + public void lockInterruptibly() throws InterruptedException {
58.343 + sync.acquireInterruptibly(1);
58.344 + }
58.345 +
58.346 + /**
58.347 + * Acquires the lock only if it is not held by another thread at the time
58.348 + * of invocation.
58.349 + *
58.350 + * <p>Acquires the lock if it is not held by another thread and
58.351 + * returns immediately with the value {@code true}, setting the
58.352 + * lock hold count to one. Even when this lock has been set to use a
58.353 + * fair ordering policy, a call to {@code tryLock()} <em>will</em>
58.354 + * immediately acquire the lock if it is available, whether or not
58.355 + * other threads are currently waiting for the lock.
58.356 + * This "barging" behavior can be useful in certain
58.357 + * circumstances, even though it breaks fairness. If you want to honor
58.358 + * the fairness setting for this lock, then use
58.359 + * {@link #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) }
58.360 + * which is almost equivalent (it also detects interruption).
58.361 + *
58.362 + * <p> If the current thread already holds this lock then the hold
58.363 + * count is incremented by one and the method returns {@code true}.
58.364 + *
58.365 + * <p>If the lock is held by another thread then this method will return
58.366 + * immediately with the value {@code false}.
58.367 + *
58.368 + * @return {@code true} if the lock was free and was acquired by the
58.369 + * current thread, or the lock was already held by the current
58.370 + * thread; and {@code false} otherwise
58.371 + */
58.372 + public boolean tryLock() {
58.373 + return sync.nonfairTryAcquire(1);
58.374 + }
58.375 +
58.376 + /**
58.377 + * Acquires the lock if it is not held by another thread within the given
58.378 + * waiting time and the current thread has not been
58.379 + * {@linkplain Thread#interrupt interrupted}.
58.380 + *
58.381 + * <p>Acquires the lock if it is not held by another thread and returns
58.382 + * immediately with the value {@code true}, setting the lock hold count
58.383 + * to one. If this lock has been set to use a fair ordering policy then
58.384 + * an available lock <em>will not</em> be acquired if any other threads
58.385 + * are waiting for the lock. This is in contrast to the {@link #tryLock()}
58.386 + * method. If you want a timed {@code tryLock} that does permit barging on
58.387 + * a fair lock then combine the timed and un-timed forms together:
58.388 + *
58.389 + * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
58.390 + * </pre>
58.391 + *
58.392 + * <p>If the current thread
58.393 + * already holds this lock then the hold count is incremented by one and
58.394 + * the method returns {@code true}.
58.395 + *
58.396 + * <p>If the lock is held by another thread then the
58.397 + * current thread becomes disabled for thread scheduling
58.398 + * purposes and lies dormant until one of three things happens:
58.399 + *
58.400 + * <ul>
58.401 + *
58.402 + * <li>The lock is acquired by the current thread; or
58.403 + *
58.404 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
58.405 + * the current thread; or
58.406 + *
58.407 + * <li>The specified waiting time elapses
58.408 + *
58.409 + * </ul>
58.410 + *
58.411 + * <p>If the lock is acquired then the value {@code true} is returned and
58.412 + * the lock hold count is set to one.
58.413 + *
58.414 + * <p>If the current thread:
58.415 + *
58.416 + * <ul>
58.417 + *
58.418 + * <li>has its interrupted status set on entry to this method; or
58.419 + *
58.420 + * <li>is {@linkplain Thread#interrupt interrupted} while
58.421 + * acquiring the lock,
58.422 + *
58.423 + * </ul>
58.424 + * then {@link InterruptedException} is thrown and the current thread's
58.425 + * interrupted status is cleared.
58.426 + *
58.427 + * <p>If the specified waiting time elapses then the value {@code false}
58.428 + * is returned. If the time is less than or equal to zero, the method
58.429 + * will not wait at all.
58.430 + *
58.431 + * <p>In this implementation, as this method is an explicit
58.432 + * interruption point, preference is given to responding to the
58.433 + * interrupt over normal or reentrant acquisition of the lock, and
58.434 + * over reporting the elapse of the waiting time.
58.435 + *
58.436 + * @param timeout the time to wait for the lock
58.437 + * @param unit the time unit of the timeout argument
58.438 + * @return {@code true} if the lock was free and was acquired by the
58.439 + * current thread, or the lock was already held by the current
58.440 + * thread; and {@code false} if the waiting time elapsed before
58.441 + * the lock could be acquired
58.442 + * @throws InterruptedException if the current thread is interrupted
58.443 + * @throws NullPointerException if the time unit is null
58.444 + *
58.445 + */
58.446 + public boolean tryLock(long timeout, TimeUnit unit)
58.447 + throws InterruptedException {
58.448 + return sync.tryAcquireNanos(1, unit.toNanos(timeout));
58.449 + }
58.450 +
58.451 + /**
58.452 + * Attempts to release this lock.
58.453 + *
58.454 + * <p>If the current thread is the holder of this lock then the hold
58.455 + * count is decremented. If the hold count is now zero then the lock
58.456 + * is released. If the current thread is not the holder of this
58.457 + * lock then {@link IllegalMonitorStateException} is thrown.
58.458 + *
58.459 + * @throws IllegalMonitorStateException if the current thread does not
58.460 + * hold this lock
58.461 + */
58.462 + public void unlock() {
58.463 + sync.release(1);
58.464 + }
58.465 +
58.466 + /**
58.467 + * Returns a {@link Condition} instance for use with this
58.468 + * {@link Lock} instance.
58.469 + *
58.470 + * <p>The returned {@link Condition} instance supports the same
58.471 + * usages as do the {@link Object} monitor methods ({@link
58.472 + * Object#wait() wait}, {@link Object#notify notify}, and {@link
58.473 + * Object#notifyAll notifyAll}) when used with the built-in
58.474 + * monitor lock.
58.475 + *
58.476 + * <ul>
58.477 + *
58.478 + * <li>If this lock is not held when any of the {@link Condition}
58.479 + * {@linkplain Condition#await() waiting} or {@linkplain
58.480 + * Condition#signal signalling} methods are called, then an {@link
58.481 + * IllegalMonitorStateException} is thrown.
58.482 + *
58.483 + * <li>When the condition {@linkplain Condition#await() waiting}
58.484 + * methods are called the lock is released and, before they
58.485 + * return, the lock is reacquired and the lock hold count restored
58.486 + * to what it was when the method was called.
58.487 + *
58.488 + * <li>If a thread is {@linkplain Thread#interrupt interrupted}
58.489 + * while waiting then the wait will terminate, an {@link
58.490 + * InterruptedException} will be thrown, and the thread's
58.491 + * interrupted status will be cleared.
58.492 + *
58.493 + * <li> Waiting threads are signalled in FIFO order.
58.494 + *
58.495 + * <li>The ordering of lock reacquisition for threads returning
58.496 + * from waiting methods is the same as for threads initially
58.497 + * acquiring the lock, which is in the default case not specified,
58.498 + * but for <em>fair</em> locks favors those threads that have been
58.499 + * waiting the longest.
58.500 + *
58.501 + * </ul>
58.502 + *
58.503 + * @return the Condition object
58.504 + */
58.505 + public Condition newCondition() {
58.506 + return sync.newCondition();
58.507 + }
58.508 +
58.509 + /**
58.510 + * Queries the number of holds on this lock by the current thread.
58.511 + *
58.512 + * <p>A thread has a hold on a lock for each lock action that is not
58.513 + * matched by an unlock action.
58.514 + *
58.515 + * <p>The hold count information is typically only used for testing and
58.516 + * debugging purposes. For example, if a certain section of code should
58.517 + * not be entered with the lock already held then we can assert that
58.518 + * fact:
58.519 + *
58.520 + * <pre>
58.521 + * class X {
58.522 + * ReentrantLock lock = new ReentrantLock();
58.523 + * // ...
58.524 + * public void m() {
58.525 + * assert lock.getHoldCount() == 0;
58.526 + * lock.lock();
58.527 + * try {
58.528 + * // ... method body
58.529 + * } finally {
58.530 + * lock.unlock();
58.531 + * }
58.532 + * }
58.533 + * }
58.534 + * </pre>
58.535 + *
58.536 + * @return the number of holds on this lock by the current thread,
58.537 + * or zero if this lock is not held by the current thread
58.538 + */
58.539 + public int getHoldCount() {
58.540 + return sync.getHoldCount();
58.541 + }
58.542 +
58.543 + /**
58.544 + * Queries if this lock is held by the current thread.
58.545 + *
58.546 + * <p>Analogous to the {@link Thread#holdsLock} method for built-in
58.547 + * monitor locks, this method is typically used for debugging and
58.548 + * testing. For example, a method that should only be called while
58.549 + * a lock is held can assert that this is the case:
58.550 + *
58.551 + * <pre>
58.552 + * class X {
58.553 + * ReentrantLock lock = new ReentrantLock();
58.554 + * // ...
58.555 + *
58.556 + * public void m() {
58.557 + * assert lock.isHeldByCurrentThread();
58.558 + * // ... method body
58.559 + * }
58.560 + * }
58.561 + * </pre>
58.562 + *
58.563 + * <p>It can also be used to ensure that a reentrant lock is used
58.564 + * in a non-reentrant manner, for example:
58.565 + *
58.566 + * <pre>
58.567 + * class X {
58.568 + * ReentrantLock lock = new ReentrantLock();
58.569 + * // ...
58.570 + *
58.571 + * public void m() {
58.572 + * assert !lock.isHeldByCurrentThread();
58.573 + * lock.lock();
58.574 + * try {
58.575 + * // ... method body
58.576 + * } finally {
58.577 + * lock.unlock();
58.578 + * }
58.579 + * }
58.580 + * }
58.581 + * </pre>
58.582 + *
58.583 + * @return {@code true} if current thread holds this lock and
58.584 + * {@code false} otherwise
58.585 + */
58.586 + public boolean isHeldByCurrentThread() {
58.587 + return sync.isHeldExclusively();
58.588 + }
58.589 +
58.590 + /**
58.591 + * Queries if this lock is held by any thread. This method is
58.592 + * designed for use in monitoring of the system state,
58.593 + * not for synchronization control.
58.594 + *
58.595 + * @return {@code true} if any thread holds this lock and
58.596 + * {@code false} otherwise
58.597 + */
58.598 + public boolean isLocked() {
58.599 + return sync.isLocked();
58.600 + }
58.601 +
58.602 + /**
58.603 + * Returns {@code true} if this lock has fairness set true.
58.604 + *
58.605 + * @return {@code true} if this lock has fairness set true
58.606 + */
58.607 + public final boolean isFair() {
58.608 + return sync instanceof FairSync;
58.609 + }
58.610 +
58.611 + /**
58.612 + * Returns the thread that currently owns this lock, or
58.613 + * {@code null} if not owned. When this method is called by a
58.614 + * thread that is not the owner, the return value reflects a
58.615 + * best-effort approximation of current lock status. For example,
58.616 + * the owner may be momentarily {@code null} even if there are
58.617 + * threads trying to acquire the lock but have not yet done so.
58.618 + * This method is designed to facilitate construction of
58.619 + * subclasses that provide more extensive lock monitoring
58.620 + * facilities.
58.621 + *
58.622 + * @return the owner, or {@code null} if not owned
58.623 + */
58.624 + protected Thread getOwner() {
58.625 + return sync.getOwner();
58.626 + }
58.627 +
58.628 + /**
58.629 + * Queries whether any threads are waiting to acquire this lock. Note that
58.630 + * because cancellations may occur at any time, a {@code true}
58.631 + * return does not guarantee that any other thread will ever
58.632 + * acquire this lock. This method is designed primarily for use in
58.633 + * monitoring of the system state.
58.634 + *
58.635 + * @return {@code true} if there may be other threads waiting to
58.636 + * acquire the lock
58.637 + */
58.638 + public final boolean hasQueuedThreads() {
58.639 + return sync.hasQueuedThreads();
58.640 + }
58.641 +
58.642 +
58.643 + /**
58.644 + * Queries whether the given thread is waiting to acquire this
58.645 + * lock. Note that because cancellations may occur at any time, a
58.646 + * {@code true} return does not guarantee that this thread
58.647 + * will ever acquire this lock. This method is designed primarily for use
58.648 + * in monitoring of the system state.
58.649 + *
58.650 + * @param thread the thread
58.651 + * @return {@code true} if the given thread is queued waiting for this lock
58.652 + * @throws NullPointerException if the thread is null
58.653 + */
58.654 + public final boolean hasQueuedThread(Thread thread) {
58.655 + return sync.isQueued(thread);
58.656 + }
58.657 +
58.658 +
58.659 + /**
58.660 + * Returns an estimate of the number of threads waiting to
58.661 + * acquire this lock. The value is only an estimate because the number of
58.662 + * threads may change dynamically while this method traverses
58.663 + * internal data structures. This method is designed for use in
58.664 + * monitoring of the system state, not for synchronization
58.665 + * control.
58.666 + *
58.667 + * @return the estimated number of threads waiting for this lock
58.668 + */
58.669 + public final int getQueueLength() {
58.670 + return sync.getQueueLength();
58.671 + }
58.672 +
58.673 + /**
58.674 + * Returns a collection containing threads that may be waiting to
58.675 + * acquire this lock. Because the actual set of threads may change
58.676 + * dynamically while constructing this result, the returned
58.677 + * collection is only a best-effort estimate. The elements of the
58.678 + * returned collection are in no particular order. This method is
58.679 + * designed to facilitate construction of subclasses that provide
58.680 + * more extensive monitoring facilities.
58.681 + *
58.682 + * @return the collection of threads
58.683 + */
58.684 + protected Collection<Thread> getQueuedThreads() {
58.685 + return sync.getQueuedThreads();
58.686 + }
58.687 +
58.688 + /**
58.689 + * Queries whether any threads are waiting on the given condition
58.690 + * associated with this lock. Note that because timeouts and
58.691 + * interrupts may occur at any time, a {@code true} return does
58.692 + * not guarantee that a future {@code signal} will awaken any
58.693 + * threads. This method is designed primarily for use in
58.694 + * monitoring of the system state.
58.695 + *
58.696 + * @param condition the condition
58.697 + * @return {@code true} if there are any waiting threads
58.698 + * @throws IllegalMonitorStateException if this lock is not held
58.699 + * @throws IllegalArgumentException if the given condition is
58.700 + * not associated with this lock
58.701 + * @throws NullPointerException if the condition is null
58.702 + */
58.703 + public boolean hasWaiters(Condition condition) {
58.704 + if (condition == null)
58.705 + throw new NullPointerException();
58.706 + if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
58.707 + throw new IllegalArgumentException("not owner");
58.708 + return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
58.709 + }
58.710 +
58.711 + /**
58.712 + * Returns an estimate of the number of threads waiting on the
58.713 + * given condition associated with this lock. Note that because
58.714 + * timeouts and interrupts may occur at any time, the estimate
58.715 + * serves only as an upper bound on the actual number of waiters.
58.716 + * This method is designed for use in monitoring of the system
58.717 + * state, not for synchronization control.
58.718 + *
58.719 + * @param condition the condition
58.720 + * @return the estimated number of waiting threads
58.721 + * @throws IllegalMonitorStateException if this lock is not held
58.722 + * @throws IllegalArgumentException if the given condition is
58.723 + * not associated with this lock
58.724 + * @throws NullPointerException if the condition is null
58.725 + */
58.726 + public int getWaitQueueLength(Condition condition) {
58.727 + if (condition == null)
58.728 + throw new NullPointerException();
58.729 + if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
58.730 + throw new IllegalArgumentException("not owner");
58.731 + return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
58.732 + }
58.733 +
58.734 + /**
58.735 + * Returns a collection containing those threads that may be
58.736 + * waiting on the given condition associated with this lock.
58.737 + * Because the actual set of threads may change dynamically while
58.738 + * constructing this result, the returned collection is only a
58.739 + * best-effort estimate. The elements of the returned collection
58.740 + * are in no particular order. This method is designed to
58.741 + * facilitate construction of subclasses that provide more
58.742 + * extensive condition monitoring facilities.
58.743 + *
58.744 + * @param condition the condition
58.745 + * @return the collection of threads
58.746 + * @throws IllegalMonitorStateException if this lock is not held
58.747 + * @throws IllegalArgumentException if the given condition is
58.748 + * not associated with this lock
58.749 + * @throws NullPointerException if the condition is null
58.750 + */
58.751 + protected Collection<Thread> getWaitingThreads(Condition condition) {
58.752 + if (condition == null)
58.753 + throw new NullPointerException();
58.754 + if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
58.755 + throw new IllegalArgumentException("not owner");
58.756 + return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
58.757 + }
58.758 +
58.759 + /**
58.760 + * Returns a string identifying this lock, as well as its lock state.
58.761 + * The state, in brackets, includes either the String {@code "Unlocked"}
58.762 + * or the String {@code "Locked by"} followed by the
58.763 + * {@linkplain Thread#getName name} of the owning thread.
58.764 + *
58.765 + * @return a string identifying this lock, as well as its lock state
58.766 + */
58.767 + public String toString() {
58.768 + Thread o = sync.getOwner();
58.769 + return super.toString() + ((o == null) ?
58.770 + "[Unlocked]" :
58.771 + "[Locked by thread " + o.getName() + "]");
58.772 + }
58.773 +}
59.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
59.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java Sat Mar 19 10:48:29 2016 +0100
59.3 @@ -0,0 +1,1486 @@
59.4 +/*
59.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
59.6 + *
59.7 + * This code is free software; you can redistribute it and/or modify it
59.8 + * under the terms of the GNU General Public License version 2 only, as
59.9 + * published by the Free Software Foundation. Oracle designates this
59.10 + * particular file as subject to the "Classpath" exception as provided
59.11 + * by Oracle in the LICENSE file that accompanied this code.
59.12 + *
59.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
59.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
59.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
59.16 + * version 2 for more details (a copy is included in the LICENSE file that
59.17 + * accompanied this code).
59.18 + *
59.19 + * You should have received a copy of the GNU General Public License version
59.20 + * 2 along with this work; if not, write to the Free Software Foundation,
59.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
59.22 + *
59.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
59.24 + * or visit www.oracle.com if you need additional information or have any
59.25 + * questions.
59.26 + */
59.27 +
59.28 +/*
59.29 + * This file is available under and governed by the GNU General Public
59.30 + * License version 2 only, as published by the Free Software Foundation.
59.31 + * However, the following notice accompanied the original version of this
59.32 + * file:
59.33 + *
59.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
59.35 + * Expert Group and released to the public domain, as explained at
59.36 + * http://creativecommons.org/publicdomain/zero/1.0/
59.37 + */
59.38 +
59.39 +package java.util.concurrent.locks;
59.40 +import java.util.concurrent.*;
59.41 +import java.util.concurrent.atomic.*;
59.42 +import java.util.*;
59.43 +
59.44 +/**
59.45 + * An implementation of {@link ReadWriteLock} supporting similar
59.46 + * semantics to {@link ReentrantLock}.
59.47 + * <p>This class has the following properties:
59.48 + *
59.49 + * <ul>
59.50 + * <li><b>Acquisition order</b>
59.51 + *
59.52 + * <p> This class does not impose a reader or writer preference
59.53 + * ordering for lock access. However, it does support an optional
59.54 + * <em>fairness</em> policy.
59.55 + *
59.56 + * <dl>
59.57 + * <dt><b><i>Non-fair mode (default)</i></b>
59.58 + * <dd>When constructed as non-fair (the default), the order of entry
59.59 + * to the read and write lock is unspecified, subject to reentrancy
59.60 + * constraints. A nonfair lock that is continuously contended may
59.61 + * indefinitely postpone one or more reader or writer threads, but
59.62 + * will normally have higher throughput than a fair lock.
59.63 + * <p>
59.64 + *
59.65 + * <dt><b><i>Fair mode</i></b>
59.66 + * <dd> When constructed as fair, threads contend for entry using an
59.67 + * approximately arrival-order policy. When the currently held lock
59.68 + * is released either the longest-waiting single writer thread will
59.69 + * be assigned the write lock, or if there is a group of reader threads
59.70 + * waiting longer than all waiting writer threads, that group will be
59.71 + * assigned the read lock.
59.72 + *
59.73 + * <p>A thread that tries to acquire a fair read lock (non-reentrantly)
59.74 + * will block if either the write lock is held, or there is a waiting
59.75 + * writer thread. The thread will not acquire the read lock until
59.76 + * after the oldest currently waiting writer thread has acquired and
59.77 + * released the write lock. Of course, if a waiting writer abandons
59.78 + * its wait, leaving one or more reader threads as the longest waiters
59.79 + * in the queue with the write lock free, then those readers will be
59.80 + * assigned the read lock.
59.81 + *
59.82 + * <p>A thread that tries to acquire a fair write lock (non-reentrantly)
59.83 + * will block unless both the read lock and write lock are free (which
59.84 + * implies there are no waiting threads). (Note that the non-blocking
59.85 + * {@link ReadLock#tryLock()} and {@link WriteLock#tryLock()} methods
59.86 + * do not honor this fair setting and will acquire the lock if it is
59.87 + * possible, regardless of waiting threads.)
59.88 + * <p>
59.89 + * </dl>
59.90 + *
59.91 + * <li><b>Reentrancy</b>
59.92 + *
59.93 + * <p>This lock allows both readers and writers to reacquire read or
59.94 + * write locks in the style of a {@link ReentrantLock}. Non-reentrant
59.95 + * readers are not allowed until all write locks held by the writing
59.96 + * thread have been released.
59.97 + *
59.98 + * <p>Additionally, a writer can acquire the read lock, but not
59.99 + * vice-versa. Among other applications, reentrancy can be useful
59.100 + * when write locks are held during calls or callbacks to methods that
59.101 + * perform reads under read locks. If a reader tries to acquire the
59.102 + * write lock it will never succeed.
59.103 + *
59.104 + * <li><b>Lock downgrading</b>
59.105 + * <p>Reentrancy also allows downgrading from the write lock to a read lock,
59.106 + * by acquiring the write lock, then the read lock and then releasing the
59.107 + * write lock. However, upgrading from a read lock to the write lock is
59.108 + * <b>not</b> possible.
59.109 + *
59.110 + * <li><b>Interruption of lock acquisition</b>
59.111 + * <p>The read lock and write lock both support interruption during lock
59.112 + * acquisition.
59.113 + *
59.114 + * <li><b>{@link Condition} support</b>
59.115 + * <p>The write lock provides a {@link Condition} implementation that
59.116 + * behaves in the same way, with respect to the write lock, as the
59.117 + * {@link Condition} implementation provided by
59.118 + * {@link ReentrantLock#newCondition} does for {@link ReentrantLock}.
59.119 + * This {@link Condition} can, of course, only be used with the write lock.
59.120 + *
59.121 + * <p>The read lock does not support a {@link Condition} and
59.122 + * {@code readLock().newCondition()} throws
59.123 + * {@code UnsupportedOperationException}.
59.124 + *
59.125 + * <li><b>Instrumentation</b>
59.126 + * <p>This class supports methods to determine whether locks
59.127 + * are held or contended. These methods are designed for monitoring
59.128 + * system state, not for synchronization control.
59.129 + * </ul>
59.130 + *
59.131 + * <p>Serialization of this class behaves in the same way as built-in
59.132 + * locks: a deserialized lock is in the unlocked state, regardless of
59.133 + * its state when serialized.
59.134 + *
59.135 + * <p><b>Sample usages</b>. Here is a code sketch showing how to perform
59.136 + * lock downgrading after updating a cache (exception handling is
59.137 + * particularly tricky when handling multiple locks in a non-nested
59.138 + * fashion):
59.139 + *
59.140 + * <pre> {@code
59.141 + * class CachedData {
59.142 + * Object data;
59.143 + * volatile boolean cacheValid;
59.144 + * final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
59.145 + *
59.146 + * void processCachedData() {
59.147 + * rwl.readLock().lock();
59.148 + * if (!cacheValid) {
59.149 + * // Must release read lock before acquiring write lock
59.150 + * rwl.readLock().unlock();
59.151 + * rwl.writeLock().lock();
59.152 + * try {
59.153 + * // Recheck state because another thread might have
59.154 + * // acquired write lock and changed state before we did.
59.155 + * if (!cacheValid) {
59.156 + * data = ...
59.157 + * cacheValid = true;
59.158 + * }
59.159 + * // Downgrade by acquiring read lock before releasing write lock
59.160 + * rwl.readLock().lock();
59.161 + * } finally {
59.162 + * rwl.writeLock().unlock(); // Unlock write, still hold read
59.163 + * }
59.164 + * }
59.165 + *
59.166 + * try {
59.167 + * use(data);
59.168 + * } finally {
59.169 + * rwl.readLock().unlock();
59.170 + * }
59.171 + * }
59.172 + * }}</pre>
59.173 + *
59.174 + * ReentrantReadWriteLocks can be used to improve concurrency in some
59.175 + * uses of some kinds of Collections. This is typically worthwhile
59.176 + * only when the collections are expected to be large, accessed by
59.177 + * more reader threads than writer threads, and entail operations with
59.178 + * overhead that outweighs synchronization overhead. For example, here
59.179 + * is a class using a TreeMap that is expected to be large and
59.180 + * concurrently accessed.
59.181 + *
59.182 + * <pre>{@code
59.183 + * class RWDictionary {
59.184 + * private final Map<String, Data> m = new TreeMap<String, Data>();
59.185 + * private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
59.186 + * private final Lock r = rwl.readLock();
59.187 + * private final Lock w = rwl.writeLock();
59.188 + *
59.189 + * public Data get(String key) {
59.190 + * r.lock();
59.191 + * try { return m.get(key); }
59.192 + * finally { r.unlock(); }
59.193 + * }
59.194 + * public String[] allKeys() {
59.195 + * r.lock();
59.196 + * try { return m.keySet().toArray(); }
59.197 + * finally { r.unlock(); }
59.198 + * }
59.199 + * public Data put(String key, Data value) {
59.200 + * w.lock();
59.201 + * try { return m.put(key, value); }
59.202 + * finally { w.unlock(); }
59.203 + * }
59.204 + * public void clear() {
59.205 + * w.lock();
59.206 + * try { m.clear(); }
59.207 + * finally { w.unlock(); }
59.208 + * }
59.209 + * }}</pre>
59.210 + *
59.211 + * <h3>Implementation Notes</h3>
59.212 + *
59.213 + * <p>This lock supports a maximum of 65535 recursive write locks
59.214 + * and 65535 read locks. Attempts to exceed these limits result in
59.215 + * {@link Error} throws from locking methods.
59.216 + *
59.217 + * @since 1.5
59.218 + * @author Doug Lea
59.219 + *
59.220 + */
59.221 +public class ReentrantReadWriteLock
59.222 + implements ReadWriteLock, java.io.Serializable {
59.223 + private static final long serialVersionUID = -6992448646407690164L;
59.224 + /** Inner class providing readlock */
59.225 + private final ReentrantReadWriteLock.ReadLock readerLock;
59.226 + /** Inner class providing writelock */
59.227 + private final ReentrantReadWriteLock.WriteLock writerLock;
59.228 + /** Performs all synchronization mechanics */
59.229 + final Sync sync;
59.230 +
59.231 + /**
59.232 + * Creates a new {@code ReentrantReadWriteLock} with
59.233 + * default (nonfair) ordering properties.
59.234 + */
59.235 + public ReentrantReadWriteLock() {
59.236 + this(false);
59.237 + }
59.238 +
59.239 + /**
59.240 + * Creates a new {@code ReentrantReadWriteLock} with
59.241 + * the given fairness policy.
59.242 + *
59.243 + * @param fair {@code true} if this lock should use a fair ordering policy
59.244 + */
59.245 + public ReentrantReadWriteLock(boolean fair) {
59.246 + sync = fair ? new FairSync() : new NonfairSync();
59.247 + readerLock = new ReadLock(this);
59.248 + writerLock = new WriteLock(this);
59.249 + }
59.250 +
59.251 + public ReentrantReadWriteLock.WriteLock writeLock() { return writerLock; }
59.252 + public ReentrantReadWriteLock.ReadLock readLock() { return readerLock; }
59.253 +
59.254 + /**
59.255 + * Synchronization implementation for ReentrantReadWriteLock.
59.256 + * Subclassed into fair and nonfair versions.
59.257 + */
59.258 + abstract static class Sync extends AbstractQueuedSynchronizer {
59.259 + private static final long serialVersionUID = 6317671515068378041L;
59.260 +
59.261 + /*
59.262 + * Read vs write count extraction constants and functions.
59.263 + * Lock state is logically divided into two unsigned shorts:
59.264 + * The lower one representing the exclusive (writer) lock hold count,
59.265 + * and the upper the shared (reader) hold count.
59.266 + */
59.267 +
59.268 + static final int SHARED_SHIFT = 16;
59.269 + static final int SHARED_UNIT = (1 << SHARED_SHIFT);
59.270 + static final int MAX_COUNT = (1 << SHARED_SHIFT) - 1;
59.271 + static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1;
59.272 +
59.273 + /** Returns the number of shared holds represented in count */
59.274 + static int sharedCount(int c) { return c >>> SHARED_SHIFT; }
59.275 + /** Returns the number of exclusive holds represented in count */
59.276 + static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; }
59.277 +
59.278 + /**
59.279 + * A counter for per-thread read hold counts.
59.280 + * Maintained as a ThreadLocal; cached in cachedHoldCounter
59.281 + */
59.282 + static final class HoldCounter {
59.283 + int count = 0;
59.284 + // Use id, not reference, to avoid garbage retention
59.285 + final long tid = Thread.currentThread().getId();
59.286 + }
59.287 +
59.288 + /**
59.289 + * ThreadLocal subclass. Easiest to explicitly define for sake
59.290 + * of deserialization mechanics.
59.291 + */
59.292 + static final class ThreadLocalHoldCounter
59.293 + extends ThreadLocal<HoldCounter> {
59.294 + public HoldCounter initialValue() {
59.295 + return new HoldCounter();
59.296 + }
59.297 + }
59.298 +
59.299 + /**
59.300 + * The number of reentrant read locks held by current thread.
59.301 + * Initialized only in constructor and readObject.
59.302 + * Removed whenever a thread's read hold count drops to 0.
59.303 + */
59.304 + private transient ThreadLocalHoldCounter readHolds;
59.305 +
59.306 + /**
59.307 + * The hold count of the last thread to successfully acquire
59.308 + * readLock. This saves ThreadLocal lookup in the common case
59.309 + * where the next thread to release is the last one to
59.310 + * acquire. This is non-volatile since it is just used
59.311 + * as a heuristic, and would be great for threads to cache.
59.312 + *
59.313 + * <p>Can outlive the Thread for which it is caching the read
59.314 + * hold count, but avoids garbage retention by not retaining a
59.315 + * reference to the Thread.
59.316 + *
59.317 + * <p>Accessed via a benign data race; relies on the memory
59.318 + * model's final field and out-of-thin-air guarantees.
59.319 + */
59.320 + private transient HoldCounter cachedHoldCounter;
59.321 +
59.322 + /**
59.323 + * firstReader is the first thread to have acquired the read lock.
59.324 + * firstReaderHoldCount is firstReader's hold count.
59.325 + *
59.326 + * <p>More precisely, firstReader is the unique thread that last
59.327 + * changed the shared count from 0 to 1, and has not released the
59.328 + * read lock since then; null if there is no such thread.
59.329 + *
59.330 + * <p>Cannot cause garbage retention unless the thread terminated
59.331 + * without relinquishing its read locks, since tryReleaseShared
59.332 + * sets it to null.
59.333 + *
59.334 + * <p>Accessed via a benign data race; relies on the memory
59.335 + * model's out-of-thin-air guarantees for references.
59.336 + *
59.337 + * <p>This allows tracking of read holds for uncontended read
59.338 + * locks to be very cheap.
59.339 + */
59.340 + private transient Thread firstReader = null;
59.341 + private transient int firstReaderHoldCount;
59.342 +
59.343 + Sync() {
59.344 + readHolds = new ThreadLocalHoldCounter();
59.345 + setState(getState()); // ensures visibility of readHolds
59.346 + }
59.347 +
59.348 + /*
59.349 + * Acquires and releases use the same code for fair and
59.350 + * nonfair locks, but differ in whether/how they allow barging
59.351 + * when queues are non-empty.
59.352 + */
59.353 +
59.354 + /**
59.355 + * Returns true if the current thread, when trying to acquire
59.356 + * the read lock, and otherwise eligible to do so, should block
59.357 + * because of policy for overtaking other waiting threads.
59.358 + */
59.359 + abstract boolean readerShouldBlock();
59.360 +
59.361 + /**
59.362 + * Returns true if the current thread, when trying to acquire
59.363 + * the write lock, and otherwise eligible to do so, should block
59.364 + * because of policy for overtaking other waiting threads.
59.365 + */
59.366 + abstract boolean writerShouldBlock();
59.367 +
59.368 + /*
59.369 + * Note that tryRelease and tryAcquire can be called by
59.370 + * Conditions. So it is possible that their arguments contain
59.371 + * both read and write holds that are all released during a
59.372 + * condition wait and re-established in tryAcquire.
59.373 + */
59.374 +
59.375 + protected final boolean tryRelease(int releases) {
59.376 + if (!isHeldExclusively())
59.377 + throw new IllegalMonitorStateException();
59.378 + int nextc = getState() - releases;
59.379 + boolean free = exclusiveCount(nextc) == 0;
59.380 + if (free)
59.381 + setExclusiveOwnerThread(null);
59.382 + setState(nextc);
59.383 + return free;
59.384 + }
59.385 +
59.386 + protected final boolean tryAcquire(int acquires) {
59.387 + /*
59.388 + * Walkthrough:
59.389 + * 1. If read count nonzero or write count nonzero
59.390 + * and owner is a different thread, fail.
59.391 + * 2. If count would saturate, fail. (This can only
59.392 + * happen if count is already nonzero.)
59.393 + * 3. Otherwise, this thread is eligible for lock if
59.394 + * it is either a reentrant acquire or
59.395 + * queue policy allows it. If so, update state
59.396 + * and set owner.
59.397 + */
59.398 + Thread current = Thread.currentThread();
59.399 + int c = getState();
59.400 + int w = exclusiveCount(c);
59.401 + if (c != 0) {
59.402 + // (Note: if c != 0 and w == 0 then shared count != 0)
59.403 + if (w == 0 || current != getExclusiveOwnerThread())
59.404 + return false;
59.405 + if (w + exclusiveCount(acquires) > MAX_COUNT)
59.406 + throw new Error("Maximum lock count exceeded");
59.407 + // Reentrant acquire
59.408 + setState(c + acquires);
59.409 + return true;
59.410 + }
59.411 + if (writerShouldBlock() ||
59.412 + !compareAndSetState(c, c + acquires))
59.413 + return false;
59.414 + setExclusiveOwnerThread(current);
59.415 + return true;
59.416 + }
59.417 +
59.418 + protected final boolean tryReleaseShared(int unused) {
59.419 + Thread current = Thread.currentThread();
59.420 + if (firstReader == current) {
59.421 + // assert firstReaderHoldCount > 0;
59.422 + if (firstReaderHoldCount == 1)
59.423 + firstReader = null;
59.424 + else
59.425 + firstReaderHoldCount--;
59.426 + } else {
59.427 + HoldCounter rh = cachedHoldCounter;
59.428 + if (rh == null || rh.tid != current.getId())
59.429 + rh = readHolds.get();
59.430 + int count = rh.count;
59.431 + if (count <= 1) {
59.432 + readHolds.remove();
59.433 + if (count <= 0)
59.434 + throw unmatchedUnlockException();
59.435 + }
59.436 + --rh.count;
59.437 + }
59.438 + for (;;) {
59.439 + int c = getState();
59.440 + int nextc = c - SHARED_UNIT;
59.441 + if (compareAndSetState(c, nextc))
59.442 + // Releasing the read lock has no effect on readers,
59.443 + // but it may allow waiting writers to proceed if
59.444 + // both read and write locks are now free.
59.445 + return nextc == 0;
59.446 + }
59.447 + }
59.448 +
59.449 + private IllegalMonitorStateException unmatchedUnlockException() {
59.450 + return new IllegalMonitorStateException(
59.451 + "attempt to unlock read lock, not locked by current thread");
59.452 + }
59.453 +
59.454 + protected final int tryAcquireShared(int unused) {
59.455 + /*
59.456 + * Walkthrough:
59.457 + * 1. If write lock held by another thread, fail.
59.458 + * 2. Otherwise, this thread is eligible for
59.459 + * lock wrt state, so ask if it should block
59.460 + * because of queue policy. If not, try
59.461 + * to grant by CASing state and updating count.
59.462 + * Note that step does not check for reentrant
59.463 + * acquires, which is postponed to full version
59.464 + * to avoid having to check hold count in
59.465 + * the more typical non-reentrant case.
59.466 + * 3. If step 2 fails either because thread
59.467 + * apparently not eligible or CAS fails or count
59.468 + * saturated, chain to version with full retry loop.
59.469 + */
59.470 + Thread current = Thread.currentThread();
59.471 + int c = getState();
59.472 + if (exclusiveCount(c) != 0 &&
59.473 + getExclusiveOwnerThread() != current)
59.474 + return -1;
59.475 + int r = sharedCount(c);
59.476 + if (!readerShouldBlock() &&
59.477 + r < MAX_COUNT &&
59.478 + compareAndSetState(c, c + SHARED_UNIT)) {
59.479 + if (r == 0) {
59.480 + firstReader = current;
59.481 + firstReaderHoldCount = 1;
59.482 + } else if (firstReader == current) {
59.483 + firstReaderHoldCount++;
59.484 + } else {
59.485 + HoldCounter rh = cachedHoldCounter;
59.486 + if (rh == null || rh.tid != current.getId())
59.487 + cachedHoldCounter = rh = readHolds.get();
59.488 + else if (rh.count == 0)
59.489 + readHolds.set(rh);
59.490 + rh.count++;
59.491 + }
59.492 + return 1;
59.493 + }
59.494 + return fullTryAcquireShared(current);
59.495 + }
59.496 +
59.497 + /**
59.498 + * Full version of acquire for reads, that handles CAS misses
59.499 + * and reentrant reads not dealt with in tryAcquireShared.
59.500 + */
59.501 + final int fullTryAcquireShared(Thread current) {
59.502 + /*
59.503 + * This code is in part redundant with that in
59.504 + * tryAcquireShared but is simpler overall by not
59.505 + * complicating tryAcquireShared with interactions between
59.506 + * retries and lazily reading hold counts.
59.507 + */
59.508 + HoldCounter rh = null;
59.509 + for (;;) {
59.510 + int c = getState();
59.511 + if (exclusiveCount(c) != 0) {
59.512 + if (getExclusiveOwnerThread() != current)
59.513 + return -1;
59.514 + // else we hold the exclusive lock; blocking here
59.515 + // would cause deadlock.
59.516 + } else if (readerShouldBlock()) {
59.517 + // Make sure we're not acquiring read lock reentrantly
59.518 + if (firstReader == current) {
59.519 + // assert firstReaderHoldCount > 0;
59.520 + } else {
59.521 + if (rh == null) {
59.522 + rh = cachedHoldCounter;
59.523 + if (rh == null || rh.tid != current.getId()) {
59.524 + rh = readHolds.get();
59.525 + if (rh.count == 0)
59.526 + readHolds.remove();
59.527 + }
59.528 + }
59.529 + if (rh.count == 0)
59.530 + return -1;
59.531 + }
59.532 + }
59.533 + if (sharedCount(c) == MAX_COUNT)
59.534 + throw new Error("Maximum lock count exceeded");
59.535 + if (compareAndSetState(c, c + SHARED_UNIT)) {
59.536 + if (sharedCount(c) == 0) {
59.537 + firstReader = current;
59.538 + firstReaderHoldCount = 1;
59.539 + } else if (firstReader == current) {
59.540 + firstReaderHoldCount++;
59.541 + } else {
59.542 + if (rh == null)
59.543 + rh = cachedHoldCounter;
59.544 + if (rh == null || rh.tid != current.getId())
59.545 + rh = readHolds.get();
59.546 + else if (rh.count == 0)
59.547 + readHolds.set(rh);
59.548 + rh.count++;
59.549 + cachedHoldCounter = rh; // cache for release
59.550 + }
59.551 + return 1;
59.552 + }
59.553 + }
59.554 + }
59.555 +
59.556 + /**
59.557 + * Performs tryLock for write, enabling barging in both modes.
59.558 + * This is identical in effect to tryAcquire except for lack
59.559 + * of calls to writerShouldBlock.
59.560 + */
59.561 + final boolean tryWriteLock() {
59.562 + Thread current = Thread.currentThread();
59.563 + int c = getState();
59.564 + if (c != 0) {
59.565 + int w = exclusiveCount(c);
59.566 + if (w == 0 || current != getExclusiveOwnerThread())
59.567 + return false;
59.568 + if (w == MAX_COUNT)
59.569 + throw new Error("Maximum lock count exceeded");
59.570 + }
59.571 + if (!compareAndSetState(c, c + 1))
59.572 + return false;
59.573 + setExclusiveOwnerThread(current);
59.574 + return true;
59.575 + }
59.576 +
59.577 + /**
59.578 + * Performs tryLock for read, enabling barging in both modes.
59.579 + * This is identical in effect to tryAcquireShared except for
59.580 + * lack of calls to readerShouldBlock.
59.581 + */
59.582 + final boolean tryReadLock() {
59.583 + Thread current = Thread.currentThread();
59.584 + for (;;) {
59.585 + int c = getState();
59.586 + if (exclusiveCount(c) != 0 &&
59.587 + getExclusiveOwnerThread() != current)
59.588 + return false;
59.589 + int r = sharedCount(c);
59.590 + if (r == MAX_COUNT)
59.591 + throw new Error("Maximum lock count exceeded");
59.592 + if (compareAndSetState(c, c + SHARED_UNIT)) {
59.593 + if (r == 0) {
59.594 + firstReader = current;
59.595 + firstReaderHoldCount = 1;
59.596 + } else if (firstReader == current) {
59.597 + firstReaderHoldCount++;
59.598 + } else {
59.599 + HoldCounter rh = cachedHoldCounter;
59.600 + if (rh == null || rh.tid != current.getId())
59.601 + cachedHoldCounter = rh = readHolds.get();
59.602 + else if (rh.count == 0)
59.603 + readHolds.set(rh);
59.604 + rh.count++;
59.605 + }
59.606 + return true;
59.607 + }
59.608 + }
59.609 + }
59.610 +
59.611 + protected final boolean isHeldExclusively() {
59.612 + // While we must in general read state before owner,
59.613 + // we don't need to do so to check if current thread is owner
59.614 + return getExclusiveOwnerThread() == Thread.currentThread();
59.615 + }
59.616 +
59.617 + // Methods relayed to outer class
59.618 +
59.619 + final ConditionObject newCondition() {
59.620 + return new ConditionObject();
59.621 + }
59.622 +
59.623 + final Thread getOwner() {
59.624 + // Must read state before owner to ensure memory consistency
59.625 + return ((exclusiveCount(getState()) == 0) ?
59.626 + null :
59.627 + getExclusiveOwnerThread());
59.628 + }
59.629 +
59.630 + final int getReadLockCount() {
59.631 + return sharedCount(getState());
59.632 + }
59.633 +
59.634 + final boolean isWriteLocked() {
59.635 + return exclusiveCount(getState()) != 0;
59.636 + }
59.637 +
59.638 + final int getWriteHoldCount() {
59.639 + return isHeldExclusively() ? exclusiveCount(getState()) : 0;
59.640 + }
59.641 +
59.642 + final int getReadHoldCount() {
59.643 + if (getReadLockCount() == 0)
59.644 + return 0;
59.645 +
59.646 + Thread current = Thread.currentThread();
59.647 + if (firstReader == current)
59.648 + return firstReaderHoldCount;
59.649 +
59.650 + HoldCounter rh = cachedHoldCounter;
59.651 + if (rh != null && rh.tid == current.getId())
59.652 + return rh.count;
59.653 +
59.654 + int count = readHolds.get().count;
59.655 + if (count == 0) readHolds.remove();
59.656 + return count;
59.657 + }
59.658 +
59.659 + /**
59.660 + * Reconstitute this lock instance from a stream
59.661 + * @param s the stream
59.662 + */
59.663 + private void readObject(java.io.ObjectInputStream s)
59.664 + throws java.io.IOException, ClassNotFoundException {
59.665 + s.defaultReadObject();
59.666 + readHolds = new ThreadLocalHoldCounter();
59.667 + setState(0); // reset to unlocked state
59.668 + }
59.669 +
59.670 + final int getCount() { return getState(); }
59.671 + }
59.672 +
59.673 + /**
59.674 + * Nonfair version of Sync
59.675 + */
59.676 + static final class NonfairSync extends Sync {
59.677 + private static final long serialVersionUID = -8159625535654395037L;
59.678 + final boolean writerShouldBlock() {
59.679 + return false; // writers can always barge
59.680 + }
59.681 + final boolean readerShouldBlock() {
59.682 + /* As a heuristic to avoid indefinite writer starvation,
59.683 + * block if the thread that momentarily appears to be head
59.684 + * of queue, if one exists, is a waiting writer. This is
59.685 + * only a probabilistic effect since a new reader will not
59.686 + * block if there is a waiting writer behind other enabled
59.687 + * readers that have not yet drained from the queue.
59.688 + */
59.689 + return apparentlyFirstQueuedIsExclusive();
59.690 + }
59.691 + }
59.692 +
59.693 + /**
59.694 + * Fair version of Sync
59.695 + */
59.696 + static final class FairSync extends Sync {
59.697 + private static final long serialVersionUID = -2274990926593161451L;
59.698 + final boolean writerShouldBlock() {
59.699 + return hasQueuedPredecessors();
59.700 + }
59.701 + final boolean readerShouldBlock() {
59.702 + return hasQueuedPredecessors();
59.703 + }
59.704 + }
59.705 +
59.706 + /**
59.707 + * The lock returned by method {@link ReentrantReadWriteLock#readLock}.
59.708 + */
59.709 + public static class ReadLock implements Lock, java.io.Serializable {
59.710 + private static final long serialVersionUID = -5992448646407690164L;
59.711 + private final Sync sync;
59.712 +
59.713 + /**
59.714 + * Constructor for use by subclasses
59.715 + *
59.716 + * @param lock the outer lock object
59.717 + * @throws NullPointerException if the lock is null
59.718 + */
59.719 + protected ReadLock(ReentrantReadWriteLock lock) {
59.720 + sync = lock.sync;
59.721 + }
59.722 +
59.723 + /**
59.724 + * Acquires the read lock.
59.725 + *
59.726 + * <p>Acquires the read lock if the write lock is not held by
59.727 + * another thread and returns immediately.
59.728 + *
59.729 + * <p>If the write lock is held by another thread then
59.730 + * the current thread becomes disabled for thread scheduling
59.731 + * purposes and lies dormant until the read lock has been acquired.
59.732 + */
59.733 + public void lock() {
59.734 + sync.acquireShared(1);
59.735 + }
59.736 +
59.737 + /**
59.738 + * Acquires the read lock unless the current thread is
59.739 + * {@linkplain Thread#interrupt interrupted}.
59.740 + *
59.741 + * <p>Acquires the read lock if the write lock is not held
59.742 + * by another thread and returns immediately.
59.743 + *
59.744 + * <p>If the write lock is held by another thread then the
59.745 + * current thread becomes disabled for thread scheduling
59.746 + * purposes and lies dormant until one of two things happens:
59.747 + *
59.748 + * <ul>
59.749 + *
59.750 + * <li>The read lock is acquired by the current thread; or
59.751 + *
59.752 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
59.753 + * the current thread.
59.754 + *
59.755 + * </ul>
59.756 + *
59.757 + * <p>If the current thread:
59.758 + *
59.759 + * <ul>
59.760 + *
59.761 + * <li>has its interrupted status set on entry to this method; or
59.762 + *
59.763 + * <li>is {@linkplain Thread#interrupt interrupted} while
59.764 + * acquiring the read lock,
59.765 + *
59.766 + * </ul>
59.767 + *
59.768 + * then {@link InterruptedException} is thrown and the current
59.769 + * thread's interrupted status is cleared.
59.770 + *
59.771 + * <p>In this implementation, as this method is an explicit
59.772 + * interruption point, preference is given to responding to
59.773 + * the interrupt over normal or reentrant acquisition of the
59.774 + * lock.
59.775 + *
59.776 + * @throws InterruptedException if the current thread is interrupted
59.777 + */
59.778 + public void lockInterruptibly() throws InterruptedException {
59.779 + sync.acquireSharedInterruptibly(1);
59.780 + }
59.781 +
59.782 + /**
59.783 + * Acquires the read lock only if the write lock is not held by
59.784 + * another thread at the time of invocation.
59.785 + *
59.786 + * <p>Acquires the read lock if the write lock is not held by
59.787 + * another thread and returns immediately with the value
59.788 + * {@code true}. Even when this lock has been set to use a
59.789 + * fair ordering policy, a call to {@code tryLock()}
59.790 + * <em>will</em> immediately acquire the read lock if it is
59.791 + * available, whether or not other threads are currently
59.792 + * waiting for the read lock. This "barging" behavior
59.793 + * can be useful in certain circumstances, even though it
59.794 + * breaks fairness. If you want to honor the fairness setting
59.795 + * for this lock, then use {@link #tryLock(long, TimeUnit)
59.796 + * tryLock(0, TimeUnit.SECONDS) } which is almost equivalent
59.797 + * (it also detects interruption).
59.798 + *
59.799 + * <p>If the write lock is held by another thread then
59.800 + * this method will return immediately with the value
59.801 + * {@code false}.
59.802 + *
59.803 + * @return {@code true} if the read lock was acquired
59.804 + */
59.805 + public boolean tryLock() {
59.806 + return sync.tryReadLock();
59.807 + }
59.808 +
59.809 + /**
59.810 + * Acquires the read lock if the write lock is not held by
59.811 + * another thread within the given waiting time and the
59.812 + * current thread has not been {@linkplain Thread#interrupt
59.813 + * interrupted}.
59.814 + *
59.815 + * <p>Acquires the read lock if the write lock is not held by
59.816 + * another thread and returns immediately with the value
59.817 + * {@code true}. If this lock has been set to use a fair
59.818 + * ordering policy then an available lock <em>will not</em> be
59.819 + * acquired if any other threads are waiting for the
59.820 + * lock. This is in contrast to the {@link #tryLock()}
59.821 + * method. If you want a timed {@code tryLock} that does
59.822 + * permit barging on a fair lock then combine the timed and
59.823 + * un-timed forms together:
59.824 + *
59.825 + * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
59.826 + * </pre>
59.827 + *
59.828 + * <p>If the write lock is held by another thread then the
59.829 + * current thread becomes disabled for thread scheduling
59.830 + * purposes and lies dormant until one of three things happens:
59.831 + *
59.832 + * <ul>
59.833 + *
59.834 + * <li>The read lock is acquired by the current thread; or
59.835 + *
59.836 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
59.837 + * the current thread; or
59.838 + *
59.839 + * <li>The specified waiting time elapses.
59.840 + *
59.841 + * </ul>
59.842 + *
59.843 + * <p>If the read lock is acquired then the value {@code true} is
59.844 + * returned.
59.845 + *
59.846 + * <p>If the current thread:
59.847 + *
59.848 + * <ul>
59.849 + *
59.850 + * <li>has its interrupted status set on entry to this method; or
59.851 + *
59.852 + * <li>is {@linkplain Thread#interrupt interrupted} while
59.853 + * acquiring the read lock,
59.854 + *
59.855 + * </ul> then {@link InterruptedException} is thrown and the
59.856 + * current thread's interrupted status is cleared.
59.857 + *
59.858 + * <p>If the specified waiting time elapses then the value
59.859 + * {@code false} is returned. If the time is less than or
59.860 + * equal to zero, the method will not wait at all.
59.861 + *
59.862 + * <p>In this implementation, as this method is an explicit
59.863 + * interruption point, preference is given to responding to
59.864 + * the interrupt over normal or reentrant acquisition of the
59.865 + * lock, and over reporting the elapse of the waiting time.
59.866 + *
59.867 + * @param timeout the time to wait for the read lock
59.868 + * @param unit the time unit of the timeout argument
59.869 + * @return {@code true} if the read lock was acquired
59.870 + * @throws InterruptedException if the current thread is interrupted
59.871 + * @throws NullPointerException if the time unit is null
59.872 + *
59.873 + */
59.874 + public boolean tryLock(long timeout, TimeUnit unit)
59.875 + throws InterruptedException {
59.876 + return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
59.877 + }
59.878 +
59.879 + /**
59.880 + * Attempts to release this lock.
59.881 + *
59.882 + * <p> If the number of readers is now zero then the lock
59.883 + * is made available for write lock attempts.
59.884 + */
59.885 + public void unlock() {
59.886 + sync.releaseShared(1);
59.887 + }
59.888 +
59.889 + /**
59.890 + * Throws {@code UnsupportedOperationException} because
59.891 + * {@code ReadLocks} do not support conditions.
59.892 + *
59.893 + * @throws UnsupportedOperationException always
59.894 + */
59.895 + public Condition newCondition() {
59.896 + throw new UnsupportedOperationException();
59.897 + }
59.898 +
59.899 + /**
59.900 + * Returns a string identifying this lock, as well as its lock state.
59.901 + * The state, in brackets, includes the String {@code "Read locks ="}
59.902 + * followed by the number of held read locks.
59.903 + *
59.904 + * @return a string identifying this lock, as well as its lock state
59.905 + */
59.906 + public String toString() {
59.907 + int r = sync.getReadLockCount();
59.908 + return super.toString() +
59.909 + "[Read locks = " + r + "]";
59.910 + }
59.911 + }
59.912 +
59.913 + /**
59.914 + * The lock returned by method {@link ReentrantReadWriteLock#writeLock}.
59.915 + */
59.916 + public static class WriteLock implements Lock, java.io.Serializable {
59.917 + private static final long serialVersionUID = -4992448646407690164L;
59.918 + private final Sync sync;
59.919 +
59.920 + /**
59.921 + * Constructor for use by subclasses
59.922 + *
59.923 + * @param lock the outer lock object
59.924 + * @throws NullPointerException if the lock is null
59.925 + */
59.926 + protected WriteLock(ReentrantReadWriteLock lock) {
59.927 + sync = lock.sync;
59.928 + }
59.929 +
59.930 + /**
59.931 + * Acquires the write lock.
59.932 + *
59.933 + * <p>Acquires the write lock if neither the read nor write lock
59.934 + * are held by another thread
59.935 + * and returns immediately, setting the write lock hold count to
59.936 + * one.
59.937 + *
59.938 + * <p>If the current thread already holds the write lock then the
59.939 + * hold count is incremented by one and the method returns
59.940 + * immediately.
59.941 + *
59.942 + * <p>If the lock is held by another thread then the current
59.943 + * thread becomes disabled for thread scheduling purposes and
59.944 + * lies dormant until the write lock has been acquired, at which
59.945 + * time the write lock hold count is set to one.
59.946 + */
59.947 + public void lock() {
59.948 + sync.acquire(1);
59.949 + }
59.950 +
59.951 + /**
59.952 + * Acquires the write lock unless the current thread is
59.953 + * {@linkplain Thread#interrupt interrupted}.
59.954 + *
59.955 + * <p>Acquires the write lock if neither the read nor write lock
59.956 + * are held by another thread
59.957 + * and returns immediately, setting the write lock hold count to
59.958 + * one.
59.959 + *
59.960 + * <p>If the current thread already holds this lock then the
59.961 + * hold count is incremented by one and the method returns
59.962 + * immediately.
59.963 + *
59.964 + * <p>If the lock is held by another thread then the current
59.965 + * thread becomes disabled for thread scheduling purposes and
59.966 + * lies dormant until one of two things happens:
59.967 + *
59.968 + * <ul>
59.969 + *
59.970 + * <li>The write lock is acquired by the current thread; or
59.971 + *
59.972 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
59.973 + * the current thread.
59.974 + *
59.975 + * </ul>
59.976 + *
59.977 + * <p>If the write lock is acquired by the current thread then the
59.978 + * lock hold count is set to one.
59.979 + *
59.980 + * <p>If the current thread:
59.981 + *
59.982 + * <ul>
59.983 + *
59.984 + * <li>has its interrupted status set on entry to this method;
59.985 + * or
59.986 + *
59.987 + * <li>is {@linkplain Thread#interrupt interrupted} while
59.988 + * acquiring the write lock,
59.989 + *
59.990 + * </ul>
59.991 + *
59.992 + * then {@link InterruptedException} is thrown and the current
59.993 + * thread's interrupted status is cleared.
59.994 + *
59.995 + * <p>In this implementation, as this method is an explicit
59.996 + * interruption point, preference is given to responding to
59.997 + * the interrupt over normal or reentrant acquisition of the
59.998 + * lock.
59.999 + *
59.1000 + * @throws InterruptedException if the current thread is interrupted
59.1001 + */
59.1002 + public void lockInterruptibly() throws InterruptedException {
59.1003 + sync.acquireInterruptibly(1);
59.1004 + }
59.1005 +
59.1006 + /**
59.1007 + * Acquires the write lock only if it is not held by another thread
59.1008 + * at the time of invocation.
59.1009 + *
59.1010 + * <p>Acquires the write lock if neither the read nor write lock
59.1011 + * are held by another thread
59.1012 + * and returns immediately with the value {@code true},
59.1013 + * setting the write lock hold count to one. Even when this lock has
59.1014 + * been set to use a fair ordering policy, a call to
59.1015 + * {@code tryLock()} <em>will</em> immediately acquire the
59.1016 + * lock if it is available, whether or not other threads are
59.1017 + * currently waiting for the write lock. This "barging"
59.1018 + * behavior can be useful in certain circumstances, even
59.1019 + * though it breaks fairness. If you want to honor the
59.1020 + * fairness setting for this lock, then use {@link
59.1021 + * #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) }
59.1022 + * which is almost equivalent (it also detects interruption).
59.1023 + *
59.1024 + * <p> If the current thread already holds this lock then the
59.1025 + * hold count is incremented by one and the method returns
59.1026 + * {@code true}.
59.1027 + *
59.1028 + * <p>If the lock is held by another thread then this method
59.1029 + * will return immediately with the value {@code false}.
59.1030 + *
59.1031 + * @return {@code true} if the lock was free and was acquired
59.1032 + * by the current thread, or the write lock was already held
59.1033 + * by the current thread; and {@code false} otherwise.
59.1034 + */
59.1035 + public boolean tryLock( ) {
59.1036 + return sync.tryWriteLock();
59.1037 + }
59.1038 +
59.1039 + /**
59.1040 + * Acquires the write lock if it is not held by another thread
59.1041 + * within the given waiting time and the current thread has
59.1042 + * not been {@linkplain Thread#interrupt interrupted}.
59.1043 + *
59.1044 + * <p>Acquires the write lock if neither the read nor write lock
59.1045 + * are held by another thread
59.1046 + * and returns immediately with the value {@code true},
59.1047 + * setting the write lock hold count to one. If this lock has been
59.1048 + * set to use a fair ordering policy then an available lock
59.1049 + * <em>will not</em> be acquired if any other threads are
59.1050 + * waiting for the write lock. This is in contrast to the {@link
59.1051 + * #tryLock()} method. If you want a timed {@code tryLock}
59.1052 + * that does permit barging on a fair lock then combine the
59.1053 + * timed and un-timed forms together:
59.1054 + *
59.1055 + * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
59.1056 + * </pre>
59.1057 + *
59.1058 + * <p>If the current thread already holds this lock then the
59.1059 + * hold count is incremented by one and the method returns
59.1060 + * {@code true}.
59.1061 + *
59.1062 + * <p>If the lock is held by another thread then the current
59.1063 + * thread becomes disabled for thread scheduling purposes and
59.1064 + * lies dormant until one of three things happens:
59.1065 + *
59.1066 + * <ul>
59.1067 + *
59.1068 + * <li>The write lock is acquired by the current thread; or
59.1069 + *
59.1070 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
59.1071 + * the current thread; or
59.1072 + *
59.1073 + * <li>The specified waiting time elapses
59.1074 + *
59.1075 + * </ul>
59.1076 + *
59.1077 + * <p>If the write lock is acquired then the value {@code true} is
59.1078 + * returned and the write lock hold count is set to one.
59.1079 + *
59.1080 + * <p>If the current thread:
59.1081 + *
59.1082 + * <ul>
59.1083 + *
59.1084 + * <li>has its interrupted status set on entry to this method;
59.1085 + * or
59.1086 + *
59.1087 + * <li>is {@linkplain Thread#interrupt interrupted} while
59.1088 + * acquiring the write lock,
59.1089 + *
59.1090 + * </ul>
59.1091 + *
59.1092 + * then {@link InterruptedException} is thrown and the current
59.1093 + * thread's interrupted status is cleared.
59.1094 + *
59.1095 + * <p>If the specified waiting time elapses then the value
59.1096 + * {@code false} is returned. If the time is less than or
59.1097 + * equal to zero, the method will not wait at all.
59.1098 + *
59.1099 + * <p>In this implementation, as this method is an explicit
59.1100 + * interruption point, preference is given to responding to
59.1101 + * the interrupt over normal or reentrant acquisition of the
59.1102 + * lock, and over reporting the elapse of the waiting time.
59.1103 + *
59.1104 + * @param timeout the time to wait for the write lock
59.1105 + * @param unit the time unit of the timeout argument
59.1106 + *
59.1107 + * @return {@code true} if the lock was free and was acquired
59.1108 + * by the current thread, or the write lock was already held by the
59.1109 + * current thread; and {@code false} if the waiting time
59.1110 + * elapsed before the lock could be acquired.
59.1111 + *
59.1112 + * @throws InterruptedException if the current thread is interrupted
59.1113 + * @throws NullPointerException if the time unit is null
59.1114 + *
59.1115 + */
59.1116 + public boolean tryLock(long timeout, TimeUnit unit)
59.1117 + throws InterruptedException {
59.1118 + return sync.tryAcquireNanos(1, unit.toNanos(timeout));
59.1119 + }
59.1120 +
59.1121 + /**
59.1122 + * Attempts to release this lock.
59.1123 + *
59.1124 + * <p>If the current thread is the holder of this lock then
59.1125 + * the hold count is decremented. If the hold count is now
59.1126 + * zero then the lock is released. If the current thread is
59.1127 + * not the holder of this lock then {@link
59.1128 + * IllegalMonitorStateException} is thrown.
59.1129 + *
59.1130 + * @throws IllegalMonitorStateException if the current thread does not
59.1131 + * hold this lock.
59.1132 + */
59.1133 + public void unlock() {
59.1134 + sync.release(1);
59.1135 + }
59.1136 +
59.1137 + /**
59.1138 + * Returns a {@link Condition} instance for use with this
59.1139 + * {@link Lock} instance.
59.1140 + * <p>The returned {@link Condition} instance supports the same
59.1141 + * usages as do the {@link Object} monitor methods ({@link
59.1142 + * Object#wait() wait}, {@link Object#notify notify}, and {@link
59.1143 + * Object#notifyAll notifyAll}) when used with the built-in
59.1144 + * monitor lock.
59.1145 + *
59.1146 + * <ul>
59.1147 + *
59.1148 + * <li>If this write lock is not held when any {@link
59.1149 + * Condition} method is called then an {@link
59.1150 + * IllegalMonitorStateException} is thrown. (Read locks are
59.1151 + * held independently of write locks, so are not checked or
59.1152 + * affected. However it is essentially always an error to
59.1153 + * invoke a condition waiting method when the current thread
59.1154 + * has also acquired read locks, since other threads that
59.1155 + * could unblock it will not be able to acquire the write
59.1156 + * lock.)
59.1157 + *
59.1158 + * <li>When the condition {@linkplain Condition#await() waiting}
59.1159 + * methods are called the write lock is released and, before
59.1160 + * they return, the write lock is reacquired and the lock hold
59.1161 + * count restored to what it was when the method was called.
59.1162 + *
59.1163 + * <li>If a thread is {@linkplain Thread#interrupt interrupted} while
59.1164 + * waiting then the wait will terminate, an {@link
59.1165 + * InterruptedException} will be thrown, and the thread's
59.1166 + * interrupted status will be cleared.
59.1167 + *
59.1168 + * <li> Waiting threads are signalled in FIFO order.
59.1169 + *
59.1170 + * <li>The ordering of lock reacquisition for threads returning
59.1171 + * from waiting methods is the same as for threads initially
59.1172 + * acquiring the lock, which is in the default case not specified,
59.1173 + * but for <em>fair</em> locks favors those threads that have been
59.1174 + * waiting the longest.
59.1175 + *
59.1176 + * </ul>
59.1177 + *
59.1178 + * @return the Condition object
59.1179 + */
59.1180 + public Condition newCondition() {
59.1181 + return sync.newCondition();
59.1182 + }
59.1183 +
59.1184 + /**
59.1185 + * Returns a string identifying this lock, as well as its lock
59.1186 + * state. The state, in brackets includes either the String
59.1187 + * {@code "Unlocked"} or the String {@code "Locked by"}
59.1188 + * followed by the {@linkplain Thread#getName name} of the owning thread.
59.1189 + *
59.1190 + * @return a string identifying this lock, as well as its lock state
59.1191 + */
59.1192 + public String toString() {
59.1193 + Thread o = sync.getOwner();
59.1194 + return super.toString() + ((o == null) ?
59.1195 + "[Unlocked]" :
59.1196 + "[Locked by thread " + o.getName() + "]");
59.1197 + }
59.1198 +
59.1199 + /**
59.1200 + * Queries if this write lock is held by the current thread.
59.1201 + * Identical in effect to {@link
59.1202 + * ReentrantReadWriteLock#isWriteLockedByCurrentThread}.
59.1203 + *
59.1204 + * @return {@code true} if the current thread holds this lock and
59.1205 + * {@code false} otherwise
59.1206 + * @since 1.6
59.1207 + */
59.1208 + public boolean isHeldByCurrentThread() {
59.1209 + return sync.isHeldExclusively();
59.1210 + }
59.1211 +
59.1212 + /**
59.1213 + * Queries the number of holds on this write lock by the current
59.1214 + * thread. A thread has a hold on a lock for each lock action
59.1215 + * that is not matched by an unlock action. Identical in effect
59.1216 + * to {@link ReentrantReadWriteLock#getWriteHoldCount}.
59.1217 + *
59.1218 + * @return the number of holds on this lock by the current thread,
59.1219 + * or zero if this lock is not held by the current thread
59.1220 + * @since 1.6
59.1221 + */
59.1222 + public int getHoldCount() {
59.1223 + return sync.getWriteHoldCount();
59.1224 + }
59.1225 + }
59.1226 +
59.1227 + // Instrumentation and status
59.1228 +
59.1229 + /**
59.1230 + * Returns {@code true} if this lock has fairness set true.
59.1231 + *
59.1232 + * @return {@code true} if this lock has fairness set true
59.1233 + */
59.1234 + public final boolean isFair() {
59.1235 + return sync instanceof FairSync;
59.1236 + }
59.1237 +
59.1238 + /**
59.1239 + * Returns the thread that currently owns the write lock, or
59.1240 + * {@code null} if not owned. When this method is called by a
59.1241 + * thread that is not the owner, the return value reflects a
59.1242 + * best-effort approximation of current lock status. For example,
59.1243 + * the owner may be momentarily {@code null} even if there are
59.1244 + * threads trying to acquire the lock but have not yet done so.
59.1245 + * This method is designed to facilitate construction of
59.1246 + * subclasses that provide more extensive lock monitoring
59.1247 + * facilities.
59.1248 + *
59.1249 + * @return the owner, or {@code null} if not owned
59.1250 + */
59.1251 + protected Thread getOwner() {
59.1252 + return sync.getOwner();
59.1253 + }
59.1254 +
59.1255 + /**
59.1256 + * Queries the number of read locks held for this lock. This
59.1257 + * method is designed for use in monitoring system state, not for
59.1258 + * synchronization control.
59.1259 + * @return the number of read locks held.
59.1260 + */
59.1261 + public int getReadLockCount() {
59.1262 + return sync.getReadLockCount();
59.1263 + }
59.1264 +
59.1265 + /**
59.1266 + * Queries if the write lock is held by any thread. This method is
59.1267 + * designed for use in monitoring system state, not for
59.1268 + * synchronization control.
59.1269 + *
59.1270 + * @return {@code true} if any thread holds the write lock and
59.1271 + * {@code false} otherwise
59.1272 + */
59.1273 + public boolean isWriteLocked() {
59.1274 + return sync.isWriteLocked();
59.1275 + }
59.1276 +
59.1277 + /**
59.1278 + * Queries if the write lock is held by the current thread.
59.1279 + *
59.1280 + * @return {@code true} if the current thread holds the write lock and
59.1281 + * {@code false} otherwise
59.1282 + */
59.1283 + public boolean isWriteLockedByCurrentThread() {
59.1284 + return sync.isHeldExclusively();
59.1285 + }
59.1286 +
59.1287 + /**
59.1288 + * Queries the number of reentrant write holds on this lock by the
59.1289 + * current thread. A writer thread has a hold on a lock for
59.1290 + * each lock action that is not matched by an unlock action.
59.1291 + *
59.1292 + * @return the number of holds on the write lock by the current thread,
59.1293 + * or zero if the write lock is not held by the current thread
59.1294 + */
59.1295 + public int getWriteHoldCount() {
59.1296 + return sync.getWriteHoldCount();
59.1297 + }
59.1298 +
59.1299 + /**
59.1300 + * Queries the number of reentrant read holds on this lock by the
59.1301 + * current thread. A reader thread has a hold on a lock for
59.1302 + * each lock action that is not matched by an unlock action.
59.1303 + *
59.1304 + * @return the number of holds on the read lock by the current thread,
59.1305 + * or zero if the read lock is not held by the current thread
59.1306 + * @since 1.6
59.1307 + */
59.1308 + public int getReadHoldCount() {
59.1309 + return sync.getReadHoldCount();
59.1310 + }
59.1311 +
59.1312 + /**
59.1313 + * Returns a collection containing threads that may be waiting to
59.1314 + * acquire the write lock. Because the actual set of threads may
59.1315 + * change dynamically while constructing this result, the returned
59.1316 + * collection is only a best-effort estimate. The elements of the
59.1317 + * returned collection are in no particular order. This method is
59.1318 + * designed to facilitate construction of subclasses that provide
59.1319 + * more extensive lock monitoring facilities.
59.1320 + *
59.1321 + * @return the collection of threads
59.1322 + */
59.1323 + protected Collection<Thread> getQueuedWriterThreads() {
59.1324 + return sync.getExclusiveQueuedThreads();
59.1325 + }
59.1326 +
59.1327 + /**
59.1328 + * Returns a collection containing threads that may be waiting to
59.1329 + * acquire the read lock. Because the actual set of threads may
59.1330 + * change dynamically while constructing this result, the returned
59.1331 + * collection is only a best-effort estimate. The elements of the
59.1332 + * returned collection are in no particular order. This method is
59.1333 + * designed to facilitate construction of subclasses that provide
59.1334 + * more extensive lock monitoring facilities.
59.1335 + *
59.1336 + * @return the collection of threads
59.1337 + */
59.1338 + protected Collection<Thread> getQueuedReaderThreads() {
59.1339 + return sync.getSharedQueuedThreads();
59.1340 + }
59.1341 +
59.1342 + /**
59.1343 + * Queries whether any threads are waiting to acquire the read or
59.1344 + * write lock. Note that because cancellations may occur at any
59.1345 + * time, a {@code true} return does not guarantee that any other
59.1346 + * thread will ever acquire a lock. This method is designed
59.1347 + * primarily for use in monitoring of the system state.
59.1348 + *
59.1349 + * @return {@code true} if there may be other threads waiting to
59.1350 + * acquire the lock
59.1351 + */
59.1352 + public final boolean hasQueuedThreads() {
59.1353 + return sync.hasQueuedThreads();
59.1354 + }
59.1355 +
59.1356 + /**
59.1357 + * Queries whether the given thread is waiting to acquire either
59.1358 + * the read or write lock. Note that because cancellations may
59.1359 + * occur at any time, a {@code true} return does not guarantee
59.1360 + * that this thread will ever acquire a lock. This method is
59.1361 + * designed primarily for use in monitoring of the system state.
59.1362 + *
59.1363 + * @param thread the thread
59.1364 + * @return {@code true} if the given thread is queued waiting for this lock
59.1365 + * @throws NullPointerException if the thread is null
59.1366 + */
59.1367 + public final boolean hasQueuedThread(Thread thread) {
59.1368 + return sync.isQueued(thread);
59.1369 + }
59.1370 +
59.1371 + /**
59.1372 + * Returns an estimate of the number of threads waiting to acquire
59.1373 + * either the read or write lock. The value is only an estimate
59.1374 + * because the number of threads may change dynamically while this
59.1375 + * method traverses internal data structures. This method is
59.1376 + * designed for use in monitoring of the system state, not for
59.1377 + * synchronization control.
59.1378 + *
59.1379 + * @return the estimated number of threads waiting for this lock
59.1380 + */
59.1381 + public final int getQueueLength() {
59.1382 + return sync.getQueueLength();
59.1383 + }
59.1384 +
59.1385 + /**
59.1386 + * Returns a collection containing threads that may be waiting to
59.1387 + * acquire either the read or write lock. Because the actual set
59.1388 + * of threads may change dynamically while constructing this
59.1389 + * result, the returned collection is only a best-effort estimate.
59.1390 + * The elements of the returned collection are in no particular
59.1391 + * order. This method is designed to facilitate construction of
59.1392 + * subclasses that provide more extensive monitoring facilities.
59.1393 + *
59.1394 + * @return the collection of threads
59.1395 + */
59.1396 + protected Collection<Thread> getQueuedThreads() {
59.1397 + return sync.getQueuedThreads();
59.1398 + }
59.1399 +
59.1400 + /**
59.1401 + * Queries whether any threads are waiting on the given condition
59.1402 + * associated with the write lock. Note that because timeouts and
59.1403 + * interrupts may occur at any time, a {@code true} return does
59.1404 + * not guarantee that a future {@code signal} will awaken any
59.1405 + * threads. This method is designed primarily for use in
59.1406 + * monitoring of the system state.
59.1407 + *
59.1408 + * @param condition the condition
59.1409 + * @return {@code true} if there are any waiting threads
59.1410 + * @throws IllegalMonitorStateException if this lock is not held
59.1411 + * @throws IllegalArgumentException if the given condition is
59.1412 + * not associated with this lock
59.1413 + * @throws NullPointerException if the condition is null
59.1414 + */
59.1415 + public boolean hasWaiters(Condition condition) {
59.1416 + if (condition == null)
59.1417 + throw new NullPointerException();
59.1418 + if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
59.1419 + throw new IllegalArgumentException("not owner");
59.1420 + return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
59.1421 + }
59.1422 +
59.1423 + /**
59.1424 + * Returns an estimate of the number of threads waiting on the
59.1425 + * given condition associated with the write lock. Note that because
59.1426 + * timeouts and interrupts may occur at any time, the estimate
59.1427 + * serves only as an upper bound on the actual number of waiters.
59.1428 + * This method is designed for use in monitoring of the system
59.1429 + * state, not for synchronization control.
59.1430 + *
59.1431 + * @param condition the condition
59.1432 + * @return the estimated number of waiting threads
59.1433 + * @throws IllegalMonitorStateException if this lock is not held
59.1434 + * @throws IllegalArgumentException if the given condition is
59.1435 + * not associated with this lock
59.1436 + * @throws NullPointerException if the condition is null
59.1437 + */
59.1438 + public int getWaitQueueLength(Condition condition) {
59.1439 + if (condition == null)
59.1440 + throw new NullPointerException();
59.1441 + if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
59.1442 + throw new IllegalArgumentException("not owner");
59.1443 + return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
59.1444 + }
59.1445 +
59.1446 + /**
59.1447 + * Returns a collection containing those threads that may be
59.1448 + * waiting on the given condition associated with the write lock.
59.1449 + * Because the actual set of threads may change dynamically while
59.1450 + * constructing this result, the returned collection is only a
59.1451 + * best-effort estimate. The elements of the returned collection
59.1452 + * are in no particular order. This method is designed to
59.1453 + * facilitate construction of subclasses that provide more
59.1454 + * extensive condition monitoring facilities.
59.1455 + *
59.1456 + * @param condition the condition
59.1457 + * @return the collection of threads
59.1458 + * @throws IllegalMonitorStateException if this lock is not held
59.1459 + * @throws IllegalArgumentException if the given condition is
59.1460 + * not associated with this lock
59.1461 + * @throws NullPointerException if the condition is null
59.1462 + */
59.1463 + protected Collection<Thread> getWaitingThreads(Condition condition) {
59.1464 + if (condition == null)
59.1465 + throw new NullPointerException();
59.1466 + if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
59.1467 + throw new IllegalArgumentException("not owner");
59.1468 + return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
59.1469 + }
59.1470 +
59.1471 + /**
59.1472 + * Returns a string identifying this lock, as well as its lock state.
59.1473 + * The state, in brackets, includes the String {@code "Write locks ="}
59.1474 + * followed by the number of reentrantly held write locks, and the
59.1475 + * String {@code "Read locks ="} followed by the number of held
59.1476 + * read locks.
59.1477 + *
59.1478 + * @return a string identifying this lock, as well as its lock state
59.1479 + */
59.1480 + public String toString() {
59.1481 + int c = sync.getCount();
59.1482 + int w = Sync.exclusiveCount(c);
59.1483 + int r = Sync.sharedCount(c);
59.1484 +
59.1485 + return super.toString() +
59.1486 + "[Write locks = " + w + ", Read locks = " + r + "]";
59.1487 + }
59.1488 +
59.1489 +}
60.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
60.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/locks/package-info.java Sat Mar 19 10:48:29 2016 +0100
60.3 @@ -0,0 +1,79 @@
60.4 +/*
60.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
60.6 + *
60.7 + * This code is free software; you can redistribute it and/or modify it
60.8 + * under the terms of the GNU General Public License version 2 only, as
60.9 + * published by the Free Software Foundation. Oracle designates this
60.10 + * particular file as subject to the "Classpath" exception as provided
60.11 + * by Oracle in the LICENSE file that accompanied this code.
60.12 + *
60.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
60.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
60.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
60.16 + * version 2 for more details (a copy is included in the LICENSE file that
60.17 + * accompanied this code).
60.18 + *
60.19 + * You should have received a copy of the GNU General Public License version
60.20 + * 2 along with this work; if not, write to the Free Software Foundation,
60.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
60.22 + *
60.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
60.24 + * or visit www.oracle.com if you need additional information or have any
60.25 + * questions.
60.26 + */
60.27 +
60.28 +/*
60.29 + * This file is available under and governed by the GNU General Public
60.30 + * License version 2 only, as published by the Free Software Foundation.
60.31 + * However, the following notice accompanied the original version of this
60.32 + * file:
60.33 + *
60.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
60.35 + * Expert Group and released to the public domain, as explained at
60.36 + * http://creativecommons.org/publicdomain/zero/1.0/
60.37 + */
60.38 +
60.39 +/**
60.40 + * Interfaces and classes providing a framework for locking and waiting
60.41 + * for conditions that is distinct from built-in synchronization and
60.42 + * monitors. The framework permits much greater flexibility in the use of
60.43 + * locks and conditions, at the expense of more awkward syntax.
60.44 + *
60.45 + * <p>The {@link java.util.concurrent.locks.Lock} interface supports
60.46 + * locking disciplines that differ in semantics (reentrant, fair, etc),
60.47 + * and that can be used in non-block-structured contexts including
60.48 + * hand-over-hand and lock reordering algorithms. The main implementation
60.49 + * is {@link java.util.concurrent.locks.ReentrantLock}.
60.50 + *
60.51 + * <p>The {@link java.util.concurrent.locks.ReadWriteLock} interface
60.52 + * similarly defines locks that may be shared among readers but are
60.53 + * exclusive to writers. Only a single implementation, {@link
60.54 + * java.util.concurrent.locks.ReentrantReadWriteLock}, is provided, since
60.55 + * it covers most standard usage contexts. But programmers may create
60.56 + * their own implementations to cover nonstandard requirements.
60.57 + *
60.58 + * <p>The {@link java.util.concurrent.locks.Condition} interface
60.59 + * describes condition variables that may be associated with Locks.
60.60 + * These are similar in usage to the implicit monitors accessed using
60.61 + * {@code Object.wait}, but offer extended capabilities.
60.62 + * In particular, multiple {@code Condition} objects may be associated
60.63 + * with a single {@code Lock}. To avoid compatibility issues, the
60.64 + * names of {@code Condition} methods are different from the
60.65 + * corresponding {@code Object} versions.
60.66 + *
60.67 + * <p>The {@link java.util.concurrent.locks.AbstractQueuedSynchronizer}
60.68 + * class serves as a useful superclass for defining locks and other
60.69 + * synchronizers that rely on queuing blocked threads. The {@link
60.70 + * java.util.concurrent.locks.AbstractQueuedLongSynchronizer} class
60.71 + * provides the same functionality but extends support to 64 bits of
60.72 + * synchronization state. Both extend class {@link
60.73 + * java.util.concurrent.locks.AbstractOwnableSynchronizer}, a simple
60.74 + * class that helps record the thread currently holding exclusive
60.75 + * synchronization. The {@link java.util.concurrent.locks.LockSupport}
60.76 + * class provides lower-level blocking and unblocking support that is
60.77 + * useful for those developers implementing their own customized lock
60.78 + * classes.
60.79 + *
60.80 + * @since 1.5
60.81 + */
60.82 +package java.util.concurrent.locks;
61.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
61.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/package-info.java Sat Mar 19 10:48:29 2016 +0100
61.3 @@ -0,0 +1,300 @@
61.4 +/*
61.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
61.6 + *
61.7 + * This code is free software; you can redistribute it and/or modify it
61.8 + * under the terms of the GNU General Public License version 2 only, as
61.9 + * published by the Free Software Foundation. Oracle designates this
61.10 + * particular file as subject to the "Classpath" exception as provided
61.11 + * by Oracle in the LICENSE file that accompanied this code.
61.12 + *
61.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
61.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
61.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
61.16 + * version 2 for more details (a copy is included in the LICENSE file that
61.17 + * accompanied this code).
61.18 + *
61.19 + * You should have received a copy of the GNU General Public License version
61.20 + * 2 along with this work; if not, write to the Free Software Foundation,
61.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
61.22 + *
61.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
61.24 + * or visit www.oracle.com if you need additional information or have any
61.25 + * questions.
61.26 + */
61.27 +
61.28 +/*
61.29 + * This file is available under and governed by the GNU General Public
61.30 + * License version 2 only, as published by the Free Software Foundation.
61.31 + * However, the following notice accompanied the original version of this
61.32 + * file:
61.33 + *
61.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
61.35 + * Expert Group and released to the public domain, as explained at
61.36 + * http://creativecommons.org/publicdomain/zero/1.0/
61.37 + */
61.38 +
61.39 +/**
61.40 + * Utility classes commonly useful in concurrent programming. This
61.41 + * package includes a few small standardized extensible frameworks, as
61.42 + * well as some classes that provide useful functionality and are
61.43 + * otherwise tedious or difficult to implement. Here are brief
61.44 + * descriptions of the main components. See also the
61.45 + * {@link java.util.concurrent.locks} and
61.46 + * {@link java.util.concurrent.atomic} packages.
61.47 + *
61.48 + * <h2>Executors</h2>
61.49 + *
61.50 + * <b>Interfaces.</b>
61.51 + *
61.52 + * {@link java.util.concurrent.Executor} is a simple standardized
61.53 + * interface for defining custom thread-like subsystems, including
61.54 + * thread pools, asynchronous IO, and lightweight task frameworks.
61.55 + * Depending on which concrete Executor class is being used, tasks may
61.56 + * execute in a newly created thread, an existing task-execution thread,
61.57 + * or the thread calling {@link java.util.concurrent.Executor#execute
61.58 + * execute}, and may execute sequentially or concurrently.
61.59 + *
61.60 + * {@link java.util.concurrent.ExecutorService} provides a more
61.61 + * complete asynchronous task execution framework. An
61.62 + * ExecutorService manages queuing and scheduling of tasks,
61.63 + * and allows controlled shutdown.
61.64 + *
61.65 + * The {@link java.util.concurrent.ScheduledExecutorService}
61.66 + * subinterface and associated interfaces add support for
61.67 + * delayed and periodic task execution. ExecutorServices
61.68 + * provide methods arranging asynchronous execution of any
61.69 + * function expressed as {@link java.util.concurrent.Callable},
61.70 + * the result-bearing analog of {@link java.lang.Runnable}.
61.71 + *
61.72 + * A {@link java.util.concurrent.Future} returns the results of
61.73 + * a function, allows determination of whether execution has
61.74 + * completed, and provides a means to cancel execution.
61.75 + *
61.76 + * A {@link java.util.concurrent.RunnableFuture} is a {@code Future}
61.77 + * that possesses a {@code run} method that upon execution,
61.78 + * sets its results.
61.79 + *
61.80 + * <p>
61.81 + *
61.82 + * <b>Implementations.</b>
61.83 + *
61.84 + * Classes {@link java.util.concurrent.ThreadPoolExecutor} and
61.85 + * {@link java.util.concurrent.ScheduledThreadPoolExecutor}
61.86 + * provide tunable, flexible thread pools.
61.87 + *
61.88 + * The {@link java.util.concurrent.Executors} class provides
61.89 + * factory methods for the most common kinds and configurations
61.90 + * of Executors, as well as a few utility methods for using
61.91 + * them. Other utilities based on {@code Executors} include the
61.92 + * concrete class {@link java.util.concurrent.FutureTask}
61.93 + * providing a common extensible implementation of Futures, and
61.94 + * {@link java.util.concurrent.ExecutorCompletionService}, that
61.95 + * assists in coordinating the processing of groups of
61.96 + * asynchronous tasks.
61.97 + *
61.98 + * <p>Class {@link java.util.concurrent.ForkJoinPool} provides an
61.99 + * Executor primarily designed for processing instances of {@link
61.100 + * java.util.concurrent.ForkJoinTask} and its subclasses. These
61.101 + * classes employ a work-stealing scheduler that attains high
61.102 + * throughput for tasks conforming to restrictions that often hold in
61.103 + * computation-intensive parallel processing.
61.104 + *
61.105 + * <h2>Queues</h2>
61.106 + *
61.107 + * The {@link java.util.concurrent.ConcurrentLinkedQueue} class
61.108 + * supplies an efficient scalable thread-safe non-blocking FIFO
61.109 + * queue.
61.110 + *
61.111 + * <p>Five implementations in {@code java.util.concurrent} support
61.112 + * the extended {@link java.util.concurrent.BlockingQueue}
61.113 + * interface, that defines blocking versions of put and take:
61.114 + * {@link java.util.concurrent.LinkedBlockingQueue},
61.115 + * {@link java.util.concurrent.ArrayBlockingQueue},
61.116 + * {@link java.util.concurrent.SynchronousQueue},
61.117 + * {@link java.util.concurrent.PriorityBlockingQueue}, and
61.118 + * {@link java.util.concurrent.DelayQueue}.
61.119 + * The different classes cover the most common usage contexts
61.120 + * for producer-consumer, messaging, parallel tasking, and
61.121 + * related concurrent designs.
61.122 + *
61.123 + * <p> Extended interface {@link java.util.concurrent.TransferQueue},
61.124 + * and implementation {@link java.util.concurrent.LinkedTransferQueue}
61.125 + * introduce a synchronous {@code transfer} method (along with related
61.126 + * features) in which a producer may optionally block awaiting its
61.127 + * consumer.
61.128 + *
61.129 + * <p>The {@link java.util.concurrent.BlockingDeque} interface
61.130 + * extends {@code BlockingQueue} to support both FIFO and LIFO
61.131 + * (stack-based) operations.
61.132 + * Class {@link java.util.concurrent.LinkedBlockingDeque}
61.133 + * provides an implementation.
61.134 + *
61.135 + * <h2>Timing</h2>
61.136 + *
61.137 + * The {@link java.util.concurrent.TimeUnit} class provides
61.138 + * multiple granularities (including nanoseconds) for
61.139 + * specifying and controlling time-out based operations. Most
61.140 + * classes in the package contain operations based on time-outs
61.141 + * in addition to indefinite waits. In all cases that
61.142 + * time-outs are used, the time-out specifies the minimum time
61.143 + * that the method should wait before indicating that it
61.144 + * timed-out. Implementations make a "best effort"
61.145 + * to detect time-outs as soon as possible after they occur.
61.146 + * However, an indefinite amount of time may elapse between a
61.147 + * time-out being detected and a thread actually executing
61.148 + * again after that time-out. All methods that accept timeout
61.149 + * parameters treat values less than or equal to zero to mean
61.150 + * not to wait at all. To wait "forever", you can use a value
61.151 + * of {@code Long.MAX_VALUE}.
61.152 + *
61.153 + * <h2>Synchronizers</h2>
61.154 + *
61.155 + * Five classes aid common special-purpose synchronization idioms.
61.156 + * <ul>
61.157 + *
61.158 + * <li>{@link java.util.concurrent.Semaphore} is a classic concurrency tool.
61.159 + *
61.160 + * <li>{@link java.util.concurrent.CountDownLatch} is a very simple yet
61.161 + * very common utility for blocking until a given number of signals,
61.162 + * events, or conditions hold.
61.163 + *
61.164 + * <li>A {@link java.util.concurrent.CyclicBarrier} is a resettable
61.165 + * multiway synchronization point useful in some styles of parallel
61.166 + * programming.
61.167 + *
61.168 + * <li>A {@link java.util.concurrent.Phaser} provides
61.169 + * a more flexible form of barrier that may be used to control phased
61.170 + * computation among multiple threads.
61.171 + *
61.172 + * <li>An {@link java.util.concurrent.Exchanger} allows two threads to
61.173 + * exchange objects at a rendezvous point, and is useful in several
61.174 + * pipeline designs.
61.175 + *
61.176 + * </ul>
61.177 + *
61.178 + * <h2>Concurrent Collections</h2>
61.179 + *
61.180 + * Besides Queues, this package supplies Collection implementations
61.181 + * designed for use in multithreaded contexts:
61.182 + * {@link java.util.concurrent.ConcurrentHashMap},
61.183 + * {@link java.util.concurrent.ConcurrentSkipListMap},
61.184 + * {@link java.util.concurrent.ConcurrentSkipListSet},
61.185 + * {@link java.util.concurrent.CopyOnWriteArrayList}, and
61.186 + * {@link java.util.concurrent.CopyOnWriteArraySet}.
61.187 + * When many threads are expected to access a given collection, a
61.188 + * {@code ConcurrentHashMap} is normally preferable to a synchronized
61.189 + * {@code HashMap}, and a {@code ConcurrentSkipListMap} is normally
61.190 + * preferable to a synchronized {@code TreeMap}.
61.191 + * A {@code CopyOnWriteArrayList} is preferable to a synchronized
61.192 + * {@code ArrayList} when the expected number of reads and traversals
61.193 + * greatly outnumber the number of updates to a list.
61.194 +
61.195 + * <p>The "Concurrent" prefix used with some classes in this package
61.196 + * is a shorthand indicating several differences from similar
61.197 + * "synchronized" classes. For example {@code java.util.Hashtable} and
61.198 + * {@code Collections.synchronizedMap(new HashMap())} are
61.199 + * synchronized. But {@link
61.200 + * java.util.concurrent.ConcurrentHashMap} is "concurrent". A
61.201 + * concurrent collection is thread-safe, but not governed by a
61.202 + * single exclusion lock. In the particular case of
61.203 + * ConcurrentHashMap, it safely permits any number of
61.204 + * concurrent reads as well as a tunable number of concurrent
61.205 + * writes. "Synchronized" classes can be useful when you need
61.206 + * to prevent all access to a collection via a single lock, at
61.207 + * the expense of poorer scalability. In other cases in which
61.208 + * multiple threads are expected to access a common collection,
61.209 + * "concurrent" versions are normally preferable. And
61.210 + * unsynchronized collections are preferable when either
61.211 + * collections are unshared, or are accessible only when
61.212 + * holding other locks.
61.213 + *
61.214 + * <p>Most concurrent Collection implementations (including most
61.215 + * Queues) also differ from the usual java.util conventions in that
61.216 + * their Iterators provide <em>weakly consistent</em> rather than
61.217 + * fast-fail traversal. A weakly consistent iterator is thread-safe,
61.218 + * but does not necessarily freeze the collection while iterating, so
61.219 + * it may (or may not) reflect any updates since the iterator was
61.220 + * created.
61.221 + *
61.222 + * <h2><a name="MemoryVisibility">Memory Consistency Properties</a></h2>
61.223 + *
61.224 + * Chapter 17 of
61.225 + * <cite>The Java™ Language Specification</cite>
61.226 + * defines the
61.227 + * <i>happens-before</i> relation on memory operations such as reads and
61.228 + * writes of shared variables. The results of a write by one thread are
61.229 + * guaranteed to be visible to a read by another thread only if the write
61.230 + * operation <i>happens-before</i> the read operation. The
61.231 + * {@code synchronized} and {@code volatile} constructs, as well as the
61.232 + * {@code Thread.start()} and {@code Thread.join()} methods, can form
61.233 + * <i>happens-before</i> relationships. In particular:
61.234 + *
61.235 + * <ul>
61.236 + * <li>Each action in a thread <i>happens-before</i> every action in that
61.237 + * thread that comes later in the program's order.
61.238 + *
61.239 + * <li>An unlock ({@code synchronized} block or method exit) of a
61.240 + * monitor <i>happens-before</i> every subsequent lock ({@code synchronized}
61.241 + * block or method entry) of that same monitor. And because
61.242 + * the <i>happens-before</i> relation is transitive, all actions
61.243 + * of a thread prior to unlocking <i>happen-before</i> all actions
61.244 + * subsequent to any thread locking that monitor.
61.245 + *
61.246 + * <li>A write to a {@code volatile} field <i>happens-before</i> every
61.247 + * subsequent read of that same field. Writes and reads of
61.248 + * {@code volatile} fields have similar memory consistency effects
61.249 + * as entering and exiting monitors, but do <em>not</em> entail
61.250 + * mutual exclusion locking.
61.251 + *
61.252 + * <li>A call to {@code start} on a thread <i>happens-before</i> any
61.253 + * action in the started thread.
61.254 + *
61.255 + * <li>All actions in a thread <i>happen-before</i> any other thread
61.256 + * successfully returns from a {@code join} on that thread.
61.257 + *
61.258 + * </ul>
61.259 + *
61.260 + *
61.261 + * The methods of all classes in {@code java.util.concurrent} and its
61.262 + * subpackages extend these guarantees to higher-level
61.263 + * synchronization. In particular:
61.264 + *
61.265 + * <ul>
61.266 + *
61.267 + * <li>Actions in a thread prior to placing an object into any concurrent
61.268 + * collection <i>happen-before</i> actions subsequent to the access or
61.269 + * removal of that element from the collection in another thread.
61.270 + *
61.271 + * <li>Actions in a thread prior to the submission of a {@code Runnable}
61.272 + * to an {@code Executor} <i>happen-before</i> its execution begins.
61.273 + * Similarly for {@code Callables} submitted to an {@code ExecutorService}.
61.274 + *
61.275 + * <li>Actions taken by the asynchronous computation represented by a
61.276 + * {@code Future} <i>happen-before</i> actions subsequent to the
61.277 + * retrieval of the result via {@code Future.get()} in another thread.
61.278 + *
61.279 + * <li>Actions prior to "releasing" synchronizer methods such as
61.280 + * {@code Lock.unlock}, {@code Semaphore.release}, and
61.281 + * {@code CountDownLatch.countDown} <i>happen-before</i> actions
61.282 + * subsequent to a successful "acquiring" method such as
61.283 + * {@code Lock.lock}, {@code Semaphore.acquire},
61.284 + * {@code Condition.await}, and {@code CountDownLatch.await} on the
61.285 + * same synchronizer object in another thread.
61.286 + *
61.287 + * <li>For each pair of threads that successfully exchange objects via
61.288 + * an {@code Exchanger}, actions prior to the {@code exchange()}
61.289 + * in each thread <i>happen-before</i> those subsequent to the
61.290 + * corresponding {@code exchange()} in another thread.
61.291 + *
61.292 + * <li>Actions prior to calling {@code CyclicBarrier.await} and
61.293 + * {@code Phaser.awaitAdvance} (as well as its variants)
61.294 + * <i>happen-before</i> actions performed by the barrier action, and
61.295 + * actions performed by the barrier action <i>happen-before</i> actions
61.296 + * subsequent to a successful return from the corresponding {@code await}
61.297 + * in other threads.
61.298 + *
61.299 + * </ul>
61.300 + *
61.301 + * @since 1.5
61.302 + */
61.303 +package java.util.concurrent;