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:46:31 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:46:31 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:46:31 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:46:31 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:46:31 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/Callable.java Sat Mar 19 10:46:31 2016 +0100
6.3 @@ -0,0 +1,65 @@
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 + * A task that returns a result and may throw an exception.
6.43 + * Implementors define a single method with no arguments called
6.44 + * <tt>call</tt>.
6.45 + *
6.46 + * <p>The <tt>Callable</tt> interface is similar to {@link
6.47 + * java.lang.Runnable}, in that both are designed for classes whose
6.48 + * instances are potentially executed by another thread. A
6.49 + * <tt>Runnable</tt>, however, does not return a result and cannot
6.50 + * throw a checked exception.
6.51 + *
6.52 + * <p> The {@link Executors} class contains utility methods to
6.53 + * convert from other common forms to <tt>Callable</tt> classes.
6.54 + *
6.55 + * @see Executor
6.56 + * @since 1.5
6.57 + * @author Doug Lea
6.58 + * @param <V> the result type of method <tt>call</tt>
6.59 + */
6.60 +public interface Callable<V> {
6.61 + /**
6.62 + * Computes a result, or throws an exception if unable to do so.
6.63 + *
6.64 + * @return computed result
6.65 + * @throws Exception if unable to compute a result
6.66 + */
6.67 + V call() throws Exception;
6.68 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/CancellationException.java Sat Mar 19 10:46:31 2016 +0100
7.3 @@ -0,0 +1,63 @@
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 + * Exception indicating that the result of a value-producing task,
7.43 + * such as a {@link FutureTask}, cannot be retrieved because the task
7.44 + * was cancelled.
7.45 + *
7.46 + * @since 1.5
7.47 + * @author Doug Lea
7.48 + */
7.49 +public class CancellationException extends IllegalStateException {
7.50 + private static final long serialVersionUID = -9202173006928992231L;
7.51 +
7.52 + /**
7.53 + * Constructs a <tt>CancellationException</tt> with no detail message.
7.54 + */
7.55 + public CancellationException() {}
7.56 +
7.57 + /**
7.58 + * Constructs a <tt>CancellationException</tt> with the specified detail
7.59 + * message.
7.60 + *
7.61 + * @param message the detail message
7.62 + */
7.63 + public CancellationException(String message) {
7.64 + super(message);
7.65 + }
7.66 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/CompletionService.java Sat Mar 19 10:46:31 2016 +0100
8.3 @@ -0,0 +1,126 @@
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 with assistance from members of JCP JSR-166
8.35 + * Expert Group and released to the public domain, as explained at
8.36 + * http://creativecommons.org/publicdomain/zero/1.0/
8.37 + */
8.38 +
8.39 +package java.util.concurrent;
8.40 +
8.41 +/**
8.42 + * A service that decouples the production of new asynchronous tasks
8.43 + * from the consumption of the results of completed tasks. Producers
8.44 + * <tt>submit</tt> tasks for execution. Consumers <tt>take</tt>
8.45 + * completed tasks and process their results in the order they
8.46 + * complete. A <tt>CompletionService</tt> can for example be used to
8.47 + * manage asynchronous IO, in which tasks that perform reads are
8.48 + * submitted in one part of a program or system, and then acted upon
8.49 + * in a different part of the program when the reads complete,
8.50 + * possibly in a different order than they were requested.
8.51 + *
8.52 + * <p>Typically, a <tt>CompletionService</tt> relies on a separate
8.53 + * {@link Executor} to actually execute the tasks, in which case the
8.54 + * <tt>CompletionService</tt> only manages an internal completion
8.55 + * queue. The {@link ExecutorCompletionService} class provides an
8.56 + * implementation of this approach.
8.57 + *
8.58 + * <p>Memory consistency effects: Actions in a thread prior to
8.59 + * submitting a task to a {@code CompletionService}
8.60 + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
8.61 + * actions taken by that task, which in turn <i>happen-before</i>
8.62 + * actions following a successful return from the corresponding {@code take()}.
8.63 + *
8.64 + */
8.65 +public interface CompletionService<V> {
8.66 + /**
8.67 + * Submits a value-returning task for execution and returns a Future
8.68 + * representing the pending results of the task. Upon completion,
8.69 + * this task may be taken or polled.
8.70 + *
8.71 + * @param task the task to submit
8.72 + * @return a Future representing pending completion of the task
8.73 + * @throws RejectedExecutionException if the task cannot be
8.74 + * scheduled for execution
8.75 + * @throws NullPointerException if the task is null
8.76 + */
8.77 + Future<V> submit(Callable<V> task);
8.78 +
8.79 + /**
8.80 + * Submits a Runnable task for execution and returns a Future
8.81 + * representing that task. Upon completion, this task may be
8.82 + * taken or polled.
8.83 + *
8.84 + * @param task the task to submit
8.85 + * @param result the result to return upon successful completion
8.86 + * @return a Future representing pending completion of the task,
8.87 + * and whose <tt>get()</tt> method will return the given
8.88 + * result value upon completion
8.89 + * @throws RejectedExecutionException if the task cannot be
8.90 + * scheduled for execution
8.91 + * @throws NullPointerException if the task is null
8.92 + */
8.93 + Future<V> submit(Runnable task, V result);
8.94 +
8.95 + /**
8.96 + * Retrieves and removes the Future representing the next
8.97 + * completed task, waiting if none are yet present.
8.98 + *
8.99 + * @return the Future representing the next completed task
8.100 + * @throws InterruptedException if interrupted while waiting
8.101 + */
8.102 + Future<V> take() throws InterruptedException;
8.103 +
8.104 +
8.105 + /**
8.106 + * Retrieves and removes the Future representing the next
8.107 + * completed task or <tt>null</tt> if none are present.
8.108 + *
8.109 + * @return the Future representing the next completed task, or
8.110 + * <tt>null</tt> if none are present
8.111 + */
8.112 + Future<V> poll();
8.113 +
8.114 + /**
8.115 + * Retrieves and removes the Future representing the next
8.116 + * completed task, waiting if necessary up to the specified wait
8.117 + * time if none are yet present.
8.118 + *
8.119 + * @param timeout how long to wait before giving up, in units of
8.120 + * <tt>unit</tt>
8.121 + * @param unit a <tt>TimeUnit</tt> determining how to interpret the
8.122 + * <tt>timeout</tt> parameter
8.123 + * @return the Future representing the next completed task or
8.124 + * <tt>null</tt> if the specified waiting time elapses
8.125 + * before one is present
8.126 + * @throws InterruptedException if interrupted while waiting
8.127 + */
8.128 + Future<V> poll(long timeout, TimeUnit unit) throws InterruptedException;
8.129 +}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ConcurrentLinkedDeque.java Sat Mar 19 10:46:31 2016 +0100
9.3 @@ -0,0 +1,1469 @@
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.AbstractCollection;
9.42 +import java.util.ArrayList;
9.43 +import java.util.Collection;
9.44 +import java.util.Deque;
9.45 +import java.util.Iterator;
9.46 +import java.util.NoSuchElementException;
9.47 +import java.util.Queue;
9.48 +
9.49 +/**
9.50 + * An unbounded concurrent {@linkplain Deque deque} based on linked nodes.
9.51 + * Concurrent insertion, removal, and access operations execute safely
9.52 + * across multiple threads.
9.53 + * A {@code ConcurrentLinkedDeque} is an appropriate choice when
9.54 + * many threads will share access to a common collection.
9.55 + * Like most other concurrent collection implementations, this class
9.56 + * does not permit the use of {@code null} elements.
9.57 + *
9.58 + * <p>Iterators are <i>weakly consistent</i>, returning elements
9.59 + * reflecting the state of the deque at some point at or since the
9.60 + * creation of the iterator. They do <em>not</em> throw {@link
9.61 + * java.util.ConcurrentModificationException
9.62 + * ConcurrentModificationException}, and may proceed concurrently with
9.63 + * other operations.
9.64 + *
9.65 + * <p>Beware that, unlike in most collections, the {@code size} method
9.66 + * is <em>NOT</em> a constant-time operation. Because of the
9.67 + * asynchronous nature of these deques, determining the current number
9.68 + * of elements requires a traversal of the elements, and so may report
9.69 + * inaccurate results if this collection is modified during traversal.
9.70 + * Additionally, the bulk operations {@code addAll},
9.71 + * {@code removeAll}, {@code retainAll}, {@code containsAll},
9.72 + * {@code equals}, and {@code toArray} are <em>not</em> guaranteed
9.73 + * to be performed atomically. For example, an iterator operating
9.74 + * concurrently with an {@code addAll} operation might view only some
9.75 + * of the added elements.
9.76 + *
9.77 + * <p>This class and its iterator implement all of the <em>optional</em>
9.78 + * methods of the {@link Deque} and {@link Iterator} interfaces.
9.79 + *
9.80 + * <p>Memory consistency effects: As with other concurrent collections,
9.81 + * actions in a thread prior to placing an object into a
9.82 + * {@code ConcurrentLinkedDeque}
9.83 + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
9.84 + * actions subsequent to the access or removal of that element from
9.85 + * the {@code ConcurrentLinkedDeque} in another thread.
9.86 + *
9.87 + * <p>This class is a member of the
9.88 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
9.89 + * Java Collections Framework</a>.
9.90 + *
9.91 + * @since 1.7
9.92 + * @author Doug Lea
9.93 + * @author Martin Buchholz
9.94 + * @param <E> the type of elements held in this collection
9.95 + */
9.96 +
9.97 +public class ConcurrentLinkedDeque<E>
9.98 + extends AbstractCollection<E>
9.99 + implements Deque<E>, java.io.Serializable {
9.100 +
9.101 + /*
9.102 + * This is an implementation of a concurrent lock-free deque
9.103 + * supporting interior removes but not interior insertions, as
9.104 + * required to support the entire Deque interface.
9.105 + *
9.106 + * We extend the techniques developed for ConcurrentLinkedQueue and
9.107 + * LinkedTransferQueue (see the internal docs for those classes).
9.108 + * Understanding the ConcurrentLinkedQueue implementation is a
9.109 + * prerequisite for understanding the implementation of this class.
9.110 + *
9.111 + * The data structure is a symmetrical doubly-linked "GC-robust"
9.112 + * linked list of nodes. We minimize the number of volatile writes
9.113 + * using two techniques: advancing multiple hops with a single CAS
9.114 + * and mixing volatile and non-volatile writes of the same memory
9.115 + * locations.
9.116 + *
9.117 + * A node contains the expected E ("item") and links to predecessor
9.118 + * ("prev") and successor ("next") nodes:
9.119 + *
9.120 + * class Node<E> { volatile Node<E> prev, next; volatile E item; }
9.121 + *
9.122 + * A node p is considered "live" if it contains a non-null item
9.123 + * (p.item != null). When an item is CASed to null, the item is
9.124 + * atomically logically deleted from the collection.
9.125 + *
9.126 + * At any time, there is precisely one "first" node with a null
9.127 + * prev reference that terminates any chain of prev references
9.128 + * starting at a live node. Similarly there is precisely one
9.129 + * "last" node terminating any chain of next references starting at
9.130 + * a live node. The "first" and "last" nodes may or may not be live.
9.131 + * The "first" and "last" nodes are always mutually reachable.
9.132 + *
9.133 + * A new element is added atomically by CASing the null prev or
9.134 + * next reference in the first or last node to a fresh node
9.135 + * containing the element. The element's node atomically becomes
9.136 + * "live" at that point.
9.137 + *
9.138 + * A node is considered "active" if it is a live node, or the
9.139 + * first or last node. Active nodes cannot be unlinked.
9.140 + *
9.141 + * A "self-link" is a next or prev reference that is the same node:
9.142 + * p.prev == p or p.next == p
9.143 + * Self-links are used in the node unlinking process. Active nodes
9.144 + * never have self-links.
9.145 + *
9.146 + * A node p is active if and only if:
9.147 + *
9.148 + * p.item != null ||
9.149 + * (p.prev == null && p.next != p) ||
9.150 + * (p.next == null && p.prev != p)
9.151 + *
9.152 + * The deque object has two node references, "head" and "tail".
9.153 + * The head and tail are only approximations to the first and last
9.154 + * nodes of the deque. The first node can always be found by
9.155 + * following prev pointers from head; likewise for tail. However,
9.156 + * it is permissible for head and tail to be referring to deleted
9.157 + * nodes that have been unlinked and so may not be reachable from
9.158 + * any live node.
9.159 + *
9.160 + * There are 3 stages of node deletion;
9.161 + * "logical deletion", "unlinking", and "gc-unlinking".
9.162 + *
9.163 + * 1. "logical deletion" by CASing item to null atomically removes
9.164 + * the element from the collection, and makes the containing node
9.165 + * eligible for unlinking.
9.166 + *
9.167 + * 2. "unlinking" makes a deleted node unreachable from active
9.168 + * nodes, and thus eventually reclaimable by GC. Unlinked nodes
9.169 + * may remain reachable indefinitely from an iterator.
9.170 + *
9.171 + * Physical node unlinking is merely an optimization (albeit a
9.172 + * critical one), and so can be performed at our convenience. At
9.173 + * any time, the set of live nodes maintained by prev and next
9.174 + * links are identical, that is, the live nodes found via next
9.175 + * links from the first node is equal to the elements found via
9.176 + * prev links from the last node. However, this is not true for
9.177 + * nodes that have already been logically deleted - such nodes may
9.178 + * be reachable in one direction only.
9.179 + *
9.180 + * 3. "gc-unlinking" takes unlinking further by making active
9.181 + * nodes unreachable from deleted nodes, making it easier for the
9.182 + * GC to reclaim future deleted nodes. This step makes the data
9.183 + * structure "gc-robust", as first described in detail by Boehm
9.184 + * (http://portal.acm.org/citation.cfm?doid=503272.503282).
9.185 + *
9.186 + * GC-unlinked nodes may remain reachable indefinitely from an
9.187 + * iterator, but unlike unlinked nodes, are never reachable from
9.188 + * head or tail.
9.189 + *
9.190 + * Making the data structure GC-robust will eliminate the risk of
9.191 + * unbounded memory retention with conservative GCs and is likely
9.192 + * to improve performance with generational GCs.
9.193 + *
9.194 + * When a node is dequeued at either end, e.g. via poll(), we would
9.195 + * like to break any references from the node to active nodes. We
9.196 + * develop further the use of self-links that was very effective in
9.197 + * other concurrent collection classes. The idea is to replace
9.198 + * prev and next pointers with special values that are interpreted
9.199 + * to mean off-the-list-at-one-end. These are approximations, but
9.200 + * good enough to preserve the properties we want in our
9.201 + * traversals, e.g. we guarantee that a traversal will never visit
9.202 + * the same element twice, but we don't guarantee whether a
9.203 + * traversal that runs out of elements will be able to see more
9.204 + * elements later after enqueues at that end. Doing gc-unlinking
9.205 + * safely is particularly tricky, since any node can be in use
9.206 + * indefinitely (for example by an iterator). We must ensure that
9.207 + * the nodes pointed at by head/tail never get gc-unlinked, since
9.208 + * head/tail are needed to get "back on track" by other nodes that
9.209 + * are gc-unlinked. gc-unlinking accounts for much of the
9.210 + * implementation complexity.
9.211 + *
9.212 + * Since neither unlinking nor gc-unlinking are necessary for
9.213 + * correctness, there are many implementation choices regarding
9.214 + * frequency (eagerness) of these operations. Since volatile
9.215 + * reads are likely to be much cheaper than CASes, saving CASes by
9.216 + * unlinking multiple adjacent nodes at a time may be a win.
9.217 + * gc-unlinking can be performed rarely and still be effective,
9.218 + * since it is most important that long chains of deleted nodes
9.219 + * are occasionally broken.
9.220 + *
9.221 + * The actual representation we use is that p.next == p means to
9.222 + * goto the first node (which in turn is reached by following prev
9.223 + * pointers from head), and p.next == null && p.prev == p means
9.224 + * that the iteration is at an end and that p is a (static final)
9.225 + * dummy node, NEXT_TERMINATOR, and not the last active node.
9.226 + * Finishing the iteration when encountering such a TERMINATOR is
9.227 + * good enough for read-only traversals, so such traversals can use
9.228 + * p.next == null as the termination condition. When we need to
9.229 + * find the last (active) node, for enqueueing a new node, we need
9.230 + * to check whether we have reached a TERMINATOR node; if so,
9.231 + * restart traversal from tail.
9.232 + *
9.233 + * The implementation is completely directionally symmetrical,
9.234 + * except that most public methods that iterate through the list
9.235 + * follow next pointers ("forward" direction).
9.236 + *
9.237 + * We believe (without full proof) that all single-element deque
9.238 + * operations (e.g., addFirst, peekLast, pollLast) are linearizable
9.239 + * (see Herlihy and Shavit's book). However, some combinations of
9.240 + * operations are known not to be linearizable. In particular,
9.241 + * when an addFirst(A) is racing with pollFirst() removing B, it is
9.242 + * possible for an observer iterating over the elements to observe
9.243 + * A B C and subsequently observe A C, even though no interior
9.244 + * removes are ever performed. Nevertheless, iterators behave
9.245 + * reasonably, providing the "weakly consistent" guarantees.
9.246 + *
9.247 + * Empirically, microbenchmarks suggest that this class adds about
9.248 + * 40% overhead relative to ConcurrentLinkedQueue, which feels as
9.249 + * good as we can hope for.
9.250 + */
9.251 +
9.252 + private static final long serialVersionUID = 876323262645176354L;
9.253 +
9.254 + /**
9.255 + * A node from which the first node on list (that is, the unique node p
9.256 + * with p.prev == null && p.next != p) can be reached in O(1) time.
9.257 + * Invariants:
9.258 + * - the first node is always O(1) reachable from head via prev links
9.259 + * - all live nodes are reachable from the first node via succ()
9.260 + * - head != null
9.261 + * - (tmp = head).next != tmp || tmp != head
9.262 + * - head is never gc-unlinked (but may be unlinked)
9.263 + * Non-invariants:
9.264 + * - head.item may or may not be null
9.265 + * - head may not be reachable from the first or last node, or from tail
9.266 + */
9.267 + private transient volatile Node<E> head;
9.268 +
9.269 + /**
9.270 + * A node from which the last node on list (that is, the unique node p
9.271 + * with p.next == null && p.prev != p) can be reached in O(1) time.
9.272 + * Invariants:
9.273 + * - the last node is always O(1) reachable from tail via next links
9.274 + * - all live nodes are reachable from the last node via pred()
9.275 + * - tail != null
9.276 + * - tail is never gc-unlinked (but may be unlinked)
9.277 + * Non-invariants:
9.278 + * - tail.item may or may not be null
9.279 + * - tail may not be reachable from the first or last node, or from head
9.280 + */
9.281 + private transient volatile Node<E> tail;
9.282 +
9.283 + private static final Node<Object> PREV_TERMINATOR, NEXT_TERMINATOR;
9.284 +
9.285 + @SuppressWarnings("unchecked")
9.286 + Node<E> prevTerminator() {
9.287 + return (Node<E>) PREV_TERMINATOR;
9.288 + }
9.289 +
9.290 + @SuppressWarnings("unchecked")
9.291 + Node<E> nextTerminator() {
9.292 + return (Node<E>) NEXT_TERMINATOR;
9.293 + }
9.294 +
9.295 + static final class Node<E> {
9.296 + volatile Node<E> prev;
9.297 + volatile E item;
9.298 + volatile Node<E> next;
9.299 +
9.300 + Node() { // default constructor for NEXT_TERMINATOR, PREV_TERMINATOR
9.301 + }
9.302 +
9.303 + /**
9.304 + * Constructs a new node. Uses relaxed write because item can
9.305 + * only be seen after publication via casNext or casPrev.
9.306 + */
9.307 + Node(E item) {
9.308 + UNSAFE.putObject(this, itemOffset, item);
9.309 + }
9.310 +
9.311 + boolean casItem(E cmp, E val) {
9.312 + return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);
9.313 + }
9.314 +
9.315 + void lazySetNext(Node<E> val) {
9.316 + UNSAFE.putOrderedObject(this, nextOffset, val);
9.317 + }
9.318 +
9.319 + boolean casNext(Node<E> cmp, Node<E> val) {
9.320 + return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
9.321 + }
9.322 +
9.323 + void lazySetPrev(Node<E> val) {
9.324 + UNSAFE.putOrderedObject(this, prevOffset, val);
9.325 + }
9.326 +
9.327 + boolean casPrev(Node<E> cmp, Node<E> val) {
9.328 + return UNSAFE.compareAndSwapObject(this, prevOffset, cmp, val);
9.329 + }
9.330 +
9.331 + // Unsafe mechanics
9.332 +
9.333 + private static final sun.misc.Unsafe UNSAFE;
9.334 + private static final long prevOffset;
9.335 + private static final long itemOffset;
9.336 + private static final long nextOffset;
9.337 +
9.338 + static {
9.339 + try {
9.340 + UNSAFE = sun.misc.Unsafe.getUnsafe();
9.341 + Class k = Node.class;
9.342 + prevOffset = UNSAFE.objectFieldOffset
9.343 + (k.getDeclaredField("prev"));
9.344 + itemOffset = UNSAFE.objectFieldOffset
9.345 + (k.getDeclaredField("item"));
9.346 + nextOffset = UNSAFE.objectFieldOffset
9.347 + (k.getDeclaredField("next"));
9.348 + } catch (Exception e) {
9.349 + throw new Error(e);
9.350 + }
9.351 + }
9.352 + }
9.353 +
9.354 + /**
9.355 + * Links e as first element.
9.356 + */
9.357 + private void linkFirst(E e) {
9.358 + checkNotNull(e);
9.359 + final Node<E> newNode = new Node<E>(e);
9.360 +
9.361 + restartFromHead:
9.362 + for (;;)
9.363 + for (Node<E> h = head, p = h, q;;) {
9.364 + if ((q = p.prev) != null &&
9.365 + (q = (p = q).prev) != null)
9.366 + // Check for head updates every other hop.
9.367 + // If p == q, we are sure to follow head instead.
9.368 + p = (h != (h = head)) ? h : q;
9.369 + else if (p.next == p) // PREV_TERMINATOR
9.370 + continue restartFromHead;
9.371 + else {
9.372 + // p is first node
9.373 + newNode.lazySetNext(p); // CAS piggyback
9.374 + if (p.casPrev(null, newNode)) {
9.375 + // Successful CAS is the linearization point
9.376 + // for e to become an element of this deque,
9.377 + // and for newNode to become "live".
9.378 + if (p != h) // hop two nodes at a time
9.379 + casHead(h, newNode); // Failure is OK.
9.380 + return;
9.381 + }
9.382 + // Lost CAS race to another thread; re-read prev
9.383 + }
9.384 + }
9.385 + }
9.386 +
9.387 + /**
9.388 + * Links e as last element.
9.389 + */
9.390 + private void linkLast(E e) {
9.391 + checkNotNull(e);
9.392 + final Node<E> newNode = new Node<E>(e);
9.393 +
9.394 + restartFromTail:
9.395 + for (;;)
9.396 + for (Node<E> t = tail, p = t, q;;) {
9.397 + if ((q = p.next) != null &&
9.398 + (q = (p = q).next) != null)
9.399 + // Check for tail updates every other hop.
9.400 + // If p == q, we are sure to follow tail instead.
9.401 + p = (t != (t = tail)) ? t : q;
9.402 + else if (p.prev == p) // NEXT_TERMINATOR
9.403 + continue restartFromTail;
9.404 + else {
9.405 + // p is last node
9.406 + newNode.lazySetPrev(p); // CAS piggyback
9.407 + if (p.casNext(null, newNode)) {
9.408 + // Successful CAS is the linearization point
9.409 + // for e to become an element of this deque,
9.410 + // and for newNode to become "live".
9.411 + if (p != t) // hop two nodes at a time
9.412 + casTail(t, newNode); // Failure is OK.
9.413 + return;
9.414 + }
9.415 + // Lost CAS race to another thread; re-read next
9.416 + }
9.417 + }
9.418 + }
9.419 +
9.420 + private static final int HOPS = 2;
9.421 +
9.422 + /**
9.423 + * Unlinks non-null node x.
9.424 + */
9.425 + void unlink(Node<E> x) {
9.426 + // assert x != null;
9.427 + // assert x.item == null;
9.428 + // assert x != PREV_TERMINATOR;
9.429 + // assert x != NEXT_TERMINATOR;
9.430 +
9.431 + final Node<E> prev = x.prev;
9.432 + final Node<E> next = x.next;
9.433 + if (prev == null) {
9.434 + unlinkFirst(x, next);
9.435 + } else if (next == null) {
9.436 + unlinkLast(x, prev);
9.437 + } else {
9.438 + // Unlink interior node.
9.439 + //
9.440 + // This is the common case, since a series of polls at the
9.441 + // same end will be "interior" removes, except perhaps for
9.442 + // the first one, since end nodes cannot be unlinked.
9.443 + //
9.444 + // At any time, all active nodes are mutually reachable by
9.445 + // following a sequence of either next or prev pointers.
9.446 + //
9.447 + // Our strategy is to find the unique active predecessor
9.448 + // and successor of x. Try to fix up their links so that
9.449 + // they point to each other, leaving x unreachable from
9.450 + // active nodes. If successful, and if x has no live
9.451 + // predecessor/successor, we additionally try to gc-unlink,
9.452 + // leaving active nodes unreachable from x, by rechecking
9.453 + // that the status of predecessor and successor are
9.454 + // unchanged and ensuring that x is not reachable from
9.455 + // tail/head, before setting x's prev/next links to their
9.456 + // logical approximate replacements, self/TERMINATOR.
9.457 + Node<E> activePred, activeSucc;
9.458 + boolean isFirst, isLast;
9.459 + int hops = 1;
9.460 +
9.461 + // Find active predecessor
9.462 + for (Node<E> p = prev; ; ++hops) {
9.463 + if (p.item != null) {
9.464 + activePred = p;
9.465 + isFirst = false;
9.466 + break;
9.467 + }
9.468 + Node<E> q = p.prev;
9.469 + if (q == null) {
9.470 + if (p.next == p)
9.471 + return;
9.472 + activePred = p;
9.473 + isFirst = true;
9.474 + break;
9.475 + }
9.476 + else if (p == q)
9.477 + return;
9.478 + else
9.479 + p = q;
9.480 + }
9.481 +
9.482 + // Find active successor
9.483 + for (Node<E> p = next; ; ++hops) {
9.484 + if (p.item != null) {
9.485 + activeSucc = p;
9.486 + isLast = false;
9.487 + break;
9.488 + }
9.489 + Node<E> q = p.next;
9.490 + if (q == null) {
9.491 + if (p.prev == p)
9.492 + return;
9.493 + activeSucc = p;
9.494 + isLast = true;
9.495 + break;
9.496 + }
9.497 + else if (p == q)
9.498 + return;
9.499 + else
9.500 + p = q;
9.501 + }
9.502 +
9.503 + // TODO: better HOP heuristics
9.504 + if (hops < HOPS
9.505 + // always squeeze out interior deleted nodes
9.506 + && (isFirst | isLast))
9.507 + return;
9.508 +
9.509 + // Squeeze out deleted nodes between activePred and
9.510 + // activeSucc, including x.
9.511 + skipDeletedSuccessors(activePred);
9.512 + skipDeletedPredecessors(activeSucc);
9.513 +
9.514 + // Try to gc-unlink, if possible
9.515 + if ((isFirst | isLast) &&
9.516 +
9.517 + // Recheck expected state of predecessor and successor
9.518 + (activePred.next == activeSucc) &&
9.519 + (activeSucc.prev == activePred) &&
9.520 + (isFirst ? activePred.prev == null : activePred.item != null) &&
9.521 + (isLast ? activeSucc.next == null : activeSucc.item != null)) {
9.522 +
9.523 + updateHead(); // Ensure x is not reachable from head
9.524 + updateTail(); // Ensure x is not reachable from tail
9.525 +
9.526 + // Finally, actually gc-unlink
9.527 + x.lazySetPrev(isFirst ? prevTerminator() : x);
9.528 + x.lazySetNext(isLast ? nextTerminator() : x);
9.529 + }
9.530 + }
9.531 + }
9.532 +
9.533 + /**
9.534 + * Unlinks non-null first node.
9.535 + */
9.536 + private void unlinkFirst(Node<E> first, Node<E> next) {
9.537 + // assert first != null;
9.538 + // assert next != null;
9.539 + // assert first.item == null;
9.540 + for (Node<E> o = null, p = next, q;;) {
9.541 + if (p.item != null || (q = p.next) == null) {
9.542 + if (o != null && p.prev != p && first.casNext(next, p)) {
9.543 + skipDeletedPredecessors(p);
9.544 + if (first.prev == null &&
9.545 + (p.next == null || p.item != null) &&
9.546 + p.prev == first) {
9.547 +
9.548 + updateHead(); // Ensure o is not reachable from head
9.549 + updateTail(); // Ensure o is not reachable from tail
9.550 +
9.551 + // Finally, actually gc-unlink
9.552 + o.lazySetNext(o);
9.553 + o.lazySetPrev(prevTerminator());
9.554 + }
9.555 + }
9.556 + return;
9.557 + }
9.558 + else if (p == q)
9.559 + return;
9.560 + else {
9.561 + o = p;
9.562 + p = q;
9.563 + }
9.564 + }
9.565 + }
9.566 +
9.567 + /**
9.568 + * Unlinks non-null last node.
9.569 + */
9.570 + private void unlinkLast(Node<E> last, Node<E> prev) {
9.571 + // assert last != null;
9.572 + // assert prev != null;
9.573 + // assert last.item == null;
9.574 + for (Node<E> o = null, p = prev, q;;) {
9.575 + if (p.item != null || (q = p.prev) == null) {
9.576 + if (o != null && p.next != p && last.casPrev(prev, p)) {
9.577 + skipDeletedSuccessors(p);
9.578 + if (last.next == null &&
9.579 + (p.prev == null || p.item != null) &&
9.580 + p.next == last) {
9.581 +
9.582 + updateHead(); // Ensure o is not reachable from head
9.583 + updateTail(); // Ensure o is not reachable from tail
9.584 +
9.585 + // Finally, actually gc-unlink
9.586 + o.lazySetPrev(o);
9.587 + o.lazySetNext(nextTerminator());
9.588 + }
9.589 + }
9.590 + return;
9.591 + }
9.592 + else if (p == q)
9.593 + return;
9.594 + else {
9.595 + o = p;
9.596 + p = q;
9.597 + }
9.598 + }
9.599 + }
9.600 +
9.601 + /**
9.602 + * Guarantees that any node which was unlinked before a call to
9.603 + * this method will be unreachable from head after it returns.
9.604 + * Does not guarantee to eliminate slack, only that head will
9.605 + * point to a node that was active while this method was running.
9.606 + */
9.607 + private final void updateHead() {
9.608 + // Either head already points to an active node, or we keep
9.609 + // trying to cas it to the first node until it does.
9.610 + Node<E> h, p, q;
9.611 + restartFromHead:
9.612 + while ((h = head).item == null && (p = h.prev) != null) {
9.613 + for (;;) {
9.614 + if ((q = p.prev) == null ||
9.615 + (q = (p = q).prev) == null) {
9.616 + // It is possible that p is PREV_TERMINATOR,
9.617 + // but if so, the CAS is guaranteed to fail.
9.618 + if (casHead(h, p))
9.619 + return;
9.620 + else
9.621 + continue restartFromHead;
9.622 + }
9.623 + else if (h != head)
9.624 + continue restartFromHead;
9.625 + else
9.626 + p = q;
9.627 + }
9.628 + }
9.629 + }
9.630 +
9.631 + /**
9.632 + * Guarantees that any node which was unlinked before a call to
9.633 + * this method will be unreachable from tail after it returns.
9.634 + * Does not guarantee to eliminate slack, only that tail will
9.635 + * point to a node that was active while this method was running.
9.636 + */
9.637 + private final void updateTail() {
9.638 + // Either tail already points to an active node, or we keep
9.639 + // trying to cas it to the last node until it does.
9.640 + Node<E> t, p, q;
9.641 + restartFromTail:
9.642 + while ((t = tail).item == null && (p = t.next) != null) {
9.643 + for (;;) {
9.644 + if ((q = p.next) == null ||
9.645 + (q = (p = q).next) == null) {
9.646 + // It is possible that p is NEXT_TERMINATOR,
9.647 + // but if so, the CAS is guaranteed to fail.
9.648 + if (casTail(t, p))
9.649 + return;
9.650 + else
9.651 + continue restartFromTail;
9.652 + }
9.653 + else if (t != tail)
9.654 + continue restartFromTail;
9.655 + else
9.656 + p = q;
9.657 + }
9.658 + }
9.659 + }
9.660 +
9.661 + private void skipDeletedPredecessors(Node<E> x) {
9.662 + whileActive:
9.663 + do {
9.664 + Node<E> prev = x.prev;
9.665 + // assert prev != null;
9.666 + // assert x != NEXT_TERMINATOR;
9.667 + // assert x != PREV_TERMINATOR;
9.668 + Node<E> p = prev;
9.669 + findActive:
9.670 + for (;;) {
9.671 + if (p.item != null)
9.672 + break findActive;
9.673 + Node<E> q = p.prev;
9.674 + if (q == null) {
9.675 + if (p.next == p)
9.676 + continue whileActive;
9.677 + break findActive;
9.678 + }
9.679 + else if (p == q)
9.680 + continue whileActive;
9.681 + else
9.682 + p = q;
9.683 + }
9.684 +
9.685 + // found active CAS target
9.686 + if (prev == p || x.casPrev(prev, p))
9.687 + return;
9.688 +
9.689 + } while (x.item != null || x.next == null);
9.690 + }
9.691 +
9.692 + private void skipDeletedSuccessors(Node<E> x) {
9.693 + whileActive:
9.694 + do {
9.695 + Node<E> next = x.next;
9.696 + // assert next != null;
9.697 + // assert x != NEXT_TERMINATOR;
9.698 + // assert x != PREV_TERMINATOR;
9.699 + Node<E> p = next;
9.700 + findActive:
9.701 + for (;;) {
9.702 + if (p.item != null)
9.703 + break findActive;
9.704 + Node<E> q = p.next;
9.705 + if (q == null) {
9.706 + if (p.prev == p)
9.707 + continue whileActive;
9.708 + break findActive;
9.709 + }
9.710 + else if (p == q)
9.711 + continue whileActive;
9.712 + else
9.713 + p = q;
9.714 + }
9.715 +
9.716 + // found active CAS target
9.717 + if (next == p || x.casNext(next, p))
9.718 + return;
9.719 +
9.720 + } while (x.item != null || x.prev == null);
9.721 + }
9.722 +
9.723 + /**
9.724 + * Returns the successor of p, or the first node if p.next has been
9.725 + * linked to self, which will only be true if traversing with a
9.726 + * stale pointer that is now off the list.
9.727 + */
9.728 + final Node<E> succ(Node<E> p) {
9.729 + // TODO: should we skip deleted nodes here?
9.730 + Node<E> q = p.next;
9.731 + return (p == q) ? first() : q;
9.732 + }
9.733 +
9.734 + /**
9.735 + * Returns the predecessor of p, or the last node if p.prev has been
9.736 + * linked to self, which will only be true if traversing with a
9.737 + * stale pointer that is now off the list.
9.738 + */
9.739 + final Node<E> pred(Node<E> p) {
9.740 + Node<E> q = p.prev;
9.741 + return (p == q) ? last() : q;
9.742 + }
9.743 +
9.744 + /**
9.745 + * Returns the first node, the unique node p for which:
9.746 + * p.prev == null && p.next != p
9.747 + * The returned node may or may not be logically deleted.
9.748 + * Guarantees that head is set to the returned node.
9.749 + */
9.750 + Node<E> first() {
9.751 + restartFromHead:
9.752 + for (;;)
9.753 + for (Node<E> h = head, p = h, q;;) {
9.754 + if ((q = p.prev) != null &&
9.755 + (q = (p = q).prev) != null)
9.756 + // Check for head updates every other hop.
9.757 + // If p == q, we are sure to follow head instead.
9.758 + p = (h != (h = head)) ? h : q;
9.759 + else if (p == h
9.760 + // It is possible that p is PREV_TERMINATOR,
9.761 + // but if so, the CAS is guaranteed to fail.
9.762 + || casHead(h, p))
9.763 + return p;
9.764 + else
9.765 + continue restartFromHead;
9.766 + }
9.767 + }
9.768 +
9.769 + /**
9.770 + * Returns the last node, the unique node p for which:
9.771 + * p.next == null && p.prev != p
9.772 + * The returned node may or may not be logically deleted.
9.773 + * Guarantees that tail is set to the returned node.
9.774 + */
9.775 + Node<E> last() {
9.776 + restartFromTail:
9.777 + for (;;)
9.778 + for (Node<E> t = tail, p = t, q;;) {
9.779 + if ((q = p.next) != null &&
9.780 + (q = (p = q).next) != null)
9.781 + // Check for tail updates every other hop.
9.782 + // If p == q, we are sure to follow tail instead.
9.783 + p = (t != (t = tail)) ? t : q;
9.784 + else if (p == t
9.785 + // It is possible that p is NEXT_TERMINATOR,
9.786 + // but if so, the CAS is guaranteed to fail.
9.787 + || casTail(t, p))
9.788 + return p;
9.789 + else
9.790 + continue restartFromTail;
9.791 + }
9.792 + }
9.793 +
9.794 + // Minor convenience utilities
9.795 +
9.796 + /**
9.797 + * Throws NullPointerException if argument is null.
9.798 + *
9.799 + * @param v the element
9.800 + */
9.801 + private static void checkNotNull(Object v) {
9.802 + if (v == null)
9.803 + throw new NullPointerException();
9.804 + }
9.805 +
9.806 + /**
9.807 + * Returns element unless it is null, in which case throws
9.808 + * NoSuchElementException.
9.809 + *
9.810 + * @param v the element
9.811 + * @return the element
9.812 + */
9.813 + private E screenNullResult(E v) {
9.814 + if (v == null)
9.815 + throw new NoSuchElementException();
9.816 + return v;
9.817 + }
9.818 +
9.819 + /**
9.820 + * Creates an array list and fills it with elements of this list.
9.821 + * Used by toArray.
9.822 + *
9.823 + * @return the arrayList
9.824 + */
9.825 + private ArrayList<E> toArrayList() {
9.826 + ArrayList<E> list = new ArrayList<E>();
9.827 + for (Node<E> p = first(); p != null; p = succ(p)) {
9.828 + E item = p.item;
9.829 + if (item != null)
9.830 + list.add(item);
9.831 + }
9.832 + return list;
9.833 + }
9.834 +
9.835 + /**
9.836 + * Constructs an empty deque.
9.837 + */
9.838 + public ConcurrentLinkedDeque() {
9.839 + head = tail = new Node<E>(null);
9.840 + }
9.841 +
9.842 + /**
9.843 + * Constructs a deque initially containing the elements of
9.844 + * the given collection, added in traversal order of the
9.845 + * collection's iterator.
9.846 + *
9.847 + * @param c the collection of elements to initially contain
9.848 + * @throws NullPointerException if the specified collection or any
9.849 + * of its elements are null
9.850 + */
9.851 + public ConcurrentLinkedDeque(Collection<? extends E> c) {
9.852 + // Copy c into a private chain of Nodes
9.853 + Node<E> h = null, t = null;
9.854 + for (E e : c) {
9.855 + checkNotNull(e);
9.856 + Node<E> newNode = new Node<E>(e);
9.857 + if (h == null)
9.858 + h = t = newNode;
9.859 + else {
9.860 + t.lazySetNext(newNode);
9.861 + newNode.lazySetPrev(t);
9.862 + t = newNode;
9.863 + }
9.864 + }
9.865 + initHeadTail(h, t);
9.866 + }
9.867 +
9.868 + /**
9.869 + * Initializes head and tail, ensuring invariants hold.
9.870 + */
9.871 + private void initHeadTail(Node<E> h, Node<E> t) {
9.872 + if (h == t) {
9.873 + if (h == null)
9.874 + h = t = new Node<E>(null);
9.875 + else {
9.876 + // Avoid edge case of a single Node with non-null item.
9.877 + Node<E> newNode = new Node<E>(null);
9.878 + t.lazySetNext(newNode);
9.879 + newNode.lazySetPrev(t);
9.880 + t = newNode;
9.881 + }
9.882 + }
9.883 + head = h;
9.884 + tail = t;
9.885 + }
9.886 +
9.887 + /**
9.888 + * Inserts the specified element at the front of this deque.
9.889 + * As the deque is unbounded, this method will never throw
9.890 + * {@link IllegalStateException}.
9.891 + *
9.892 + * @throws NullPointerException if the specified element is null
9.893 + */
9.894 + public void addFirst(E e) {
9.895 + linkFirst(e);
9.896 + }
9.897 +
9.898 + /**
9.899 + * Inserts the specified element at the end of this deque.
9.900 + * As the deque is unbounded, this method will never throw
9.901 + * {@link IllegalStateException}.
9.902 + *
9.903 + * <p>This method is equivalent to {@link #add}.
9.904 + *
9.905 + * @throws NullPointerException if the specified element is null
9.906 + */
9.907 + public void addLast(E e) {
9.908 + linkLast(e);
9.909 + }
9.910 +
9.911 + /**
9.912 + * Inserts the specified element at the front of this deque.
9.913 + * As the deque is unbounded, this method will never return {@code false}.
9.914 + *
9.915 + * @return {@code true} (as specified by {@link Deque#offerFirst})
9.916 + * @throws NullPointerException if the specified element is null
9.917 + */
9.918 + public boolean offerFirst(E e) {
9.919 + linkFirst(e);
9.920 + return true;
9.921 + }
9.922 +
9.923 + /**
9.924 + * Inserts the specified element at the end of this deque.
9.925 + * As the deque is unbounded, this method will never return {@code false}.
9.926 + *
9.927 + * <p>This method is equivalent to {@link #add}.
9.928 + *
9.929 + * @return {@code true} (as specified by {@link Deque#offerLast})
9.930 + * @throws NullPointerException if the specified element is null
9.931 + */
9.932 + public boolean offerLast(E e) {
9.933 + linkLast(e);
9.934 + return true;
9.935 + }
9.936 +
9.937 + public E peekFirst() {
9.938 + for (Node<E> p = first(); p != null; p = succ(p)) {
9.939 + E item = p.item;
9.940 + if (item != null)
9.941 + return item;
9.942 + }
9.943 + return null;
9.944 + }
9.945 +
9.946 + public E peekLast() {
9.947 + for (Node<E> p = last(); p != null; p = pred(p)) {
9.948 + E item = p.item;
9.949 + if (item != null)
9.950 + return item;
9.951 + }
9.952 + return null;
9.953 + }
9.954 +
9.955 + /**
9.956 + * @throws NoSuchElementException {@inheritDoc}
9.957 + */
9.958 + public E getFirst() {
9.959 + return screenNullResult(peekFirst());
9.960 + }
9.961 +
9.962 + /**
9.963 + * @throws NoSuchElementException {@inheritDoc}
9.964 + */
9.965 + public E getLast() {
9.966 + return screenNullResult(peekLast());
9.967 + }
9.968 +
9.969 + public E pollFirst() {
9.970 + for (Node<E> p = first(); p != null; p = succ(p)) {
9.971 + E item = p.item;
9.972 + if (item != null && p.casItem(item, null)) {
9.973 + unlink(p);
9.974 + return item;
9.975 + }
9.976 + }
9.977 + return null;
9.978 + }
9.979 +
9.980 + public E pollLast() {
9.981 + for (Node<E> p = last(); p != null; p = pred(p)) {
9.982 + E item = p.item;
9.983 + if (item != null && p.casItem(item, null)) {
9.984 + unlink(p);
9.985 + return item;
9.986 + }
9.987 + }
9.988 + return null;
9.989 + }
9.990 +
9.991 + /**
9.992 + * @throws NoSuchElementException {@inheritDoc}
9.993 + */
9.994 + public E removeFirst() {
9.995 + return screenNullResult(pollFirst());
9.996 + }
9.997 +
9.998 + /**
9.999 + * @throws NoSuchElementException {@inheritDoc}
9.1000 + */
9.1001 + public E removeLast() {
9.1002 + return screenNullResult(pollLast());
9.1003 + }
9.1004 +
9.1005 + // *** Queue and stack methods ***
9.1006 +
9.1007 + /**
9.1008 + * Inserts the specified element at the tail of this deque.
9.1009 + * As the deque is unbounded, this method will never return {@code false}.
9.1010 + *
9.1011 + * @return {@code true} (as specified by {@link Queue#offer})
9.1012 + * @throws NullPointerException if the specified element is null
9.1013 + */
9.1014 + public boolean offer(E e) {
9.1015 + return offerLast(e);
9.1016 + }
9.1017 +
9.1018 + /**
9.1019 + * Inserts the specified element at the tail of this deque.
9.1020 + * As the deque is unbounded, this method will never throw
9.1021 + * {@link IllegalStateException} or return {@code false}.
9.1022 + *
9.1023 + * @return {@code true} (as specified by {@link Collection#add})
9.1024 + * @throws NullPointerException if the specified element is null
9.1025 + */
9.1026 + public boolean add(E e) {
9.1027 + return offerLast(e);
9.1028 + }
9.1029 +
9.1030 + public E poll() { return pollFirst(); }
9.1031 + public E remove() { return removeFirst(); }
9.1032 + public E peek() { return peekFirst(); }
9.1033 + public E element() { return getFirst(); }
9.1034 + public void push(E e) { addFirst(e); }
9.1035 + public E pop() { return removeFirst(); }
9.1036 +
9.1037 + /**
9.1038 + * Removes the first element {@code e} such that
9.1039 + * {@code o.equals(e)}, if such an element exists in this deque.
9.1040 + * If the deque does not contain the element, it is unchanged.
9.1041 + *
9.1042 + * @param o element to be removed from this deque, if present
9.1043 + * @return {@code true} if the deque contained the specified element
9.1044 + * @throws NullPointerException if the specified element is null
9.1045 + */
9.1046 + public boolean removeFirstOccurrence(Object o) {
9.1047 + checkNotNull(o);
9.1048 + for (Node<E> p = first(); p != null; p = succ(p)) {
9.1049 + E item = p.item;
9.1050 + if (item != null && o.equals(item) && p.casItem(item, null)) {
9.1051 + unlink(p);
9.1052 + return true;
9.1053 + }
9.1054 + }
9.1055 + return false;
9.1056 + }
9.1057 +
9.1058 + /**
9.1059 + * Removes the last element {@code e} such that
9.1060 + * {@code o.equals(e)}, if such an element exists in this deque.
9.1061 + * If the deque does not contain the element, it is unchanged.
9.1062 + *
9.1063 + * @param o element to be removed from this deque, if present
9.1064 + * @return {@code true} if the deque contained the specified element
9.1065 + * @throws NullPointerException if the specified element is null
9.1066 + */
9.1067 + public boolean removeLastOccurrence(Object o) {
9.1068 + checkNotNull(o);
9.1069 + for (Node<E> p = last(); p != null; p = pred(p)) {
9.1070 + E item = p.item;
9.1071 + if (item != null && o.equals(item) && p.casItem(item, null)) {
9.1072 + unlink(p);
9.1073 + return true;
9.1074 + }
9.1075 + }
9.1076 + return false;
9.1077 + }
9.1078 +
9.1079 + /**
9.1080 + * Returns {@code true} if this deque contains at least one
9.1081 + * element {@code e} such that {@code o.equals(e)}.
9.1082 + *
9.1083 + * @param o element whose presence in this deque is to be tested
9.1084 + * @return {@code true} if this deque contains the specified element
9.1085 + */
9.1086 + public boolean contains(Object o) {
9.1087 + if (o == null) return false;
9.1088 + for (Node<E> p = first(); p != null; p = succ(p)) {
9.1089 + E item = p.item;
9.1090 + if (item != null && o.equals(item))
9.1091 + return true;
9.1092 + }
9.1093 + return false;
9.1094 + }
9.1095 +
9.1096 + /**
9.1097 + * Returns {@code true} if this collection contains no elements.
9.1098 + *
9.1099 + * @return {@code true} if this collection contains no elements
9.1100 + */
9.1101 + public boolean isEmpty() {
9.1102 + return peekFirst() == null;
9.1103 + }
9.1104 +
9.1105 + /**
9.1106 + * Returns the number of elements in this deque. If this deque
9.1107 + * contains more than {@code Integer.MAX_VALUE} elements, it
9.1108 + * returns {@code Integer.MAX_VALUE}.
9.1109 + *
9.1110 + * <p>Beware that, unlike in most collections, this method is
9.1111 + * <em>NOT</em> a constant-time operation. Because of the
9.1112 + * asynchronous nature of these deques, determining the current
9.1113 + * number of elements requires traversing them all to count them.
9.1114 + * Additionally, it is possible for the size to change during
9.1115 + * execution of this method, in which case the returned result
9.1116 + * will be inaccurate. Thus, this method is typically not very
9.1117 + * useful in concurrent applications.
9.1118 + *
9.1119 + * @return the number of elements in this deque
9.1120 + */
9.1121 + public int size() {
9.1122 + int count = 0;
9.1123 + for (Node<E> p = first(); p != null; p = succ(p))
9.1124 + if (p.item != null)
9.1125 + // Collection.size() spec says to max out
9.1126 + if (++count == Integer.MAX_VALUE)
9.1127 + break;
9.1128 + return count;
9.1129 + }
9.1130 +
9.1131 + /**
9.1132 + * Removes the first element {@code e} such that
9.1133 + * {@code o.equals(e)}, if such an element exists in this deque.
9.1134 + * If the deque does not contain the element, it is unchanged.
9.1135 + *
9.1136 + * @param o element to be removed from this deque, if present
9.1137 + * @return {@code true} if the deque contained the specified element
9.1138 + * @throws NullPointerException if the specified element is null
9.1139 + */
9.1140 + public boolean remove(Object o) {
9.1141 + return removeFirstOccurrence(o);
9.1142 + }
9.1143 +
9.1144 + /**
9.1145 + * Appends all of the elements in the specified collection to the end of
9.1146 + * this deque, in the order that they are returned by the specified
9.1147 + * collection's iterator. Attempts to {@code addAll} of a deque to
9.1148 + * itself result in {@code IllegalArgumentException}.
9.1149 + *
9.1150 + * @param c the elements to be inserted into this deque
9.1151 + * @return {@code true} if this deque changed as a result of the call
9.1152 + * @throws NullPointerException if the specified collection or any
9.1153 + * of its elements are null
9.1154 + * @throws IllegalArgumentException if the collection is this deque
9.1155 + */
9.1156 + public boolean addAll(Collection<? extends E> c) {
9.1157 + if (c == this)
9.1158 + // As historically specified in AbstractQueue#addAll
9.1159 + throw new IllegalArgumentException();
9.1160 +
9.1161 + // Copy c into a private chain of Nodes
9.1162 + Node<E> beginningOfTheEnd = null, last = null;
9.1163 + for (E e : c) {
9.1164 + checkNotNull(e);
9.1165 + Node<E> newNode = new Node<E>(e);
9.1166 + if (beginningOfTheEnd == null)
9.1167 + beginningOfTheEnd = last = newNode;
9.1168 + else {
9.1169 + last.lazySetNext(newNode);
9.1170 + newNode.lazySetPrev(last);
9.1171 + last = newNode;
9.1172 + }
9.1173 + }
9.1174 + if (beginningOfTheEnd == null)
9.1175 + return false;
9.1176 +
9.1177 + // Atomically append the chain at the tail of this collection
9.1178 + restartFromTail:
9.1179 + for (;;)
9.1180 + for (Node<E> t = tail, p = t, q;;) {
9.1181 + if ((q = p.next) != null &&
9.1182 + (q = (p = q).next) != null)
9.1183 + // Check for tail updates every other hop.
9.1184 + // If p == q, we are sure to follow tail instead.
9.1185 + p = (t != (t = tail)) ? t : q;
9.1186 + else if (p.prev == p) // NEXT_TERMINATOR
9.1187 + continue restartFromTail;
9.1188 + else {
9.1189 + // p is last node
9.1190 + beginningOfTheEnd.lazySetPrev(p); // CAS piggyback
9.1191 + if (p.casNext(null, beginningOfTheEnd)) {
9.1192 + // Successful CAS is the linearization point
9.1193 + // for all elements to be added to this deque.
9.1194 + if (!casTail(t, last)) {
9.1195 + // Try a little harder to update tail,
9.1196 + // since we may be adding many elements.
9.1197 + t = tail;
9.1198 + if (last.next == null)
9.1199 + casTail(t, last);
9.1200 + }
9.1201 + return true;
9.1202 + }
9.1203 + // Lost CAS race to another thread; re-read next
9.1204 + }
9.1205 + }
9.1206 + }
9.1207 +
9.1208 + /**
9.1209 + * Removes all of the elements from this deque.
9.1210 + */
9.1211 + public void clear() {
9.1212 + while (pollFirst() != null)
9.1213 + ;
9.1214 + }
9.1215 +
9.1216 + /**
9.1217 + * Returns an array containing all of the elements in this deque, in
9.1218 + * proper sequence (from first to last element).
9.1219 + *
9.1220 + * <p>The returned array will be "safe" in that no references to it are
9.1221 + * maintained by this deque. (In other words, this method must allocate
9.1222 + * a new array). The caller is thus free to modify the returned array.
9.1223 + *
9.1224 + * <p>This method acts as bridge between array-based and collection-based
9.1225 + * APIs.
9.1226 + *
9.1227 + * @return an array containing all of the elements in this deque
9.1228 + */
9.1229 + public Object[] toArray() {
9.1230 + return toArrayList().toArray();
9.1231 + }
9.1232 +
9.1233 + /**
9.1234 + * Returns an array containing all of the elements in this deque,
9.1235 + * in proper sequence (from first to last element); the runtime
9.1236 + * type of the returned array is that of the specified array. If
9.1237 + * the deque fits in the specified array, it is returned therein.
9.1238 + * Otherwise, a new array is allocated with the runtime type of
9.1239 + * the specified array and the size of this deque.
9.1240 + *
9.1241 + * <p>If this deque fits in the specified array with room to spare
9.1242 + * (i.e., the array has more elements than this deque), the element in
9.1243 + * the array immediately following the end of the deque is set to
9.1244 + * {@code null}.
9.1245 + *
9.1246 + * <p>Like the {@link #toArray()} method, this method acts as
9.1247 + * bridge between array-based and collection-based APIs. Further,
9.1248 + * this method allows precise control over the runtime type of the
9.1249 + * output array, and may, under certain circumstances, be used to
9.1250 + * save allocation costs.
9.1251 + *
9.1252 + * <p>Suppose {@code x} is a deque known to contain only strings.
9.1253 + * The following code can be used to dump the deque into a newly
9.1254 + * allocated array of {@code String}:
9.1255 + *
9.1256 + * <pre>
9.1257 + * String[] y = x.toArray(new String[0]);</pre>
9.1258 + *
9.1259 + * Note that {@code toArray(new Object[0])} is identical in function to
9.1260 + * {@code toArray()}.
9.1261 + *
9.1262 + * @param a the array into which the elements of the deque are to
9.1263 + * be stored, if it is big enough; otherwise, a new array of the
9.1264 + * same runtime type is allocated for this purpose
9.1265 + * @return an array containing all of the elements in this deque
9.1266 + * @throws ArrayStoreException if the runtime type of the specified array
9.1267 + * is not a supertype of the runtime type of every element in
9.1268 + * this deque
9.1269 + * @throws NullPointerException if the specified array is null
9.1270 + */
9.1271 + public <T> T[] toArray(T[] a) {
9.1272 + return toArrayList().toArray(a);
9.1273 + }
9.1274 +
9.1275 + /**
9.1276 + * Returns an iterator over the elements in this deque in proper sequence.
9.1277 + * The elements will be returned in order from first (head) to last (tail).
9.1278 + *
9.1279 + * <p>The returned iterator is a "weakly consistent" iterator that
9.1280 + * will never throw {@link java.util.ConcurrentModificationException
9.1281 + * ConcurrentModificationException}, and guarantees to traverse
9.1282 + * elements as they existed upon construction of the iterator, and
9.1283 + * may (but is not guaranteed to) reflect any modifications
9.1284 + * subsequent to construction.
9.1285 + *
9.1286 + * @return an iterator over the elements in this deque in proper sequence
9.1287 + */
9.1288 + public Iterator<E> iterator() {
9.1289 + return new Itr();
9.1290 + }
9.1291 +
9.1292 + /**
9.1293 + * Returns an iterator over the elements in this deque in reverse
9.1294 + * sequential order. The elements will be returned in order from
9.1295 + * last (tail) to first (head).
9.1296 + *
9.1297 + * <p>The returned iterator is a "weakly consistent" iterator that
9.1298 + * will never throw {@link java.util.ConcurrentModificationException
9.1299 + * ConcurrentModificationException}, and guarantees to traverse
9.1300 + * elements as they existed upon construction of the iterator, and
9.1301 + * may (but is not guaranteed to) reflect any modifications
9.1302 + * subsequent to construction.
9.1303 + *
9.1304 + * @return an iterator over the elements in this deque in reverse order
9.1305 + */
9.1306 + public Iterator<E> descendingIterator() {
9.1307 + return new DescendingItr();
9.1308 + }
9.1309 +
9.1310 + private abstract class AbstractItr implements Iterator<E> {
9.1311 + /**
9.1312 + * Next node to return item for.
9.1313 + */
9.1314 + private Node<E> nextNode;
9.1315 +
9.1316 + /**
9.1317 + * nextItem holds on to item fields because once we claim
9.1318 + * that an element exists in hasNext(), we must return it in
9.1319 + * the following next() call even if it was in the process of
9.1320 + * being removed when hasNext() was called.
9.1321 + */
9.1322 + private E nextItem;
9.1323 +
9.1324 + /**
9.1325 + * Node returned by most recent call to next. Needed by remove.
9.1326 + * Reset to null if this element is deleted by a call to remove.
9.1327 + */
9.1328 + private Node<E> lastRet;
9.1329 +
9.1330 + abstract Node<E> startNode();
9.1331 + abstract Node<E> nextNode(Node<E> p);
9.1332 +
9.1333 + AbstractItr() {
9.1334 + advance();
9.1335 + }
9.1336 +
9.1337 + /**
9.1338 + * Sets nextNode and nextItem to next valid node, or to null
9.1339 + * if no such.
9.1340 + */
9.1341 + private void advance() {
9.1342 + lastRet = nextNode;
9.1343 +
9.1344 + Node<E> p = (nextNode == null) ? startNode() : nextNode(nextNode);
9.1345 + for (;; p = nextNode(p)) {
9.1346 + if (p == null) {
9.1347 + // p might be active end or TERMINATOR node; both are OK
9.1348 + nextNode = null;
9.1349 + nextItem = null;
9.1350 + break;
9.1351 + }
9.1352 + E item = p.item;
9.1353 + if (item != null) {
9.1354 + nextNode = p;
9.1355 + nextItem = item;
9.1356 + break;
9.1357 + }
9.1358 + }
9.1359 + }
9.1360 +
9.1361 + public boolean hasNext() {
9.1362 + return nextItem != null;
9.1363 + }
9.1364 +
9.1365 + public E next() {
9.1366 + E item = nextItem;
9.1367 + if (item == null) throw new NoSuchElementException();
9.1368 + advance();
9.1369 + return item;
9.1370 + }
9.1371 +
9.1372 + public void remove() {
9.1373 + Node<E> l = lastRet;
9.1374 + if (l == null) throw new IllegalStateException();
9.1375 + l.item = null;
9.1376 + unlink(l);
9.1377 + lastRet = null;
9.1378 + }
9.1379 + }
9.1380 +
9.1381 + /** Forward iterator */
9.1382 + private class Itr extends AbstractItr {
9.1383 + Node<E> startNode() { return first(); }
9.1384 + Node<E> nextNode(Node<E> p) { return succ(p); }
9.1385 + }
9.1386 +
9.1387 + /** Descending iterator */
9.1388 + private class DescendingItr extends AbstractItr {
9.1389 + Node<E> startNode() { return last(); }
9.1390 + Node<E> nextNode(Node<E> p) { return pred(p); }
9.1391 + }
9.1392 +
9.1393 + /**
9.1394 + * Saves the state to a stream (that is, serializes it).
9.1395 + *
9.1396 + * @serialData All of the elements (each an {@code E}) in
9.1397 + * the proper order, followed by a null
9.1398 + * @param s the stream
9.1399 + */
9.1400 + private void writeObject(java.io.ObjectOutputStream s)
9.1401 + throws java.io.IOException {
9.1402 +
9.1403 + // Write out any hidden stuff
9.1404 + s.defaultWriteObject();
9.1405 +
9.1406 + // Write out all elements in the proper order.
9.1407 + for (Node<E> p = first(); p != null; p = succ(p)) {
9.1408 + E item = p.item;
9.1409 + if (item != null)
9.1410 + s.writeObject(item);
9.1411 + }
9.1412 +
9.1413 + // Use trailing null as sentinel
9.1414 + s.writeObject(null);
9.1415 + }
9.1416 +
9.1417 + /**
9.1418 + * Reconstitutes the instance from a stream (that is, deserializes it).
9.1419 + * @param s the stream
9.1420 + */
9.1421 + private void readObject(java.io.ObjectInputStream s)
9.1422 + throws java.io.IOException, ClassNotFoundException {
9.1423 + s.defaultReadObject();
9.1424 +
9.1425 + // Read in elements until trailing null sentinel found
9.1426 + Node<E> h = null, t = null;
9.1427 + Object item;
9.1428 + while ((item = s.readObject()) != null) {
9.1429 + @SuppressWarnings("unchecked")
9.1430 + Node<E> newNode = new Node<E>((E) item);
9.1431 + if (h == null)
9.1432 + h = t = newNode;
9.1433 + else {
9.1434 + t.lazySetNext(newNode);
9.1435 + newNode.lazySetPrev(t);
9.1436 + t = newNode;
9.1437 + }
9.1438 + }
9.1439 + initHeadTail(h, t);
9.1440 + }
9.1441 +
9.1442 +
9.1443 + private boolean casHead(Node<E> cmp, Node<E> val) {
9.1444 + return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
9.1445 + }
9.1446 +
9.1447 + private boolean casTail(Node<E> cmp, Node<E> val) {
9.1448 + return UNSAFE.compareAndSwapObject(this, tailOffset, cmp, val);
9.1449 + }
9.1450 +
9.1451 + // Unsafe mechanics
9.1452 +
9.1453 + private static final sun.misc.Unsafe UNSAFE;
9.1454 + private static final long headOffset;
9.1455 + private static final long tailOffset;
9.1456 + static {
9.1457 + PREV_TERMINATOR = new Node<Object>();
9.1458 + PREV_TERMINATOR.next = PREV_TERMINATOR;
9.1459 + NEXT_TERMINATOR = new Node<Object>();
9.1460 + NEXT_TERMINATOR.prev = NEXT_TERMINATOR;
9.1461 + try {
9.1462 + UNSAFE = sun.misc.Unsafe.getUnsafe();
9.1463 + Class k = ConcurrentLinkedDeque.class;
9.1464 + headOffset = UNSAFE.objectFieldOffset
9.1465 + (k.getDeclaredField("head"));
9.1466 + tailOffset = UNSAFE.objectFieldOffset
9.1467 + (k.getDeclaredField("tail"));
9.1468 + } catch (Exception e) {
9.1469 + throw new Error(e);
9.1470 + }
9.1471 + }
9.1472 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java Sat Mar 19 10:46:31 2016 +0100
10.3 @@ -0,0 +1,835 @@
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 and Martin Buchholz with assistance from members of
10.35 + * JCP JSR-166 Expert Group and released to the public domain, as explained
10.36 + * at http://creativecommons.org/publicdomain/zero/1.0/
10.37 + */
10.38 +
10.39 +package java.util.concurrent;
10.40 +
10.41 +import java.util.AbstractQueue;
10.42 +import java.util.ArrayList;
10.43 +import java.util.Collection;
10.44 +import java.util.Iterator;
10.45 +import java.util.NoSuchElementException;
10.46 +import java.util.Queue;
10.47 +
10.48 +/**
10.49 + * An unbounded thread-safe {@linkplain Queue queue} based on linked nodes.
10.50 + * This queue orders elements FIFO (first-in-first-out).
10.51 + * The <em>head</em> of the queue is that element that has been on the
10.52 + * queue the longest time.
10.53 + * The <em>tail</em> of the queue is that element that has been on the
10.54 + * queue the shortest time. New elements
10.55 + * are inserted at the tail of the queue, and the queue retrieval
10.56 + * operations obtain elements at the head of the queue.
10.57 + * A {@code ConcurrentLinkedQueue} is an appropriate choice when
10.58 + * many threads will share access to a common collection.
10.59 + * Like most other concurrent collection implementations, this class
10.60 + * does not permit the use of {@code null} elements.
10.61 + *
10.62 + * <p>This implementation employs an efficient "wait-free"
10.63 + * algorithm based on one described in <a
10.64 + * href="http://www.cs.rochester.edu/u/michael/PODC96.html"> Simple,
10.65 + * Fast, and Practical Non-Blocking and Blocking Concurrent Queue
10.66 + * Algorithms</a> by Maged M. Michael and Michael L. Scott.
10.67 + *
10.68 + * <p>Iterators are <i>weakly consistent</i>, returning elements
10.69 + * reflecting the state of the queue at some point at or since the
10.70 + * creation of the iterator. They do <em>not</em> throw {@link
10.71 + * java.util.ConcurrentModificationException}, and may proceed concurrently
10.72 + * with other operations. Elements contained in the queue since the creation
10.73 + * of the iterator will be returned exactly once.
10.74 + *
10.75 + * <p>Beware that, unlike in most collections, the {@code size} method
10.76 + * is <em>NOT</em> a constant-time operation. Because of the
10.77 + * asynchronous nature of these queues, determining the current number
10.78 + * of elements requires a traversal of the elements, and so may report
10.79 + * inaccurate results if this collection is modified during traversal.
10.80 + * Additionally, the bulk operations {@code addAll},
10.81 + * {@code removeAll}, {@code retainAll}, {@code containsAll},
10.82 + * {@code equals}, and {@code toArray} are <em>not</em> guaranteed
10.83 + * to be performed atomically. For example, an iterator operating
10.84 + * concurrently with an {@code addAll} operation might view only some
10.85 + * of the added elements.
10.86 + *
10.87 + * <p>This class and its iterator implement all of the <em>optional</em>
10.88 + * methods of the {@link Queue} and {@link Iterator} interfaces.
10.89 + *
10.90 + * <p>Memory consistency effects: As with other concurrent
10.91 + * collections, actions in a thread prior to placing an object into a
10.92 + * {@code ConcurrentLinkedQueue}
10.93 + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
10.94 + * actions subsequent to the access or removal of that element from
10.95 + * the {@code ConcurrentLinkedQueue} in another thread.
10.96 + *
10.97 + * <p>This class is a member of the
10.98 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
10.99 + * Java Collections Framework</a>.
10.100 + *
10.101 + * @since 1.5
10.102 + * @author Doug Lea
10.103 + * @param <E> the type of elements held in this collection
10.104 + *
10.105 + */
10.106 +public class ConcurrentLinkedQueue<E> extends AbstractQueue<E>
10.107 + implements Queue<E>, java.io.Serializable {
10.108 + private static final long serialVersionUID = 196745693267521676L;
10.109 +
10.110 + /*
10.111 + * This is a modification of the Michael & Scott algorithm,
10.112 + * adapted for a garbage-collected environment, with support for
10.113 + * interior node deletion (to support remove(Object)). For
10.114 + * explanation, read the paper.
10.115 + *
10.116 + * Note that like most non-blocking algorithms in this package,
10.117 + * this implementation relies on the fact that in garbage
10.118 + * collected systems, there is no possibility of ABA problems due
10.119 + * to recycled nodes, so there is no need to use "counted
10.120 + * pointers" or related techniques seen in versions used in
10.121 + * non-GC'ed settings.
10.122 + *
10.123 + * The fundamental invariants are:
10.124 + * - There is exactly one (last) Node with a null next reference,
10.125 + * which is CASed when enqueueing. This last Node can be
10.126 + * reached in O(1) time from tail, but tail is merely an
10.127 + * optimization - it can always be reached in O(N) time from
10.128 + * head as well.
10.129 + * - The elements contained in the queue are the non-null items in
10.130 + * Nodes that are reachable from head. CASing the item
10.131 + * reference of a Node to null atomically removes it from the
10.132 + * queue. Reachability of all elements from head must remain
10.133 + * true even in the case of concurrent modifications that cause
10.134 + * head to advance. A dequeued Node may remain in use
10.135 + * indefinitely due to creation of an Iterator or simply a
10.136 + * poll() that has lost its time slice.
10.137 + *
10.138 + * The above might appear to imply that all Nodes are GC-reachable
10.139 + * from a predecessor dequeued Node. That would cause two problems:
10.140 + * - allow a rogue Iterator to cause unbounded memory retention
10.141 + * - cause cross-generational linking of old Nodes to new Nodes if
10.142 + * a Node was tenured while live, which generational GCs have a
10.143 + * hard time dealing with, causing repeated major collections.
10.144 + * However, only non-deleted Nodes need to be reachable from
10.145 + * dequeued Nodes, and reachability does not necessarily have to
10.146 + * be of the kind understood by the GC. We use the trick of
10.147 + * linking a Node that has just been dequeued to itself. Such a
10.148 + * self-link implicitly means to advance to head.
10.149 + *
10.150 + * Both head and tail are permitted to lag. In fact, failing to
10.151 + * update them every time one could is a significant optimization
10.152 + * (fewer CASes). As with LinkedTransferQueue (see the internal
10.153 + * documentation for that class), we use a slack threshold of two;
10.154 + * that is, we update head/tail when the current pointer appears
10.155 + * to be two or more steps away from the first/last node.
10.156 + *
10.157 + * Since head and tail are updated concurrently and independently,
10.158 + * it is possible for tail to lag behind head (why not)?
10.159 + *
10.160 + * CASing a Node's item reference to null atomically removes the
10.161 + * element from the queue. Iterators skip over Nodes with null
10.162 + * items. Prior implementations of this class had a race between
10.163 + * poll() and remove(Object) where the same element would appear
10.164 + * to be successfully removed by two concurrent operations. The
10.165 + * method remove(Object) also lazily unlinks deleted Nodes, but
10.166 + * this is merely an optimization.
10.167 + *
10.168 + * When constructing a Node (before enqueuing it) we avoid paying
10.169 + * for a volatile write to item by using Unsafe.putObject instead
10.170 + * of a normal write. This allows the cost of enqueue to be
10.171 + * "one-and-a-half" CASes.
10.172 + *
10.173 + * Both head and tail may or may not point to a Node with a
10.174 + * non-null item. If the queue is empty, all items must of course
10.175 + * be null. Upon creation, both head and tail refer to a dummy
10.176 + * Node with null item. Both head and tail are only updated using
10.177 + * CAS, so they never regress, although again this is merely an
10.178 + * optimization.
10.179 + */
10.180 +
10.181 + private static class Node<E> {
10.182 + volatile E item;
10.183 + volatile Node<E> next;
10.184 +
10.185 + /**
10.186 + * Constructs a new node. Uses relaxed write because item can
10.187 + * only be seen after publication via casNext.
10.188 + */
10.189 + Node(E item) {
10.190 + UNSAFE.putObject(this, itemOffset, item);
10.191 + }
10.192 +
10.193 + boolean casItem(E cmp, E val) {
10.194 + return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);
10.195 + }
10.196 +
10.197 + void lazySetNext(Node<E> val) {
10.198 + UNSAFE.putOrderedObject(this, nextOffset, val);
10.199 + }
10.200 +
10.201 + boolean casNext(Node<E> cmp, Node<E> val) {
10.202 + return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
10.203 + }
10.204 +
10.205 + // Unsafe mechanics
10.206 +
10.207 + private static final sun.misc.Unsafe UNSAFE;
10.208 + private static final long itemOffset;
10.209 + private static final long nextOffset;
10.210 +
10.211 + static {
10.212 + try {
10.213 + UNSAFE = sun.misc.Unsafe.getUnsafe();
10.214 + Class k = Node.class;
10.215 + itemOffset = UNSAFE.objectFieldOffset
10.216 + (k.getDeclaredField("item"));
10.217 + nextOffset = UNSAFE.objectFieldOffset
10.218 + (k.getDeclaredField("next"));
10.219 + } catch (Exception e) {
10.220 + throw new Error(e);
10.221 + }
10.222 + }
10.223 + }
10.224 +
10.225 + /**
10.226 + * A node from which the first live (non-deleted) node (if any)
10.227 + * can be reached in O(1) time.
10.228 + * Invariants:
10.229 + * - all live nodes are reachable from head via succ()
10.230 + * - head != null
10.231 + * - (tmp = head).next != tmp || tmp != head
10.232 + * Non-invariants:
10.233 + * - head.item may or may not be null.
10.234 + * - it is permitted for tail to lag behind head, that is, for tail
10.235 + * to not be reachable from head!
10.236 + */
10.237 + private transient volatile Node<E> head;
10.238 +
10.239 + /**
10.240 + * A node from which the last node on list (that is, the unique
10.241 + * node with node.next == null) can be reached in O(1) time.
10.242 + * Invariants:
10.243 + * - the last node is always reachable from tail via succ()
10.244 + * - tail != null
10.245 + * Non-invariants:
10.246 + * - tail.item may or may not be null.
10.247 + * - it is permitted for tail to lag behind head, that is, for tail
10.248 + * to not be reachable from head!
10.249 + * - tail.next may or may not be self-pointing to tail.
10.250 + */
10.251 + private transient volatile Node<E> tail;
10.252 +
10.253 +
10.254 + /**
10.255 + * Creates a {@code ConcurrentLinkedQueue} that is initially empty.
10.256 + */
10.257 + public ConcurrentLinkedQueue() {
10.258 + head = tail = new Node<E>(null);
10.259 + }
10.260 +
10.261 + /**
10.262 + * Creates a {@code ConcurrentLinkedQueue}
10.263 + * initially containing the elements of the given collection,
10.264 + * added in traversal order of the collection's iterator.
10.265 + *
10.266 + * @param c the collection of elements to initially contain
10.267 + * @throws NullPointerException if the specified collection or any
10.268 + * of its elements are null
10.269 + */
10.270 + public ConcurrentLinkedQueue(Collection<? extends E> c) {
10.271 + Node<E> h = null, t = null;
10.272 + for (E e : c) {
10.273 + checkNotNull(e);
10.274 + Node<E> newNode = new Node<E>(e);
10.275 + if (h == null)
10.276 + h = t = newNode;
10.277 + else {
10.278 + t.lazySetNext(newNode);
10.279 + t = newNode;
10.280 + }
10.281 + }
10.282 + if (h == null)
10.283 + h = t = new Node<E>(null);
10.284 + head = h;
10.285 + tail = t;
10.286 + }
10.287 +
10.288 + // Have to override just to update the javadoc
10.289 +
10.290 + /**
10.291 + * Inserts the specified element at the tail of this queue.
10.292 + * As the queue is unbounded, this method will never throw
10.293 + * {@link IllegalStateException} or return {@code false}.
10.294 + *
10.295 + * @return {@code true} (as specified by {@link Collection#add})
10.296 + * @throws NullPointerException if the specified element is null
10.297 + */
10.298 + public boolean add(E e) {
10.299 + return offer(e);
10.300 + }
10.301 +
10.302 + /**
10.303 + * Try to CAS head to p. If successful, repoint old head to itself
10.304 + * as sentinel for succ(), below.
10.305 + */
10.306 + final void updateHead(Node<E> h, Node<E> p) {
10.307 + if (h != p && casHead(h, p))
10.308 + h.lazySetNext(h);
10.309 + }
10.310 +
10.311 + /**
10.312 + * Returns the successor of p, or the head node if p.next has been
10.313 + * linked to self, which will only be true if traversing with a
10.314 + * stale pointer that is now off the list.
10.315 + */
10.316 + final Node<E> succ(Node<E> p) {
10.317 + Node<E> next = p.next;
10.318 + return (p == next) ? head : next;
10.319 + }
10.320 +
10.321 + /**
10.322 + * Inserts the specified element at the tail of this queue.
10.323 + * As the queue is unbounded, this method will never return {@code false}.
10.324 + *
10.325 + * @return {@code true} (as specified by {@link Queue#offer})
10.326 + * @throws NullPointerException if the specified element is null
10.327 + */
10.328 + public boolean offer(E e) {
10.329 + checkNotNull(e);
10.330 + final Node<E> newNode = new Node<E>(e);
10.331 +
10.332 + for (Node<E> t = tail, p = t;;) {
10.333 + Node<E> q = p.next;
10.334 + if (q == null) {
10.335 + // p is last node
10.336 + if (p.casNext(null, newNode)) {
10.337 + // Successful CAS is the linearization point
10.338 + // for e to become an element of this queue,
10.339 + // and for newNode to become "live".
10.340 + if (p != t) // hop two nodes at a time
10.341 + casTail(t, newNode); // Failure is OK.
10.342 + return true;
10.343 + }
10.344 + // Lost CAS race to another thread; re-read next
10.345 + }
10.346 + else if (p == q)
10.347 + // We have fallen off list. If tail is unchanged, it
10.348 + // will also be off-list, in which case we need to
10.349 + // jump to head, from which all live nodes are always
10.350 + // reachable. Else the new tail is a better bet.
10.351 + p = (t != (t = tail)) ? t : head;
10.352 + else
10.353 + // Check for tail updates after two hops.
10.354 + p = (p != t && t != (t = tail)) ? t : q;
10.355 + }
10.356 + }
10.357 +
10.358 + public E poll() {
10.359 + restartFromHead:
10.360 + for (;;) {
10.361 + for (Node<E> h = head, p = h, q;;) {
10.362 + E item = p.item;
10.363 +
10.364 + if (item != null && p.casItem(item, null)) {
10.365 + // Successful CAS is the linearization point
10.366 + // for item to be removed from this queue.
10.367 + if (p != h) // hop two nodes at a time
10.368 + updateHead(h, ((q = p.next) != null) ? q : p);
10.369 + return item;
10.370 + }
10.371 + else if ((q = p.next) == null) {
10.372 + updateHead(h, p);
10.373 + return null;
10.374 + }
10.375 + else if (p == q)
10.376 + continue restartFromHead;
10.377 + else
10.378 + p = q;
10.379 + }
10.380 + }
10.381 + }
10.382 +
10.383 + public E peek() {
10.384 + restartFromHead:
10.385 + for (;;) {
10.386 + for (Node<E> h = head, p = h, q;;) {
10.387 + E item = p.item;
10.388 + if (item != null || (q = p.next) == null) {
10.389 + updateHead(h, p);
10.390 + return item;
10.391 + }
10.392 + else if (p == q)
10.393 + continue restartFromHead;
10.394 + else
10.395 + p = q;
10.396 + }
10.397 + }
10.398 + }
10.399 +
10.400 + /**
10.401 + * Returns the first live (non-deleted) node on list, or null if none.
10.402 + * This is yet another variant of poll/peek; here returning the
10.403 + * first node, not element. We could make peek() a wrapper around
10.404 + * first(), but that would cost an extra volatile read of item,
10.405 + * and the need to add a retry loop to deal with the possibility
10.406 + * of losing a race to a concurrent poll().
10.407 + */
10.408 + Node<E> first() {
10.409 + restartFromHead:
10.410 + for (;;) {
10.411 + for (Node<E> h = head, p = h, q;;) {
10.412 + boolean hasItem = (p.item != null);
10.413 + if (hasItem || (q = p.next) == null) {
10.414 + updateHead(h, p);
10.415 + return hasItem ? p : null;
10.416 + }
10.417 + else if (p == q)
10.418 + continue restartFromHead;
10.419 + else
10.420 + p = q;
10.421 + }
10.422 + }
10.423 + }
10.424 +
10.425 + /**
10.426 + * Returns {@code true} if this queue contains no elements.
10.427 + *
10.428 + * @return {@code true} if this queue contains no elements
10.429 + */
10.430 + public boolean isEmpty() {
10.431 + return first() == null;
10.432 + }
10.433 +
10.434 + /**
10.435 + * Returns the number of elements in this queue. If this queue
10.436 + * contains more than {@code Integer.MAX_VALUE} elements, returns
10.437 + * {@code Integer.MAX_VALUE}.
10.438 + *
10.439 + * <p>Beware that, unlike in most collections, this method is
10.440 + * <em>NOT</em> a constant-time operation. Because of the
10.441 + * asynchronous nature of these queues, determining the current
10.442 + * number of elements requires an O(n) traversal.
10.443 + * Additionally, if elements are added or removed during execution
10.444 + * of this method, the returned result may be inaccurate. Thus,
10.445 + * this method is typically not very useful in concurrent
10.446 + * applications.
10.447 + *
10.448 + * @return the number of elements in this queue
10.449 + */
10.450 + public int size() {
10.451 + int count = 0;
10.452 + for (Node<E> p = first(); p != null; p = succ(p))
10.453 + if (p.item != null)
10.454 + // Collection.size() spec says to max out
10.455 + if (++count == Integer.MAX_VALUE)
10.456 + break;
10.457 + return count;
10.458 + }
10.459 +
10.460 + /**
10.461 + * Returns {@code true} if this queue contains the specified element.
10.462 + * More formally, returns {@code true} if and only if this queue contains
10.463 + * at least one element {@code e} such that {@code o.equals(e)}.
10.464 + *
10.465 + * @param o object to be checked for containment in this queue
10.466 + * @return {@code true} if this queue contains the specified element
10.467 + */
10.468 + public boolean contains(Object o) {
10.469 + if (o == null) return false;
10.470 + for (Node<E> p = first(); p != null; p = succ(p)) {
10.471 + E item = p.item;
10.472 + if (item != null && o.equals(item))
10.473 + return true;
10.474 + }
10.475 + return false;
10.476 + }
10.477 +
10.478 + /**
10.479 + * Removes a single instance of the specified element from this queue,
10.480 + * if it is present. More formally, removes an element {@code e} such
10.481 + * that {@code o.equals(e)}, if this queue contains one or more such
10.482 + * elements.
10.483 + * Returns {@code true} if this queue contained the specified element
10.484 + * (or equivalently, if this queue changed as a result of the call).
10.485 + *
10.486 + * @param o element to be removed from this queue, if present
10.487 + * @return {@code true} if this queue changed as a result of the call
10.488 + */
10.489 + public boolean remove(Object o) {
10.490 + if (o == null) return false;
10.491 + Node<E> pred = null;
10.492 + for (Node<E> p = first(); p != null; p = succ(p)) {
10.493 + E item = p.item;
10.494 + if (item != null &&
10.495 + o.equals(item) &&
10.496 + p.casItem(item, null)) {
10.497 + Node<E> next = succ(p);
10.498 + if (pred != null && next != null)
10.499 + pred.casNext(p, next);
10.500 + return true;
10.501 + }
10.502 + pred = p;
10.503 + }
10.504 + return false;
10.505 + }
10.506 +
10.507 + /**
10.508 + * Appends all of the elements in the specified collection to the end of
10.509 + * this queue, in the order that they are returned by the specified
10.510 + * collection's iterator. Attempts to {@code addAll} of a queue to
10.511 + * itself result in {@code IllegalArgumentException}.
10.512 + *
10.513 + * @param c the elements to be inserted into this queue
10.514 + * @return {@code true} if this queue changed as a result of the call
10.515 + * @throws NullPointerException if the specified collection or any
10.516 + * of its elements are null
10.517 + * @throws IllegalArgumentException if the collection is this queue
10.518 + */
10.519 + public boolean addAll(Collection<? extends E> c) {
10.520 + if (c == this)
10.521 + // As historically specified in AbstractQueue#addAll
10.522 + throw new IllegalArgumentException();
10.523 +
10.524 + // Copy c into a private chain of Nodes
10.525 + Node<E> beginningOfTheEnd = null, last = null;
10.526 + for (E e : c) {
10.527 + checkNotNull(e);
10.528 + Node<E> newNode = new Node<E>(e);
10.529 + if (beginningOfTheEnd == null)
10.530 + beginningOfTheEnd = last = newNode;
10.531 + else {
10.532 + last.lazySetNext(newNode);
10.533 + last = newNode;
10.534 + }
10.535 + }
10.536 + if (beginningOfTheEnd == null)
10.537 + return false;
10.538 +
10.539 + // Atomically append the chain at the tail of this collection
10.540 + for (Node<E> t = tail, p = t;;) {
10.541 + Node<E> q = p.next;
10.542 + if (q == null) {
10.543 + // p is last node
10.544 + if (p.casNext(null, beginningOfTheEnd)) {
10.545 + // Successful CAS is the linearization point
10.546 + // for all elements to be added to this queue.
10.547 + if (!casTail(t, last)) {
10.548 + // Try a little harder to update tail,
10.549 + // since we may be adding many elements.
10.550 + t = tail;
10.551 + if (last.next == null)
10.552 + casTail(t, last);
10.553 + }
10.554 + return true;
10.555 + }
10.556 + // Lost CAS race to another thread; re-read next
10.557 + }
10.558 + else if (p == q)
10.559 + // We have fallen off list. If tail is unchanged, it
10.560 + // will also be off-list, in which case we need to
10.561 + // jump to head, from which all live nodes are always
10.562 + // reachable. Else the new tail is a better bet.
10.563 + p = (t != (t = tail)) ? t : head;
10.564 + else
10.565 + // Check for tail updates after two hops.
10.566 + p = (p != t && t != (t = tail)) ? t : q;
10.567 + }
10.568 + }
10.569 +
10.570 + /**
10.571 + * Returns an array containing all of the elements in this queue, in
10.572 + * proper sequence.
10.573 + *
10.574 + * <p>The returned array will be "safe" in that no references to it are
10.575 + * maintained by this queue. (In other words, this method must allocate
10.576 + * a new array). The caller is thus free to modify the returned array.
10.577 + *
10.578 + * <p>This method acts as bridge between array-based and collection-based
10.579 + * APIs.
10.580 + *
10.581 + * @return an array containing all of the elements in this queue
10.582 + */
10.583 + public Object[] toArray() {
10.584 + // Use ArrayList to deal with resizing.
10.585 + ArrayList<E> al = new ArrayList<E>();
10.586 + for (Node<E> p = first(); p != null; p = succ(p)) {
10.587 + E item = p.item;
10.588 + if (item != null)
10.589 + al.add(item);
10.590 + }
10.591 + return al.toArray();
10.592 + }
10.593 +
10.594 + /**
10.595 + * Returns an array containing all of the elements in this queue, in
10.596 + * proper sequence; the runtime type of the returned array is that of
10.597 + * the specified array. If the queue fits in the specified array, it
10.598 + * is returned therein. Otherwise, a new array is allocated with the
10.599 + * runtime type of the specified array and the size of this queue.
10.600 + *
10.601 + * <p>If this queue fits in the specified array with room to spare
10.602 + * (i.e., the array has more elements than this queue), the element in
10.603 + * the array immediately following the end of the queue is set to
10.604 + * {@code null}.
10.605 + *
10.606 + * <p>Like the {@link #toArray()} method, this method acts as bridge between
10.607 + * array-based and collection-based APIs. Further, this method allows
10.608 + * precise control over the runtime type of the output array, and may,
10.609 + * under certain circumstances, be used to save allocation costs.
10.610 + *
10.611 + * <p>Suppose {@code x} is a queue known to contain only strings.
10.612 + * The following code can be used to dump the queue into a newly
10.613 + * allocated array of {@code String}:
10.614 + *
10.615 + * <pre>
10.616 + * String[] y = x.toArray(new String[0]);</pre>
10.617 + *
10.618 + * Note that {@code toArray(new Object[0])} is identical in function to
10.619 + * {@code toArray()}.
10.620 + *
10.621 + * @param a the array into which the elements of the queue are to
10.622 + * be stored, if it is big enough; otherwise, a new array of the
10.623 + * same runtime type is allocated for this purpose
10.624 + * @return an array containing all of the elements in this queue
10.625 + * @throws ArrayStoreException if the runtime type of the specified array
10.626 + * is not a supertype of the runtime type of every element in
10.627 + * this queue
10.628 + * @throws NullPointerException if the specified array is null
10.629 + */
10.630 + @SuppressWarnings("unchecked")
10.631 + public <T> T[] toArray(T[] a) {
10.632 + // try to use sent-in array
10.633 + int k = 0;
10.634 + Node<E> p;
10.635 + for (p = first(); p != null && k < a.length; p = succ(p)) {
10.636 + E item = p.item;
10.637 + if (item != null)
10.638 + a[k++] = (T)item;
10.639 + }
10.640 + if (p == null) {
10.641 + if (k < a.length)
10.642 + a[k] = null;
10.643 + return a;
10.644 + }
10.645 +
10.646 + // If won't fit, use ArrayList version
10.647 + ArrayList<E> al = new ArrayList<E>();
10.648 + for (Node<E> q = first(); q != null; q = succ(q)) {
10.649 + E item = q.item;
10.650 + if (item != null)
10.651 + al.add(item);
10.652 + }
10.653 + return al.toArray(a);
10.654 + }
10.655 +
10.656 + /**
10.657 + * Returns an iterator over the elements in this queue in proper sequence.
10.658 + * The elements will be returned in order from first (head) to last (tail).
10.659 + *
10.660 + * <p>The returned iterator is a "weakly consistent" iterator that
10.661 + * will never throw {@link java.util.ConcurrentModificationException
10.662 + * ConcurrentModificationException}, and guarantees to traverse
10.663 + * elements as they existed upon construction of the iterator, and
10.664 + * may (but is not guaranteed to) reflect any modifications
10.665 + * subsequent to construction.
10.666 + *
10.667 + * @return an iterator over the elements in this queue in proper sequence
10.668 + */
10.669 + public Iterator<E> iterator() {
10.670 + return new Itr();
10.671 + }
10.672 +
10.673 + private class Itr implements Iterator<E> {
10.674 + /**
10.675 + * Next node to return item for.
10.676 + */
10.677 + private Node<E> nextNode;
10.678 +
10.679 + /**
10.680 + * nextItem holds on to item fields because once we claim
10.681 + * that an element exists in hasNext(), we must return it in
10.682 + * the following next() call even if it was in the process of
10.683 + * being removed when hasNext() was called.
10.684 + */
10.685 + private E nextItem;
10.686 +
10.687 + /**
10.688 + * Node of the last returned item, to support remove.
10.689 + */
10.690 + private Node<E> lastRet;
10.691 +
10.692 + Itr() {
10.693 + advance();
10.694 + }
10.695 +
10.696 + /**
10.697 + * Moves to next valid node and returns item to return for
10.698 + * next(), or null if no such.
10.699 + */
10.700 + private E advance() {
10.701 + lastRet = nextNode;
10.702 + E x = nextItem;
10.703 +
10.704 + Node<E> pred, p;
10.705 + if (nextNode == null) {
10.706 + p = first();
10.707 + pred = null;
10.708 + } else {
10.709 + pred = nextNode;
10.710 + p = succ(nextNode);
10.711 + }
10.712 +
10.713 + for (;;) {
10.714 + if (p == null) {
10.715 + nextNode = null;
10.716 + nextItem = null;
10.717 + return x;
10.718 + }
10.719 + E item = p.item;
10.720 + if (item != null) {
10.721 + nextNode = p;
10.722 + nextItem = item;
10.723 + return x;
10.724 + } else {
10.725 + // skip over nulls
10.726 + Node<E> next = succ(p);
10.727 + if (pred != null && next != null)
10.728 + pred.casNext(p, next);
10.729 + p = next;
10.730 + }
10.731 + }
10.732 + }
10.733 +
10.734 + public boolean hasNext() {
10.735 + return nextNode != null;
10.736 + }
10.737 +
10.738 + public E next() {
10.739 + if (nextNode == null) throw new NoSuchElementException();
10.740 + return advance();
10.741 + }
10.742 +
10.743 + public void remove() {
10.744 + Node<E> l = lastRet;
10.745 + if (l == null) throw new IllegalStateException();
10.746 + // rely on a future traversal to relink.
10.747 + l.item = null;
10.748 + lastRet = null;
10.749 + }
10.750 + }
10.751 +
10.752 + /**
10.753 + * Saves the state to a stream (that is, serializes it).
10.754 + *
10.755 + * @serialData All of the elements (each an {@code E}) in
10.756 + * the proper order, followed by a null
10.757 + * @param s the stream
10.758 + */
10.759 + private void writeObject(java.io.ObjectOutputStream s)
10.760 + throws java.io.IOException {
10.761 +
10.762 + // Write out any hidden stuff
10.763 + s.defaultWriteObject();
10.764 +
10.765 + // Write out all elements in the proper order.
10.766 + for (Node<E> p = first(); p != null; p = succ(p)) {
10.767 + Object item = p.item;
10.768 + if (item != null)
10.769 + s.writeObject(item);
10.770 + }
10.771 +
10.772 + // Use trailing null as sentinel
10.773 + s.writeObject(null);
10.774 + }
10.775 +
10.776 + /**
10.777 + * Reconstitutes the instance from a stream (that is, deserializes it).
10.778 + * @param s the stream
10.779 + */
10.780 + private void readObject(java.io.ObjectInputStream s)
10.781 + throws java.io.IOException, ClassNotFoundException {
10.782 + s.defaultReadObject();
10.783 +
10.784 + // Read in elements until trailing null sentinel found
10.785 + Node<E> h = null, t = null;
10.786 + Object item;
10.787 + while ((item = s.readObject()) != null) {
10.788 + @SuppressWarnings("unchecked")
10.789 + Node<E> newNode = new Node<E>((E) item);
10.790 + if (h == null)
10.791 + h = t = newNode;
10.792 + else {
10.793 + t.lazySetNext(newNode);
10.794 + t = newNode;
10.795 + }
10.796 + }
10.797 + if (h == null)
10.798 + h = t = new Node<E>(null);
10.799 + head = h;
10.800 + tail = t;
10.801 + }
10.802 +
10.803 + /**
10.804 + * Throws NullPointerException if argument is null.
10.805 + *
10.806 + * @param v the element
10.807 + */
10.808 + private static void checkNotNull(Object v) {
10.809 + if (v == null)
10.810 + throw new NullPointerException();
10.811 + }
10.812 +
10.813 + private boolean casTail(Node<E> cmp, Node<E> val) {
10.814 + return UNSAFE.compareAndSwapObject(this, tailOffset, cmp, val);
10.815 + }
10.816 +
10.817 + private boolean casHead(Node<E> cmp, Node<E> val) {
10.818 + return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
10.819 + }
10.820 +
10.821 + // Unsafe mechanics
10.822 +
10.823 + private static final sun.misc.Unsafe UNSAFE;
10.824 + private static final long headOffset;
10.825 + private static final long tailOffset;
10.826 + static {
10.827 + try {
10.828 + UNSAFE = sun.misc.Unsafe.getUnsafe();
10.829 + Class k = ConcurrentLinkedQueue.class;
10.830 + headOffset = UNSAFE.objectFieldOffset
10.831 + (k.getDeclaredField("head"));
10.832 + tailOffset = UNSAFE.objectFieldOffset
10.833 + (k.getDeclaredField("tail"));
10.834 + } catch (Exception e) {
10.835 + throw new Error(e);
10.836 + }
10.837 + }
10.838 +}
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ConcurrentNavigableMap.java Sat Mar 19 10:46:31 2016 +0100
11.3 @@ -0,0 +1,177 @@
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 +
11.42 +/**
11.43 + * A {@link ConcurrentMap} supporting {@link NavigableMap} operations,
11.44 + * and recursively so for its navigable sub-maps.
11.45 + *
11.46 + * <p>This interface is a member of the
11.47 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
11.48 + * Java Collections Framework</a>.
11.49 + *
11.50 + * @author Doug Lea
11.51 + * @param <K> the type of keys maintained by this map
11.52 + * @param <V> the type of mapped values
11.53 + * @since 1.6
11.54 + */
11.55 +public interface ConcurrentNavigableMap<K,V>
11.56 + extends ConcurrentMap<K,V>, NavigableMap<K,V>
11.57 +{
11.58 + /**
11.59 + * @throws ClassCastException {@inheritDoc}
11.60 + * @throws NullPointerException {@inheritDoc}
11.61 + * @throws IllegalArgumentException {@inheritDoc}
11.62 + */
11.63 + ConcurrentNavigableMap<K,V> subMap(K fromKey, boolean fromInclusive,
11.64 + K toKey, boolean toInclusive);
11.65 +
11.66 + /**
11.67 + * @throws ClassCastException {@inheritDoc}
11.68 + * @throws NullPointerException {@inheritDoc}
11.69 + * @throws IllegalArgumentException {@inheritDoc}
11.70 + */
11.71 + ConcurrentNavigableMap<K,V> headMap(K toKey, boolean inclusive);
11.72 +
11.73 +
11.74 + /**
11.75 + * @throws ClassCastException {@inheritDoc}
11.76 + * @throws NullPointerException {@inheritDoc}
11.77 + * @throws IllegalArgumentException {@inheritDoc}
11.78 + */
11.79 + ConcurrentNavigableMap<K,V> tailMap(K fromKey, boolean inclusive);
11.80 +
11.81 + /**
11.82 + * @throws ClassCastException {@inheritDoc}
11.83 + * @throws NullPointerException {@inheritDoc}
11.84 + * @throws IllegalArgumentException {@inheritDoc}
11.85 + */
11.86 + ConcurrentNavigableMap<K,V> subMap(K fromKey, K toKey);
11.87 +
11.88 + /**
11.89 + * @throws ClassCastException {@inheritDoc}
11.90 + * @throws NullPointerException {@inheritDoc}
11.91 + * @throws IllegalArgumentException {@inheritDoc}
11.92 + */
11.93 + ConcurrentNavigableMap<K,V> headMap(K toKey);
11.94 +
11.95 + /**
11.96 + * @throws ClassCastException {@inheritDoc}
11.97 + * @throws NullPointerException {@inheritDoc}
11.98 + * @throws IllegalArgumentException {@inheritDoc}
11.99 + */
11.100 + ConcurrentNavigableMap<K,V> tailMap(K fromKey);
11.101 +
11.102 + /**
11.103 + * Returns a reverse order view of the mappings contained in this map.
11.104 + * The descending map is backed by this map, so changes to the map are
11.105 + * reflected in the descending map, and vice-versa.
11.106 + *
11.107 + * <p>The returned map has an ordering equivalent to
11.108 + * <tt>{@link Collections#reverseOrder(Comparator) Collections.reverseOrder}(comparator())</tt>.
11.109 + * The expression {@code m.descendingMap().descendingMap()} returns a
11.110 + * view of {@code m} essentially equivalent to {@code m}.
11.111 + *
11.112 + * @return a reverse order view of this map
11.113 + */
11.114 + ConcurrentNavigableMap<K,V> descendingMap();
11.115 +
11.116 + /**
11.117 + * Returns a {@link NavigableSet} view of the keys contained in this map.
11.118 + * The set's iterator returns the keys in ascending order.
11.119 + * The set is backed by the map, so changes to the map are
11.120 + * reflected in the set, and vice-versa. The set supports element
11.121 + * removal, which removes the corresponding mapping from the map,
11.122 + * via the {@code Iterator.remove}, {@code Set.remove},
11.123 + * {@code removeAll}, {@code retainAll}, and {@code clear}
11.124 + * operations. It does not support the {@code add} or {@code addAll}
11.125 + * operations.
11.126 + *
11.127 + * <p>The view's {@code iterator} is a "weakly consistent" iterator
11.128 + * that will never throw {@link ConcurrentModificationException},
11.129 + * and guarantees to traverse elements as they existed upon
11.130 + * construction of the iterator, and may (but is not guaranteed to)
11.131 + * reflect any modifications subsequent to construction.
11.132 + *
11.133 + * @return a navigable set view of the keys in this map
11.134 + */
11.135 + public NavigableSet<K> navigableKeySet();
11.136 +
11.137 + /**
11.138 + * Returns a {@link NavigableSet} view of the keys contained in this map.
11.139 + * The set's iterator returns the keys in ascending order.
11.140 + * The set is backed by the map, so changes to the map are
11.141 + * reflected in the set, and vice-versa. The set supports element
11.142 + * removal, which removes the corresponding mapping from the map,
11.143 + * via the {@code Iterator.remove}, {@code Set.remove},
11.144 + * {@code removeAll}, {@code retainAll}, and {@code clear}
11.145 + * operations. It does not support the {@code add} or {@code addAll}
11.146 + * operations.
11.147 + *
11.148 + * <p>The view's {@code iterator} is a "weakly consistent" iterator
11.149 + * that will never throw {@link ConcurrentModificationException},
11.150 + * and guarantees to traverse elements as they existed upon
11.151 + * construction of the iterator, and may (but is not guaranteed to)
11.152 + * reflect any modifications subsequent to construction.
11.153 + *
11.154 + * <p>This method is equivalent to method {@code navigableKeySet}.
11.155 + *
11.156 + * @return a navigable set view of the keys in this map
11.157 + */
11.158 + NavigableSet<K> keySet();
11.159 +
11.160 + /**
11.161 + * Returns a reverse order {@link NavigableSet} view of the keys contained in this map.
11.162 + * The set's iterator returns the keys in descending order.
11.163 + * The set is backed by the map, so changes to the map are
11.164 + * reflected in the set, and vice-versa. The set supports element
11.165 + * removal, which removes the corresponding mapping from the map,
11.166 + * via the {@code Iterator.remove}, {@code Set.remove},
11.167 + * {@code removeAll}, {@code retainAll}, and {@code clear}
11.168 + * operations. It does not support the {@code add} or {@code addAll}
11.169 + * operations.
11.170 + *
11.171 + * <p>The view's {@code iterator} is a "weakly consistent" iterator
11.172 + * that will never throw {@link ConcurrentModificationException},
11.173 + * and guarantees to traverse elements as they existed upon
11.174 + * construction of the iterator, and may (but is not guaranteed to)
11.175 + * reflect any modifications subsequent to construction.
11.176 + *
11.177 + * @return a reverse order navigable set view of the keys in this map
11.178 + */
11.179 + public NavigableSet<K> descendingKeySet();
11.180 +}
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ConcurrentSkipListMap.java Sat Mar 19 10:46:31 2016 +0100
12.3 @@ -0,0 +1,3119 @@
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 java.util.concurrent.atomic.*;
12.42 +
12.43 +/**
12.44 + * A scalable concurrent {@link ConcurrentNavigableMap} implementation.
12.45 + * The map is sorted according to the {@linkplain Comparable natural
12.46 + * ordering} of its keys, or by a {@link Comparator} provided at map
12.47 + * creation time, depending on which constructor is used.
12.48 + *
12.49 + * <p>This class implements a concurrent variant of <a
12.50 + * href="http://en.wikipedia.org/wiki/Skip_list" target="_top">SkipLists</a>
12.51 + * providing expected average <i>log(n)</i> time cost for the
12.52 + * <tt>containsKey</tt>, <tt>get</tt>, <tt>put</tt> and
12.53 + * <tt>remove</tt> operations and their variants. Insertion, removal,
12.54 + * update, and access operations safely execute concurrently by
12.55 + * multiple threads. Iterators are <i>weakly consistent</i>, returning
12.56 + * elements reflecting the state of the map at some point at or since
12.57 + * the creation of the iterator. They do <em>not</em> throw {@link
12.58 + * ConcurrentModificationException}, and may proceed concurrently with
12.59 + * other operations. Ascending key ordered views and their iterators
12.60 + * are faster than descending ones.
12.61 + *
12.62 + * <p>All <tt>Map.Entry</tt> pairs returned by methods in this class
12.63 + * and its views represent snapshots of mappings at the time they were
12.64 + * produced. They do <em>not</em> support the <tt>Entry.setValue</tt>
12.65 + * method. (Note however that it is possible to change mappings in the
12.66 + * associated map using <tt>put</tt>, <tt>putIfAbsent</tt>, or
12.67 + * <tt>replace</tt>, depending on exactly which effect you need.)
12.68 + *
12.69 + * <p>Beware that, unlike in most collections, the <tt>size</tt>
12.70 + * method is <em>not</em> a constant-time operation. Because of the
12.71 + * asynchronous nature of these maps, determining the current number
12.72 + * of elements requires a traversal of the elements, and so may report
12.73 + * inaccurate results if this collection is modified during traversal.
12.74 + * Additionally, the bulk operations <tt>putAll</tt>, <tt>equals</tt>,
12.75 + * <tt>toArray</tt>, <tt>containsValue</tt>, and <tt>clear</tt> are
12.76 + * <em>not</em> guaranteed to be performed atomically. For example, an
12.77 + * iterator operating concurrently with a <tt>putAll</tt> operation
12.78 + * might view only some of the added elements.
12.79 + *
12.80 + * <p>This class and its views and iterators implement all of the
12.81 + * <em>optional</em> methods of the {@link Map} and {@link Iterator}
12.82 + * interfaces. Like most other concurrent collections, this class does
12.83 + * <em>not</em> permit the use of <tt>null</tt> keys or values because some
12.84 + * null return values cannot be reliably distinguished from the absence of
12.85 + * elements.
12.86 + *
12.87 + * <p>This class is a member of the
12.88 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
12.89 + * Java Collections Framework</a>.
12.90 + *
12.91 + * @author Doug Lea
12.92 + * @param <K> the type of keys maintained by this map
12.93 + * @param <V> the type of mapped values
12.94 + * @since 1.6
12.95 + */
12.96 +public class ConcurrentSkipListMap<K,V> extends AbstractMap<K,V>
12.97 + implements ConcurrentNavigableMap<K,V>,
12.98 + Cloneable,
12.99 + java.io.Serializable {
12.100 + /*
12.101 + * This class implements a tree-like two-dimensionally linked skip
12.102 + * list in which the index levels are represented in separate
12.103 + * nodes from the base nodes holding data. There are two reasons
12.104 + * for taking this approach instead of the usual array-based
12.105 + * structure: 1) Array based implementations seem to encounter
12.106 + * more complexity and overhead 2) We can use cheaper algorithms
12.107 + * for the heavily-traversed index lists than can be used for the
12.108 + * base lists. Here's a picture of some of the basics for a
12.109 + * possible list with 2 levels of index:
12.110 + *
12.111 + * Head nodes Index nodes
12.112 + * +-+ right +-+ +-+
12.113 + * |2|---------------->| |--------------------->| |->null
12.114 + * +-+ +-+ +-+
12.115 + * | down | |
12.116 + * v v v
12.117 + * +-+ +-+ +-+ +-+ +-+ +-+
12.118 + * |1|----------->| |->| |------>| |----------->| |------>| |->null
12.119 + * +-+ +-+ +-+ +-+ +-+ +-+
12.120 + * v | | | | |
12.121 + * Nodes next v v v v v
12.122 + * +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+
12.123 + * | |->|A|->|B|->|C|->|D|->|E|->|F|->|G|->|H|->|I|->|J|->|K|->null
12.124 + * +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+
12.125 + *
12.126 + * The base lists use a variant of the HM linked ordered set
12.127 + * algorithm. See Tim Harris, "A pragmatic implementation of
12.128 + * non-blocking linked lists"
12.129 + * http://www.cl.cam.ac.uk/~tlh20/publications.html and Maged
12.130 + * Michael "High Performance Dynamic Lock-Free Hash Tables and
12.131 + * List-Based Sets"
12.132 + * http://www.research.ibm.com/people/m/michael/pubs.htm. The
12.133 + * basic idea in these lists is to mark the "next" pointers of
12.134 + * deleted nodes when deleting to avoid conflicts with concurrent
12.135 + * insertions, and when traversing to keep track of triples
12.136 + * (predecessor, node, successor) in order to detect when and how
12.137 + * to unlink these deleted nodes.
12.138 + *
12.139 + * Rather than using mark-bits to mark list deletions (which can
12.140 + * be slow and space-intensive using AtomicMarkedReference), nodes
12.141 + * use direct CAS'able next pointers. On deletion, instead of
12.142 + * marking a pointer, they splice in another node that can be
12.143 + * thought of as standing for a marked pointer (indicating this by
12.144 + * using otherwise impossible field values). Using plain nodes
12.145 + * acts roughly like "boxed" implementations of marked pointers,
12.146 + * but uses new nodes only when nodes are deleted, not for every
12.147 + * link. This requires less space and supports faster
12.148 + * traversal. Even if marked references were better supported by
12.149 + * JVMs, traversal using this technique might still be faster
12.150 + * because any search need only read ahead one more node than
12.151 + * otherwise required (to check for trailing marker) rather than
12.152 + * unmasking mark bits or whatever on each read.
12.153 + *
12.154 + * This approach maintains the essential property needed in the HM
12.155 + * algorithm of changing the next-pointer of a deleted node so
12.156 + * that any other CAS of it will fail, but implements the idea by
12.157 + * changing the pointer to point to a different node, not by
12.158 + * marking it. While it would be possible to further squeeze
12.159 + * space by defining marker nodes not to have key/value fields, it
12.160 + * isn't worth the extra type-testing overhead. The deletion
12.161 + * markers are rarely encountered during traversal and are
12.162 + * normally quickly garbage collected. (Note that this technique
12.163 + * would not work well in systems without garbage collection.)
12.164 + *
12.165 + * In addition to using deletion markers, the lists also use
12.166 + * nullness of value fields to indicate deletion, in a style
12.167 + * similar to typical lazy-deletion schemes. If a node's value is
12.168 + * null, then it is considered logically deleted and ignored even
12.169 + * though it is still reachable. This maintains proper control of
12.170 + * concurrent replace vs delete operations -- an attempted replace
12.171 + * must fail if a delete beat it by nulling field, and a delete
12.172 + * must return the last non-null value held in the field. (Note:
12.173 + * Null, rather than some special marker, is used for value fields
12.174 + * here because it just so happens to mesh with the Map API
12.175 + * requirement that method get returns null if there is no
12.176 + * mapping, which allows nodes to remain concurrently readable
12.177 + * even when deleted. Using any other marker value here would be
12.178 + * messy at best.)
12.179 + *
12.180 + * Here's the sequence of events for a deletion of node n with
12.181 + * predecessor b and successor f, initially:
12.182 + *
12.183 + * +------+ +------+ +------+
12.184 + * ... | b |------>| n |----->| f | ...
12.185 + * +------+ +------+ +------+
12.186 + *
12.187 + * 1. CAS n's value field from non-null to null.
12.188 + * From this point on, no public operations encountering
12.189 + * the node consider this mapping to exist. However, other
12.190 + * ongoing insertions and deletions might still modify
12.191 + * n's next pointer.
12.192 + *
12.193 + * 2. CAS n's next pointer to point to a new marker node.
12.194 + * From this point on, no other nodes can be appended to n.
12.195 + * which avoids deletion errors in CAS-based linked lists.
12.196 + *
12.197 + * +------+ +------+ +------+ +------+
12.198 + * ... | b |------>| n |----->|marker|------>| f | ...
12.199 + * +------+ +------+ +------+ +------+
12.200 + *
12.201 + * 3. CAS b's next pointer over both n and its marker.
12.202 + * From this point on, no new traversals will encounter n,
12.203 + * and it can eventually be GCed.
12.204 + * +------+ +------+
12.205 + * ... | b |----------------------------------->| f | ...
12.206 + * +------+ +------+
12.207 + *
12.208 + * A failure at step 1 leads to simple retry due to a lost race
12.209 + * with another operation. Steps 2-3 can fail because some other
12.210 + * thread noticed during a traversal a node with null value and
12.211 + * helped out by marking and/or unlinking. This helping-out
12.212 + * ensures that no thread can become stuck waiting for progress of
12.213 + * the deleting thread. The use of marker nodes slightly
12.214 + * complicates helping-out code because traversals must track
12.215 + * consistent reads of up to four nodes (b, n, marker, f), not
12.216 + * just (b, n, f), although the next field of a marker is
12.217 + * immutable, and once a next field is CAS'ed to point to a
12.218 + * marker, it never again changes, so this requires less care.
12.219 + *
12.220 + * Skip lists add indexing to this scheme, so that the base-level
12.221 + * traversals start close to the locations being found, inserted
12.222 + * or deleted -- usually base level traversals only traverse a few
12.223 + * nodes. This doesn't change the basic algorithm except for the
12.224 + * need to make sure base traversals start at predecessors (here,
12.225 + * b) that are not (structurally) deleted, otherwise retrying
12.226 + * after processing the deletion.
12.227 + *
12.228 + * Index levels are maintained as lists with volatile next fields,
12.229 + * using CAS to link and unlink. Races are allowed in index-list
12.230 + * operations that can (rarely) fail to link in a new index node
12.231 + * or delete one. (We can't do this of course for data nodes.)
12.232 + * However, even when this happens, the index lists remain sorted,
12.233 + * so correctly serve as indices. This can impact performance,
12.234 + * but since skip lists are probabilistic anyway, the net result
12.235 + * is that under contention, the effective "p" value may be lower
12.236 + * than its nominal value. And race windows are kept small enough
12.237 + * that in practice these failures are rare, even under a lot of
12.238 + * contention.
12.239 + *
12.240 + * The fact that retries (for both base and index lists) are
12.241 + * relatively cheap due to indexing allows some minor
12.242 + * simplifications of retry logic. Traversal restarts are
12.243 + * performed after most "helping-out" CASes. This isn't always
12.244 + * strictly necessary, but the implicit backoffs tend to help
12.245 + * reduce other downstream failed CAS's enough to outweigh restart
12.246 + * cost. This worsens the worst case, but seems to improve even
12.247 + * highly contended cases.
12.248 + *
12.249 + * Unlike most skip-list implementations, index insertion and
12.250 + * deletion here require a separate traversal pass occuring after
12.251 + * the base-level action, to add or remove index nodes. This adds
12.252 + * to single-threaded overhead, but improves contended
12.253 + * multithreaded performance by narrowing interference windows,
12.254 + * and allows deletion to ensure that all index nodes will be made
12.255 + * unreachable upon return from a public remove operation, thus
12.256 + * avoiding unwanted garbage retention. This is more important
12.257 + * here than in some other data structures because we cannot null
12.258 + * out node fields referencing user keys since they might still be
12.259 + * read by other ongoing traversals.
12.260 + *
12.261 + * Indexing uses skip list parameters that maintain good search
12.262 + * performance while using sparser-than-usual indices: The
12.263 + * hardwired parameters k=1, p=0.5 (see method randomLevel) mean
12.264 + * that about one-quarter of the nodes have indices. Of those that
12.265 + * do, half have one level, a quarter have two, and so on (see
12.266 + * Pugh's Skip List Cookbook, sec 3.4). The expected total space
12.267 + * requirement for a map is slightly less than for the current
12.268 + * implementation of java.util.TreeMap.
12.269 + *
12.270 + * Changing the level of the index (i.e, the height of the
12.271 + * tree-like structure) also uses CAS. The head index has initial
12.272 + * level/height of one. Creation of an index with height greater
12.273 + * than the current level adds a level to the head index by
12.274 + * CAS'ing on a new top-most head. To maintain good performance
12.275 + * after a lot of removals, deletion methods heuristically try to
12.276 + * reduce the height if the topmost levels appear to be empty.
12.277 + * This may encounter races in which it possible (but rare) to
12.278 + * reduce and "lose" a level just as it is about to contain an
12.279 + * index (that will then never be encountered). This does no
12.280 + * structural harm, and in practice appears to be a better option
12.281 + * than allowing unrestrained growth of levels.
12.282 + *
12.283 + * The code for all this is more verbose than you'd like. Most
12.284 + * operations entail locating an element (or position to insert an
12.285 + * element). The code to do this can't be nicely factored out
12.286 + * because subsequent uses require a snapshot of predecessor
12.287 + * and/or successor and/or value fields which can't be returned
12.288 + * all at once, at least not without creating yet another object
12.289 + * to hold them -- creating such little objects is an especially
12.290 + * bad idea for basic internal search operations because it adds
12.291 + * to GC overhead. (This is one of the few times I've wished Java
12.292 + * had macros.) Instead, some traversal code is interleaved within
12.293 + * insertion and removal operations. The control logic to handle
12.294 + * all the retry conditions is sometimes twisty. Most search is
12.295 + * broken into 2 parts. findPredecessor() searches index nodes
12.296 + * only, returning a base-level predecessor of the key. findNode()
12.297 + * finishes out the base-level search. Even with this factoring,
12.298 + * there is a fair amount of near-duplication of code to handle
12.299 + * variants.
12.300 + *
12.301 + * For explanation of algorithms sharing at least a couple of
12.302 + * features with this one, see Mikhail Fomitchev's thesis
12.303 + * (http://www.cs.yorku.ca/~mikhail/), Keir Fraser's thesis
12.304 + * (http://www.cl.cam.ac.uk/users/kaf24/), and Hakan Sundell's
12.305 + * thesis (http://www.cs.chalmers.se/~phs/).
12.306 + *
12.307 + * Given the use of tree-like index nodes, you might wonder why
12.308 + * this doesn't use some kind of search tree instead, which would
12.309 + * support somewhat faster search operations. The reason is that
12.310 + * there are no known efficient lock-free insertion and deletion
12.311 + * algorithms for search trees. The immutability of the "down"
12.312 + * links of index nodes (as opposed to mutable "left" fields in
12.313 + * true trees) makes this tractable using only CAS operations.
12.314 + *
12.315 + * Notation guide for local variables
12.316 + * Node: b, n, f for predecessor, node, successor
12.317 + * Index: q, r, d for index node, right, down.
12.318 + * t for another index node
12.319 + * Head: h
12.320 + * Levels: j
12.321 + * Keys: k, key
12.322 + * Values: v, value
12.323 + * Comparisons: c
12.324 + */
12.325 +
12.326 + private static final long serialVersionUID = -8627078645895051609L;
12.327 +
12.328 + /**
12.329 + * Generates the initial random seed for the cheaper per-instance
12.330 + * random number generators used in randomLevel.
12.331 + */
12.332 + private static final Random seedGenerator = new Random();
12.333 +
12.334 + /**
12.335 + * Special value used to identify base-level header
12.336 + */
12.337 + private static final Object BASE_HEADER = new Object();
12.338 +
12.339 + /**
12.340 + * The topmost head index of the skiplist.
12.341 + */
12.342 + private transient volatile HeadIndex<K,V> head;
12.343 +
12.344 + /**
12.345 + * The comparator used to maintain order in this map, or null
12.346 + * if using natural ordering.
12.347 + * @serial
12.348 + */
12.349 + private final Comparator<? super K> comparator;
12.350 +
12.351 + /**
12.352 + * Seed for simple random number generator. Not volatile since it
12.353 + * doesn't matter too much if different threads don't see updates.
12.354 + */
12.355 + private transient int randomSeed;
12.356 +
12.357 + /** Lazily initialized key set */
12.358 + private transient KeySet keySet;
12.359 + /** Lazily initialized entry set */
12.360 + private transient EntrySet entrySet;
12.361 + /** Lazily initialized values collection */
12.362 + private transient Values values;
12.363 + /** Lazily initialized descending key set */
12.364 + private transient ConcurrentNavigableMap<K,V> descendingMap;
12.365 +
12.366 + /**
12.367 + * Initializes or resets state. Needed by constructors, clone,
12.368 + * clear, readObject. and ConcurrentSkipListSet.clone.
12.369 + * (Note that comparator must be separately initialized.)
12.370 + */
12.371 + final void initialize() {
12.372 + keySet = null;
12.373 + entrySet = null;
12.374 + values = null;
12.375 + descendingMap = null;
12.376 + randomSeed = seedGenerator.nextInt() | 0x0100; // ensure nonzero
12.377 + head = new HeadIndex<K,V>(new Node<K,V>(null, BASE_HEADER, null),
12.378 + null, null, 1);
12.379 + }
12.380 +
12.381 + /**
12.382 + * compareAndSet head node
12.383 + */
12.384 + private boolean casHead(HeadIndex<K,V> cmp, HeadIndex<K,V> val) {
12.385 + return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
12.386 + }
12.387 +
12.388 + /* ---------------- Nodes -------------- */
12.389 +
12.390 + /**
12.391 + * Nodes hold keys and values, and are singly linked in sorted
12.392 + * order, possibly with some intervening marker nodes. The list is
12.393 + * headed by a dummy node accessible as head.node. The value field
12.394 + * is declared only as Object because it takes special non-V
12.395 + * values for marker and header nodes.
12.396 + */
12.397 + static final class Node<K,V> {
12.398 + final K key;
12.399 + volatile Object value;
12.400 + volatile Node<K,V> next;
12.401 +
12.402 + /**
12.403 + * Creates a new regular node.
12.404 + */
12.405 + Node(K key, Object value, Node<K,V> next) {
12.406 + this.key = key;
12.407 + this.value = value;
12.408 + this.next = next;
12.409 + }
12.410 +
12.411 + /**
12.412 + * Creates a new marker node. A marker is distinguished by
12.413 + * having its value field point to itself. Marker nodes also
12.414 + * have null keys, a fact that is exploited in a few places,
12.415 + * but this doesn't distinguish markers from the base-level
12.416 + * header node (head.node), which also has a null key.
12.417 + */
12.418 + Node(Node<K,V> next) {
12.419 + this.key = null;
12.420 + this.value = this;
12.421 + this.next = next;
12.422 + }
12.423 +
12.424 + /**
12.425 + * compareAndSet value field
12.426 + */
12.427 + boolean casValue(Object cmp, Object val) {
12.428 + return UNSAFE.compareAndSwapObject(this, valueOffset, cmp, val);
12.429 + }
12.430 +
12.431 + /**
12.432 + * compareAndSet next field
12.433 + */
12.434 + boolean casNext(Node<K,V> cmp, Node<K,V> val) {
12.435 + return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
12.436 + }
12.437 +
12.438 + /**
12.439 + * Returns true if this node is a marker. This method isn't
12.440 + * actually called in any current code checking for markers
12.441 + * because callers will have already read value field and need
12.442 + * to use that read (not another done here) and so directly
12.443 + * test if value points to node.
12.444 + * @param n a possibly null reference to a node
12.445 + * @return true if this node is a marker node
12.446 + */
12.447 + boolean isMarker() {
12.448 + return value == this;
12.449 + }
12.450 +
12.451 + /**
12.452 + * Returns true if this node is the header of base-level list.
12.453 + * @return true if this node is header node
12.454 + */
12.455 + boolean isBaseHeader() {
12.456 + return value == BASE_HEADER;
12.457 + }
12.458 +
12.459 + /**
12.460 + * Tries to append a deletion marker to this node.
12.461 + * @param f the assumed current successor of this node
12.462 + * @return true if successful
12.463 + */
12.464 + boolean appendMarker(Node<K,V> f) {
12.465 + return casNext(f, new Node<K,V>(f));
12.466 + }
12.467 +
12.468 + /**
12.469 + * Helps out a deletion by appending marker or unlinking from
12.470 + * predecessor. This is called during traversals when value
12.471 + * field seen to be null.
12.472 + * @param b predecessor
12.473 + * @param f successor
12.474 + */
12.475 + void helpDelete(Node<K,V> b, Node<K,V> f) {
12.476 + /*
12.477 + * Rechecking links and then doing only one of the
12.478 + * help-out stages per call tends to minimize CAS
12.479 + * interference among helping threads.
12.480 + */
12.481 + if (f == next && this == b.next) {
12.482 + if (f == null || f.value != f) // not already marked
12.483 + appendMarker(f);
12.484 + else
12.485 + b.casNext(this, f.next);
12.486 + }
12.487 + }
12.488 +
12.489 + /**
12.490 + * Returns value if this node contains a valid key-value pair,
12.491 + * else null.
12.492 + * @return this node's value if it isn't a marker or header or
12.493 + * is deleted, else null.
12.494 + */
12.495 + V getValidValue() {
12.496 + Object v = value;
12.497 + if (v == this || v == BASE_HEADER)
12.498 + return null;
12.499 + return (V)v;
12.500 + }
12.501 +
12.502 + /**
12.503 + * Creates and returns a new SimpleImmutableEntry holding current
12.504 + * mapping if this node holds a valid value, else null.
12.505 + * @return new entry or null
12.506 + */
12.507 + AbstractMap.SimpleImmutableEntry<K,V> createSnapshot() {
12.508 + V v = getValidValue();
12.509 + if (v == null)
12.510 + return null;
12.511 + return new AbstractMap.SimpleImmutableEntry<K,V>(key, v);
12.512 + }
12.513 +
12.514 + // UNSAFE mechanics
12.515 +
12.516 + private static final sun.misc.Unsafe UNSAFE;
12.517 + private static final long valueOffset;
12.518 + private static final long nextOffset;
12.519 +
12.520 + static {
12.521 + try {
12.522 + UNSAFE = sun.misc.Unsafe.getUnsafe();
12.523 + Class k = Node.class;
12.524 + valueOffset = UNSAFE.objectFieldOffset
12.525 + (k.getDeclaredField("value"));
12.526 + nextOffset = UNSAFE.objectFieldOffset
12.527 + (k.getDeclaredField("next"));
12.528 + } catch (Exception e) {
12.529 + throw new Error(e);
12.530 + }
12.531 + }
12.532 + }
12.533 +
12.534 + /* ---------------- Indexing -------------- */
12.535 +
12.536 + /**
12.537 + * Index nodes represent the levels of the skip list. Note that
12.538 + * even though both Nodes and Indexes have forward-pointing
12.539 + * fields, they have different types and are handled in different
12.540 + * ways, that can't nicely be captured by placing field in a
12.541 + * shared abstract class.
12.542 + */
12.543 + static class Index<K,V> {
12.544 + final Node<K,V> node;
12.545 + final Index<K,V> down;
12.546 + volatile Index<K,V> right;
12.547 +
12.548 + /**
12.549 + * Creates index node with given values.
12.550 + */
12.551 + Index(Node<K,V> node, Index<K,V> down, Index<K,V> right) {
12.552 + this.node = node;
12.553 + this.down = down;
12.554 + this.right = right;
12.555 + }
12.556 +
12.557 + /**
12.558 + * compareAndSet right field
12.559 + */
12.560 + final boolean casRight(Index<K,V> cmp, Index<K,V> val) {
12.561 + return UNSAFE.compareAndSwapObject(this, rightOffset, cmp, val);
12.562 + }
12.563 +
12.564 + /**
12.565 + * Returns true if the node this indexes has been deleted.
12.566 + * @return true if indexed node is known to be deleted
12.567 + */
12.568 + final boolean indexesDeletedNode() {
12.569 + return node.value == null;
12.570 + }
12.571 +
12.572 + /**
12.573 + * Tries to CAS newSucc as successor. To minimize races with
12.574 + * unlink that may lose this index node, if the node being
12.575 + * indexed is known to be deleted, it doesn't try to link in.
12.576 + * @param succ the expected current successor
12.577 + * @param newSucc the new successor
12.578 + * @return true if successful
12.579 + */
12.580 + final boolean link(Index<K,V> succ, Index<K,V> newSucc) {
12.581 + Node<K,V> n = node;
12.582 + newSucc.right = succ;
12.583 + return n.value != null && casRight(succ, newSucc);
12.584 + }
12.585 +
12.586 + /**
12.587 + * Tries to CAS right field to skip over apparent successor
12.588 + * succ. Fails (forcing a retraversal by caller) if this node
12.589 + * is known to be deleted.
12.590 + * @param succ the expected current successor
12.591 + * @return true if successful
12.592 + */
12.593 + final boolean unlink(Index<K,V> succ) {
12.594 + return !indexesDeletedNode() && casRight(succ, succ.right);
12.595 + }
12.596 +
12.597 + // Unsafe mechanics
12.598 + private static final sun.misc.Unsafe UNSAFE;
12.599 + private static final long rightOffset;
12.600 + static {
12.601 + try {
12.602 + UNSAFE = sun.misc.Unsafe.getUnsafe();
12.603 + Class k = Index.class;
12.604 + rightOffset = UNSAFE.objectFieldOffset
12.605 + (k.getDeclaredField("right"));
12.606 + } catch (Exception e) {
12.607 + throw new Error(e);
12.608 + }
12.609 + }
12.610 + }
12.611 +
12.612 + /* ---------------- Head nodes -------------- */
12.613 +
12.614 + /**
12.615 + * Nodes heading each level keep track of their level.
12.616 + */
12.617 + static final class HeadIndex<K,V> extends Index<K,V> {
12.618 + final int level;
12.619 + HeadIndex(Node<K,V> node, Index<K,V> down, Index<K,V> right, int level) {
12.620 + super(node, down, right);
12.621 + this.level = level;
12.622 + }
12.623 + }
12.624 +
12.625 + /* ---------------- Comparison utilities -------------- */
12.626 +
12.627 + /**
12.628 + * Represents a key with a comparator as a Comparable.
12.629 + *
12.630 + * Because most sorted collections seem to use natural ordering on
12.631 + * Comparables (Strings, Integers, etc), most internal methods are
12.632 + * geared to use them. This is generally faster than checking
12.633 + * per-comparison whether to use comparator or comparable because
12.634 + * it doesn't require a (Comparable) cast for each comparison.
12.635 + * (Optimizers can only sometimes remove such redundant checks
12.636 + * themselves.) When Comparators are used,
12.637 + * ComparableUsingComparators are created so that they act in the
12.638 + * same way as natural orderings. This penalizes use of
12.639 + * Comparators vs Comparables, which seems like the right
12.640 + * tradeoff.
12.641 + */
12.642 + static final class ComparableUsingComparator<K> implements Comparable<K> {
12.643 + final K actualKey;
12.644 + final Comparator<? super K> cmp;
12.645 + ComparableUsingComparator(K key, Comparator<? super K> cmp) {
12.646 + this.actualKey = key;
12.647 + this.cmp = cmp;
12.648 + }
12.649 + public int compareTo(K k2) {
12.650 + return cmp.compare(actualKey, k2);
12.651 + }
12.652 + }
12.653 +
12.654 + /**
12.655 + * If using comparator, return a ComparableUsingComparator, else
12.656 + * cast key as Comparable, which may cause ClassCastException,
12.657 + * which is propagated back to caller.
12.658 + */
12.659 + private Comparable<? super K> comparable(Object key)
12.660 + throws ClassCastException {
12.661 + if (key == null)
12.662 + throw new NullPointerException();
12.663 + if (comparator != null)
12.664 + return new ComparableUsingComparator<K>((K)key, comparator);
12.665 + else
12.666 + return (Comparable<? super K>)key;
12.667 + }
12.668 +
12.669 + /**
12.670 + * Compares using comparator or natural ordering. Used when the
12.671 + * ComparableUsingComparator approach doesn't apply.
12.672 + */
12.673 + int compare(K k1, K k2) throws ClassCastException {
12.674 + Comparator<? super K> cmp = comparator;
12.675 + if (cmp != null)
12.676 + return cmp.compare(k1, k2);
12.677 + else
12.678 + return ((Comparable<? super K>)k1).compareTo(k2);
12.679 + }
12.680 +
12.681 + /**
12.682 + * Returns true if given key greater than or equal to least and
12.683 + * strictly less than fence, bypassing either test if least or
12.684 + * fence are null. Needed mainly in submap operations.
12.685 + */
12.686 + boolean inHalfOpenRange(K key, K least, K fence) {
12.687 + if (key == null)
12.688 + throw new NullPointerException();
12.689 + return ((least == null || compare(key, least) >= 0) &&
12.690 + (fence == null || compare(key, fence) < 0));
12.691 + }
12.692 +
12.693 + /**
12.694 + * Returns true if given key greater than or equal to least and less
12.695 + * or equal to fence. Needed mainly in submap operations.
12.696 + */
12.697 + boolean inOpenRange(K key, K least, K fence) {
12.698 + if (key == null)
12.699 + throw new NullPointerException();
12.700 + return ((least == null || compare(key, least) >= 0) &&
12.701 + (fence == null || compare(key, fence) <= 0));
12.702 + }
12.703 +
12.704 + /* ---------------- Traversal -------------- */
12.705 +
12.706 + /**
12.707 + * Returns a base-level node with key strictly less than given key,
12.708 + * or the base-level header if there is no such node. Also
12.709 + * unlinks indexes to deleted nodes found along the way. Callers
12.710 + * rely on this side-effect of clearing indices to deleted nodes.
12.711 + * @param key the key
12.712 + * @return a predecessor of key
12.713 + */
12.714 + private Node<K,V> findPredecessor(Comparable<? super K> key) {
12.715 + if (key == null)
12.716 + throw new NullPointerException(); // don't postpone errors
12.717 + for (;;) {
12.718 + Index<K,V> q = head;
12.719 + Index<K,V> r = q.right;
12.720 + for (;;) {
12.721 + if (r != null) {
12.722 + Node<K,V> n = r.node;
12.723 + K k = n.key;
12.724 + if (n.value == null) {
12.725 + if (!q.unlink(r))
12.726 + break; // restart
12.727 + r = q.right; // reread r
12.728 + continue;
12.729 + }
12.730 + if (key.compareTo(k) > 0) {
12.731 + q = r;
12.732 + r = r.right;
12.733 + continue;
12.734 + }
12.735 + }
12.736 + Index<K,V> d = q.down;
12.737 + if (d != null) {
12.738 + q = d;
12.739 + r = d.right;
12.740 + } else
12.741 + return q.node;
12.742 + }
12.743 + }
12.744 + }
12.745 +
12.746 + /**
12.747 + * Returns node holding key or null if no such, clearing out any
12.748 + * deleted nodes seen along the way. Repeatedly traverses at
12.749 + * base-level looking for key starting at predecessor returned
12.750 + * from findPredecessor, processing base-level deletions as
12.751 + * encountered. Some callers rely on this side-effect of clearing
12.752 + * deleted nodes.
12.753 + *
12.754 + * Restarts occur, at traversal step centered on node n, if:
12.755 + *
12.756 + * (1) After reading n's next field, n is no longer assumed
12.757 + * predecessor b's current successor, which means that
12.758 + * we don't have a consistent 3-node snapshot and so cannot
12.759 + * unlink any subsequent deleted nodes encountered.
12.760 + *
12.761 + * (2) n's value field is null, indicating n is deleted, in
12.762 + * which case we help out an ongoing structural deletion
12.763 + * before retrying. Even though there are cases where such
12.764 + * unlinking doesn't require restart, they aren't sorted out
12.765 + * here because doing so would not usually outweigh cost of
12.766 + * restarting.
12.767 + *
12.768 + * (3) n is a marker or n's predecessor's value field is null,
12.769 + * indicating (among other possibilities) that
12.770 + * findPredecessor returned a deleted node. We can't unlink
12.771 + * the node because we don't know its predecessor, so rely
12.772 + * on another call to findPredecessor to notice and return
12.773 + * some earlier predecessor, which it will do. This check is
12.774 + * only strictly needed at beginning of loop, (and the
12.775 + * b.value check isn't strictly needed at all) but is done
12.776 + * each iteration to help avoid contention with other
12.777 + * threads by callers that will fail to be able to change
12.778 + * links, and so will retry anyway.
12.779 + *
12.780 + * The traversal loops in doPut, doRemove, and findNear all
12.781 + * include the same three kinds of checks. And specialized
12.782 + * versions appear in findFirst, and findLast and their
12.783 + * variants. They can't easily share code because each uses the
12.784 + * reads of fields held in locals occurring in the orders they
12.785 + * were performed.
12.786 + *
12.787 + * @param key the key
12.788 + * @return node holding key, or null if no such
12.789 + */
12.790 + private Node<K,V> findNode(Comparable<? super K> key) {
12.791 + for (;;) {
12.792 + Node<K,V> b = findPredecessor(key);
12.793 + Node<K,V> n = b.next;
12.794 + for (;;) {
12.795 + if (n == null)
12.796 + return null;
12.797 + Node<K,V> f = n.next;
12.798 + if (n != b.next) // inconsistent read
12.799 + break;
12.800 + Object v = n.value;
12.801 + if (v == null) { // n is deleted
12.802 + n.helpDelete(b, f);
12.803 + break;
12.804 + }
12.805 + if (v == n || b.value == null) // b is deleted
12.806 + break;
12.807 + int c = key.compareTo(n.key);
12.808 + if (c == 0)
12.809 + return n;
12.810 + if (c < 0)
12.811 + return null;
12.812 + b = n;
12.813 + n = f;
12.814 + }
12.815 + }
12.816 + }
12.817 +
12.818 + /**
12.819 + * Gets value for key using findNode.
12.820 + * @param okey the key
12.821 + * @return the value, or null if absent
12.822 + */
12.823 + private V doGet(Object okey) {
12.824 + Comparable<? super K> key = comparable(okey);
12.825 + /*
12.826 + * Loop needed here and elsewhere in case value field goes
12.827 + * null just as it is about to be returned, in which case we
12.828 + * lost a race with a deletion, so must retry.
12.829 + */
12.830 + for (;;) {
12.831 + Node<K,V> n = findNode(key);
12.832 + if (n == null)
12.833 + return null;
12.834 + Object v = n.value;
12.835 + if (v != null)
12.836 + return (V)v;
12.837 + }
12.838 + }
12.839 +
12.840 + /* ---------------- Insertion -------------- */
12.841 +
12.842 + /**
12.843 + * Main insertion method. Adds element if not present, or
12.844 + * replaces value if present and onlyIfAbsent is false.
12.845 + * @param kkey the key
12.846 + * @param value the value that must be associated with key
12.847 + * @param onlyIfAbsent if should not insert if already present
12.848 + * @return the old value, or null if newly inserted
12.849 + */
12.850 + private V doPut(K kkey, V value, boolean onlyIfAbsent) {
12.851 + Comparable<? super K> key = comparable(kkey);
12.852 + for (;;) {
12.853 + Node<K,V> b = findPredecessor(key);
12.854 + Node<K,V> n = b.next;
12.855 + for (;;) {
12.856 + if (n != null) {
12.857 + Node<K,V> f = n.next;
12.858 + if (n != b.next) // inconsistent read
12.859 + break;
12.860 + Object v = n.value;
12.861 + if (v == null) { // n is deleted
12.862 + n.helpDelete(b, f);
12.863 + break;
12.864 + }
12.865 + if (v == n || b.value == null) // b is deleted
12.866 + break;
12.867 + int c = key.compareTo(n.key);
12.868 + if (c > 0) {
12.869 + b = n;
12.870 + n = f;
12.871 + continue;
12.872 + }
12.873 + if (c == 0) {
12.874 + if (onlyIfAbsent || n.casValue(v, value))
12.875 + return (V)v;
12.876 + else
12.877 + break; // restart if lost race to replace value
12.878 + }
12.879 + // else c < 0; fall through
12.880 + }
12.881 +
12.882 + Node<K,V> z = new Node<K,V>(kkey, value, n);
12.883 + if (!b.casNext(n, z))
12.884 + break; // restart if lost race to append to b
12.885 + int level = randomLevel();
12.886 + if (level > 0)
12.887 + insertIndex(z, level);
12.888 + return null;
12.889 + }
12.890 + }
12.891 + }
12.892 +
12.893 + /**
12.894 + * Returns a random level for inserting a new node.
12.895 + * Hardwired to k=1, p=0.5, max 31 (see above and
12.896 + * Pugh's "Skip List Cookbook", sec 3.4).
12.897 + *
12.898 + * This uses the simplest of the generators described in George
12.899 + * Marsaglia's "Xorshift RNGs" paper. This is not a high-quality
12.900 + * generator but is acceptable here.
12.901 + */
12.902 + private int randomLevel() {
12.903 + int x = randomSeed;
12.904 + x ^= x << 13;
12.905 + x ^= x >>> 17;
12.906 + randomSeed = x ^= x << 5;
12.907 + if ((x & 0x80000001) != 0) // test highest and lowest bits
12.908 + return 0;
12.909 + int level = 1;
12.910 + while (((x >>>= 1) & 1) != 0) ++level;
12.911 + return level;
12.912 + }
12.913 +
12.914 + /**
12.915 + * Creates and adds index nodes for the given node.
12.916 + * @param z the node
12.917 + * @param level the level of the index
12.918 + */
12.919 + private void insertIndex(Node<K,V> z, int level) {
12.920 + HeadIndex<K,V> h = head;
12.921 + int max = h.level;
12.922 +
12.923 + if (level <= max) {
12.924 + Index<K,V> idx = null;
12.925 + for (int i = 1; i <= level; ++i)
12.926 + idx = new Index<K,V>(z, idx, null);
12.927 + addIndex(idx, h, level);
12.928 +
12.929 + } else { // Add a new level
12.930 + /*
12.931 + * To reduce interference by other threads checking for
12.932 + * empty levels in tryReduceLevel, new levels are added
12.933 + * with initialized right pointers. Which in turn requires
12.934 + * keeping levels in an array to access them while
12.935 + * creating new head index nodes from the opposite
12.936 + * direction.
12.937 + */
12.938 + level = max + 1;
12.939 + Index<K,V>[] idxs = (Index<K,V>[])new Index[level+1];
12.940 + Index<K,V> idx = null;
12.941 + for (int i = 1; i <= level; ++i)
12.942 + idxs[i] = idx = new Index<K,V>(z, idx, null);
12.943 +
12.944 + HeadIndex<K,V> oldh;
12.945 + int k;
12.946 + for (;;) {
12.947 + oldh = head;
12.948 + int oldLevel = oldh.level;
12.949 + if (level <= oldLevel) { // lost race to add level
12.950 + k = level;
12.951 + break;
12.952 + }
12.953 + HeadIndex<K,V> newh = oldh;
12.954 + Node<K,V> oldbase = oldh.node;
12.955 + for (int j = oldLevel+1; j <= level; ++j)
12.956 + newh = new HeadIndex<K,V>(oldbase, newh, idxs[j], j);
12.957 + if (casHead(oldh, newh)) {
12.958 + k = oldLevel;
12.959 + break;
12.960 + }
12.961 + }
12.962 + addIndex(idxs[k], oldh, k);
12.963 + }
12.964 + }
12.965 +
12.966 + /**
12.967 + * Adds given index nodes from given level down to 1.
12.968 + * @param idx the topmost index node being inserted
12.969 + * @param h the value of head to use to insert. This must be
12.970 + * snapshotted by callers to provide correct insertion level
12.971 + * @param indexLevel the level of the index
12.972 + */
12.973 + private void addIndex(Index<K,V> idx, HeadIndex<K,V> h, int indexLevel) {
12.974 + // Track next level to insert in case of retries
12.975 + int insertionLevel = indexLevel;
12.976 + Comparable<? super K> key = comparable(idx.node.key);
12.977 + if (key == null) throw new NullPointerException();
12.978 +
12.979 + // Similar to findPredecessor, but adding index nodes along
12.980 + // path to key.
12.981 + for (;;) {
12.982 + int j = h.level;
12.983 + Index<K,V> q = h;
12.984 + Index<K,V> r = q.right;
12.985 + Index<K,V> t = idx;
12.986 + for (;;) {
12.987 + if (r != null) {
12.988 + Node<K,V> n = r.node;
12.989 + // compare before deletion check avoids needing recheck
12.990 + int c = key.compareTo(n.key);
12.991 + if (n.value == null) {
12.992 + if (!q.unlink(r))
12.993 + break;
12.994 + r = q.right;
12.995 + continue;
12.996 + }
12.997 + if (c > 0) {
12.998 + q = r;
12.999 + r = r.right;
12.1000 + continue;
12.1001 + }
12.1002 + }
12.1003 +
12.1004 + if (j == insertionLevel) {
12.1005 + // Don't insert index if node already deleted
12.1006 + if (t.indexesDeletedNode()) {
12.1007 + findNode(key); // cleans up
12.1008 + return;
12.1009 + }
12.1010 + if (!q.link(r, t))
12.1011 + break; // restart
12.1012 + if (--insertionLevel == 0) {
12.1013 + // need final deletion check before return
12.1014 + if (t.indexesDeletedNode())
12.1015 + findNode(key);
12.1016 + return;
12.1017 + }
12.1018 + }
12.1019 +
12.1020 + if (--j >= insertionLevel && j < indexLevel)
12.1021 + t = t.down;
12.1022 + q = q.down;
12.1023 + r = q.right;
12.1024 + }
12.1025 + }
12.1026 + }
12.1027 +
12.1028 + /* ---------------- Deletion -------------- */
12.1029 +
12.1030 + /**
12.1031 + * Main deletion method. Locates node, nulls value, appends a
12.1032 + * deletion marker, unlinks predecessor, removes associated index
12.1033 + * nodes, and possibly reduces head index level.
12.1034 + *
12.1035 + * Index nodes are cleared out simply by calling findPredecessor.
12.1036 + * which unlinks indexes to deleted nodes found along path to key,
12.1037 + * which will include the indexes to this node. This is done
12.1038 + * unconditionally. We can't check beforehand whether there are
12.1039 + * index nodes because it might be the case that some or all
12.1040 + * indexes hadn't been inserted yet for this node during initial
12.1041 + * search for it, and we'd like to ensure lack of garbage
12.1042 + * retention, so must call to be sure.
12.1043 + *
12.1044 + * @param okey the key
12.1045 + * @param value if non-null, the value that must be
12.1046 + * associated with key
12.1047 + * @return the node, or null if not found
12.1048 + */
12.1049 + final V doRemove(Object okey, Object value) {
12.1050 + Comparable<? super K> key = comparable(okey);
12.1051 + for (;;) {
12.1052 + Node<K,V> b = findPredecessor(key);
12.1053 + Node<K,V> n = b.next;
12.1054 + for (;;) {
12.1055 + if (n == null)
12.1056 + return null;
12.1057 + Node<K,V> f = n.next;
12.1058 + if (n != b.next) // inconsistent read
12.1059 + break;
12.1060 + Object v = n.value;
12.1061 + if (v == null) { // n is deleted
12.1062 + n.helpDelete(b, f);
12.1063 + break;
12.1064 + }
12.1065 + if (v == n || b.value == null) // b is deleted
12.1066 + break;
12.1067 + int c = key.compareTo(n.key);
12.1068 + if (c < 0)
12.1069 + return null;
12.1070 + if (c > 0) {
12.1071 + b = n;
12.1072 + n = f;
12.1073 + continue;
12.1074 + }
12.1075 + if (value != null && !value.equals(v))
12.1076 + return null;
12.1077 + if (!n.casValue(v, null))
12.1078 + break;
12.1079 + if (!n.appendMarker(f) || !b.casNext(n, f))
12.1080 + findNode(key); // Retry via findNode
12.1081 + else {
12.1082 + findPredecessor(key); // Clean index
12.1083 + if (head.right == null)
12.1084 + tryReduceLevel();
12.1085 + }
12.1086 + return (V)v;
12.1087 + }
12.1088 + }
12.1089 + }
12.1090 +
12.1091 + /**
12.1092 + * Possibly reduce head level if it has no nodes. This method can
12.1093 + * (rarely) make mistakes, in which case levels can disappear even
12.1094 + * though they are about to contain index nodes. This impacts
12.1095 + * performance, not correctness. To minimize mistakes as well as
12.1096 + * to reduce hysteresis, the level is reduced by one only if the
12.1097 + * topmost three levels look empty. Also, if the removed level
12.1098 + * looks non-empty after CAS, we try to change it back quick
12.1099 + * before anyone notices our mistake! (This trick works pretty
12.1100 + * well because this method will practically never make mistakes
12.1101 + * unless current thread stalls immediately before first CAS, in
12.1102 + * which case it is very unlikely to stall again immediately
12.1103 + * afterwards, so will recover.)
12.1104 + *
12.1105 + * We put up with all this rather than just let levels grow
12.1106 + * because otherwise, even a small map that has undergone a large
12.1107 + * number of insertions and removals will have a lot of levels,
12.1108 + * slowing down access more than would an occasional unwanted
12.1109 + * reduction.
12.1110 + */
12.1111 + private void tryReduceLevel() {
12.1112 + HeadIndex<K,V> h = head;
12.1113 + HeadIndex<K,V> d;
12.1114 + HeadIndex<K,V> e;
12.1115 + if (h.level > 3 &&
12.1116 + (d = (HeadIndex<K,V>)h.down) != null &&
12.1117 + (e = (HeadIndex<K,V>)d.down) != null &&
12.1118 + e.right == null &&
12.1119 + d.right == null &&
12.1120 + h.right == null &&
12.1121 + casHead(h, d) && // try to set
12.1122 + h.right != null) // recheck
12.1123 + casHead(d, h); // try to backout
12.1124 + }
12.1125 +
12.1126 + /* ---------------- Finding and removing first element -------------- */
12.1127 +
12.1128 + /**
12.1129 + * Specialized variant of findNode to get first valid node.
12.1130 + * @return first node or null if empty
12.1131 + */
12.1132 + Node<K,V> findFirst() {
12.1133 + for (;;) {
12.1134 + Node<K,V> b = head.node;
12.1135 + Node<K,V> n = b.next;
12.1136 + if (n == null)
12.1137 + return null;
12.1138 + if (n.value != null)
12.1139 + return n;
12.1140 + n.helpDelete(b, n.next);
12.1141 + }
12.1142 + }
12.1143 +
12.1144 + /**
12.1145 + * Removes first entry; returns its snapshot.
12.1146 + * @return null if empty, else snapshot of first entry
12.1147 + */
12.1148 + Map.Entry<K,V> doRemoveFirstEntry() {
12.1149 + for (;;) {
12.1150 + Node<K,V> b = head.node;
12.1151 + Node<K,V> n = b.next;
12.1152 + if (n == null)
12.1153 + return null;
12.1154 + Node<K,V> f = n.next;
12.1155 + if (n != b.next)
12.1156 + continue;
12.1157 + Object v = n.value;
12.1158 + if (v == null) {
12.1159 + n.helpDelete(b, f);
12.1160 + continue;
12.1161 + }
12.1162 + if (!n.casValue(v, null))
12.1163 + continue;
12.1164 + if (!n.appendMarker(f) || !b.casNext(n, f))
12.1165 + findFirst(); // retry
12.1166 + clearIndexToFirst();
12.1167 + return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, (V)v);
12.1168 + }
12.1169 + }
12.1170 +
12.1171 + /**
12.1172 + * Clears out index nodes associated with deleted first entry.
12.1173 + */
12.1174 + private void clearIndexToFirst() {
12.1175 + for (;;) {
12.1176 + Index<K,V> q = head;
12.1177 + for (;;) {
12.1178 + Index<K,V> r = q.right;
12.1179 + if (r != null && r.indexesDeletedNode() && !q.unlink(r))
12.1180 + break;
12.1181 + if ((q = q.down) == null) {
12.1182 + if (head.right == null)
12.1183 + tryReduceLevel();
12.1184 + return;
12.1185 + }
12.1186 + }
12.1187 + }
12.1188 + }
12.1189 +
12.1190 +
12.1191 + /* ---------------- Finding and removing last element -------------- */
12.1192 +
12.1193 + /**
12.1194 + * Specialized version of find to get last valid node.
12.1195 + * @return last node or null if empty
12.1196 + */
12.1197 + Node<K,V> findLast() {
12.1198 + /*
12.1199 + * findPredecessor can't be used to traverse index level
12.1200 + * because this doesn't use comparisons. So traversals of
12.1201 + * both levels are folded together.
12.1202 + */
12.1203 + Index<K,V> q = head;
12.1204 + for (;;) {
12.1205 + Index<K,V> d, r;
12.1206 + if ((r = q.right) != null) {
12.1207 + if (r.indexesDeletedNode()) {
12.1208 + q.unlink(r);
12.1209 + q = head; // restart
12.1210 + }
12.1211 + else
12.1212 + q = r;
12.1213 + } else if ((d = q.down) != null) {
12.1214 + q = d;
12.1215 + } else {
12.1216 + Node<K,V> b = q.node;
12.1217 + Node<K,V> n = b.next;
12.1218 + for (;;) {
12.1219 + if (n == null)
12.1220 + return b.isBaseHeader() ? null : b;
12.1221 + Node<K,V> f = n.next; // inconsistent read
12.1222 + if (n != b.next)
12.1223 + break;
12.1224 + Object v = n.value;
12.1225 + if (v == null) { // n is deleted
12.1226 + n.helpDelete(b, f);
12.1227 + break;
12.1228 + }
12.1229 + if (v == n || b.value == null) // b is deleted
12.1230 + break;
12.1231 + b = n;
12.1232 + n = f;
12.1233 + }
12.1234 + q = head; // restart
12.1235 + }
12.1236 + }
12.1237 + }
12.1238 +
12.1239 + /**
12.1240 + * Specialized variant of findPredecessor to get predecessor of last
12.1241 + * valid node. Needed when removing the last entry. It is possible
12.1242 + * that all successors of returned node will have been deleted upon
12.1243 + * return, in which case this method can be retried.
12.1244 + * @return likely predecessor of last node
12.1245 + */
12.1246 + private Node<K,V> findPredecessorOfLast() {
12.1247 + for (;;) {
12.1248 + Index<K,V> q = head;
12.1249 + for (;;) {
12.1250 + Index<K,V> d, r;
12.1251 + if ((r = q.right) != null) {
12.1252 + if (r.indexesDeletedNode()) {
12.1253 + q.unlink(r);
12.1254 + break; // must restart
12.1255 + }
12.1256 + // proceed as far across as possible without overshooting
12.1257 + if (r.node.next != null) {
12.1258 + q = r;
12.1259 + continue;
12.1260 + }
12.1261 + }
12.1262 + if ((d = q.down) != null)
12.1263 + q = d;
12.1264 + else
12.1265 + return q.node;
12.1266 + }
12.1267 + }
12.1268 + }
12.1269 +
12.1270 + /**
12.1271 + * Removes last entry; returns its snapshot.
12.1272 + * Specialized variant of doRemove.
12.1273 + * @return null if empty, else snapshot of last entry
12.1274 + */
12.1275 + Map.Entry<K,V> doRemoveLastEntry() {
12.1276 + for (;;) {
12.1277 + Node<K,V> b = findPredecessorOfLast();
12.1278 + Node<K,V> n = b.next;
12.1279 + if (n == null) {
12.1280 + if (b.isBaseHeader()) // empty
12.1281 + return null;
12.1282 + else
12.1283 + continue; // all b's successors are deleted; retry
12.1284 + }
12.1285 + for (;;) {
12.1286 + Node<K,V> f = n.next;
12.1287 + if (n != b.next) // inconsistent read
12.1288 + break;
12.1289 + Object v = n.value;
12.1290 + if (v == null) { // n is deleted
12.1291 + n.helpDelete(b, f);
12.1292 + break;
12.1293 + }
12.1294 + if (v == n || b.value == null) // b is deleted
12.1295 + break;
12.1296 + if (f != null) {
12.1297 + b = n;
12.1298 + n = f;
12.1299 + continue;
12.1300 + }
12.1301 + if (!n.casValue(v, null))
12.1302 + break;
12.1303 + K key = n.key;
12.1304 + Comparable<? super K> ck = comparable(key);
12.1305 + if (!n.appendMarker(f) || !b.casNext(n, f))
12.1306 + findNode(ck); // Retry via findNode
12.1307 + else {
12.1308 + findPredecessor(ck); // Clean index
12.1309 + if (head.right == null)
12.1310 + tryReduceLevel();
12.1311 + }
12.1312 + return new AbstractMap.SimpleImmutableEntry<K,V>(key, (V)v);
12.1313 + }
12.1314 + }
12.1315 + }
12.1316 +
12.1317 + /* ---------------- Relational operations -------------- */
12.1318 +
12.1319 + // Control values OR'ed as arguments to findNear
12.1320 +
12.1321 + private static final int EQ = 1;
12.1322 + private static final int LT = 2;
12.1323 + private static final int GT = 0; // Actually checked as !LT
12.1324 +
12.1325 + /**
12.1326 + * Utility for ceiling, floor, lower, higher methods.
12.1327 + * @param kkey the key
12.1328 + * @param rel the relation -- OR'ed combination of EQ, LT, GT
12.1329 + * @return nearest node fitting relation, or null if no such
12.1330 + */
12.1331 + Node<K,V> findNear(K kkey, int rel) {
12.1332 + Comparable<? super K> key = comparable(kkey);
12.1333 + for (;;) {
12.1334 + Node<K,V> b = findPredecessor(key);
12.1335 + Node<K,V> n = b.next;
12.1336 + for (;;) {
12.1337 + if (n == null)
12.1338 + return ((rel & LT) == 0 || b.isBaseHeader()) ? null : b;
12.1339 + Node<K,V> f = n.next;
12.1340 + if (n != b.next) // inconsistent read
12.1341 + break;
12.1342 + Object v = n.value;
12.1343 + if (v == null) { // n is deleted
12.1344 + n.helpDelete(b, f);
12.1345 + break;
12.1346 + }
12.1347 + if (v == n || b.value == null) // b is deleted
12.1348 + break;
12.1349 + int c = key.compareTo(n.key);
12.1350 + if ((c == 0 && (rel & EQ) != 0) ||
12.1351 + (c < 0 && (rel & LT) == 0))
12.1352 + return n;
12.1353 + if ( c <= 0 && (rel & LT) != 0)
12.1354 + return b.isBaseHeader() ? null : b;
12.1355 + b = n;
12.1356 + n = f;
12.1357 + }
12.1358 + }
12.1359 + }
12.1360 +
12.1361 + /**
12.1362 + * Returns SimpleImmutableEntry for results of findNear.
12.1363 + * @param key the key
12.1364 + * @param rel the relation -- OR'ed combination of EQ, LT, GT
12.1365 + * @return Entry fitting relation, or null if no such
12.1366 + */
12.1367 + AbstractMap.SimpleImmutableEntry<K,V> getNear(K key, int rel) {
12.1368 + for (;;) {
12.1369 + Node<K,V> n = findNear(key, rel);
12.1370 + if (n == null)
12.1371 + return null;
12.1372 + AbstractMap.SimpleImmutableEntry<K,V> e = n.createSnapshot();
12.1373 + if (e != null)
12.1374 + return e;
12.1375 + }
12.1376 + }
12.1377 +
12.1378 +
12.1379 + /* ---------------- Constructors -------------- */
12.1380 +
12.1381 + /**
12.1382 + * Constructs a new, empty map, sorted according to the
12.1383 + * {@linkplain Comparable natural ordering} of the keys.
12.1384 + */
12.1385 + public ConcurrentSkipListMap() {
12.1386 + this.comparator = null;
12.1387 + initialize();
12.1388 + }
12.1389 +
12.1390 + /**
12.1391 + * Constructs a new, empty map, sorted according to the specified
12.1392 + * comparator.
12.1393 + *
12.1394 + * @param comparator the comparator that will be used to order this map.
12.1395 + * If <tt>null</tt>, the {@linkplain Comparable natural
12.1396 + * ordering} of the keys will be used.
12.1397 + */
12.1398 + public ConcurrentSkipListMap(Comparator<? super K> comparator) {
12.1399 + this.comparator = comparator;
12.1400 + initialize();
12.1401 + }
12.1402 +
12.1403 + /**
12.1404 + * Constructs a new map containing the same mappings as the given map,
12.1405 + * sorted according to the {@linkplain Comparable natural ordering} of
12.1406 + * the keys.
12.1407 + *
12.1408 + * @param m the map whose mappings are to be placed in this map
12.1409 + * @throws ClassCastException if the keys in <tt>m</tt> are not
12.1410 + * {@link Comparable}, or are not mutually comparable
12.1411 + * @throws NullPointerException if the specified map or any of its keys
12.1412 + * or values are null
12.1413 + */
12.1414 + public ConcurrentSkipListMap(Map<? extends K, ? extends V> m) {
12.1415 + this.comparator = null;
12.1416 + initialize();
12.1417 + putAll(m);
12.1418 + }
12.1419 +
12.1420 + /**
12.1421 + * Constructs a new map containing the same mappings and using the
12.1422 + * same ordering as the specified sorted map.
12.1423 + *
12.1424 + * @param m the sorted map whose mappings are to be placed in this
12.1425 + * map, and whose comparator is to be used to sort this map
12.1426 + * @throws NullPointerException if the specified sorted map or any of
12.1427 + * its keys or values are null
12.1428 + */
12.1429 + public ConcurrentSkipListMap(SortedMap<K, ? extends V> m) {
12.1430 + this.comparator = m.comparator();
12.1431 + initialize();
12.1432 + buildFromSorted(m);
12.1433 + }
12.1434 +
12.1435 + /**
12.1436 + * Returns a shallow copy of this <tt>ConcurrentSkipListMap</tt>
12.1437 + * instance. (The keys and values themselves are not cloned.)
12.1438 + *
12.1439 + * @return a shallow copy of this map
12.1440 + */
12.1441 + public ConcurrentSkipListMap<K,V> clone() {
12.1442 + ConcurrentSkipListMap<K,V> clone = null;
12.1443 + try {
12.1444 + clone = (ConcurrentSkipListMap<K,V>) super.clone();
12.1445 + } catch (CloneNotSupportedException e) {
12.1446 + throw new InternalError();
12.1447 + }
12.1448 +
12.1449 + clone.initialize();
12.1450 + clone.buildFromSorted(this);
12.1451 + return clone;
12.1452 + }
12.1453 +
12.1454 + /**
12.1455 + * Streamlined bulk insertion to initialize from elements of
12.1456 + * given sorted map. Call only from constructor or clone
12.1457 + * method.
12.1458 + */
12.1459 + private void buildFromSorted(SortedMap<K, ? extends V> map) {
12.1460 + if (map == null)
12.1461 + throw new NullPointerException();
12.1462 +
12.1463 + HeadIndex<K,V> h = head;
12.1464 + Node<K,V> basepred = h.node;
12.1465 +
12.1466 + // Track the current rightmost node at each level. Uses an
12.1467 + // ArrayList to avoid committing to initial or maximum level.
12.1468 + ArrayList<Index<K,V>> preds = new ArrayList<Index<K,V>>();
12.1469 +
12.1470 + // initialize
12.1471 + for (int i = 0; i <= h.level; ++i)
12.1472 + preds.add(null);
12.1473 + Index<K,V> q = h;
12.1474 + for (int i = h.level; i > 0; --i) {
12.1475 + preds.set(i, q);
12.1476 + q = q.down;
12.1477 + }
12.1478 +
12.1479 + Iterator<? extends Map.Entry<? extends K, ? extends V>> it =
12.1480 + map.entrySet().iterator();
12.1481 + while (it.hasNext()) {
12.1482 + Map.Entry<? extends K, ? extends V> e = it.next();
12.1483 + int j = randomLevel();
12.1484 + if (j > h.level) j = h.level + 1;
12.1485 + K k = e.getKey();
12.1486 + V v = e.getValue();
12.1487 + if (k == null || v == null)
12.1488 + throw new NullPointerException();
12.1489 + Node<K,V> z = new Node<K,V>(k, v, null);
12.1490 + basepred.next = z;
12.1491 + basepred = z;
12.1492 + if (j > 0) {
12.1493 + Index<K,V> idx = null;
12.1494 + for (int i = 1; i <= j; ++i) {
12.1495 + idx = new Index<K,V>(z, idx, null);
12.1496 + if (i > h.level)
12.1497 + h = new HeadIndex<K,V>(h.node, h, idx, i);
12.1498 +
12.1499 + if (i < preds.size()) {
12.1500 + preds.get(i).right = idx;
12.1501 + preds.set(i, idx);
12.1502 + } else
12.1503 + preds.add(idx);
12.1504 + }
12.1505 + }
12.1506 + }
12.1507 + head = h;
12.1508 + }
12.1509 +
12.1510 + /* ---------------- Serialization -------------- */
12.1511 +
12.1512 + /**
12.1513 + * Save the state of this map to a stream.
12.1514 + *
12.1515 + * @serialData The key (Object) and value (Object) for each
12.1516 + * key-value mapping represented by the map, followed by
12.1517 + * <tt>null</tt>. The key-value mappings are emitted in key-order
12.1518 + * (as determined by the Comparator, or by the keys' natural
12.1519 + * ordering if no Comparator).
12.1520 + */
12.1521 + private void writeObject(java.io.ObjectOutputStream s)
12.1522 + throws java.io.IOException {
12.1523 + // Write out the Comparator and any hidden stuff
12.1524 + s.defaultWriteObject();
12.1525 +
12.1526 + // Write out keys and values (alternating)
12.1527 + for (Node<K,V> n = findFirst(); n != null; n = n.next) {
12.1528 + V v = n.getValidValue();
12.1529 + if (v != null) {
12.1530 + s.writeObject(n.key);
12.1531 + s.writeObject(v);
12.1532 + }
12.1533 + }
12.1534 + s.writeObject(null);
12.1535 + }
12.1536 +
12.1537 + /**
12.1538 + * Reconstitute the map from a stream.
12.1539 + */
12.1540 + private void readObject(final java.io.ObjectInputStream s)
12.1541 + throws java.io.IOException, ClassNotFoundException {
12.1542 + // Read in the Comparator and any hidden stuff
12.1543 + s.defaultReadObject();
12.1544 + // Reset transients
12.1545 + initialize();
12.1546 +
12.1547 + /*
12.1548 + * This is nearly identical to buildFromSorted, but is
12.1549 + * distinct because readObject calls can't be nicely adapted
12.1550 + * as the kind of iterator needed by buildFromSorted. (They
12.1551 + * can be, but doing so requires type cheats and/or creation
12.1552 + * of adaptor classes.) It is simpler to just adapt the code.
12.1553 + */
12.1554 +
12.1555 + HeadIndex<K,V> h = head;
12.1556 + Node<K,V> basepred = h.node;
12.1557 + ArrayList<Index<K,V>> preds = new ArrayList<Index<K,V>>();
12.1558 + for (int i = 0; i <= h.level; ++i)
12.1559 + preds.add(null);
12.1560 + Index<K,V> q = h;
12.1561 + for (int i = h.level; i > 0; --i) {
12.1562 + preds.set(i, q);
12.1563 + q = q.down;
12.1564 + }
12.1565 +
12.1566 + for (;;) {
12.1567 + Object k = s.readObject();
12.1568 + if (k == null)
12.1569 + break;
12.1570 + Object v = s.readObject();
12.1571 + if (v == null)
12.1572 + throw new NullPointerException();
12.1573 + K key = (K) k;
12.1574 + V val = (V) v;
12.1575 + int j = randomLevel();
12.1576 + if (j > h.level) j = h.level + 1;
12.1577 + Node<K,V> z = new Node<K,V>(key, val, null);
12.1578 + basepred.next = z;
12.1579 + basepred = z;
12.1580 + if (j > 0) {
12.1581 + Index<K,V> idx = null;
12.1582 + for (int i = 1; i <= j; ++i) {
12.1583 + idx = new Index<K,V>(z, idx, null);
12.1584 + if (i > h.level)
12.1585 + h = new HeadIndex<K,V>(h.node, h, idx, i);
12.1586 +
12.1587 + if (i < preds.size()) {
12.1588 + preds.get(i).right = idx;
12.1589 + preds.set(i, idx);
12.1590 + } else
12.1591 + preds.add(idx);
12.1592 + }
12.1593 + }
12.1594 + }
12.1595 + head = h;
12.1596 + }
12.1597 +
12.1598 + /* ------ Map API methods ------ */
12.1599 +
12.1600 + /**
12.1601 + * Returns <tt>true</tt> if this map contains a mapping for the specified
12.1602 + * key.
12.1603 + *
12.1604 + * @param key key whose presence in this map is to be tested
12.1605 + * @return <tt>true</tt> if this map contains a mapping for the specified key
12.1606 + * @throws ClassCastException if the specified key cannot be compared
12.1607 + * with the keys currently in the map
12.1608 + * @throws NullPointerException if the specified key is null
12.1609 + */
12.1610 + public boolean containsKey(Object key) {
12.1611 + return doGet(key) != null;
12.1612 + }
12.1613 +
12.1614 + /**
12.1615 + * Returns the value to which the specified key is mapped,
12.1616 + * or {@code null} if this map contains no mapping for the key.
12.1617 + *
12.1618 + * <p>More formally, if this map contains a mapping from a key
12.1619 + * {@code k} to a value {@code v} such that {@code key} compares
12.1620 + * equal to {@code k} according to the map's ordering, then this
12.1621 + * method returns {@code v}; otherwise it returns {@code null}.
12.1622 + * (There can be at most one such mapping.)
12.1623 + *
12.1624 + * @throws ClassCastException if the specified key cannot be compared
12.1625 + * with the keys currently in the map
12.1626 + * @throws NullPointerException if the specified key is null
12.1627 + */
12.1628 + public V get(Object key) {
12.1629 + return doGet(key);
12.1630 + }
12.1631 +
12.1632 + /**
12.1633 + * Associates the specified value with the specified key in this map.
12.1634 + * If the map previously contained a mapping for the key, the old
12.1635 + * value is replaced.
12.1636 + *
12.1637 + * @param key key with which the specified value is to be associated
12.1638 + * @param value value to be associated with the specified key
12.1639 + * @return the previous value associated with the specified key, or
12.1640 + * <tt>null</tt> if there was no mapping for the key
12.1641 + * @throws ClassCastException if the specified key cannot be compared
12.1642 + * with the keys currently in the map
12.1643 + * @throws NullPointerException if the specified key or value is null
12.1644 + */
12.1645 + public V put(K key, V value) {
12.1646 + if (value == null)
12.1647 + throw new NullPointerException();
12.1648 + return doPut(key, value, false);
12.1649 + }
12.1650 +
12.1651 + /**
12.1652 + * Removes the mapping for the specified key from this map if present.
12.1653 + *
12.1654 + * @param key key for which mapping should be removed
12.1655 + * @return the previous value associated with the specified key, or
12.1656 + * <tt>null</tt> if there was no mapping for the key
12.1657 + * @throws ClassCastException if the specified key cannot be compared
12.1658 + * with the keys currently in the map
12.1659 + * @throws NullPointerException if the specified key is null
12.1660 + */
12.1661 + public V remove(Object key) {
12.1662 + return doRemove(key, null);
12.1663 + }
12.1664 +
12.1665 + /**
12.1666 + * Returns <tt>true</tt> if this map maps one or more keys to the
12.1667 + * specified value. This operation requires time linear in the
12.1668 + * map size. Additionally, it is possible for the map to change
12.1669 + * during execution of this method, in which case the returned
12.1670 + * result may be inaccurate.
12.1671 + *
12.1672 + * @param value value whose presence in this map is to be tested
12.1673 + * @return <tt>true</tt> if a mapping to <tt>value</tt> exists;
12.1674 + * <tt>false</tt> otherwise
12.1675 + * @throws NullPointerException if the specified value is null
12.1676 + */
12.1677 + public boolean containsValue(Object value) {
12.1678 + if (value == null)
12.1679 + throw new NullPointerException();
12.1680 + for (Node<K,V> n = findFirst(); n != null; n = n.next) {
12.1681 + V v = n.getValidValue();
12.1682 + if (v != null && value.equals(v))
12.1683 + return true;
12.1684 + }
12.1685 + return false;
12.1686 + }
12.1687 +
12.1688 + /**
12.1689 + * Returns the number of key-value mappings in this map. If this map
12.1690 + * contains more than <tt>Integer.MAX_VALUE</tt> elements, it
12.1691 + * returns <tt>Integer.MAX_VALUE</tt>.
12.1692 + *
12.1693 + * <p>Beware that, unlike in most collections, this method is
12.1694 + * <em>NOT</em> a constant-time operation. Because of the
12.1695 + * asynchronous nature of these maps, determining the current
12.1696 + * number of elements requires traversing them all to count them.
12.1697 + * Additionally, it is possible for the size to change during
12.1698 + * execution of this method, in which case the returned result
12.1699 + * will be inaccurate. Thus, this method is typically not very
12.1700 + * useful in concurrent applications.
12.1701 + *
12.1702 + * @return the number of elements in this map
12.1703 + */
12.1704 + public int size() {
12.1705 + long count = 0;
12.1706 + for (Node<K,V> n = findFirst(); n != null; n = n.next) {
12.1707 + if (n.getValidValue() != null)
12.1708 + ++count;
12.1709 + }
12.1710 + return (count >= Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int) count;
12.1711 + }
12.1712 +
12.1713 + /**
12.1714 + * Returns <tt>true</tt> if this map contains no key-value mappings.
12.1715 + * @return <tt>true</tt> if this map contains no key-value mappings
12.1716 + */
12.1717 + public boolean isEmpty() {
12.1718 + return findFirst() == null;
12.1719 + }
12.1720 +
12.1721 + /**
12.1722 + * Removes all of the mappings from this map.
12.1723 + */
12.1724 + public void clear() {
12.1725 + initialize();
12.1726 + }
12.1727 +
12.1728 + /* ---------------- View methods -------------- */
12.1729 +
12.1730 + /*
12.1731 + * Note: Lazy initialization works for views because view classes
12.1732 + * are stateless/immutable so it doesn't matter wrt correctness if
12.1733 + * more than one is created (which will only rarely happen). Even
12.1734 + * so, the following idiom conservatively ensures that the method
12.1735 + * returns the one it created if it does so, not one created by
12.1736 + * another racing thread.
12.1737 + */
12.1738 +
12.1739 + /**
12.1740 + * Returns a {@link NavigableSet} view of the keys contained in this map.
12.1741 + * The set's iterator returns the keys in ascending order.
12.1742 + * The set is backed by the map, so changes to the map are
12.1743 + * reflected in the set, and vice-versa. The set supports element
12.1744 + * removal, which removes the corresponding mapping from the map,
12.1745 + * via the {@code Iterator.remove}, {@code Set.remove},
12.1746 + * {@code removeAll}, {@code retainAll}, and {@code clear}
12.1747 + * operations. It does not support the {@code add} or {@code addAll}
12.1748 + * operations.
12.1749 + *
12.1750 + * <p>The view's {@code iterator} is a "weakly consistent" iterator
12.1751 + * that will never throw {@link ConcurrentModificationException},
12.1752 + * and guarantees to traverse elements as they existed upon
12.1753 + * construction of the iterator, and may (but is not guaranteed to)
12.1754 + * reflect any modifications subsequent to construction.
12.1755 + *
12.1756 + * <p>This method is equivalent to method {@code navigableKeySet}.
12.1757 + *
12.1758 + * @return a navigable set view of the keys in this map
12.1759 + */
12.1760 + public NavigableSet<K> keySet() {
12.1761 + KeySet ks = keySet;
12.1762 + return (ks != null) ? ks : (keySet = new KeySet(this));
12.1763 + }
12.1764 +
12.1765 + public NavigableSet<K> navigableKeySet() {
12.1766 + KeySet ks = keySet;
12.1767 + return (ks != null) ? ks : (keySet = new KeySet(this));
12.1768 + }
12.1769 +
12.1770 + /**
12.1771 + * Returns a {@link Collection} view of the values contained in this map.
12.1772 + * The collection's iterator returns the values in ascending order
12.1773 + * of the corresponding keys.
12.1774 + * The collection is backed by the map, so changes to the map are
12.1775 + * reflected in the collection, and vice-versa. The collection
12.1776 + * supports element removal, which removes the corresponding
12.1777 + * mapping from the map, via the <tt>Iterator.remove</tt>,
12.1778 + * <tt>Collection.remove</tt>, <tt>removeAll</tt>,
12.1779 + * <tt>retainAll</tt> and <tt>clear</tt> operations. It does not
12.1780 + * support the <tt>add</tt> or <tt>addAll</tt> operations.
12.1781 + *
12.1782 + * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator
12.1783 + * that will never throw {@link ConcurrentModificationException},
12.1784 + * and guarantees to traverse elements as they existed upon
12.1785 + * construction of the iterator, and may (but is not guaranteed to)
12.1786 + * reflect any modifications subsequent to construction.
12.1787 + */
12.1788 + public Collection<V> values() {
12.1789 + Values vs = values;
12.1790 + return (vs != null) ? vs : (values = new Values(this));
12.1791 + }
12.1792 +
12.1793 + /**
12.1794 + * Returns a {@link Set} view of the mappings contained in this map.
12.1795 + * The set's iterator returns the entries in ascending key order.
12.1796 + * The set is backed by the map, so changes to the map are
12.1797 + * reflected in the set, and vice-versa. The set supports element
12.1798 + * removal, which removes the corresponding mapping from the map,
12.1799 + * via the <tt>Iterator.remove</tt>, <tt>Set.remove</tt>,
12.1800 + * <tt>removeAll</tt>, <tt>retainAll</tt> and <tt>clear</tt>
12.1801 + * operations. It does not support the <tt>add</tt> or
12.1802 + * <tt>addAll</tt> operations.
12.1803 + *
12.1804 + * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator
12.1805 + * that will never throw {@link ConcurrentModificationException},
12.1806 + * and guarantees to traverse elements as they existed upon
12.1807 + * construction of the iterator, and may (but is not guaranteed to)
12.1808 + * reflect any modifications subsequent to construction.
12.1809 + *
12.1810 + * <p>The <tt>Map.Entry</tt> elements returned by
12.1811 + * <tt>iterator.next()</tt> do <em>not</em> support the
12.1812 + * <tt>setValue</tt> operation.
12.1813 + *
12.1814 + * @return a set view of the mappings contained in this map,
12.1815 + * sorted in ascending key order
12.1816 + */
12.1817 + public Set<Map.Entry<K,V>> entrySet() {
12.1818 + EntrySet es = entrySet;
12.1819 + return (es != null) ? es : (entrySet = new EntrySet(this));
12.1820 + }
12.1821 +
12.1822 + public ConcurrentNavigableMap<K,V> descendingMap() {
12.1823 + ConcurrentNavigableMap<K,V> dm = descendingMap;
12.1824 + return (dm != null) ? dm : (descendingMap = new SubMap<K,V>
12.1825 + (this, null, false, null, false, true));
12.1826 + }
12.1827 +
12.1828 + public NavigableSet<K> descendingKeySet() {
12.1829 + return descendingMap().navigableKeySet();
12.1830 + }
12.1831 +
12.1832 + /* ---------------- AbstractMap Overrides -------------- */
12.1833 +
12.1834 + /**
12.1835 + * Compares the specified object with this map for equality.
12.1836 + * Returns <tt>true</tt> if the given object is also a map and the
12.1837 + * two maps represent the same mappings. More formally, two maps
12.1838 + * <tt>m1</tt> and <tt>m2</tt> represent the same mappings if
12.1839 + * <tt>m1.entrySet().equals(m2.entrySet())</tt>. This
12.1840 + * operation may return misleading results if either map is
12.1841 + * concurrently modified during execution of this method.
12.1842 + *
12.1843 + * @param o object to be compared for equality with this map
12.1844 + * @return <tt>true</tt> if the specified object is equal to this map
12.1845 + */
12.1846 + public boolean equals(Object o) {
12.1847 + if (o == this)
12.1848 + return true;
12.1849 + if (!(o instanceof Map))
12.1850 + return false;
12.1851 + Map<?,?> m = (Map<?,?>) o;
12.1852 + try {
12.1853 + for (Map.Entry<K,V> e : this.entrySet())
12.1854 + if (! e.getValue().equals(m.get(e.getKey())))
12.1855 + return false;
12.1856 + for (Map.Entry<?,?> e : m.entrySet()) {
12.1857 + Object k = e.getKey();
12.1858 + Object v = e.getValue();
12.1859 + if (k == null || v == null || !v.equals(get(k)))
12.1860 + return false;
12.1861 + }
12.1862 + return true;
12.1863 + } catch (ClassCastException unused) {
12.1864 + return false;
12.1865 + } catch (NullPointerException unused) {
12.1866 + return false;
12.1867 + }
12.1868 + }
12.1869 +
12.1870 + /* ------ ConcurrentMap API methods ------ */
12.1871 +
12.1872 + /**
12.1873 + * {@inheritDoc}
12.1874 + *
12.1875 + * @return the previous value associated with the specified key,
12.1876 + * or <tt>null</tt> if there was no mapping for the key
12.1877 + * @throws ClassCastException if the specified key cannot be compared
12.1878 + * with the keys currently in the map
12.1879 + * @throws NullPointerException if the specified key or value is null
12.1880 + */
12.1881 + public V putIfAbsent(K key, V value) {
12.1882 + if (value == null)
12.1883 + throw new NullPointerException();
12.1884 + return doPut(key, value, true);
12.1885 + }
12.1886 +
12.1887 + /**
12.1888 + * {@inheritDoc}
12.1889 + *
12.1890 + * @throws ClassCastException if the specified key cannot be compared
12.1891 + * with the keys currently in the map
12.1892 + * @throws NullPointerException if the specified key is null
12.1893 + */
12.1894 + public boolean remove(Object key, Object value) {
12.1895 + if (key == null)
12.1896 + throw new NullPointerException();
12.1897 + if (value == null)
12.1898 + return false;
12.1899 + return doRemove(key, value) != null;
12.1900 + }
12.1901 +
12.1902 + /**
12.1903 + * {@inheritDoc}
12.1904 + *
12.1905 + * @throws ClassCastException if the specified key cannot be compared
12.1906 + * with the keys currently in the map
12.1907 + * @throws NullPointerException if any of the arguments are null
12.1908 + */
12.1909 + public boolean replace(K key, V oldValue, V newValue) {
12.1910 + if (oldValue == null || newValue == null)
12.1911 + throw new NullPointerException();
12.1912 + Comparable<? super K> k = comparable(key);
12.1913 + for (;;) {
12.1914 + Node<K,V> n = findNode(k);
12.1915 + if (n == null)
12.1916 + return false;
12.1917 + Object v = n.value;
12.1918 + if (v != null) {
12.1919 + if (!oldValue.equals(v))
12.1920 + return false;
12.1921 + if (n.casValue(v, newValue))
12.1922 + return true;
12.1923 + }
12.1924 + }
12.1925 + }
12.1926 +
12.1927 + /**
12.1928 + * {@inheritDoc}
12.1929 + *
12.1930 + * @return the previous value associated with the specified key,
12.1931 + * or <tt>null</tt> if there was no mapping for the key
12.1932 + * @throws ClassCastException if the specified key cannot be compared
12.1933 + * with the keys currently in the map
12.1934 + * @throws NullPointerException if the specified key or value is null
12.1935 + */
12.1936 + public V replace(K key, V value) {
12.1937 + if (value == null)
12.1938 + throw new NullPointerException();
12.1939 + Comparable<? super K> k = comparable(key);
12.1940 + for (;;) {
12.1941 + Node<K,V> n = findNode(k);
12.1942 + if (n == null)
12.1943 + return null;
12.1944 + Object v = n.value;
12.1945 + if (v != null && n.casValue(v, value))
12.1946 + return (V)v;
12.1947 + }
12.1948 + }
12.1949 +
12.1950 + /* ------ SortedMap API methods ------ */
12.1951 +
12.1952 + public Comparator<? super K> comparator() {
12.1953 + return comparator;
12.1954 + }
12.1955 +
12.1956 + /**
12.1957 + * @throws NoSuchElementException {@inheritDoc}
12.1958 + */
12.1959 + public K firstKey() {
12.1960 + Node<K,V> n = findFirst();
12.1961 + if (n == null)
12.1962 + throw new NoSuchElementException();
12.1963 + return n.key;
12.1964 + }
12.1965 +
12.1966 + /**
12.1967 + * @throws NoSuchElementException {@inheritDoc}
12.1968 + */
12.1969 + public K lastKey() {
12.1970 + Node<K,V> n = findLast();
12.1971 + if (n == null)
12.1972 + throw new NoSuchElementException();
12.1973 + return n.key;
12.1974 + }
12.1975 +
12.1976 + /**
12.1977 + * @throws ClassCastException {@inheritDoc}
12.1978 + * @throws NullPointerException if {@code fromKey} or {@code toKey} is null
12.1979 + * @throws IllegalArgumentException {@inheritDoc}
12.1980 + */
12.1981 + public ConcurrentNavigableMap<K,V> subMap(K fromKey,
12.1982 + boolean fromInclusive,
12.1983 + K toKey,
12.1984 + boolean toInclusive) {
12.1985 + if (fromKey == null || toKey == null)
12.1986 + throw new NullPointerException();
12.1987 + return new SubMap<K,V>
12.1988 + (this, fromKey, fromInclusive, toKey, toInclusive, false);
12.1989 + }
12.1990 +
12.1991 + /**
12.1992 + * @throws ClassCastException {@inheritDoc}
12.1993 + * @throws NullPointerException if {@code toKey} is null
12.1994 + * @throws IllegalArgumentException {@inheritDoc}
12.1995 + */
12.1996 + public ConcurrentNavigableMap<K,V> headMap(K toKey,
12.1997 + boolean inclusive) {
12.1998 + if (toKey == null)
12.1999 + throw new NullPointerException();
12.2000 + return new SubMap<K,V>
12.2001 + (this, null, false, toKey, inclusive, false);
12.2002 + }
12.2003 +
12.2004 + /**
12.2005 + * @throws ClassCastException {@inheritDoc}
12.2006 + * @throws NullPointerException if {@code fromKey} is null
12.2007 + * @throws IllegalArgumentException {@inheritDoc}
12.2008 + */
12.2009 + public ConcurrentNavigableMap<K,V> tailMap(K fromKey,
12.2010 + boolean inclusive) {
12.2011 + if (fromKey == null)
12.2012 + throw new NullPointerException();
12.2013 + return new SubMap<K,V>
12.2014 + (this, fromKey, inclusive, null, false, false);
12.2015 + }
12.2016 +
12.2017 + /**
12.2018 + * @throws ClassCastException {@inheritDoc}
12.2019 + * @throws NullPointerException if {@code fromKey} or {@code toKey} is null
12.2020 + * @throws IllegalArgumentException {@inheritDoc}
12.2021 + */
12.2022 + public ConcurrentNavigableMap<K,V> subMap(K fromKey, K toKey) {
12.2023 + return subMap(fromKey, true, toKey, false);
12.2024 + }
12.2025 +
12.2026 + /**
12.2027 + * @throws ClassCastException {@inheritDoc}
12.2028 + * @throws NullPointerException if {@code toKey} is null
12.2029 + * @throws IllegalArgumentException {@inheritDoc}
12.2030 + */
12.2031 + public ConcurrentNavigableMap<K,V> headMap(K toKey) {
12.2032 + return headMap(toKey, false);
12.2033 + }
12.2034 +
12.2035 + /**
12.2036 + * @throws ClassCastException {@inheritDoc}
12.2037 + * @throws NullPointerException if {@code fromKey} is null
12.2038 + * @throws IllegalArgumentException {@inheritDoc}
12.2039 + */
12.2040 + public ConcurrentNavigableMap<K,V> tailMap(K fromKey) {
12.2041 + return tailMap(fromKey, true);
12.2042 + }
12.2043 +
12.2044 + /* ---------------- Relational operations -------------- */
12.2045 +
12.2046 + /**
12.2047 + * Returns a key-value mapping associated with the greatest key
12.2048 + * strictly less than the given key, or <tt>null</tt> if there is
12.2049 + * no such key. The returned entry does <em>not</em> support the
12.2050 + * <tt>Entry.setValue</tt> method.
12.2051 + *
12.2052 + * @throws ClassCastException {@inheritDoc}
12.2053 + * @throws NullPointerException if the specified key is null
12.2054 + */
12.2055 + public Map.Entry<K,V> lowerEntry(K key) {
12.2056 + return getNear(key, LT);
12.2057 + }
12.2058 +
12.2059 + /**
12.2060 + * @throws ClassCastException {@inheritDoc}
12.2061 + * @throws NullPointerException if the specified key is null
12.2062 + */
12.2063 + public K lowerKey(K key) {
12.2064 + Node<K,V> n = findNear(key, LT);
12.2065 + return (n == null) ? null : n.key;
12.2066 + }
12.2067 +
12.2068 + /**
12.2069 + * Returns a key-value mapping associated with the greatest key
12.2070 + * less than or equal to the given key, or <tt>null</tt> if there
12.2071 + * is no such key. The returned entry does <em>not</em> support
12.2072 + * the <tt>Entry.setValue</tt> method.
12.2073 + *
12.2074 + * @param key the key
12.2075 + * @throws ClassCastException {@inheritDoc}
12.2076 + * @throws NullPointerException if the specified key is null
12.2077 + */
12.2078 + public Map.Entry<K,V> floorEntry(K key) {
12.2079 + return getNear(key, LT|EQ);
12.2080 + }
12.2081 +
12.2082 + /**
12.2083 + * @param key the key
12.2084 + * @throws ClassCastException {@inheritDoc}
12.2085 + * @throws NullPointerException if the specified key is null
12.2086 + */
12.2087 + public K floorKey(K key) {
12.2088 + Node<K,V> n = findNear(key, LT|EQ);
12.2089 + return (n == null) ? null : n.key;
12.2090 + }
12.2091 +
12.2092 + /**
12.2093 + * Returns a key-value mapping associated with the least key
12.2094 + * greater than or equal to the given key, or <tt>null</tt> if
12.2095 + * there is no such entry. The returned entry does <em>not</em>
12.2096 + * support the <tt>Entry.setValue</tt> method.
12.2097 + *
12.2098 + * @throws ClassCastException {@inheritDoc}
12.2099 + * @throws NullPointerException if the specified key is null
12.2100 + */
12.2101 + public Map.Entry<K,V> ceilingEntry(K key) {
12.2102 + return getNear(key, GT|EQ);
12.2103 + }
12.2104 +
12.2105 + /**
12.2106 + * @throws ClassCastException {@inheritDoc}
12.2107 + * @throws NullPointerException if the specified key is null
12.2108 + */
12.2109 + public K ceilingKey(K key) {
12.2110 + Node<K,V> n = findNear(key, GT|EQ);
12.2111 + return (n == null) ? null : n.key;
12.2112 + }
12.2113 +
12.2114 + /**
12.2115 + * Returns a key-value mapping associated with the least key
12.2116 + * strictly greater than the given key, or <tt>null</tt> if there
12.2117 + * is no such key. The returned entry does <em>not</em> support
12.2118 + * the <tt>Entry.setValue</tt> method.
12.2119 + *
12.2120 + * @param key the key
12.2121 + * @throws ClassCastException {@inheritDoc}
12.2122 + * @throws NullPointerException if the specified key is null
12.2123 + */
12.2124 + public Map.Entry<K,V> higherEntry(K key) {
12.2125 + return getNear(key, GT);
12.2126 + }
12.2127 +
12.2128 + /**
12.2129 + * @param key the key
12.2130 + * @throws ClassCastException {@inheritDoc}
12.2131 + * @throws NullPointerException if the specified key is null
12.2132 + */
12.2133 + public K higherKey(K key) {
12.2134 + Node<K,V> n = findNear(key, GT);
12.2135 + return (n == null) ? null : n.key;
12.2136 + }
12.2137 +
12.2138 + /**
12.2139 + * Returns a key-value mapping associated with the least
12.2140 + * key in this map, or <tt>null</tt> if the map is empty.
12.2141 + * The returned entry does <em>not</em> support
12.2142 + * the <tt>Entry.setValue</tt> method.
12.2143 + */
12.2144 + public Map.Entry<K,V> firstEntry() {
12.2145 + for (;;) {
12.2146 + Node<K,V> n = findFirst();
12.2147 + if (n == null)
12.2148 + return null;
12.2149 + AbstractMap.SimpleImmutableEntry<K,V> e = n.createSnapshot();
12.2150 + if (e != null)
12.2151 + return e;
12.2152 + }
12.2153 + }
12.2154 +
12.2155 + /**
12.2156 + * Returns a key-value mapping associated with the greatest
12.2157 + * key in this map, or <tt>null</tt> if the map is empty.
12.2158 + * The returned entry does <em>not</em> support
12.2159 + * the <tt>Entry.setValue</tt> method.
12.2160 + */
12.2161 + public Map.Entry<K,V> lastEntry() {
12.2162 + for (;;) {
12.2163 + Node<K,V> n = findLast();
12.2164 + if (n == null)
12.2165 + return null;
12.2166 + AbstractMap.SimpleImmutableEntry<K,V> e = n.createSnapshot();
12.2167 + if (e != null)
12.2168 + return e;
12.2169 + }
12.2170 + }
12.2171 +
12.2172 + /**
12.2173 + * Removes and returns a key-value mapping associated with
12.2174 + * the least key in this map, or <tt>null</tt> if the map is empty.
12.2175 + * The returned entry does <em>not</em> support
12.2176 + * the <tt>Entry.setValue</tt> method.
12.2177 + */
12.2178 + public Map.Entry<K,V> pollFirstEntry() {
12.2179 + return doRemoveFirstEntry();
12.2180 + }
12.2181 +
12.2182 + /**
12.2183 + * Removes and returns a key-value mapping associated with
12.2184 + * the greatest key in this map, or <tt>null</tt> if the map is empty.
12.2185 + * The returned entry does <em>not</em> support
12.2186 + * the <tt>Entry.setValue</tt> method.
12.2187 + */
12.2188 + public Map.Entry<K,V> pollLastEntry() {
12.2189 + return doRemoveLastEntry();
12.2190 + }
12.2191 +
12.2192 +
12.2193 + /* ---------------- Iterators -------------- */
12.2194 +
12.2195 + /**
12.2196 + * Base of iterator classes:
12.2197 + */
12.2198 + abstract class Iter<T> implements Iterator<T> {
12.2199 + /** the last node returned by next() */
12.2200 + Node<K,V> lastReturned;
12.2201 + /** the next node to return from next(); */
12.2202 + Node<K,V> next;
12.2203 + /** Cache of next value field to maintain weak consistency */
12.2204 + V nextValue;
12.2205 +
12.2206 + /** Initializes ascending iterator for entire range. */
12.2207 + Iter() {
12.2208 + for (;;) {
12.2209 + next = findFirst();
12.2210 + if (next == null)
12.2211 + break;
12.2212 + Object x = next.value;
12.2213 + if (x != null && x != next) {
12.2214 + nextValue = (V) x;
12.2215 + break;
12.2216 + }
12.2217 + }
12.2218 + }
12.2219 +
12.2220 + public final boolean hasNext() {
12.2221 + return next != null;
12.2222 + }
12.2223 +
12.2224 + /** Advances next to higher entry. */
12.2225 + final void advance() {
12.2226 + if (next == null)
12.2227 + throw new NoSuchElementException();
12.2228 + lastReturned = next;
12.2229 + for (;;) {
12.2230 + next = next.next;
12.2231 + if (next == null)
12.2232 + break;
12.2233 + Object x = next.value;
12.2234 + if (x != null && x != next) {
12.2235 + nextValue = (V) x;
12.2236 + break;
12.2237 + }
12.2238 + }
12.2239 + }
12.2240 +
12.2241 + public void remove() {
12.2242 + Node<K,V> l = lastReturned;
12.2243 + if (l == null)
12.2244 + throw new IllegalStateException();
12.2245 + // It would not be worth all of the overhead to directly
12.2246 + // unlink from here. Using remove is fast enough.
12.2247 + ConcurrentSkipListMap.this.remove(l.key);
12.2248 + lastReturned = null;
12.2249 + }
12.2250 +
12.2251 + }
12.2252 +
12.2253 + final class ValueIterator extends Iter<V> {
12.2254 + public V next() {
12.2255 + V v = nextValue;
12.2256 + advance();
12.2257 + return v;
12.2258 + }
12.2259 + }
12.2260 +
12.2261 + final class KeyIterator extends Iter<K> {
12.2262 + public K next() {
12.2263 + Node<K,V> n = next;
12.2264 + advance();
12.2265 + return n.key;
12.2266 + }
12.2267 + }
12.2268 +
12.2269 + final class EntryIterator extends Iter<Map.Entry<K,V>> {
12.2270 + public Map.Entry<K,V> next() {
12.2271 + Node<K,V> n = next;
12.2272 + V v = nextValue;
12.2273 + advance();
12.2274 + return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, v);
12.2275 + }
12.2276 + }
12.2277 +
12.2278 + // Factory methods for iterators needed by ConcurrentSkipListSet etc
12.2279 +
12.2280 + Iterator<K> keyIterator() {
12.2281 + return new KeyIterator();
12.2282 + }
12.2283 +
12.2284 + Iterator<V> valueIterator() {
12.2285 + return new ValueIterator();
12.2286 + }
12.2287 +
12.2288 + Iterator<Map.Entry<K,V>> entryIterator() {
12.2289 + return new EntryIterator();
12.2290 + }
12.2291 +
12.2292 + /* ---------------- View Classes -------------- */
12.2293 +
12.2294 + /*
12.2295 + * View classes are static, delegating to a ConcurrentNavigableMap
12.2296 + * to allow use by SubMaps, which outweighs the ugliness of
12.2297 + * needing type-tests for Iterator methods.
12.2298 + */
12.2299 +
12.2300 + static final <E> List<E> toList(Collection<E> c) {
12.2301 + // Using size() here would be a pessimization.
12.2302 + List<E> list = new ArrayList<E>();
12.2303 + for (E e : c)
12.2304 + list.add(e);
12.2305 + return list;
12.2306 + }
12.2307 +
12.2308 + static final class KeySet<E>
12.2309 + extends AbstractSet<E> implements NavigableSet<E> {
12.2310 + private final ConcurrentNavigableMap<E,Object> m;
12.2311 + KeySet(ConcurrentNavigableMap<E,Object> map) { m = map; }
12.2312 + public int size() { return m.size(); }
12.2313 + public boolean isEmpty() { return m.isEmpty(); }
12.2314 + public boolean contains(Object o) { return m.containsKey(o); }
12.2315 + public boolean remove(Object o) { return m.remove(o) != null; }
12.2316 + public void clear() { m.clear(); }
12.2317 + public E lower(E e) { return m.lowerKey(e); }
12.2318 + public E floor(E e) { return m.floorKey(e); }
12.2319 + public E ceiling(E e) { return m.ceilingKey(e); }
12.2320 + public E higher(E e) { return m.higherKey(e); }
12.2321 + public Comparator<? super E> comparator() { return m.comparator(); }
12.2322 + public E first() { return m.firstKey(); }
12.2323 + public E last() { return m.lastKey(); }
12.2324 + public E pollFirst() {
12.2325 + Map.Entry<E,Object> e = m.pollFirstEntry();
12.2326 + return (e == null) ? null : e.getKey();
12.2327 + }
12.2328 + public E pollLast() {
12.2329 + Map.Entry<E,Object> e = m.pollLastEntry();
12.2330 + return (e == null) ? null : e.getKey();
12.2331 + }
12.2332 + public Iterator<E> iterator() {
12.2333 + if (m instanceof ConcurrentSkipListMap)
12.2334 + return ((ConcurrentSkipListMap<E,Object>)m).keyIterator();
12.2335 + else
12.2336 + return ((ConcurrentSkipListMap.SubMap<E,Object>)m).keyIterator();
12.2337 + }
12.2338 + public boolean equals(Object o) {
12.2339 + if (o == this)
12.2340 + return true;
12.2341 + if (!(o instanceof Set))
12.2342 + return false;
12.2343 + Collection<?> c = (Collection<?>) o;
12.2344 + try {
12.2345 + return containsAll(c) && c.containsAll(this);
12.2346 + } catch (ClassCastException unused) {
12.2347 + return false;
12.2348 + } catch (NullPointerException unused) {
12.2349 + return false;
12.2350 + }
12.2351 + }
12.2352 + public Object[] toArray() { return toList(this).toArray(); }
12.2353 + public <T> T[] toArray(T[] a) { return toList(this).toArray(a); }
12.2354 + public Iterator<E> descendingIterator() {
12.2355 + return descendingSet().iterator();
12.2356 + }
12.2357 + public NavigableSet<E> subSet(E fromElement,
12.2358 + boolean fromInclusive,
12.2359 + E toElement,
12.2360 + boolean toInclusive) {
12.2361 + return new KeySet<E>(m.subMap(fromElement, fromInclusive,
12.2362 + toElement, toInclusive));
12.2363 + }
12.2364 + public NavigableSet<E> headSet(E toElement, boolean inclusive) {
12.2365 + return new KeySet<E>(m.headMap(toElement, inclusive));
12.2366 + }
12.2367 + public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
12.2368 + return new KeySet<E>(m.tailMap(fromElement, inclusive));
12.2369 + }
12.2370 + public NavigableSet<E> subSet(E fromElement, E toElement) {
12.2371 + return subSet(fromElement, true, toElement, false);
12.2372 + }
12.2373 + public NavigableSet<E> headSet(E toElement) {
12.2374 + return headSet(toElement, false);
12.2375 + }
12.2376 + public NavigableSet<E> tailSet(E fromElement) {
12.2377 + return tailSet(fromElement, true);
12.2378 + }
12.2379 + public NavigableSet<E> descendingSet() {
12.2380 + return new KeySet(m.descendingMap());
12.2381 + }
12.2382 + }
12.2383 +
12.2384 + static final class Values<E> extends AbstractCollection<E> {
12.2385 + private final ConcurrentNavigableMap<Object, E> m;
12.2386 + Values(ConcurrentNavigableMap<Object, E> map) {
12.2387 + m = map;
12.2388 + }
12.2389 + public Iterator<E> iterator() {
12.2390 + if (m instanceof ConcurrentSkipListMap)
12.2391 + return ((ConcurrentSkipListMap<Object,E>)m).valueIterator();
12.2392 + else
12.2393 + return ((SubMap<Object,E>)m).valueIterator();
12.2394 + }
12.2395 + public boolean isEmpty() {
12.2396 + return m.isEmpty();
12.2397 + }
12.2398 + public int size() {
12.2399 + return m.size();
12.2400 + }
12.2401 + public boolean contains(Object o) {
12.2402 + return m.containsValue(o);
12.2403 + }
12.2404 + public void clear() {
12.2405 + m.clear();
12.2406 + }
12.2407 + public Object[] toArray() { return toList(this).toArray(); }
12.2408 + public <T> T[] toArray(T[] a) { return toList(this).toArray(a); }
12.2409 + }
12.2410 +
12.2411 + static final class EntrySet<K1,V1> extends AbstractSet<Map.Entry<K1,V1>> {
12.2412 + private final ConcurrentNavigableMap<K1, V1> m;
12.2413 + EntrySet(ConcurrentNavigableMap<K1, V1> map) {
12.2414 + m = map;
12.2415 + }
12.2416 +
12.2417 + public Iterator<Map.Entry<K1,V1>> iterator() {
12.2418 + if (m instanceof ConcurrentSkipListMap)
12.2419 + return ((ConcurrentSkipListMap<K1,V1>)m).entryIterator();
12.2420 + else
12.2421 + return ((SubMap<K1,V1>)m).entryIterator();
12.2422 + }
12.2423 +
12.2424 + public boolean contains(Object o) {
12.2425 + if (!(o instanceof Map.Entry))
12.2426 + return false;
12.2427 + Map.Entry<K1,V1> e = (Map.Entry<K1,V1>)o;
12.2428 + V1 v = m.get(e.getKey());
12.2429 + return v != null && v.equals(e.getValue());
12.2430 + }
12.2431 + public boolean remove(Object o) {
12.2432 + if (!(o instanceof Map.Entry))
12.2433 + return false;
12.2434 + Map.Entry<K1,V1> e = (Map.Entry<K1,V1>)o;
12.2435 + return m.remove(e.getKey(),
12.2436 + e.getValue());
12.2437 + }
12.2438 + public boolean isEmpty() {
12.2439 + return m.isEmpty();
12.2440 + }
12.2441 + public int size() {
12.2442 + return m.size();
12.2443 + }
12.2444 + public void clear() {
12.2445 + m.clear();
12.2446 + }
12.2447 + public boolean equals(Object o) {
12.2448 + if (o == this)
12.2449 + return true;
12.2450 + if (!(o instanceof Set))
12.2451 + return false;
12.2452 + Collection<?> c = (Collection<?>) o;
12.2453 + try {
12.2454 + return containsAll(c) && c.containsAll(this);
12.2455 + } catch (ClassCastException unused) {
12.2456 + return false;
12.2457 + } catch (NullPointerException unused) {
12.2458 + return false;
12.2459 + }
12.2460 + }
12.2461 + public Object[] toArray() { return toList(this).toArray(); }
12.2462 + public <T> T[] toArray(T[] a) { return toList(this).toArray(a); }
12.2463 + }
12.2464 +
12.2465 + /**
12.2466 + * Submaps returned by {@link ConcurrentSkipListMap} submap operations
12.2467 + * represent a subrange of mappings of their underlying
12.2468 + * maps. Instances of this class support all methods of their
12.2469 + * underlying maps, differing in that mappings outside their range are
12.2470 + * ignored, and attempts to add mappings outside their ranges result
12.2471 + * in {@link IllegalArgumentException}. Instances of this class are
12.2472 + * constructed only using the <tt>subMap</tt>, <tt>headMap</tt>, and
12.2473 + * <tt>tailMap</tt> methods of their underlying maps.
12.2474 + *
12.2475 + * @serial include
12.2476 + */
12.2477 + static final class SubMap<K,V> extends AbstractMap<K,V>
12.2478 + implements ConcurrentNavigableMap<K,V>, Cloneable,
12.2479 + java.io.Serializable {
12.2480 + private static final long serialVersionUID = -7647078645895051609L;
12.2481 +
12.2482 + /** Underlying map */
12.2483 + private final ConcurrentSkipListMap<K,V> m;
12.2484 + /** lower bound key, or null if from start */
12.2485 + private final K lo;
12.2486 + /** upper bound key, or null if to end */
12.2487 + private final K hi;
12.2488 + /** inclusion flag for lo */
12.2489 + private final boolean loInclusive;
12.2490 + /** inclusion flag for hi */
12.2491 + private final boolean hiInclusive;
12.2492 + /** direction */
12.2493 + private final boolean isDescending;
12.2494 +
12.2495 + // Lazily initialized view holders
12.2496 + private transient KeySet<K> keySetView;
12.2497 + private transient Set<Map.Entry<K,V>> entrySetView;
12.2498 + private transient Collection<V> valuesView;
12.2499 +
12.2500 + /**
12.2501 + * Creates a new submap, initializing all fields
12.2502 + */
12.2503 + SubMap(ConcurrentSkipListMap<K,V> map,
12.2504 + K fromKey, boolean fromInclusive,
12.2505 + K toKey, boolean toInclusive,
12.2506 + boolean isDescending) {
12.2507 + if (fromKey != null && toKey != null &&
12.2508 + map.compare(fromKey, toKey) > 0)
12.2509 + throw new IllegalArgumentException("inconsistent range");
12.2510 + this.m = map;
12.2511 + this.lo = fromKey;
12.2512 + this.hi = toKey;
12.2513 + this.loInclusive = fromInclusive;
12.2514 + this.hiInclusive = toInclusive;
12.2515 + this.isDescending = isDescending;
12.2516 + }
12.2517 +
12.2518 + /* ---------------- Utilities -------------- */
12.2519 +
12.2520 + private boolean tooLow(K key) {
12.2521 + if (lo != null) {
12.2522 + int c = m.compare(key, lo);
12.2523 + if (c < 0 || (c == 0 && !loInclusive))
12.2524 + return true;
12.2525 + }
12.2526 + return false;
12.2527 + }
12.2528 +
12.2529 + private boolean tooHigh(K key) {
12.2530 + if (hi != null) {
12.2531 + int c = m.compare(key, hi);
12.2532 + if (c > 0 || (c == 0 && !hiInclusive))
12.2533 + return true;
12.2534 + }
12.2535 + return false;
12.2536 + }
12.2537 +
12.2538 + private boolean inBounds(K key) {
12.2539 + return !tooLow(key) && !tooHigh(key);
12.2540 + }
12.2541 +
12.2542 + private void checkKeyBounds(K key) throws IllegalArgumentException {
12.2543 + if (key == null)
12.2544 + throw new NullPointerException();
12.2545 + if (!inBounds(key))
12.2546 + throw new IllegalArgumentException("key out of range");
12.2547 + }
12.2548 +
12.2549 + /**
12.2550 + * Returns true if node key is less than upper bound of range
12.2551 + */
12.2552 + private boolean isBeforeEnd(ConcurrentSkipListMap.Node<K,V> n) {
12.2553 + if (n == null)
12.2554 + return false;
12.2555 + if (hi == null)
12.2556 + return true;
12.2557 + K k = n.key;
12.2558 + if (k == null) // pass by markers and headers
12.2559 + return true;
12.2560 + int c = m.compare(k, hi);
12.2561 + if (c > 0 || (c == 0 && !hiInclusive))
12.2562 + return false;
12.2563 + return true;
12.2564 + }
12.2565 +
12.2566 + /**
12.2567 + * Returns lowest node. This node might not be in range, so
12.2568 + * most usages need to check bounds
12.2569 + */
12.2570 + private ConcurrentSkipListMap.Node<K,V> loNode() {
12.2571 + if (lo == null)
12.2572 + return m.findFirst();
12.2573 + else if (loInclusive)
12.2574 + return m.findNear(lo, m.GT|m.EQ);
12.2575 + else
12.2576 + return m.findNear(lo, m.GT);
12.2577 + }
12.2578 +
12.2579 + /**
12.2580 + * Returns highest node. This node might not be in range, so
12.2581 + * most usages need to check bounds
12.2582 + */
12.2583 + private ConcurrentSkipListMap.Node<K,V> hiNode() {
12.2584 + if (hi == null)
12.2585 + return m.findLast();
12.2586 + else if (hiInclusive)
12.2587 + return m.findNear(hi, m.LT|m.EQ);
12.2588 + else
12.2589 + return m.findNear(hi, m.LT);
12.2590 + }
12.2591 +
12.2592 + /**
12.2593 + * Returns lowest absolute key (ignoring directonality)
12.2594 + */
12.2595 + private K lowestKey() {
12.2596 + ConcurrentSkipListMap.Node<K,V> n = loNode();
12.2597 + if (isBeforeEnd(n))
12.2598 + return n.key;
12.2599 + else
12.2600 + throw new NoSuchElementException();
12.2601 + }
12.2602 +
12.2603 + /**
12.2604 + * Returns highest absolute key (ignoring directonality)
12.2605 + */
12.2606 + private K highestKey() {
12.2607 + ConcurrentSkipListMap.Node<K,V> n = hiNode();
12.2608 + if (n != null) {
12.2609 + K last = n.key;
12.2610 + if (inBounds(last))
12.2611 + return last;
12.2612 + }
12.2613 + throw new NoSuchElementException();
12.2614 + }
12.2615 +
12.2616 + private Map.Entry<K,V> lowestEntry() {
12.2617 + for (;;) {
12.2618 + ConcurrentSkipListMap.Node<K,V> n = loNode();
12.2619 + if (!isBeforeEnd(n))
12.2620 + return null;
12.2621 + Map.Entry<K,V> e = n.createSnapshot();
12.2622 + if (e != null)
12.2623 + return e;
12.2624 + }
12.2625 + }
12.2626 +
12.2627 + private Map.Entry<K,V> highestEntry() {
12.2628 + for (;;) {
12.2629 + ConcurrentSkipListMap.Node<K,V> n = hiNode();
12.2630 + if (n == null || !inBounds(n.key))
12.2631 + return null;
12.2632 + Map.Entry<K,V> e = n.createSnapshot();
12.2633 + if (e != null)
12.2634 + return e;
12.2635 + }
12.2636 + }
12.2637 +
12.2638 + private Map.Entry<K,V> removeLowest() {
12.2639 + for (;;) {
12.2640 + Node<K,V> n = loNode();
12.2641 + if (n == null)
12.2642 + return null;
12.2643 + K k = n.key;
12.2644 + if (!inBounds(k))
12.2645 + return null;
12.2646 + V v = m.doRemove(k, null);
12.2647 + if (v != null)
12.2648 + return new AbstractMap.SimpleImmutableEntry<K,V>(k, v);
12.2649 + }
12.2650 + }
12.2651 +
12.2652 + private Map.Entry<K,V> removeHighest() {
12.2653 + for (;;) {
12.2654 + Node<K,V> n = hiNode();
12.2655 + if (n == null)
12.2656 + return null;
12.2657 + K k = n.key;
12.2658 + if (!inBounds(k))
12.2659 + return null;
12.2660 + V v = m.doRemove(k, null);
12.2661 + if (v != null)
12.2662 + return new AbstractMap.SimpleImmutableEntry<K,V>(k, v);
12.2663 + }
12.2664 + }
12.2665 +
12.2666 + /**
12.2667 + * Submap version of ConcurrentSkipListMap.getNearEntry
12.2668 + */
12.2669 + private Map.Entry<K,V> getNearEntry(K key, int rel) {
12.2670 + if (isDescending) { // adjust relation for direction
12.2671 + if ((rel & m.LT) == 0)
12.2672 + rel |= m.LT;
12.2673 + else
12.2674 + rel &= ~m.LT;
12.2675 + }
12.2676 + if (tooLow(key))
12.2677 + return ((rel & m.LT) != 0) ? null : lowestEntry();
12.2678 + if (tooHigh(key))
12.2679 + return ((rel & m.LT) != 0) ? highestEntry() : null;
12.2680 + for (;;) {
12.2681 + Node<K,V> n = m.findNear(key, rel);
12.2682 + if (n == null || !inBounds(n.key))
12.2683 + return null;
12.2684 + K k = n.key;
12.2685 + V v = n.getValidValue();
12.2686 + if (v != null)
12.2687 + return new AbstractMap.SimpleImmutableEntry<K,V>(k, v);
12.2688 + }
12.2689 + }
12.2690 +
12.2691 + // Almost the same as getNearEntry, except for keys
12.2692 + private K getNearKey(K key, int rel) {
12.2693 + if (isDescending) { // adjust relation for direction
12.2694 + if ((rel & m.LT) == 0)
12.2695 + rel |= m.LT;
12.2696 + else
12.2697 + rel &= ~m.LT;
12.2698 + }
12.2699 + if (tooLow(key)) {
12.2700 + if ((rel & m.LT) == 0) {
12.2701 + ConcurrentSkipListMap.Node<K,V> n = loNode();
12.2702 + if (isBeforeEnd(n))
12.2703 + return n.key;
12.2704 + }
12.2705 + return null;
12.2706 + }
12.2707 + if (tooHigh(key)) {
12.2708 + if ((rel & m.LT) != 0) {
12.2709 + ConcurrentSkipListMap.Node<K,V> n = hiNode();
12.2710 + if (n != null) {
12.2711 + K last = n.key;
12.2712 + if (inBounds(last))
12.2713 + return last;
12.2714 + }
12.2715 + }
12.2716 + return null;
12.2717 + }
12.2718 + for (;;) {
12.2719 + Node<K,V> n = m.findNear(key, rel);
12.2720 + if (n == null || !inBounds(n.key))
12.2721 + return null;
12.2722 + K k = n.key;
12.2723 + V v = n.getValidValue();
12.2724 + if (v != null)
12.2725 + return k;
12.2726 + }
12.2727 + }
12.2728 +
12.2729 + /* ---------------- Map API methods -------------- */
12.2730 +
12.2731 + public boolean containsKey(Object key) {
12.2732 + if (key == null) throw new NullPointerException();
12.2733 + K k = (K)key;
12.2734 + return inBounds(k) && m.containsKey(k);
12.2735 + }
12.2736 +
12.2737 + public V get(Object key) {
12.2738 + if (key == null) throw new NullPointerException();
12.2739 + K k = (K)key;
12.2740 + return ((!inBounds(k)) ? null : m.get(k));
12.2741 + }
12.2742 +
12.2743 + public V put(K key, V value) {
12.2744 + checkKeyBounds(key);
12.2745 + return m.put(key, value);
12.2746 + }
12.2747 +
12.2748 + public V remove(Object key) {
12.2749 + K k = (K)key;
12.2750 + return (!inBounds(k)) ? null : m.remove(k);
12.2751 + }
12.2752 +
12.2753 + public int size() {
12.2754 + long count = 0;
12.2755 + for (ConcurrentSkipListMap.Node<K,V> n = loNode();
12.2756 + isBeforeEnd(n);
12.2757 + n = n.next) {
12.2758 + if (n.getValidValue() != null)
12.2759 + ++count;
12.2760 + }
12.2761 + return count >= Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)count;
12.2762 + }
12.2763 +
12.2764 + public boolean isEmpty() {
12.2765 + return !isBeforeEnd(loNode());
12.2766 + }
12.2767 +
12.2768 + public boolean containsValue(Object value) {
12.2769 + if (value == null)
12.2770 + throw new NullPointerException();
12.2771 + for (ConcurrentSkipListMap.Node<K,V> n = loNode();
12.2772 + isBeforeEnd(n);
12.2773 + n = n.next) {
12.2774 + V v = n.getValidValue();
12.2775 + if (v != null && value.equals(v))
12.2776 + return true;
12.2777 + }
12.2778 + return false;
12.2779 + }
12.2780 +
12.2781 + public void clear() {
12.2782 + for (ConcurrentSkipListMap.Node<K,V> n = loNode();
12.2783 + isBeforeEnd(n);
12.2784 + n = n.next) {
12.2785 + if (n.getValidValue() != null)
12.2786 + m.remove(n.key);
12.2787 + }
12.2788 + }
12.2789 +
12.2790 + /* ---------------- ConcurrentMap API methods -------------- */
12.2791 +
12.2792 + public V putIfAbsent(K key, V value) {
12.2793 + checkKeyBounds(key);
12.2794 + return m.putIfAbsent(key, value);
12.2795 + }
12.2796 +
12.2797 + public boolean remove(Object key, Object value) {
12.2798 + K k = (K)key;
12.2799 + return inBounds(k) && m.remove(k, value);
12.2800 + }
12.2801 +
12.2802 + public boolean replace(K key, V oldValue, V newValue) {
12.2803 + checkKeyBounds(key);
12.2804 + return m.replace(key, oldValue, newValue);
12.2805 + }
12.2806 +
12.2807 + public V replace(K key, V value) {
12.2808 + checkKeyBounds(key);
12.2809 + return m.replace(key, value);
12.2810 + }
12.2811 +
12.2812 + /* ---------------- SortedMap API methods -------------- */
12.2813 +
12.2814 + public Comparator<? super K> comparator() {
12.2815 + Comparator<? super K> cmp = m.comparator();
12.2816 + if (isDescending)
12.2817 + return Collections.reverseOrder(cmp);
12.2818 + else
12.2819 + return cmp;
12.2820 + }
12.2821 +
12.2822 + /**
12.2823 + * Utility to create submaps, where given bounds override
12.2824 + * unbounded(null) ones and/or are checked against bounded ones.
12.2825 + */
12.2826 + private SubMap<K,V> newSubMap(K fromKey,
12.2827 + boolean fromInclusive,
12.2828 + K toKey,
12.2829 + boolean toInclusive) {
12.2830 + if (isDescending) { // flip senses
12.2831 + K tk = fromKey;
12.2832 + fromKey = toKey;
12.2833 + toKey = tk;
12.2834 + boolean ti = fromInclusive;
12.2835 + fromInclusive = toInclusive;
12.2836 + toInclusive = ti;
12.2837 + }
12.2838 + if (lo != null) {
12.2839 + if (fromKey == null) {
12.2840 + fromKey = lo;
12.2841 + fromInclusive = loInclusive;
12.2842 + }
12.2843 + else {
12.2844 + int c = m.compare(fromKey, lo);
12.2845 + if (c < 0 || (c == 0 && !loInclusive && fromInclusive))
12.2846 + throw new IllegalArgumentException("key out of range");
12.2847 + }
12.2848 + }
12.2849 + if (hi != null) {
12.2850 + if (toKey == null) {
12.2851 + toKey = hi;
12.2852 + toInclusive = hiInclusive;
12.2853 + }
12.2854 + else {
12.2855 + int c = m.compare(toKey, hi);
12.2856 + if (c > 0 || (c == 0 && !hiInclusive && toInclusive))
12.2857 + throw new IllegalArgumentException("key out of range");
12.2858 + }
12.2859 + }
12.2860 + return new SubMap<K,V>(m, fromKey, fromInclusive,
12.2861 + toKey, toInclusive, isDescending);
12.2862 + }
12.2863 +
12.2864 + public SubMap<K,V> subMap(K fromKey,
12.2865 + boolean fromInclusive,
12.2866 + K toKey,
12.2867 + boolean toInclusive) {
12.2868 + if (fromKey == null || toKey == null)
12.2869 + throw new NullPointerException();
12.2870 + return newSubMap(fromKey, fromInclusive, toKey, toInclusive);
12.2871 + }
12.2872 +
12.2873 + public SubMap<K,V> headMap(K toKey,
12.2874 + boolean inclusive) {
12.2875 + if (toKey == null)
12.2876 + throw new NullPointerException();
12.2877 + return newSubMap(null, false, toKey, inclusive);
12.2878 + }
12.2879 +
12.2880 + public SubMap<K,V> tailMap(K fromKey,
12.2881 + boolean inclusive) {
12.2882 + if (fromKey == null)
12.2883 + throw new NullPointerException();
12.2884 + return newSubMap(fromKey, inclusive, null, false);
12.2885 + }
12.2886 +
12.2887 + public SubMap<K,V> subMap(K fromKey, K toKey) {
12.2888 + return subMap(fromKey, true, toKey, false);
12.2889 + }
12.2890 +
12.2891 + public SubMap<K,V> headMap(K toKey) {
12.2892 + return headMap(toKey, false);
12.2893 + }
12.2894 +
12.2895 + public SubMap<K,V> tailMap(K fromKey) {
12.2896 + return tailMap(fromKey, true);
12.2897 + }
12.2898 +
12.2899 + public SubMap<K,V> descendingMap() {
12.2900 + return new SubMap<K,V>(m, lo, loInclusive,
12.2901 + hi, hiInclusive, !isDescending);
12.2902 + }
12.2903 +
12.2904 + /* ---------------- Relational methods -------------- */
12.2905 +
12.2906 + public Map.Entry<K,V> ceilingEntry(K key) {
12.2907 + return getNearEntry(key, (m.GT|m.EQ));
12.2908 + }
12.2909 +
12.2910 + public K ceilingKey(K key) {
12.2911 + return getNearKey(key, (m.GT|m.EQ));
12.2912 + }
12.2913 +
12.2914 + public Map.Entry<K,V> lowerEntry(K key) {
12.2915 + return getNearEntry(key, (m.LT));
12.2916 + }
12.2917 +
12.2918 + public K lowerKey(K key) {
12.2919 + return getNearKey(key, (m.LT));
12.2920 + }
12.2921 +
12.2922 + public Map.Entry<K,V> floorEntry(K key) {
12.2923 + return getNearEntry(key, (m.LT|m.EQ));
12.2924 + }
12.2925 +
12.2926 + public K floorKey(K key) {
12.2927 + return getNearKey(key, (m.LT|m.EQ));
12.2928 + }
12.2929 +
12.2930 + public Map.Entry<K,V> higherEntry(K key) {
12.2931 + return getNearEntry(key, (m.GT));
12.2932 + }
12.2933 +
12.2934 + public K higherKey(K key) {
12.2935 + return getNearKey(key, (m.GT));
12.2936 + }
12.2937 +
12.2938 + public K firstKey() {
12.2939 + return isDescending ? highestKey() : lowestKey();
12.2940 + }
12.2941 +
12.2942 + public K lastKey() {
12.2943 + return isDescending ? lowestKey() : highestKey();
12.2944 + }
12.2945 +
12.2946 + public Map.Entry<K,V> firstEntry() {
12.2947 + return isDescending ? highestEntry() : lowestEntry();
12.2948 + }
12.2949 +
12.2950 + public Map.Entry<K,V> lastEntry() {
12.2951 + return isDescending ? lowestEntry() : highestEntry();
12.2952 + }
12.2953 +
12.2954 + public Map.Entry<K,V> pollFirstEntry() {
12.2955 + return isDescending ? removeHighest() : removeLowest();
12.2956 + }
12.2957 +
12.2958 + public Map.Entry<K,V> pollLastEntry() {
12.2959 + return isDescending ? removeLowest() : removeHighest();
12.2960 + }
12.2961 +
12.2962 + /* ---------------- Submap Views -------------- */
12.2963 +
12.2964 + public NavigableSet<K> keySet() {
12.2965 + KeySet<K> ks = keySetView;
12.2966 + return (ks != null) ? ks : (keySetView = new KeySet(this));
12.2967 + }
12.2968 +
12.2969 + public NavigableSet<K> navigableKeySet() {
12.2970 + KeySet<K> ks = keySetView;
12.2971 + return (ks != null) ? ks : (keySetView = new KeySet(this));
12.2972 + }
12.2973 +
12.2974 + public Collection<V> values() {
12.2975 + Collection<V> vs = valuesView;
12.2976 + return (vs != null) ? vs : (valuesView = new Values(this));
12.2977 + }
12.2978 +
12.2979 + public Set<Map.Entry<K,V>> entrySet() {
12.2980 + Set<Map.Entry<K,V>> es = entrySetView;
12.2981 + return (es != null) ? es : (entrySetView = new EntrySet(this));
12.2982 + }
12.2983 +
12.2984 + public NavigableSet<K> descendingKeySet() {
12.2985 + return descendingMap().navigableKeySet();
12.2986 + }
12.2987 +
12.2988 + Iterator<K> keyIterator() {
12.2989 + return new SubMapKeyIterator();
12.2990 + }
12.2991 +
12.2992 + Iterator<V> valueIterator() {
12.2993 + return new SubMapValueIterator();
12.2994 + }
12.2995 +
12.2996 + Iterator<Map.Entry<K,V>> entryIterator() {
12.2997 + return new SubMapEntryIterator();
12.2998 + }
12.2999 +
12.3000 + /**
12.3001 + * Variant of main Iter class to traverse through submaps.
12.3002 + */
12.3003 + abstract class SubMapIter<T> implements Iterator<T> {
12.3004 + /** the last node returned by next() */
12.3005 + Node<K,V> lastReturned;
12.3006 + /** the next node to return from next(); */
12.3007 + Node<K,V> next;
12.3008 + /** Cache of next value field to maintain weak consistency */
12.3009 + V nextValue;
12.3010 +
12.3011 + SubMapIter() {
12.3012 + for (;;) {
12.3013 + next = isDescending ? hiNode() : loNode();
12.3014 + if (next == null)
12.3015 + break;
12.3016 + Object x = next.value;
12.3017 + if (x != null && x != next) {
12.3018 + if (! inBounds(next.key))
12.3019 + next = null;
12.3020 + else
12.3021 + nextValue = (V) x;
12.3022 + break;
12.3023 + }
12.3024 + }
12.3025 + }
12.3026 +
12.3027 + public final boolean hasNext() {
12.3028 + return next != null;
12.3029 + }
12.3030 +
12.3031 + final void advance() {
12.3032 + if (next == null)
12.3033 + throw new NoSuchElementException();
12.3034 + lastReturned = next;
12.3035 + if (isDescending)
12.3036 + descend();
12.3037 + else
12.3038 + ascend();
12.3039 + }
12.3040 +
12.3041 + private void ascend() {
12.3042 + for (;;) {
12.3043 + next = next.next;
12.3044 + if (next == null)
12.3045 + break;
12.3046 + Object x = next.value;
12.3047 + if (x != null && x != next) {
12.3048 + if (tooHigh(next.key))
12.3049 + next = null;
12.3050 + else
12.3051 + nextValue = (V) x;
12.3052 + break;
12.3053 + }
12.3054 + }
12.3055 + }
12.3056 +
12.3057 + private void descend() {
12.3058 + for (;;) {
12.3059 + next = m.findNear(lastReturned.key, LT);
12.3060 + if (next == null)
12.3061 + break;
12.3062 + Object x = next.value;
12.3063 + if (x != null && x != next) {
12.3064 + if (tooLow(next.key))
12.3065 + next = null;
12.3066 + else
12.3067 + nextValue = (V) x;
12.3068 + break;
12.3069 + }
12.3070 + }
12.3071 + }
12.3072 +
12.3073 + public void remove() {
12.3074 + Node<K,V> l = lastReturned;
12.3075 + if (l == null)
12.3076 + throw new IllegalStateException();
12.3077 + m.remove(l.key);
12.3078 + lastReturned = null;
12.3079 + }
12.3080 +
12.3081 + }
12.3082 +
12.3083 + final class SubMapValueIterator extends SubMapIter<V> {
12.3084 + public V next() {
12.3085 + V v = nextValue;
12.3086 + advance();
12.3087 + return v;
12.3088 + }
12.3089 + }
12.3090 +
12.3091 + final class SubMapKeyIterator extends SubMapIter<K> {
12.3092 + public K next() {
12.3093 + Node<K,V> n = next;
12.3094 + advance();
12.3095 + return n.key;
12.3096 + }
12.3097 + }
12.3098 +
12.3099 + final class SubMapEntryIterator extends SubMapIter<Map.Entry<K,V>> {
12.3100 + public Map.Entry<K,V> next() {
12.3101 + Node<K,V> n = next;
12.3102 + V v = nextValue;
12.3103 + advance();
12.3104 + return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, v);
12.3105 + }
12.3106 + }
12.3107 + }
12.3108 +
12.3109 + // Unsafe mechanics
12.3110 + private static final sun.misc.Unsafe UNSAFE;
12.3111 + private static final long headOffset;
12.3112 + static {
12.3113 + try {
12.3114 + UNSAFE = sun.misc.Unsafe.getUnsafe();
12.3115 + Class k = ConcurrentSkipListMap.class;
12.3116 + headOffset = UNSAFE.objectFieldOffset
12.3117 + (k.getDeclaredField("head"));
12.3118 + } catch (Exception e) {
12.3119 + throw new Error(e);
12.3120 + }
12.3121 + }
12.3122 +}
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ConcurrentSkipListSet.java Sat Mar 19 10:46:31 2016 +0100
13.3 @@ -0,0 +1,491 @@
13.4 +/*
13.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
13.6 + *
13.7 + * This code is free software; you can redistribute it and/or modify it
13.8 + * under the terms of the GNU General Public License version 2 only, as
13.9 + * published by the Free Software Foundation. Oracle designates this
13.10 + * particular file as subject to the "Classpath" exception as provided
13.11 + * by Oracle in the LICENSE file that accompanied this code.
13.12 + *
13.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
13.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13.16 + * version 2 for more details (a copy is included in the LICENSE file that
13.17 + * accompanied this code).
13.18 + *
13.19 + * You should have received a copy of the GNU General Public License version
13.20 + * 2 along with this work; if not, write to the Free Software Foundation,
13.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
13.22 + *
13.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
13.24 + * or visit www.oracle.com if you need additional information or have any
13.25 + * questions.
13.26 + */
13.27 +
13.28 +/*
13.29 + * This file is available under and governed by the GNU General Public
13.30 + * License version 2 only, as published by the Free Software Foundation.
13.31 + * However, the following notice accompanied the original version of this
13.32 + * file:
13.33 + *
13.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
13.35 + * Expert Group and released to the public domain, as explained at
13.36 + * http://creativecommons.org/publicdomain/zero/1.0/
13.37 + */
13.38 +
13.39 +package java.util.concurrent;
13.40 +import java.util.*;
13.41 +import sun.misc.Unsafe;
13.42 +
13.43 +/**
13.44 + * A scalable concurrent {@link NavigableSet} implementation based on
13.45 + * a {@link ConcurrentSkipListMap}. The elements of the set are kept
13.46 + * sorted according to their {@linkplain Comparable natural ordering},
13.47 + * or by a {@link Comparator} provided at set creation time, depending
13.48 + * on which constructor is used.
13.49 + *
13.50 + * <p>This implementation provides expected average <i>log(n)</i> time
13.51 + * cost for the <tt>contains</tt>, <tt>add</tt>, and <tt>remove</tt>
13.52 + * operations and their variants. Insertion, removal, and access
13.53 + * operations safely execute concurrently by multiple threads.
13.54 + * Iterators are <i>weakly consistent</i>, returning elements
13.55 + * reflecting the state of the set at some point at or since the
13.56 + * creation of the iterator. They do <em>not</em> throw {@link
13.57 + * ConcurrentModificationException}, and may proceed concurrently with
13.58 + * other operations. Ascending ordered views and their iterators are
13.59 + * faster than descending ones.
13.60 + *
13.61 + * <p>Beware that, unlike in most collections, the <tt>size</tt>
13.62 + * method is <em>not</em> a constant-time operation. Because of the
13.63 + * asynchronous nature of these sets, determining the current number
13.64 + * of elements requires a traversal of the elements, and so may report
13.65 + * inaccurate results if this collection is modified during traversal.
13.66 + * Additionally, the bulk operations <tt>addAll</tt>,
13.67 + * <tt>removeAll</tt>, <tt>retainAll</tt>, <tt>containsAll</tt>,
13.68 + * <tt>equals</tt>, and <tt>toArray</tt> are <em>not</em> guaranteed
13.69 + * to be performed atomically. For example, an iterator operating
13.70 + * concurrently with an <tt>addAll</tt> operation might view only some
13.71 + * of the added elements.
13.72 + *
13.73 + * <p>This class and its iterators implement all of the
13.74 + * <em>optional</em> methods of the {@link Set} and {@link Iterator}
13.75 + * interfaces. Like most other concurrent collection implementations,
13.76 + * this class does not permit the use of <tt>null</tt> elements,
13.77 + * because <tt>null</tt> arguments and return values cannot be reliably
13.78 + * distinguished from the absence of elements.
13.79 + *
13.80 + * <p>This class is a member of the
13.81 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
13.82 + * Java Collections Framework</a>.
13.83 + *
13.84 + * @author Doug Lea
13.85 + * @param <E> the type of elements maintained by this set
13.86 + * @since 1.6
13.87 + */
13.88 +public class ConcurrentSkipListSet<E>
13.89 + extends AbstractSet<E>
13.90 + implements NavigableSet<E>, Cloneable, java.io.Serializable {
13.91 +
13.92 + private static final long serialVersionUID = -2479143111061671589L;
13.93 +
13.94 + /**
13.95 + * The underlying map. Uses Boolean.TRUE as value for each
13.96 + * element. This field is declared final for the sake of thread
13.97 + * safety, which entails some ugliness in clone()
13.98 + */
13.99 + private final ConcurrentNavigableMap<E,Object> m;
13.100 +
13.101 + /**
13.102 + * Constructs a new, empty set that orders its elements according to
13.103 + * their {@linkplain Comparable natural ordering}.
13.104 + */
13.105 + public ConcurrentSkipListSet() {
13.106 + m = new ConcurrentSkipListMap<E,Object>();
13.107 + }
13.108 +
13.109 + /**
13.110 + * Constructs a new, empty set that orders its elements according to
13.111 + * the specified comparator.
13.112 + *
13.113 + * @param comparator the comparator that will be used to order this set.
13.114 + * If <tt>null</tt>, the {@linkplain Comparable natural
13.115 + * ordering} of the elements will be used.
13.116 + */
13.117 + public ConcurrentSkipListSet(Comparator<? super E> comparator) {
13.118 + m = new ConcurrentSkipListMap<E,Object>(comparator);
13.119 + }
13.120 +
13.121 + /**
13.122 + * Constructs a new set containing the elements in the specified
13.123 + * collection, that orders its elements according to their
13.124 + * {@linkplain Comparable natural ordering}.
13.125 + *
13.126 + * @param c The elements that will comprise the new set
13.127 + * @throws ClassCastException if the elements in <tt>c</tt> are
13.128 + * not {@link Comparable}, or are not mutually comparable
13.129 + * @throws NullPointerException if the specified collection or any
13.130 + * of its elements are null
13.131 + */
13.132 + public ConcurrentSkipListSet(Collection<? extends E> c) {
13.133 + m = new ConcurrentSkipListMap<E,Object>();
13.134 + addAll(c);
13.135 + }
13.136 +
13.137 + /**
13.138 + * Constructs a new set containing the same elements and using the
13.139 + * same ordering as the specified sorted set.
13.140 + *
13.141 + * @param s sorted set whose elements will comprise the new set
13.142 + * @throws NullPointerException if the specified sorted set or any
13.143 + * of its elements are null
13.144 + */
13.145 + public ConcurrentSkipListSet(SortedSet<E> s) {
13.146 + m = new ConcurrentSkipListMap<E,Object>(s.comparator());
13.147 + addAll(s);
13.148 + }
13.149 +
13.150 + /**
13.151 + * For use by submaps
13.152 + */
13.153 + ConcurrentSkipListSet(ConcurrentNavigableMap<E,Object> m) {
13.154 + this.m = m;
13.155 + }
13.156 +
13.157 + /**
13.158 + * Returns a shallow copy of this <tt>ConcurrentSkipListSet</tt>
13.159 + * instance. (The elements themselves are not cloned.)
13.160 + *
13.161 + * @return a shallow copy of this set
13.162 + */
13.163 + public ConcurrentSkipListSet<E> clone() {
13.164 + ConcurrentSkipListSet<E> clone = null;
13.165 + try {
13.166 + clone = (ConcurrentSkipListSet<E>) super.clone();
13.167 + clone.setMap(new ConcurrentSkipListMap(m));
13.168 + } catch (CloneNotSupportedException e) {
13.169 + throw new InternalError();
13.170 + }
13.171 +
13.172 + return clone;
13.173 + }
13.174 +
13.175 + /* ---------------- Set operations -------------- */
13.176 +
13.177 + /**
13.178 + * Returns the number of elements in this set. If this set
13.179 + * contains more than <tt>Integer.MAX_VALUE</tt> elements, it
13.180 + * returns <tt>Integer.MAX_VALUE</tt>.
13.181 + *
13.182 + * <p>Beware that, unlike in most collections, this method is
13.183 + * <em>NOT</em> a constant-time operation. Because of the
13.184 + * asynchronous nature of these sets, determining the current
13.185 + * number of elements requires traversing them all to count them.
13.186 + * Additionally, it is possible for the size to change during
13.187 + * execution of this method, in which case the returned result
13.188 + * will be inaccurate. Thus, this method is typically not very
13.189 + * useful in concurrent applications.
13.190 + *
13.191 + * @return the number of elements in this set
13.192 + */
13.193 + public int size() {
13.194 + return m.size();
13.195 + }
13.196 +
13.197 + /**
13.198 + * Returns <tt>true</tt> if this set contains no elements.
13.199 + * @return <tt>true</tt> if this set contains no elements
13.200 + */
13.201 + public boolean isEmpty() {
13.202 + return m.isEmpty();
13.203 + }
13.204 +
13.205 + /**
13.206 + * Returns <tt>true</tt> if this set contains the specified element.
13.207 + * More formally, returns <tt>true</tt> if and only if this set
13.208 + * contains an element <tt>e</tt> such that <tt>o.equals(e)</tt>.
13.209 + *
13.210 + * @param o object to be checked for containment in this set
13.211 + * @return <tt>true</tt> if this set contains the specified element
13.212 + * @throws ClassCastException if the specified element cannot be
13.213 + * compared with the elements currently in this set
13.214 + * @throws NullPointerException if the specified element is null
13.215 + */
13.216 + public boolean contains(Object o) {
13.217 + return m.containsKey(o);
13.218 + }
13.219 +
13.220 + /**
13.221 + * Adds the specified element to this set if it is not already present.
13.222 + * More formally, adds the specified element <tt>e</tt> to this set if
13.223 + * the set contains no element <tt>e2</tt> such that <tt>e.equals(e2)</tt>.
13.224 + * If this set already contains the element, the call leaves the set
13.225 + * unchanged and returns <tt>false</tt>.
13.226 + *
13.227 + * @param e element to be added to this set
13.228 + * @return <tt>true</tt> if this set did not already contain the
13.229 + * specified element
13.230 + * @throws ClassCastException if <tt>e</tt> cannot be compared
13.231 + * with the elements currently in this set
13.232 + * @throws NullPointerException if the specified element is null
13.233 + */
13.234 + public boolean add(E e) {
13.235 + return m.putIfAbsent(e, Boolean.TRUE) == null;
13.236 + }
13.237 +
13.238 + /**
13.239 + * Removes the specified element from this set if it is present.
13.240 + * More formally, removes an element <tt>e</tt> such that
13.241 + * <tt>o.equals(e)</tt>, if this set contains such an element.
13.242 + * Returns <tt>true</tt> if this set contained the element (or
13.243 + * equivalently, if this set changed as a result of the call).
13.244 + * (This set will not contain the element once the call returns.)
13.245 + *
13.246 + * @param o object to be removed from this set, if present
13.247 + * @return <tt>true</tt> if this set contained the specified element
13.248 + * @throws ClassCastException if <tt>o</tt> cannot be compared
13.249 + * with the elements currently in this set
13.250 + * @throws NullPointerException if the specified element is null
13.251 + */
13.252 + public boolean remove(Object o) {
13.253 + return m.remove(o, Boolean.TRUE);
13.254 + }
13.255 +
13.256 + /**
13.257 + * Removes all of the elements from this set.
13.258 + */
13.259 + public void clear() {
13.260 + m.clear();
13.261 + }
13.262 +
13.263 + /**
13.264 + * Returns an iterator over the elements in this set in ascending order.
13.265 + *
13.266 + * @return an iterator over the elements in this set in ascending order
13.267 + */
13.268 + public Iterator<E> iterator() {
13.269 + return m.navigableKeySet().iterator();
13.270 + }
13.271 +
13.272 + /**
13.273 + * Returns an iterator over the elements in this set in descending order.
13.274 + *
13.275 + * @return an iterator over the elements in this set in descending order
13.276 + */
13.277 + public Iterator<E> descendingIterator() {
13.278 + return m.descendingKeySet().iterator();
13.279 + }
13.280 +
13.281 +
13.282 + /* ---------------- AbstractSet Overrides -------------- */
13.283 +
13.284 + /**
13.285 + * Compares the specified object with this set for equality. Returns
13.286 + * <tt>true</tt> if the specified object is also a set, the two sets
13.287 + * have the same size, and every member of the specified set is
13.288 + * contained in this set (or equivalently, every member of this set is
13.289 + * contained in the specified set). This definition ensures that the
13.290 + * equals method works properly across different implementations of the
13.291 + * set interface.
13.292 + *
13.293 + * @param o the object to be compared for equality with this set
13.294 + * @return <tt>true</tt> if the specified object is equal to this set
13.295 + */
13.296 + public boolean equals(Object o) {
13.297 + // Override AbstractSet version to avoid calling size()
13.298 + if (o == this)
13.299 + return true;
13.300 + if (!(o instanceof Set))
13.301 + return false;
13.302 + Collection<?> c = (Collection<?>) o;
13.303 + try {
13.304 + return containsAll(c) && c.containsAll(this);
13.305 + } catch (ClassCastException unused) {
13.306 + return false;
13.307 + } catch (NullPointerException unused) {
13.308 + return false;
13.309 + }
13.310 + }
13.311 +
13.312 + /**
13.313 + * Removes from this set all of its elements that are contained in
13.314 + * the specified collection. If the specified collection is also
13.315 + * a set, this operation effectively modifies this set so that its
13.316 + * value is the <i>asymmetric set difference</i> of the two sets.
13.317 + *
13.318 + * @param c collection containing elements to be removed from this set
13.319 + * @return <tt>true</tt> if this set changed as a result of the call
13.320 + * @throws ClassCastException if the types of one or more elements in this
13.321 + * set are incompatible with the specified collection
13.322 + * @throws NullPointerException if the specified collection or any
13.323 + * of its elements are null
13.324 + */
13.325 + public boolean removeAll(Collection<?> c) {
13.326 + // Override AbstractSet version to avoid unnecessary call to size()
13.327 + boolean modified = false;
13.328 + for (Iterator<?> i = c.iterator(); i.hasNext(); )
13.329 + if (remove(i.next()))
13.330 + modified = true;
13.331 + return modified;
13.332 + }
13.333 +
13.334 + /* ---------------- Relational operations -------------- */
13.335 +
13.336 + /**
13.337 + * @throws ClassCastException {@inheritDoc}
13.338 + * @throws NullPointerException if the specified element is null
13.339 + */
13.340 + public E lower(E e) {
13.341 + return m.lowerKey(e);
13.342 + }
13.343 +
13.344 + /**
13.345 + * @throws ClassCastException {@inheritDoc}
13.346 + * @throws NullPointerException if the specified element is null
13.347 + */
13.348 + public E floor(E e) {
13.349 + return m.floorKey(e);
13.350 + }
13.351 +
13.352 + /**
13.353 + * @throws ClassCastException {@inheritDoc}
13.354 + * @throws NullPointerException if the specified element is null
13.355 + */
13.356 + public E ceiling(E e) {
13.357 + return m.ceilingKey(e);
13.358 + }
13.359 +
13.360 + /**
13.361 + * @throws ClassCastException {@inheritDoc}
13.362 + * @throws NullPointerException if the specified element is null
13.363 + */
13.364 + public E higher(E e) {
13.365 + return m.higherKey(e);
13.366 + }
13.367 +
13.368 + public E pollFirst() {
13.369 + Map.Entry<E,Object> e = m.pollFirstEntry();
13.370 + return (e == null) ? null : e.getKey();
13.371 + }
13.372 +
13.373 + public E pollLast() {
13.374 + Map.Entry<E,Object> e = m.pollLastEntry();
13.375 + return (e == null) ? null : e.getKey();
13.376 + }
13.377 +
13.378 +
13.379 + /* ---------------- SortedSet operations -------------- */
13.380 +
13.381 +
13.382 + public Comparator<? super E> comparator() {
13.383 + return m.comparator();
13.384 + }
13.385 +
13.386 + /**
13.387 + * @throws NoSuchElementException {@inheritDoc}
13.388 + */
13.389 + public E first() {
13.390 + return m.firstKey();
13.391 + }
13.392 +
13.393 + /**
13.394 + * @throws NoSuchElementException {@inheritDoc}
13.395 + */
13.396 + public E last() {
13.397 + return m.lastKey();
13.398 + }
13.399 +
13.400 + /**
13.401 + * @throws ClassCastException {@inheritDoc}
13.402 + * @throws NullPointerException if {@code fromElement} or
13.403 + * {@code toElement} is null
13.404 + * @throws IllegalArgumentException {@inheritDoc}
13.405 + */
13.406 + public NavigableSet<E> subSet(E fromElement,
13.407 + boolean fromInclusive,
13.408 + E toElement,
13.409 + boolean toInclusive) {
13.410 + return new ConcurrentSkipListSet<E>
13.411 + (m.subMap(fromElement, fromInclusive,
13.412 + toElement, toInclusive));
13.413 + }
13.414 +
13.415 + /**
13.416 + * @throws ClassCastException {@inheritDoc}
13.417 + * @throws NullPointerException if {@code toElement} is null
13.418 + * @throws IllegalArgumentException {@inheritDoc}
13.419 + */
13.420 + public NavigableSet<E> headSet(E toElement, boolean inclusive) {
13.421 + return new ConcurrentSkipListSet<E>(m.headMap(toElement, inclusive));
13.422 + }
13.423 +
13.424 + /**
13.425 + * @throws ClassCastException {@inheritDoc}
13.426 + * @throws NullPointerException if {@code fromElement} is null
13.427 + * @throws IllegalArgumentException {@inheritDoc}
13.428 + */
13.429 + public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
13.430 + return new ConcurrentSkipListSet<E>(m.tailMap(fromElement, inclusive));
13.431 + }
13.432 +
13.433 + /**
13.434 + * @throws ClassCastException {@inheritDoc}
13.435 + * @throws NullPointerException if {@code fromElement} or
13.436 + * {@code toElement} is null
13.437 + * @throws IllegalArgumentException {@inheritDoc}
13.438 + */
13.439 + public NavigableSet<E> subSet(E fromElement, E toElement) {
13.440 + return subSet(fromElement, true, toElement, false);
13.441 + }
13.442 +
13.443 + /**
13.444 + * @throws ClassCastException {@inheritDoc}
13.445 + * @throws NullPointerException if {@code toElement} is null
13.446 + * @throws IllegalArgumentException {@inheritDoc}
13.447 + */
13.448 + public NavigableSet<E> headSet(E toElement) {
13.449 + return headSet(toElement, false);
13.450 + }
13.451 +
13.452 + /**
13.453 + * @throws ClassCastException {@inheritDoc}
13.454 + * @throws NullPointerException if {@code fromElement} is null
13.455 + * @throws IllegalArgumentException {@inheritDoc}
13.456 + */
13.457 + public NavigableSet<E> tailSet(E fromElement) {
13.458 + return tailSet(fromElement, true);
13.459 + }
13.460 +
13.461 + /**
13.462 + * Returns a reverse order view of the elements contained in this set.
13.463 + * The descending set is backed by this set, so changes to the set are
13.464 + * reflected in the descending set, and vice-versa.
13.465 + *
13.466 + * <p>The returned set has an ordering equivalent to
13.467 + * <tt>{@link Collections#reverseOrder(Comparator) Collections.reverseOrder}(comparator())</tt>.
13.468 + * The expression {@code s.descendingSet().descendingSet()} returns a
13.469 + * view of {@code s} essentially equivalent to {@code s}.
13.470 + *
13.471 + * @return a reverse order view of this set
13.472 + */
13.473 + public NavigableSet<E> descendingSet() {
13.474 + return new ConcurrentSkipListSet(m.descendingMap());
13.475 + }
13.476 +
13.477 + // Support for resetting map in clone
13.478 + private void setMap(ConcurrentNavigableMap<E,Object> map) {
13.479 + UNSAFE.putObjectVolatile(this, mapOffset, map);
13.480 + }
13.481 +
13.482 + private static final sun.misc.Unsafe UNSAFE;
13.483 + private static final long mapOffset;
13.484 + static {
13.485 + try {
13.486 + UNSAFE = sun.misc.Unsafe.getUnsafe();
13.487 + Class k = ConcurrentSkipListSet.class;
13.488 + mapOffset = UNSAFE.objectFieldOffset
13.489 + (k.getDeclaredField("m"));
13.490 + } catch (Exception e) {
13.491 + throw new Error(e);
13.492 + }
13.493 + }
13.494 +}
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/CopyOnWriteArrayList.java Sat Mar 19 10:46:31 2016 +0100
14.3 @@ -0,0 +1,1340 @@
14.4 +/*
14.5 + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
14.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
14.7 + *
14.8 + * This code is free software; you can redistribute it and/or modify it
14.9 + * under the terms of the GNU General Public License version 2 only, as
14.10 + * published by the Free Software Foundation. Oracle designates this
14.11 + * particular file as subject to the "Classpath" exception as provided
14.12 + * by Oracle in the LICENSE file that accompanied this code.
14.13 + *
14.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
14.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14.17 + * version 2 for more details (a copy is included in the LICENSE file that
14.18 + * accompanied this code).
14.19 + *
14.20 + * You should have received a copy of the GNU General Public License version
14.21 + * 2 along with this work; if not, write to the Free Software Foundation,
14.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
14.23 + *
14.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
14.25 + * or visit www.oracle.com if you need additional information or have any
14.26 + * questions.
14.27 + */
14.28 +
14.29 +/*
14.30 + * Written by Doug Lea with assistance from members of JCP JSR-166
14.31 + * Expert Group. Adapted and released, under explicit permission,
14.32 + * from JDK ArrayList.java which carries the following copyright:
14.33 + *
14.34 + * Copyright 1997 by Sun Microsystems, Inc.,
14.35 + * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
14.36 + * All rights reserved.
14.37 + */
14.38 +
14.39 +package java.util.concurrent;
14.40 +import java.util.*;
14.41 +import java.util.concurrent.locks.*;
14.42 +import sun.misc.Unsafe;
14.43 +
14.44 +/**
14.45 + * A thread-safe variant of {@link java.util.ArrayList} in which all mutative
14.46 + * operations (<tt>add</tt>, <tt>set</tt>, and so on) are implemented by
14.47 + * making a fresh copy of the underlying array.
14.48 + *
14.49 + * <p> This is ordinarily too costly, but may be <em>more</em> efficient
14.50 + * than alternatives when traversal operations vastly outnumber
14.51 + * mutations, and is useful when you cannot or don't want to
14.52 + * synchronize traversals, yet need to preclude interference among
14.53 + * concurrent threads. The "snapshot" style iterator method uses a
14.54 + * reference to the state of the array at the point that the iterator
14.55 + * was created. This array never changes during the lifetime of the
14.56 + * iterator, so interference is impossible and the iterator is
14.57 + * guaranteed not to throw <tt>ConcurrentModificationException</tt>.
14.58 + * The iterator will not reflect additions, removals, or changes to
14.59 + * the list since the iterator was created. Element-changing
14.60 + * operations on iterators themselves (<tt>remove</tt>, <tt>set</tt>, and
14.61 + * <tt>add</tt>) are not supported. These methods throw
14.62 + * <tt>UnsupportedOperationException</tt>.
14.63 + *
14.64 + * <p>All elements are permitted, including <tt>null</tt>.
14.65 + *
14.66 + * <p>Memory consistency effects: As with other concurrent
14.67 + * collections, actions in a thread prior to placing an object into a
14.68 + * {@code CopyOnWriteArrayList}
14.69 + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
14.70 + * actions subsequent to the access or removal of that element from
14.71 + * the {@code CopyOnWriteArrayList} in another thread.
14.72 + *
14.73 + * <p>This class is a member of the
14.74 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
14.75 + * Java Collections Framework</a>.
14.76 + *
14.77 + * @since 1.5
14.78 + * @author Doug Lea
14.79 + * @param <E> the type of elements held in this collection
14.80 + */
14.81 +public class CopyOnWriteArrayList<E>
14.82 + implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
14.83 + private static final long serialVersionUID = 8673264195747942595L;
14.84 +
14.85 + /** The lock protecting all mutators */
14.86 + transient final ReentrantLock lock = new ReentrantLock();
14.87 +
14.88 + /** The array, accessed only via getArray/setArray. */
14.89 + private volatile transient Object[] array;
14.90 +
14.91 + /**
14.92 + * Gets the array. Non-private so as to also be accessible
14.93 + * from CopyOnWriteArraySet class.
14.94 + */
14.95 + final Object[] getArray() {
14.96 + return array;
14.97 + }
14.98 +
14.99 + /**
14.100 + * Sets the array.
14.101 + */
14.102 + final void setArray(Object[] a) {
14.103 + array = a;
14.104 + }
14.105 +
14.106 + /**
14.107 + * Creates an empty list.
14.108 + */
14.109 + public CopyOnWriteArrayList() {
14.110 + setArray(new Object[0]);
14.111 + }
14.112 +
14.113 + /**
14.114 + * Creates a list containing the elements of the specified
14.115 + * collection, in the order they are returned by the collection's
14.116 + * iterator.
14.117 + *
14.118 + * @param c the collection of initially held elements
14.119 + * @throws NullPointerException if the specified collection is null
14.120 + */
14.121 + public CopyOnWriteArrayList(Collection<? extends E> c) {
14.122 + Object[] elements = c.toArray();
14.123 + // c.toArray might (incorrectly) not return Object[] (see 6260652)
14.124 + if (elements.getClass() != Object[].class)
14.125 + elements = Arrays.copyOf(elements, elements.length, Object[].class);
14.126 + setArray(elements);
14.127 + }
14.128 +
14.129 + /**
14.130 + * Creates a list holding a copy of the given array.
14.131 + *
14.132 + * @param toCopyIn the array (a copy of this array is used as the
14.133 + * internal array)
14.134 + * @throws NullPointerException if the specified array is null
14.135 + */
14.136 + public CopyOnWriteArrayList(E[] toCopyIn) {
14.137 + setArray(Arrays.copyOf(toCopyIn, toCopyIn.length, Object[].class));
14.138 + }
14.139 +
14.140 + /**
14.141 + * Returns the number of elements in this list.
14.142 + *
14.143 + * @return the number of elements in this list
14.144 + */
14.145 + public int size() {
14.146 + return getArray().length;
14.147 + }
14.148 +
14.149 + /**
14.150 + * Returns <tt>true</tt> if this list contains no elements.
14.151 + *
14.152 + * @return <tt>true</tt> if this list contains no elements
14.153 + */
14.154 + public boolean isEmpty() {
14.155 + return size() == 0;
14.156 + }
14.157 +
14.158 + /**
14.159 + * Test for equality, coping with nulls.
14.160 + */
14.161 + private static boolean eq(Object o1, Object o2) {
14.162 + return (o1 == null ? o2 == null : o1.equals(o2));
14.163 + }
14.164 +
14.165 + /**
14.166 + * static version of indexOf, to allow repeated calls without
14.167 + * needing to re-acquire array each time.
14.168 + * @param o element to search for
14.169 + * @param elements the array
14.170 + * @param index first index to search
14.171 + * @param fence one past last index to search
14.172 + * @return index of element, or -1 if absent
14.173 + */
14.174 + private static int indexOf(Object o, Object[] elements,
14.175 + int index, int fence) {
14.176 + if (o == null) {
14.177 + for (int i = index; i < fence; i++)
14.178 + if (elements[i] == null)
14.179 + return i;
14.180 + } else {
14.181 + for (int i = index; i < fence; i++)
14.182 + if (o.equals(elements[i]))
14.183 + return i;
14.184 + }
14.185 + return -1;
14.186 + }
14.187 +
14.188 + /**
14.189 + * static version of lastIndexOf.
14.190 + * @param o element to search for
14.191 + * @param elements the array
14.192 + * @param index first index to search
14.193 + * @return index of element, or -1 if absent
14.194 + */
14.195 + private static int lastIndexOf(Object o, Object[] elements, int index) {
14.196 + if (o == null) {
14.197 + for (int i = index; i >= 0; i--)
14.198 + if (elements[i] == null)
14.199 + return i;
14.200 + } else {
14.201 + for (int i = index; i >= 0; i--)
14.202 + if (o.equals(elements[i]))
14.203 + return i;
14.204 + }
14.205 + return -1;
14.206 + }
14.207 +
14.208 + /**
14.209 + * Returns <tt>true</tt> if this list contains the specified element.
14.210 + * More formally, returns <tt>true</tt> if and only if this list contains
14.211 + * at least one element <tt>e</tt> such that
14.212 + * <tt>(o==null ? e==null : o.equals(e))</tt>.
14.213 + *
14.214 + * @param o element whose presence in this list is to be tested
14.215 + * @return <tt>true</tt> if this list contains the specified element
14.216 + */
14.217 + public boolean contains(Object o) {
14.218 + Object[] elements = getArray();
14.219 + return indexOf(o, elements, 0, elements.length) >= 0;
14.220 + }
14.221 +
14.222 + /**
14.223 + * {@inheritDoc}
14.224 + */
14.225 + public int indexOf(Object o) {
14.226 + Object[] elements = getArray();
14.227 + return indexOf(o, elements, 0, elements.length);
14.228 + }
14.229 +
14.230 + /**
14.231 + * Returns the index of the first occurrence of the specified element in
14.232 + * this list, searching forwards from <tt>index</tt>, or returns -1 if
14.233 + * the element is not found.
14.234 + * More formally, returns the lowest index <tt>i</tt> such that
14.235 + * <tt>(i >= index && (e==null ? get(i)==null : e.equals(get(i))))</tt>,
14.236 + * or -1 if there is no such index.
14.237 + *
14.238 + * @param e element to search for
14.239 + * @param index index to start searching from
14.240 + * @return the index of the first occurrence of the element in
14.241 + * this list at position <tt>index</tt> or later in the list;
14.242 + * <tt>-1</tt> if the element is not found.
14.243 + * @throws IndexOutOfBoundsException if the specified index is negative
14.244 + */
14.245 + public int indexOf(E e, int index) {
14.246 + Object[] elements = getArray();
14.247 + return indexOf(e, elements, index, elements.length);
14.248 + }
14.249 +
14.250 + /**
14.251 + * {@inheritDoc}
14.252 + */
14.253 + public int lastIndexOf(Object o) {
14.254 + Object[] elements = getArray();
14.255 + return lastIndexOf(o, elements, elements.length - 1);
14.256 + }
14.257 +
14.258 + /**
14.259 + * Returns the index of the last occurrence of the specified element in
14.260 + * this list, searching backwards from <tt>index</tt>, or returns -1 if
14.261 + * the element is not found.
14.262 + * More formally, returns the highest index <tt>i</tt> such that
14.263 + * <tt>(i <= index && (e==null ? get(i)==null : e.equals(get(i))))</tt>,
14.264 + * or -1 if there is no such index.
14.265 + *
14.266 + * @param e element to search for
14.267 + * @param index index to start searching backwards from
14.268 + * @return the index of the last occurrence of the element at position
14.269 + * less than or equal to <tt>index</tt> in this list;
14.270 + * -1 if the element is not found.
14.271 + * @throws IndexOutOfBoundsException if the specified index is greater
14.272 + * than or equal to the current size of this list
14.273 + */
14.274 + public int lastIndexOf(E e, int index) {
14.275 + Object[] elements = getArray();
14.276 + return lastIndexOf(e, elements, index);
14.277 + }
14.278 +
14.279 + /**
14.280 + * Returns a shallow copy of this list. (The elements themselves
14.281 + * are not copied.)
14.282 + *
14.283 + * @return a clone of this list
14.284 + */
14.285 + public Object clone() {
14.286 + try {
14.287 + CopyOnWriteArrayList c = (CopyOnWriteArrayList)(super.clone());
14.288 + c.resetLock();
14.289 + return c;
14.290 + } catch (CloneNotSupportedException e) {
14.291 + // this shouldn't happen, since we are Cloneable
14.292 + throw new InternalError();
14.293 + }
14.294 + }
14.295 +
14.296 + /**
14.297 + * Returns an array containing all of the elements in this list
14.298 + * in proper sequence (from first to last element).
14.299 + *
14.300 + * <p>The returned array will be "safe" in that no references to it are
14.301 + * maintained by this list. (In other words, this method must allocate
14.302 + * a new array). The caller is thus free to modify the returned array.
14.303 + *
14.304 + * <p>This method acts as bridge between array-based and collection-based
14.305 + * APIs.
14.306 + *
14.307 + * @return an array containing all the elements in this list
14.308 + */
14.309 + public Object[] toArray() {
14.310 + Object[] elements = getArray();
14.311 + return Arrays.copyOf(elements, elements.length);
14.312 + }
14.313 +
14.314 + /**
14.315 + * Returns an array containing all of the elements in this list in
14.316 + * proper sequence (from first to last element); the runtime type of
14.317 + * the returned array is that of the specified array. If the list fits
14.318 + * in the specified array, it is returned therein. Otherwise, a new
14.319 + * array is allocated with the runtime type of the specified array and
14.320 + * the size of this list.
14.321 + *
14.322 + * <p>If this list fits in the specified array with room to spare
14.323 + * (i.e., the array has more elements than this list), the element in
14.324 + * the array immediately following the end of the list is set to
14.325 + * <tt>null</tt>. (This is useful in determining the length of this
14.326 + * list <i>only</i> if the caller knows that this list does not contain
14.327 + * any null elements.)
14.328 + *
14.329 + * <p>Like the {@link #toArray()} method, this method acts as bridge between
14.330 + * array-based and collection-based APIs. Further, this method allows
14.331 + * precise control over the runtime type of the output array, and may,
14.332 + * under certain circumstances, be used to save allocation costs.
14.333 + *
14.334 + * <p>Suppose <tt>x</tt> is a list known to contain only strings.
14.335 + * The following code can be used to dump the list into a newly
14.336 + * allocated array of <tt>String</tt>:
14.337 + *
14.338 + * <pre>
14.339 + * String[] y = x.toArray(new String[0]);</pre>
14.340 + *
14.341 + * Note that <tt>toArray(new Object[0])</tt> is identical in function to
14.342 + * <tt>toArray()</tt>.
14.343 + *
14.344 + * @param a the array into which the elements of the list are to
14.345 + * be stored, if it is big enough; otherwise, a new array of the
14.346 + * same runtime type is allocated for this purpose.
14.347 + * @return an array containing all the elements in this list
14.348 + * @throws ArrayStoreException if the runtime type of the specified array
14.349 + * is not a supertype of the runtime type of every element in
14.350 + * this list
14.351 + * @throws NullPointerException if the specified array is null
14.352 + */
14.353 + @SuppressWarnings("unchecked")
14.354 + public <T> T[] toArray(T a[]) {
14.355 + Object[] elements = getArray();
14.356 + int len = elements.length;
14.357 + if (a.length < len)
14.358 + return (T[]) Arrays.copyOf(elements, len, a.getClass());
14.359 + else {
14.360 + System.arraycopy(elements, 0, a, 0, len);
14.361 + if (a.length > len)
14.362 + a[len] = null;
14.363 + return a;
14.364 + }
14.365 + }
14.366 +
14.367 + // Positional Access Operations
14.368 +
14.369 + @SuppressWarnings("unchecked")
14.370 + private E get(Object[] a, int index) {
14.371 + return (E) a[index];
14.372 + }
14.373 +
14.374 + /**
14.375 + * {@inheritDoc}
14.376 + *
14.377 + * @throws IndexOutOfBoundsException {@inheritDoc}
14.378 + */
14.379 + public E get(int index) {
14.380 + return get(getArray(), index);
14.381 + }
14.382 +
14.383 + /**
14.384 + * Replaces the element at the specified position in this list with the
14.385 + * specified element.
14.386 + *
14.387 + * @throws IndexOutOfBoundsException {@inheritDoc}
14.388 + */
14.389 + public E set(int index, E element) {
14.390 + final ReentrantLock lock = this.lock;
14.391 + lock.lock();
14.392 + try {
14.393 + Object[] elements = getArray();
14.394 + E oldValue = get(elements, index);
14.395 +
14.396 + if (oldValue != element) {
14.397 + int len = elements.length;
14.398 + Object[] newElements = Arrays.copyOf(elements, len);
14.399 + newElements[index] = element;
14.400 + setArray(newElements);
14.401 + } else {
14.402 + // Not quite a no-op; ensures volatile write semantics
14.403 + setArray(elements);
14.404 + }
14.405 + return oldValue;
14.406 + } finally {
14.407 + lock.unlock();
14.408 + }
14.409 + }
14.410 +
14.411 + /**
14.412 + * Appends the specified element to the end of this list.
14.413 + *
14.414 + * @param e element to be appended to this list
14.415 + * @return <tt>true</tt> (as specified by {@link Collection#add})
14.416 + */
14.417 + public boolean add(E e) {
14.418 + final ReentrantLock lock = this.lock;
14.419 + lock.lock();
14.420 + try {
14.421 + Object[] elements = getArray();
14.422 + int len = elements.length;
14.423 + Object[] newElements = Arrays.copyOf(elements, len + 1);
14.424 + newElements[len] = e;
14.425 + setArray(newElements);
14.426 + return true;
14.427 + } finally {
14.428 + lock.unlock();
14.429 + }
14.430 + }
14.431 +
14.432 + /**
14.433 + * Inserts the specified element at the specified position in this
14.434 + * list. Shifts the element currently at that position (if any) and
14.435 + * any subsequent elements to the right (adds one to their indices).
14.436 + *
14.437 + * @throws IndexOutOfBoundsException {@inheritDoc}
14.438 + */
14.439 + public void add(int index, E element) {
14.440 + final ReentrantLock lock = this.lock;
14.441 + lock.lock();
14.442 + try {
14.443 + Object[] elements = getArray();
14.444 + int len = elements.length;
14.445 + if (index > len || index < 0)
14.446 + throw new IndexOutOfBoundsException("Index: "+index+
14.447 + ", Size: "+len);
14.448 + Object[] newElements;
14.449 + int numMoved = len - index;
14.450 + if (numMoved == 0)
14.451 + newElements = Arrays.copyOf(elements, len + 1);
14.452 + else {
14.453 + newElements = new Object[len + 1];
14.454 + System.arraycopy(elements, 0, newElements, 0, index);
14.455 + System.arraycopy(elements, index, newElements, index + 1,
14.456 + numMoved);
14.457 + }
14.458 + newElements[index] = element;
14.459 + setArray(newElements);
14.460 + } finally {
14.461 + lock.unlock();
14.462 + }
14.463 + }
14.464 +
14.465 + /**
14.466 + * Removes the element at the specified position in this list.
14.467 + * Shifts any subsequent elements to the left (subtracts one from their
14.468 + * indices). Returns the element that was removed from the list.
14.469 + *
14.470 + * @throws IndexOutOfBoundsException {@inheritDoc}
14.471 + */
14.472 + public E remove(int index) {
14.473 + final ReentrantLock lock = this.lock;
14.474 + lock.lock();
14.475 + try {
14.476 + Object[] elements = getArray();
14.477 + int len = elements.length;
14.478 + E oldValue = get(elements, index);
14.479 + int numMoved = len - index - 1;
14.480 + if (numMoved == 0)
14.481 + setArray(Arrays.copyOf(elements, len - 1));
14.482 + else {
14.483 + Object[] newElements = new Object[len - 1];
14.484 + System.arraycopy(elements, 0, newElements, 0, index);
14.485 + System.arraycopy(elements, index + 1, newElements, index,
14.486 + numMoved);
14.487 + setArray(newElements);
14.488 + }
14.489 + return oldValue;
14.490 + } finally {
14.491 + lock.unlock();
14.492 + }
14.493 + }
14.494 +
14.495 + /**
14.496 + * Removes the first occurrence of the specified element from this list,
14.497 + * if it is present. If this list does not contain the element, it is
14.498 + * unchanged. More formally, removes the element with the lowest index
14.499 + * <tt>i</tt> such that
14.500 + * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>
14.501 + * (if such an element exists). Returns <tt>true</tt> if this list
14.502 + * contained the specified element (or equivalently, if this list
14.503 + * changed as a result of the call).
14.504 + *
14.505 + * @param o element to be removed from this list, if present
14.506 + * @return <tt>true</tt> if this list contained the specified element
14.507 + */
14.508 + public boolean remove(Object o) {
14.509 + final ReentrantLock lock = this.lock;
14.510 + lock.lock();
14.511 + try {
14.512 + Object[] elements = getArray();
14.513 + int len = elements.length;
14.514 + if (len != 0) {
14.515 + // Copy while searching for element to remove
14.516 + // This wins in the normal case of element being present
14.517 + int newlen = len - 1;
14.518 + Object[] newElements = new Object[newlen];
14.519 +
14.520 + for (int i = 0; i < newlen; ++i) {
14.521 + if (eq(o, elements[i])) {
14.522 + // found one; copy remaining and exit
14.523 + for (int k = i + 1; k < len; ++k)
14.524 + newElements[k-1] = elements[k];
14.525 + setArray(newElements);
14.526 + return true;
14.527 + } else
14.528 + newElements[i] = elements[i];
14.529 + }
14.530 +
14.531 + // special handling for last cell
14.532 + if (eq(o, elements[newlen])) {
14.533 + setArray(newElements);
14.534 + return true;
14.535 + }
14.536 + }
14.537 + return false;
14.538 + } finally {
14.539 + lock.unlock();
14.540 + }
14.541 + }
14.542 +
14.543 + /**
14.544 + * Removes from this list all of the elements whose index is between
14.545 + * <tt>fromIndex</tt>, inclusive, and <tt>toIndex</tt>, exclusive.
14.546 + * Shifts any succeeding elements to the left (reduces their index).
14.547 + * This call shortens the list by <tt>(toIndex - fromIndex)</tt> elements.
14.548 + * (If <tt>toIndex==fromIndex</tt>, this operation has no effect.)
14.549 + *
14.550 + * @param fromIndex index of first element to be removed
14.551 + * @param toIndex index after last element to be removed
14.552 + * @throws IndexOutOfBoundsException if fromIndex or toIndex out of range
14.553 + * ({@code{fromIndex < 0 || toIndex > size() || toIndex < fromIndex})
14.554 + */
14.555 + private void removeRange(int fromIndex, int toIndex) {
14.556 + final ReentrantLock lock = this.lock;
14.557 + lock.lock();
14.558 + try {
14.559 + Object[] elements = getArray();
14.560 + int len = elements.length;
14.561 +
14.562 + if (fromIndex < 0 || toIndex > len || toIndex < fromIndex)
14.563 + throw new IndexOutOfBoundsException();
14.564 + int newlen = len - (toIndex - fromIndex);
14.565 + int numMoved = len - toIndex;
14.566 + if (numMoved == 0)
14.567 + setArray(Arrays.copyOf(elements, newlen));
14.568 + else {
14.569 + Object[] newElements = new Object[newlen];
14.570 + System.arraycopy(elements, 0, newElements, 0, fromIndex);
14.571 + System.arraycopy(elements, toIndex, newElements,
14.572 + fromIndex, numMoved);
14.573 + setArray(newElements);
14.574 + }
14.575 + } finally {
14.576 + lock.unlock();
14.577 + }
14.578 + }
14.579 +
14.580 + /**
14.581 + * Append the element if not present.
14.582 + *
14.583 + * @param e element to be added to this list, if absent
14.584 + * @return <tt>true</tt> if the element was added
14.585 + */
14.586 + public boolean addIfAbsent(E e) {
14.587 + final ReentrantLock lock = this.lock;
14.588 + lock.lock();
14.589 + try {
14.590 + // Copy while checking if already present.
14.591 + // This wins in the most common case where it is not present
14.592 + Object[] elements = getArray();
14.593 + int len = elements.length;
14.594 + Object[] newElements = new Object[len + 1];
14.595 + for (int i = 0; i < len; ++i) {
14.596 + if (eq(e, elements[i]))
14.597 + return false; // exit, throwing away copy
14.598 + else
14.599 + newElements[i] = elements[i];
14.600 + }
14.601 + newElements[len] = e;
14.602 + setArray(newElements);
14.603 + return true;
14.604 + } finally {
14.605 + lock.unlock();
14.606 + }
14.607 + }
14.608 +
14.609 + /**
14.610 + * Returns <tt>true</tt> if this list contains all of the elements of the
14.611 + * specified collection.
14.612 + *
14.613 + * @param c collection to be checked for containment in this list
14.614 + * @return <tt>true</tt> if this list contains all of the elements of the
14.615 + * specified collection
14.616 + * @throws NullPointerException if the specified collection is null
14.617 + * @see #contains(Object)
14.618 + */
14.619 + public boolean containsAll(Collection<?> c) {
14.620 + Object[] elements = getArray();
14.621 + int len = elements.length;
14.622 + for (Object e : c) {
14.623 + if (indexOf(e, elements, 0, len) < 0)
14.624 + return false;
14.625 + }
14.626 + return true;
14.627 + }
14.628 +
14.629 + /**
14.630 + * Removes from this list all of its elements that are contained in
14.631 + * the specified collection. This is a particularly expensive operation
14.632 + * in this class because of the need for an internal temporary array.
14.633 + *
14.634 + * @param c collection containing elements to be removed from this list
14.635 + * @return <tt>true</tt> if this list changed as a result of the call
14.636 + * @throws ClassCastException if the class of an element of this list
14.637 + * is incompatible with the specified collection
14.638 + * (<a href="../Collection.html#optional-restrictions">optional</a>)
14.639 + * @throws NullPointerException if this list contains a null element and the
14.640 + * specified collection does not permit null elements
14.641 + * (<a href="../Collection.html#optional-restrictions">optional</a>),
14.642 + * or if the specified collection is null
14.643 + * @see #remove(Object)
14.644 + */
14.645 + public boolean removeAll(Collection<?> c) {
14.646 + final ReentrantLock lock = this.lock;
14.647 + lock.lock();
14.648 + try {
14.649 + Object[] elements = getArray();
14.650 + int len = elements.length;
14.651 + if (len != 0) {
14.652 + // temp array holds those elements we know we want to keep
14.653 + int newlen = 0;
14.654 + Object[] temp = new Object[len];
14.655 + for (int i = 0; i < len; ++i) {
14.656 + Object element = elements[i];
14.657 + if (!c.contains(element))
14.658 + temp[newlen++] = element;
14.659 + }
14.660 + if (newlen != len) {
14.661 + setArray(Arrays.copyOf(temp, newlen));
14.662 + return true;
14.663 + }
14.664 + }
14.665 + return false;
14.666 + } finally {
14.667 + lock.unlock();
14.668 + }
14.669 + }
14.670 +
14.671 + /**
14.672 + * Retains only the elements in this list that are contained in the
14.673 + * specified collection. In other words, removes from this list all of
14.674 + * its elements that are not contained in the specified collection.
14.675 + *
14.676 + * @param c collection containing elements to be retained in this list
14.677 + * @return <tt>true</tt> if this list changed as a result of the call
14.678 + * @throws ClassCastException if the class of an element of this list
14.679 + * is incompatible with the specified collection
14.680 + * (<a href="../Collection.html#optional-restrictions">optional</a>)
14.681 + * @throws NullPointerException if this list contains a null element and the
14.682 + * specified collection does not permit null elements
14.683 + * (<a href="../Collection.html#optional-restrictions">optional</a>),
14.684 + * or if the specified collection is null
14.685 + * @see #remove(Object)
14.686 + */
14.687 + public boolean retainAll(Collection<?> c) {
14.688 + final ReentrantLock lock = this.lock;
14.689 + lock.lock();
14.690 + try {
14.691 + Object[] elements = getArray();
14.692 + int len = elements.length;
14.693 + if (len != 0) {
14.694 + // temp array holds those elements we know we want to keep
14.695 + int newlen = 0;
14.696 + Object[] temp = new Object[len];
14.697 + for (int i = 0; i < len; ++i) {
14.698 + Object element = elements[i];
14.699 + if (c.contains(element))
14.700 + temp[newlen++] = element;
14.701 + }
14.702 + if (newlen != len) {
14.703 + setArray(Arrays.copyOf(temp, newlen));
14.704 + return true;
14.705 + }
14.706 + }
14.707 + return false;
14.708 + } finally {
14.709 + lock.unlock();
14.710 + }
14.711 + }
14.712 +
14.713 + /**
14.714 + * Appends all of the elements in the specified collection that
14.715 + * are not already contained in this list, to the end of
14.716 + * this list, in the order that they are returned by the
14.717 + * specified collection's iterator.
14.718 + *
14.719 + * @param c collection containing elements to be added to this list
14.720 + * @return the number of elements added
14.721 + * @throws NullPointerException if the specified collection is null
14.722 + * @see #addIfAbsent(Object)
14.723 + */
14.724 + public int addAllAbsent(Collection<? extends E> c) {
14.725 + Object[] cs = c.toArray();
14.726 + if (cs.length == 0)
14.727 + return 0;
14.728 + Object[] uniq = new Object[cs.length];
14.729 + final ReentrantLock lock = this.lock;
14.730 + lock.lock();
14.731 + try {
14.732 + Object[] elements = getArray();
14.733 + int len = elements.length;
14.734 + int added = 0;
14.735 + for (int i = 0; i < cs.length; ++i) { // scan for duplicates
14.736 + Object e = cs[i];
14.737 + if (indexOf(e, elements, 0, len) < 0 &&
14.738 + indexOf(e, uniq, 0, added) < 0)
14.739 + uniq[added++] = e;
14.740 + }
14.741 + if (added > 0) {
14.742 + Object[] newElements = Arrays.copyOf(elements, len + added);
14.743 + System.arraycopy(uniq, 0, newElements, len, added);
14.744 + setArray(newElements);
14.745 + }
14.746 + return added;
14.747 + } finally {
14.748 + lock.unlock();
14.749 + }
14.750 + }
14.751 +
14.752 + /**
14.753 + * Removes all of the elements from this list.
14.754 + * The list will be empty after this call returns.
14.755 + */
14.756 + public void clear() {
14.757 + final ReentrantLock lock = this.lock;
14.758 + lock.lock();
14.759 + try {
14.760 + setArray(new Object[0]);
14.761 + } finally {
14.762 + lock.unlock();
14.763 + }
14.764 + }
14.765 +
14.766 + /**
14.767 + * Appends all of the elements in the specified collection to the end
14.768 + * of this list, in the order that they are returned by the specified
14.769 + * collection's iterator.
14.770 + *
14.771 + * @param c collection containing elements to be added to this list
14.772 + * @return <tt>true</tt> if this list changed as a result of the call
14.773 + * @throws NullPointerException if the specified collection is null
14.774 + * @see #add(Object)
14.775 + */
14.776 + public boolean addAll(Collection<? extends E> c) {
14.777 + Object[] cs = c.toArray();
14.778 + if (cs.length == 0)
14.779 + return false;
14.780 + final ReentrantLock lock = this.lock;
14.781 + lock.lock();
14.782 + try {
14.783 + Object[] elements = getArray();
14.784 + int len = elements.length;
14.785 + Object[] newElements = Arrays.copyOf(elements, len + cs.length);
14.786 + System.arraycopy(cs, 0, newElements, len, cs.length);
14.787 + setArray(newElements);
14.788 + return true;
14.789 + } finally {
14.790 + lock.unlock();
14.791 + }
14.792 + }
14.793 +
14.794 + /**
14.795 + * Inserts all of the elements in the specified collection into this
14.796 + * list, starting at the specified position. Shifts the element
14.797 + * currently at that position (if any) and any subsequent elements to
14.798 + * the right (increases their indices). The new elements will appear
14.799 + * in this list in the order that they are returned by the
14.800 + * specified collection's iterator.
14.801 + *
14.802 + * @param index index at which to insert the first element
14.803 + * from the specified collection
14.804 + * @param c collection containing elements to be added to this list
14.805 + * @return <tt>true</tt> if this list changed as a result of the call
14.806 + * @throws IndexOutOfBoundsException {@inheritDoc}
14.807 + * @throws NullPointerException if the specified collection is null
14.808 + * @see #add(int,Object)
14.809 + */
14.810 + public boolean addAll(int index, Collection<? extends E> c) {
14.811 + Object[] cs = c.toArray();
14.812 + final ReentrantLock lock = this.lock;
14.813 + lock.lock();
14.814 + try {
14.815 + Object[] elements = getArray();
14.816 + int len = elements.length;
14.817 + if (index > len || index < 0)
14.818 + throw new IndexOutOfBoundsException("Index: "+index+
14.819 + ", Size: "+len);
14.820 + if (cs.length == 0)
14.821 + return false;
14.822 + int numMoved = len - index;
14.823 + Object[] newElements;
14.824 + if (numMoved == 0)
14.825 + newElements = Arrays.copyOf(elements, len + cs.length);
14.826 + else {
14.827 + newElements = new Object[len + cs.length];
14.828 + System.arraycopy(elements, 0, newElements, 0, index);
14.829 + System.arraycopy(elements, index,
14.830 + newElements, index + cs.length,
14.831 + numMoved);
14.832 + }
14.833 + System.arraycopy(cs, 0, newElements, index, cs.length);
14.834 + setArray(newElements);
14.835 + return true;
14.836 + } finally {
14.837 + lock.unlock();
14.838 + }
14.839 + }
14.840 +
14.841 + /**
14.842 + * Saves the state of the list to a stream (that is, serializes it).
14.843 + *
14.844 + * @serialData The length of the array backing the list is emitted
14.845 + * (int), followed by all of its elements (each an Object)
14.846 + * in the proper order.
14.847 + * @param s the stream
14.848 + */
14.849 + private void writeObject(java.io.ObjectOutputStream s)
14.850 + throws java.io.IOException{
14.851 +
14.852 + s.defaultWriteObject();
14.853 +
14.854 + Object[] elements = getArray();
14.855 + // Write out array length
14.856 + s.writeInt(elements.length);
14.857 +
14.858 + // Write out all elements in the proper order.
14.859 + for (Object element : elements)
14.860 + s.writeObject(element);
14.861 + }
14.862 +
14.863 + /**
14.864 + * Reconstitutes the list from a stream (that is, deserializes it).
14.865 + *
14.866 + * @param s the stream
14.867 + */
14.868 + private void readObject(java.io.ObjectInputStream s)
14.869 + throws java.io.IOException, ClassNotFoundException {
14.870 +
14.871 + s.defaultReadObject();
14.872 +
14.873 + // bind to new lock
14.874 + resetLock();
14.875 +
14.876 + // Read in array length and allocate array
14.877 + int len = s.readInt();
14.878 + Object[] elements = new Object[len];
14.879 +
14.880 + // Read in all elements in the proper order.
14.881 + for (int i = 0; i < len; i++)
14.882 + elements[i] = s.readObject();
14.883 + setArray(elements);
14.884 + }
14.885 +
14.886 + /**
14.887 + * Returns a string representation of this list. The string
14.888 + * representation consists of the string representations of the list's
14.889 + * elements in the order they are returned by its iterator, enclosed in
14.890 + * square brackets (<tt>"[]"</tt>). Adjacent elements are separated by
14.891 + * the characters <tt>", "</tt> (comma and space). Elements are
14.892 + * converted to strings as by {@link String#valueOf(Object)}.
14.893 + *
14.894 + * @return a string representation of this list
14.895 + */
14.896 + public String toString() {
14.897 + return Arrays.toString(getArray());
14.898 + }
14.899 +
14.900 + /**
14.901 + * Compares the specified object with this list for equality.
14.902 + * Returns {@code true} if the specified object is the same object
14.903 + * as this object, or if it is also a {@link List} and the sequence
14.904 + * of elements returned by an {@linkplain List#iterator() iterator}
14.905 + * over the specified list is the same as the sequence returned by
14.906 + * an iterator over this list. The two sequences are considered to
14.907 + * be the same if they have the same length and corresponding
14.908 + * elements at the same position in the sequence are <em>equal</em>.
14.909 + * Two elements {@code e1} and {@code e2} are considered
14.910 + * <em>equal</em> if {@code (e1==null ? e2==null : e1.equals(e2))}.
14.911 + *
14.912 + * @param o the object to be compared for equality with this list
14.913 + * @return {@code true} if the specified object is equal to this list
14.914 + */
14.915 + public boolean equals(Object o) {
14.916 + if (o == this)
14.917 + return true;
14.918 + if (!(o instanceof List))
14.919 + return false;
14.920 +
14.921 + List<?> list = (List<?>)(o);
14.922 + Iterator<?> it = list.iterator();
14.923 + Object[] elements = getArray();
14.924 + int len = elements.length;
14.925 + for (int i = 0; i < len; ++i)
14.926 + if (!it.hasNext() || !eq(elements[i], it.next()))
14.927 + return false;
14.928 + if (it.hasNext())
14.929 + return false;
14.930 + return true;
14.931 + }
14.932 +
14.933 + /**
14.934 + * Returns the hash code value for this list.
14.935 + *
14.936 + * <p>This implementation uses the definition in {@link List#hashCode}.
14.937 + *
14.938 + * @return the hash code value for this list
14.939 + */
14.940 + public int hashCode() {
14.941 + int hashCode = 1;
14.942 + Object[] elements = getArray();
14.943 + int len = elements.length;
14.944 + for (int i = 0; i < len; ++i) {
14.945 + Object obj = elements[i];
14.946 + hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
14.947 + }
14.948 + return hashCode;
14.949 + }
14.950 +
14.951 + /**
14.952 + * Returns an iterator over the elements in this list in proper sequence.
14.953 + *
14.954 + * <p>The returned iterator provides a snapshot of the state of the list
14.955 + * when the iterator was constructed. No synchronization is needed while
14.956 + * traversing the iterator. The iterator does <em>NOT</em> support the
14.957 + * <tt>remove</tt> method.
14.958 + *
14.959 + * @return an iterator over the elements in this list in proper sequence
14.960 + */
14.961 + public Iterator<E> iterator() {
14.962 + return new COWIterator<E>(getArray(), 0);
14.963 + }
14.964 +
14.965 + /**
14.966 + * {@inheritDoc}
14.967 + *
14.968 + * <p>The returned iterator provides a snapshot of the state of the list
14.969 + * when the iterator was constructed. No synchronization is needed while
14.970 + * traversing the iterator. The iterator does <em>NOT</em> support the
14.971 + * <tt>remove</tt>, <tt>set</tt> or <tt>add</tt> methods.
14.972 + */
14.973 + public ListIterator<E> listIterator() {
14.974 + return new COWIterator<E>(getArray(), 0);
14.975 + }
14.976 +
14.977 + /**
14.978 + * {@inheritDoc}
14.979 + *
14.980 + * <p>The returned iterator provides a snapshot of the state of the list
14.981 + * when the iterator was constructed. No synchronization is needed while
14.982 + * traversing the iterator. The iterator does <em>NOT</em> support the
14.983 + * <tt>remove</tt>, <tt>set</tt> or <tt>add</tt> methods.
14.984 + *
14.985 + * @throws IndexOutOfBoundsException {@inheritDoc}
14.986 + */
14.987 + public ListIterator<E> listIterator(final int index) {
14.988 + Object[] elements = getArray();
14.989 + int len = elements.length;
14.990 + if (index<0 || index>len)
14.991 + throw new IndexOutOfBoundsException("Index: "+index);
14.992 +
14.993 + return new COWIterator<E>(elements, index);
14.994 + }
14.995 +
14.996 + private static class COWIterator<E> implements ListIterator<E> {
14.997 + /** Snapshot of the array */
14.998 + private final Object[] snapshot;
14.999 + /** Index of element to be returned by subsequent call to next. */
14.1000 + private int cursor;
14.1001 +
14.1002 + private COWIterator(Object[] elements, int initialCursor) {
14.1003 + cursor = initialCursor;
14.1004 + snapshot = elements;
14.1005 + }
14.1006 +
14.1007 + public boolean hasNext() {
14.1008 + return cursor < snapshot.length;
14.1009 + }
14.1010 +
14.1011 + public boolean hasPrevious() {
14.1012 + return cursor > 0;
14.1013 + }
14.1014 +
14.1015 + @SuppressWarnings("unchecked")
14.1016 + public E next() {
14.1017 + if (! hasNext())
14.1018 + throw new NoSuchElementException();
14.1019 + return (E) snapshot[cursor++];
14.1020 + }
14.1021 +
14.1022 + @SuppressWarnings("unchecked")
14.1023 + public E previous() {
14.1024 + if (! hasPrevious())
14.1025 + throw new NoSuchElementException();
14.1026 + return (E) snapshot[--cursor];
14.1027 + }
14.1028 +
14.1029 + public int nextIndex() {
14.1030 + return cursor;
14.1031 + }
14.1032 +
14.1033 + public int previousIndex() {
14.1034 + return cursor-1;
14.1035 + }
14.1036 +
14.1037 + /**
14.1038 + * Not supported. Always throws UnsupportedOperationException.
14.1039 + * @throws UnsupportedOperationException always; <tt>remove</tt>
14.1040 + * is not supported by this iterator.
14.1041 + */
14.1042 + public void remove() {
14.1043 + throw new UnsupportedOperationException();
14.1044 + }
14.1045 +
14.1046 + /**
14.1047 + * Not supported. Always throws UnsupportedOperationException.
14.1048 + * @throws UnsupportedOperationException always; <tt>set</tt>
14.1049 + * is not supported by this iterator.
14.1050 + */
14.1051 + public void set(E e) {
14.1052 + throw new UnsupportedOperationException();
14.1053 + }
14.1054 +
14.1055 + /**
14.1056 + * Not supported. Always throws UnsupportedOperationException.
14.1057 + * @throws UnsupportedOperationException always; <tt>add</tt>
14.1058 + * is not supported by this iterator.
14.1059 + */
14.1060 + public void add(E e) {
14.1061 + throw new UnsupportedOperationException();
14.1062 + }
14.1063 + }
14.1064 +
14.1065 + /**
14.1066 + * Returns a view of the portion of this list between
14.1067 + * <tt>fromIndex</tt>, inclusive, and <tt>toIndex</tt>, exclusive.
14.1068 + * The returned list is backed by this list, so changes in the
14.1069 + * returned list are reflected in this list.
14.1070 + *
14.1071 + * <p>The semantics of the list returned by this method become
14.1072 + * undefined if the backing list (i.e., this list) is modified in
14.1073 + * any way other than via the returned list.
14.1074 + *
14.1075 + * @param fromIndex low endpoint (inclusive) of the subList
14.1076 + * @param toIndex high endpoint (exclusive) of the subList
14.1077 + * @return a view of the specified range within this list
14.1078 + * @throws IndexOutOfBoundsException {@inheritDoc}
14.1079 + */
14.1080 + public List<E> subList(int fromIndex, int toIndex) {
14.1081 + final ReentrantLock lock = this.lock;
14.1082 + lock.lock();
14.1083 + try {
14.1084 + Object[] elements = getArray();
14.1085 + int len = elements.length;
14.1086 + if (fromIndex < 0 || toIndex > len || fromIndex > toIndex)
14.1087 + throw new IndexOutOfBoundsException();
14.1088 + return new COWSubList<E>(this, fromIndex, toIndex);
14.1089 + } finally {
14.1090 + lock.unlock();
14.1091 + }
14.1092 + }
14.1093 +
14.1094 + /**
14.1095 + * Sublist for CopyOnWriteArrayList.
14.1096 + * This class extends AbstractList merely for convenience, to
14.1097 + * avoid having to define addAll, etc. This doesn't hurt, but
14.1098 + * is wasteful. This class does not need or use modCount
14.1099 + * mechanics in AbstractList, but does need to check for
14.1100 + * concurrent modification using similar mechanics. On each
14.1101 + * operation, the array that we expect the backing list to use
14.1102 + * is checked and updated. Since we do this for all of the
14.1103 + * base operations invoked by those defined in AbstractList,
14.1104 + * all is well. While inefficient, this is not worth
14.1105 + * improving. The kinds of list operations inherited from
14.1106 + * AbstractList are already so slow on COW sublists that
14.1107 + * adding a bit more space/time doesn't seem even noticeable.
14.1108 + */
14.1109 + private static class COWSubList<E>
14.1110 + extends AbstractList<E>
14.1111 + implements RandomAccess
14.1112 + {
14.1113 + private final CopyOnWriteArrayList<E> l;
14.1114 + private final int offset;
14.1115 + private int size;
14.1116 + private Object[] expectedArray;
14.1117 +
14.1118 + // only call this holding l's lock
14.1119 + COWSubList(CopyOnWriteArrayList<E> list,
14.1120 + int fromIndex, int toIndex) {
14.1121 + l = list;
14.1122 + expectedArray = l.getArray();
14.1123 + offset = fromIndex;
14.1124 + size = toIndex - fromIndex;
14.1125 + }
14.1126 +
14.1127 + // only call this holding l's lock
14.1128 + private void checkForComodification() {
14.1129 + if (l.getArray() != expectedArray)
14.1130 + throw new ConcurrentModificationException();
14.1131 + }
14.1132 +
14.1133 + // only call this holding l's lock
14.1134 + private void rangeCheck(int index) {
14.1135 + if (index<0 || index>=size)
14.1136 + throw new IndexOutOfBoundsException("Index: "+index+
14.1137 + ",Size: "+size);
14.1138 + }
14.1139 +
14.1140 + public E set(int index, E element) {
14.1141 + final ReentrantLock lock = l.lock;
14.1142 + lock.lock();
14.1143 + try {
14.1144 + rangeCheck(index);
14.1145 + checkForComodification();
14.1146 + E x = l.set(index+offset, element);
14.1147 + expectedArray = l.getArray();
14.1148 + return x;
14.1149 + } finally {
14.1150 + lock.unlock();
14.1151 + }
14.1152 + }
14.1153 +
14.1154 + public E get(int index) {
14.1155 + final ReentrantLock lock = l.lock;
14.1156 + lock.lock();
14.1157 + try {
14.1158 + rangeCheck(index);
14.1159 + checkForComodification();
14.1160 + return l.get(index+offset);
14.1161 + } finally {
14.1162 + lock.unlock();
14.1163 + }
14.1164 + }
14.1165 +
14.1166 + public int size() {
14.1167 + final ReentrantLock lock = l.lock;
14.1168 + lock.lock();
14.1169 + try {
14.1170 + checkForComodification();
14.1171 + return size;
14.1172 + } finally {
14.1173 + lock.unlock();
14.1174 + }
14.1175 + }
14.1176 +
14.1177 + public void add(int index, E element) {
14.1178 + final ReentrantLock lock = l.lock;
14.1179 + lock.lock();
14.1180 + try {
14.1181 + checkForComodification();
14.1182 + if (index<0 || index>size)
14.1183 + throw new IndexOutOfBoundsException();
14.1184 + l.add(index+offset, element);
14.1185 + expectedArray = l.getArray();
14.1186 + size++;
14.1187 + } finally {
14.1188 + lock.unlock();
14.1189 + }
14.1190 + }
14.1191 +
14.1192 + public void clear() {
14.1193 + final ReentrantLock lock = l.lock;
14.1194 + lock.lock();
14.1195 + try {
14.1196 + checkForComodification();
14.1197 + l.removeRange(offset, offset+size);
14.1198 + expectedArray = l.getArray();
14.1199 + size = 0;
14.1200 + } finally {
14.1201 + lock.unlock();
14.1202 + }
14.1203 + }
14.1204 +
14.1205 + public E remove(int index) {
14.1206 + final ReentrantLock lock = l.lock;
14.1207 + lock.lock();
14.1208 + try {
14.1209 + rangeCheck(index);
14.1210 + checkForComodification();
14.1211 + E result = l.remove(index+offset);
14.1212 + expectedArray = l.getArray();
14.1213 + size--;
14.1214 + return result;
14.1215 + } finally {
14.1216 + lock.unlock();
14.1217 + }
14.1218 + }
14.1219 +
14.1220 + public boolean remove(Object o) {
14.1221 + int index = indexOf(o);
14.1222 + if (index == -1)
14.1223 + return false;
14.1224 + remove(index);
14.1225 + return true;
14.1226 + }
14.1227 +
14.1228 + public Iterator<E> iterator() {
14.1229 + final ReentrantLock lock = l.lock;
14.1230 + lock.lock();
14.1231 + try {
14.1232 + checkForComodification();
14.1233 + return new COWSubListIterator<E>(l, 0, offset, size);
14.1234 + } finally {
14.1235 + lock.unlock();
14.1236 + }
14.1237 + }
14.1238 +
14.1239 + public ListIterator<E> listIterator(final int index) {
14.1240 + final ReentrantLock lock = l.lock;
14.1241 + lock.lock();
14.1242 + try {
14.1243 + checkForComodification();
14.1244 + if (index<0 || index>size)
14.1245 + throw new IndexOutOfBoundsException("Index: "+index+
14.1246 + ", Size: "+size);
14.1247 + return new COWSubListIterator<E>(l, index, offset, size);
14.1248 + } finally {
14.1249 + lock.unlock();
14.1250 + }
14.1251 + }
14.1252 +
14.1253 + public List<E> subList(int fromIndex, int toIndex) {
14.1254 + final ReentrantLock lock = l.lock;
14.1255 + lock.lock();
14.1256 + try {
14.1257 + checkForComodification();
14.1258 + if (fromIndex<0 || toIndex>size)
14.1259 + throw new IndexOutOfBoundsException();
14.1260 + return new COWSubList<E>(l, fromIndex + offset,
14.1261 + toIndex + offset);
14.1262 + } finally {
14.1263 + lock.unlock();
14.1264 + }
14.1265 + }
14.1266 +
14.1267 + }
14.1268 +
14.1269 +
14.1270 + private static class COWSubListIterator<E> implements ListIterator<E> {
14.1271 + private final ListIterator<E> i;
14.1272 + private final int index;
14.1273 + private final int offset;
14.1274 + private final int size;
14.1275 +
14.1276 + COWSubListIterator(List<E> l, int index, int offset,
14.1277 + int size) {
14.1278 + this.index = index;
14.1279 + this.offset = offset;
14.1280 + this.size = size;
14.1281 + i = l.listIterator(index+offset);
14.1282 + }
14.1283 +
14.1284 + public boolean hasNext() {
14.1285 + return nextIndex() < size;
14.1286 + }
14.1287 +
14.1288 + public E next() {
14.1289 + if (hasNext())
14.1290 + return i.next();
14.1291 + else
14.1292 + throw new NoSuchElementException();
14.1293 + }
14.1294 +
14.1295 + public boolean hasPrevious() {
14.1296 + return previousIndex() >= 0;
14.1297 + }
14.1298 +
14.1299 + public E previous() {
14.1300 + if (hasPrevious())
14.1301 + return i.previous();
14.1302 + else
14.1303 + throw new NoSuchElementException();
14.1304 + }
14.1305 +
14.1306 + public int nextIndex() {
14.1307 + return i.nextIndex() - offset;
14.1308 + }
14.1309 +
14.1310 + public int previousIndex() {
14.1311 + return i.previousIndex() - offset;
14.1312 + }
14.1313 +
14.1314 + public void remove() {
14.1315 + throw new UnsupportedOperationException();
14.1316 + }
14.1317 +
14.1318 + public void set(E e) {
14.1319 + throw new UnsupportedOperationException();
14.1320 + }
14.1321 +
14.1322 + public void add(E e) {
14.1323 + throw new UnsupportedOperationException();
14.1324 + }
14.1325 + }
14.1326 +
14.1327 + // Support for resetting lock while deserializing
14.1328 + private void resetLock() {
14.1329 + UNSAFE.putObjectVolatile(this, lockOffset, new ReentrantLock());
14.1330 + }
14.1331 + private static final sun.misc.Unsafe UNSAFE;
14.1332 + private static final long lockOffset;
14.1333 + static {
14.1334 + try {
14.1335 + UNSAFE = sun.misc.Unsafe.getUnsafe();
14.1336 + Class k = CopyOnWriteArrayList.class;
14.1337 + lockOffset = UNSAFE.objectFieldOffset
14.1338 + (k.getDeclaredField("lock"));
14.1339 + } catch (Exception e) {
14.1340 + throw new Error(e);
14.1341 + }
14.1342 + }
14.1343 +}
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/CopyOnWriteArraySet.java Sat Mar 19 10:46:31 2016 +0100
15.3 @@ -0,0 +1,392 @@
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.*;
15.41 +
15.42 +/**
15.43 + * A {@link java.util.Set} that uses an internal {@link CopyOnWriteArrayList}
15.44 + * for all of its operations. Thus, it shares the same basic properties:
15.45 + * <ul>
15.46 + * <li>It is best suited for applications in which set sizes generally
15.47 + * stay small, read-only operations
15.48 + * vastly outnumber mutative operations, and you need
15.49 + * to prevent interference among threads during traversal.
15.50 + * <li>It is thread-safe.
15.51 + * <li>Mutative operations (<tt>add</tt>, <tt>set</tt>, <tt>remove</tt>, etc.)
15.52 + * are expensive since they usually entail copying the entire underlying
15.53 + * array.
15.54 + * <li>Iterators do not support the mutative <tt>remove</tt> operation.
15.55 + * <li>Traversal via iterators is fast and cannot encounter
15.56 + * interference from other threads. Iterators rely on
15.57 + * unchanging snapshots of the array at the time the iterators were
15.58 + * constructed.
15.59 + * </ul>
15.60 + *
15.61 + * <p> <b>Sample Usage.</b> The following code sketch uses a
15.62 + * copy-on-write set to maintain a set of Handler objects that
15.63 + * perform some action upon state updates.
15.64 + *
15.65 + * <pre> {@code
15.66 + * class Handler { void handle(); ... }
15.67 + *
15.68 + * class X {
15.69 + * private final CopyOnWriteArraySet<Handler> handlers
15.70 + * = new CopyOnWriteArraySet<Handler>();
15.71 + * public void addHandler(Handler h) { handlers.add(h); }
15.72 + *
15.73 + * private long internalState;
15.74 + * private synchronized void changeState() { internalState = ...; }
15.75 + *
15.76 + * public void update() {
15.77 + * changeState();
15.78 + * for (Handler handler : handlers)
15.79 + * handler.handle();
15.80 + * }
15.81 + * }}</pre>
15.82 + *
15.83 + * <p>This class is a member of the
15.84 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
15.85 + * Java Collections Framework</a>.
15.86 + *
15.87 + * @see CopyOnWriteArrayList
15.88 + * @since 1.5
15.89 + * @author Doug Lea
15.90 + * @param <E> the type of elements held in this collection
15.91 + */
15.92 +public class CopyOnWriteArraySet<E> extends AbstractSet<E>
15.93 + implements java.io.Serializable {
15.94 + private static final long serialVersionUID = 5457747651344034263L;
15.95 +
15.96 + private final CopyOnWriteArrayList<E> al;
15.97 +
15.98 + /**
15.99 + * Creates an empty set.
15.100 + */
15.101 + public CopyOnWriteArraySet() {
15.102 + al = new CopyOnWriteArrayList<E>();
15.103 + }
15.104 +
15.105 + /**
15.106 + * Creates a set containing all of the elements of the specified
15.107 + * collection.
15.108 + *
15.109 + * @param c the collection of elements to initially contain
15.110 + * @throws NullPointerException if the specified collection is null
15.111 + */
15.112 + public CopyOnWriteArraySet(Collection<? extends E> c) {
15.113 + al = new CopyOnWriteArrayList<E>();
15.114 + al.addAllAbsent(c);
15.115 + }
15.116 +
15.117 + /**
15.118 + * Returns the number of elements in this set.
15.119 + *
15.120 + * @return the number of elements in this set
15.121 + */
15.122 + public int size() {
15.123 + return al.size();
15.124 + }
15.125 +
15.126 + /**
15.127 + * Returns <tt>true</tt> if this set contains no elements.
15.128 + *
15.129 + * @return <tt>true</tt> if this set contains no elements
15.130 + */
15.131 + public boolean isEmpty() {
15.132 + return al.isEmpty();
15.133 + }
15.134 +
15.135 + /**
15.136 + * Returns <tt>true</tt> if this set contains the specified element.
15.137 + * More formally, returns <tt>true</tt> if and only if this set
15.138 + * contains an element <tt>e</tt> such that
15.139 + * <tt>(o==null ? e==null : o.equals(e))</tt>.
15.140 + *
15.141 + * @param o element whose presence in this set is to be tested
15.142 + * @return <tt>true</tt> if this set contains the specified element
15.143 + */
15.144 + public boolean contains(Object o) {
15.145 + return al.contains(o);
15.146 + }
15.147 +
15.148 + /**
15.149 + * Returns an array containing all of the elements in this set.
15.150 + * If this set makes any guarantees as to what order its elements
15.151 + * are returned by its iterator, this method must return the
15.152 + * elements in the same order.
15.153 + *
15.154 + * <p>The returned array will be "safe" in that no references to it
15.155 + * are maintained by this set. (In other words, this method must
15.156 + * allocate a new array even if this set is backed by an array).
15.157 + * The caller is thus free to modify the returned array.
15.158 + *
15.159 + * <p>This method acts as bridge between array-based and collection-based
15.160 + * APIs.
15.161 + *
15.162 + * @return an array containing all the elements in this set
15.163 + */
15.164 + public Object[] toArray() {
15.165 + return al.toArray();
15.166 + }
15.167 +
15.168 + /**
15.169 + * Returns an array containing all of the elements in this set; the
15.170 + * runtime type of the returned array is that of the specified array.
15.171 + * If the set fits in the specified array, it is returned therein.
15.172 + * Otherwise, a new array is allocated with the runtime type of the
15.173 + * specified array and the size of this set.
15.174 + *
15.175 + * <p>If this set fits in the specified array with room to spare
15.176 + * (i.e., the array has more elements than this set), the element in
15.177 + * the array immediately following the end of the set is set to
15.178 + * <tt>null</tt>. (This is useful in determining the length of this
15.179 + * set <i>only</i> if the caller knows that this set does not contain
15.180 + * any null elements.)
15.181 + *
15.182 + * <p>If this set makes any guarantees as to what order its elements
15.183 + * are returned by its iterator, this method must return the elements
15.184 + * in the same order.
15.185 + *
15.186 + * <p>Like the {@link #toArray()} method, this method acts as bridge between
15.187 + * array-based and collection-based APIs. Further, this method allows
15.188 + * precise control over the runtime type of the output array, and may,
15.189 + * under certain circumstances, be used to save allocation costs.
15.190 + *
15.191 + * <p>Suppose <tt>x</tt> is a set known to contain only strings.
15.192 + * The following code can be used to dump the set into a newly allocated
15.193 + * array of <tt>String</tt>:
15.194 + *
15.195 + * <pre>
15.196 + * String[] y = x.toArray(new String[0]);</pre>
15.197 + *
15.198 + * Note that <tt>toArray(new Object[0])</tt> is identical in function to
15.199 + * <tt>toArray()</tt>.
15.200 + *
15.201 + * @param a the array into which the elements of this set are to be
15.202 + * stored, if it is big enough; otherwise, a new array of the same
15.203 + * runtime type is allocated for this purpose.
15.204 + * @return an array containing all the elements in this set
15.205 + * @throws ArrayStoreException if the runtime type of the specified array
15.206 + * is not a supertype of the runtime type of every element in this
15.207 + * set
15.208 + * @throws NullPointerException if the specified array is null
15.209 + */
15.210 + public <T> T[] toArray(T[] a) {
15.211 + return al.toArray(a);
15.212 + }
15.213 +
15.214 + /**
15.215 + * Removes all of the elements from this set.
15.216 + * The set will be empty after this call returns.
15.217 + */
15.218 + public void clear() {
15.219 + al.clear();
15.220 + }
15.221 +
15.222 + /**
15.223 + * Removes the specified element from this set if it is present.
15.224 + * More formally, removes an element <tt>e</tt> such that
15.225 + * <tt>(o==null ? e==null : o.equals(e))</tt>,
15.226 + * if this set contains such an element. Returns <tt>true</tt> if
15.227 + * this set contained the element (or equivalently, if this set
15.228 + * changed as a result of the call). (This set will not contain the
15.229 + * element once the call returns.)
15.230 + *
15.231 + * @param o object to be removed from this set, if present
15.232 + * @return <tt>true</tt> if this set contained the specified element
15.233 + */
15.234 + public boolean remove(Object o) {
15.235 + return al.remove(o);
15.236 + }
15.237 +
15.238 + /**
15.239 + * Adds the specified element to this set if it is not already present.
15.240 + * More formally, adds the specified element <tt>e</tt> to this set if
15.241 + * the set contains no element <tt>e2</tt> such that
15.242 + * <tt>(e==null ? e2==null : e.equals(e2))</tt>.
15.243 + * If this set already contains the element, the call leaves the set
15.244 + * unchanged and returns <tt>false</tt>.
15.245 + *
15.246 + * @param e element to be added to this set
15.247 + * @return <tt>true</tt> if this set did not already contain the specified
15.248 + * element
15.249 + */
15.250 + public boolean add(E e) {
15.251 + return al.addIfAbsent(e);
15.252 + }
15.253 +
15.254 + /**
15.255 + * Returns <tt>true</tt> if this set contains all of the elements of the
15.256 + * specified collection. If the specified collection is also a set, this
15.257 + * method returns <tt>true</tt> if it is a <i>subset</i> of this set.
15.258 + *
15.259 + * @param c collection to be checked for containment in this set
15.260 + * @return <tt>true</tt> if this set contains all of the elements of the
15.261 + * specified collection
15.262 + * @throws NullPointerException if the specified collection is null
15.263 + * @see #contains(Object)
15.264 + */
15.265 + public boolean containsAll(Collection<?> c) {
15.266 + return al.containsAll(c);
15.267 + }
15.268 +
15.269 + /**
15.270 + * Adds all of the elements in the specified collection to this set if
15.271 + * they're not already present. If the specified collection is also a
15.272 + * set, the <tt>addAll</tt> operation effectively modifies this set so
15.273 + * that its value is the <i>union</i> of the two sets. The behavior of
15.274 + * this operation is undefined if the specified collection is modified
15.275 + * while the operation is in progress.
15.276 + *
15.277 + * @param c collection containing elements to be added to this set
15.278 + * @return <tt>true</tt> if this set changed as a result of the call
15.279 + * @throws NullPointerException if the specified collection is null
15.280 + * @see #add(Object)
15.281 + */
15.282 + public boolean addAll(Collection<? extends E> c) {
15.283 + return al.addAllAbsent(c) > 0;
15.284 + }
15.285 +
15.286 + /**
15.287 + * Removes from this set all of its elements that are contained in the
15.288 + * specified collection. If the specified collection is also a set,
15.289 + * this operation effectively modifies this set so that its value is the
15.290 + * <i>asymmetric set difference</i> of the two sets.
15.291 + *
15.292 + * @param c collection containing elements to be removed from this set
15.293 + * @return <tt>true</tt> if this set changed as a result of the call
15.294 + * @throws ClassCastException if the class of an element of this set
15.295 + * is incompatible with the specified collection (optional)
15.296 + * @throws NullPointerException if this set contains a null element and the
15.297 + * specified collection does not permit null elements (optional),
15.298 + * or if the specified collection is null
15.299 + * @see #remove(Object)
15.300 + */
15.301 + public boolean removeAll(Collection<?> c) {
15.302 + return al.removeAll(c);
15.303 + }
15.304 +
15.305 + /**
15.306 + * Retains only the elements in this set that are contained in the
15.307 + * specified collection. In other words, removes from this set all of
15.308 + * its elements that are not contained in the specified collection. If
15.309 + * the specified collection is also a set, this operation effectively
15.310 + * modifies this set so that its value is the <i>intersection</i> of the
15.311 + * two sets.
15.312 + *
15.313 + * @param c collection containing elements to be retained in this set
15.314 + * @return <tt>true</tt> if this set changed as a result of the call
15.315 + * @throws ClassCastException if the class of an element of this set
15.316 + * is incompatible with the specified collection (optional)
15.317 + * @throws NullPointerException if this set contains a null element and the
15.318 + * specified collection does not permit null elements (optional),
15.319 + * or if the specified collection is null
15.320 + * @see #remove(Object)
15.321 + */
15.322 + public boolean retainAll(Collection<?> c) {
15.323 + return al.retainAll(c);
15.324 + }
15.325 +
15.326 + /**
15.327 + * Returns an iterator over the elements contained in this set
15.328 + * in the order in which these elements were added.
15.329 + *
15.330 + * <p>The returned iterator provides a snapshot of the state of the set
15.331 + * when the iterator was constructed. No synchronization is needed while
15.332 + * traversing the iterator. The iterator does <em>NOT</em> support the
15.333 + * <tt>remove</tt> method.
15.334 + *
15.335 + * @return an iterator over the elements in this set
15.336 + */
15.337 + public Iterator<E> iterator() {
15.338 + return al.iterator();
15.339 + }
15.340 +
15.341 + /**
15.342 + * Compares the specified object with this set for equality.
15.343 + * Returns {@code true} if the specified object is the same object
15.344 + * as this object, or if it is also a {@link Set} and the elements
15.345 + * returned by an {@linkplain List#iterator() iterator} over the
15.346 + * specified set are the same as the elements returned by an
15.347 + * iterator over this set. More formally, the two iterators are
15.348 + * considered to return the same elements if they return the same
15.349 + * number of elements and for every element {@code e1} returned by
15.350 + * the iterator over the specified set, there is an element
15.351 + * {@code e2} returned by the iterator over this set such that
15.352 + * {@code (e1==null ? e2==null : e1.equals(e2))}.
15.353 + *
15.354 + * @param o object to be compared for equality with this set
15.355 + * @return {@code true} if the specified object is equal to this set
15.356 + */
15.357 + public boolean equals(Object o) {
15.358 + if (o == this)
15.359 + return true;
15.360 + if (!(o instanceof Set))
15.361 + return false;
15.362 + Set<?> set = (Set<?>)(o);
15.363 + Iterator<?> it = set.iterator();
15.364 +
15.365 + // Uses O(n^2) algorithm that is only appropriate
15.366 + // for small sets, which CopyOnWriteArraySets should be.
15.367 +
15.368 + // Use a single snapshot of underlying array
15.369 + Object[] elements = al.getArray();
15.370 + int len = elements.length;
15.371 + // Mark matched elements to avoid re-checking
15.372 + boolean[] matched = new boolean[len];
15.373 + int k = 0;
15.374 + outer: while (it.hasNext()) {
15.375 + if (++k > len)
15.376 + return false;
15.377 + Object x = it.next();
15.378 + for (int i = 0; i < len; ++i) {
15.379 + if (!matched[i] && eq(x, elements[i])) {
15.380 + matched[i] = true;
15.381 + continue outer;
15.382 + }
15.383 + }
15.384 + return false;
15.385 + }
15.386 + return k == len;
15.387 + }
15.388 +
15.389 + /**
15.390 + * Test for equality, coping with nulls.
15.391 + */
15.392 + private static boolean eq(Object o1, Object o2) {
15.393 + return (o1 == null ? o2 == null : o1.equals(o2));
15.394 + }
15.395 +}
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
16.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/CountDownLatch.java Sat Mar 19 10:46:31 2016 +0100
16.3 @@ -0,0 +1,320 @@
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 +import java.util.concurrent.atomic.*;
16.42 +
16.43 +/**
16.44 + * A synchronization aid that allows one or more threads to wait until
16.45 + * a set of operations being performed in other threads completes.
16.46 + *
16.47 + * <p>A {@code CountDownLatch} is initialized with a given <em>count</em>.
16.48 + * The {@link #await await} methods block until the current count reaches
16.49 + * zero due to invocations of the {@link #countDown} method, after which
16.50 + * all waiting threads are released and any subsequent invocations of
16.51 + * {@link #await await} return immediately. This is a one-shot phenomenon
16.52 + * -- the count cannot be reset. If you need a version that resets the
16.53 + * count, consider using a {@link CyclicBarrier}.
16.54 + *
16.55 + * <p>A {@code CountDownLatch} is a versatile synchronization tool
16.56 + * and can be used for a number of purposes. A
16.57 + * {@code CountDownLatch} initialized with a count of one serves as a
16.58 + * simple on/off latch, or gate: all threads invoking {@link #await await}
16.59 + * wait at the gate until it is opened by a thread invoking {@link
16.60 + * #countDown}. A {@code CountDownLatch} initialized to <em>N</em>
16.61 + * can be used to make one thread wait until <em>N</em> threads have
16.62 + * completed some action, or some action has been completed N times.
16.63 + *
16.64 + * <p>A useful property of a {@code CountDownLatch} is that it
16.65 + * doesn't require that threads calling {@code countDown} wait for
16.66 + * the count to reach zero before proceeding, it simply prevents any
16.67 + * thread from proceeding past an {@link #await await} until all
16.68 + * threads could pass.
16.69 + *
16.70 + * <p><b>Sample usage:</b> Here is a pair of classes in which a group
16.71 + * of worker threads use two countdown latches:
16.72 + * <ul>
16.73 + * <li>The first is a start signal that prevents any worker from proceeding
16.74 + * until the driver is ready for them to proceed;
16.75 + * <li>The second is a completion signal that allows the driver to wait
16.76 + * until all workers have completed.
16.77 + * </ul>
16.78 + *
16.79 + * <pre>
16.80 + * class Driver { // ...
16.81 + * void main() throws InterruptedException {
16.82 + * CountDownLatch startSignal = new CountDownLatch(1);
16.83 + * CountDownLatch doneSignal = new CountDownLatch(N);
16.84 + *
16.85 + * for (int i = 0; i < N; ++i) // create and start threads
16.86 + * new Thread(new Worker(startSignal, doneSignal)).start();
16.87 + *
16.88 + * doSomethingElse(); // don't let run yet
16.89 + * startSignal.countDown(); // let all threads proceed
16.90 + * doSomethingElse();
16.91 + * doneSignal.await(); // wait for all to finish
16.92 + * }
16.93 + * }
16.94 + *
16.95 + * class Worker implements Runnable {
16.96 + * private final CountDownLatch startSignal;
16.97 + * private final CountDownLatch doneSignal;
16.98 + * Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
16.99 + * this.startSignal = startSignal;
16.100 + * this.doneSignal = doneSignal;
16.101 + * }
16.102 + * public void run() {
16.103 + * try {
16.104 + * startSignal.await();
16.105 + * doWork();
16.106 + * doneSignal.countDown();
16.107 + * } catch (InterruptedException ex) {} // return;
16.108 + * }
16.109 + *
16.110 + * void doWork() { ... }
16.111 + * }
16.112 + *
16.113 + * </pre>
16.114 + *
16.115 + * <p>Another typical usage would be to divide a problem into N parts,
16.116 + * describe each part with a Runnable that executes that portion and
16.117 + * counts down on the latch, and queue all the Runnables to an
16.118 + * Executor. When all sub-parts are complete, the coordinating thread
16.119 + * will be able to pass through await. (When threads must repeatedly
16.120 + * count down in this way, instead use a {@link CyclicBarrier}.)
16.121 + *
16.122 + * <pre>
16.123 + * class Driver2 { // ...
16.124 + * void main() throws InterruptedException {
16.125 + * CountDownLatch doneSignal = new CountDownLatch(N);
16.126 + * Executor e = ...
16.127 + *
16.128 + * for (int i = 0; i < N; ++i) // create and start threads
16.129 + * e.execute(new WorkerRunnable(doneSignal, i));
16.130 + *
16.131 + * doneSignal.await(); // wait for all to finish
16.132 + * }
16.133 + * }
16.134 + *
16.135 + * class WorkerRunnable implements Runnable {
16.136 + * private final CountDownLatch doneSignal;
16.137 + * private final int i;
16.138 + * WorkerRunnable(CountDownLatch doneSignal, int i) {
16.139 + * this.doneSignal = doneSignal;
16.140 + * this.i = i;
16.141 + * }
16.142 + * public void run() {
16.143 + * try {
16.144 + * doWork(i);
16.145 + * doneSignal.countDown();
16.146 + * } catch (InterruptedException ex) {} // return;
16.147 + * }
16.148 + *
16.149 + * void doWork() { ... }
16.150 + * }
16.151 + *
16.152 + * </pre>
16.153 + *
16.154 + * <p>Memory consistency effects: Until the count reaches
16.155 + * zero, actions in a thread prior to calling
16.156 + * {@code countDown()}
16.157 + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
16.158 + * actions following a successful return from a corresponding
16.159 + * {@code await()} in another thread.
16.160 + *
16.161 + * @since 1.5
16.162 + * @author Doug Lea
16.163 + */
16.164 +public class CountDownLatch {
16.165 + /**
16.166 + * Synchronization control For CountDownLatch.
16.167 + * Uses AQS state to represent count.
16.168 + */
16.169 + private static final class Sync extends AbstractQueuedSynchronizer {
16.170 + private static final long serialVersionUID = 4982264981922014374L;
16.171 +
16.172 + Sync(int count) {
16.173 + setState(count);
16.174 + }
16.175 +
16.176 + int getCount() {
16.177 + return getState();
16.178 + }
16.179 +
16.180 + protected int tryAcquireShared(int acquires) {
16.181 + return (getState() == 0) ? 1 : -1;
16.182 + }
16.183 +
16.184 + protected boolean tryReleaseShared(int releases) {
16.185 + // Decrement count; signal when transition to zero
16.186 + for (;;) {
16.187 + int c = getState();
16.188 + if (c == 0)
16.189 + return false;
16.190 + int nextc = c-1;
16.191 + if (compareAndSetState(c, nextc))
16.192 + return nextc == 0;
16.193 + }
16.194 + }
16.195 + }
16.196 +
16.197 + private final Sync sync;
16.198 +
16.199 + /**
16.200 + * Constructs a {@code CountDownLatch} initialized with the given count.
16.201 + *
16.202 + * @param count the number of times {@link #countDown} must be invoked
16.203 + * before threads can pass through {@link #await}
16.204 + * @throws IllegalArgumentException if {@code count} is negative
16.205 + */
16.206 + public CountDownLatch(int count) {
16.207 + if (count < 0) throw new IllegalArgumentException("count < 0");
16.208 + this.sync = new Sync(count);
16.209 + }
16.210 +
16.211 + /**
16.212 + * Causes the current thread to wait until the latch has counted down to
16.213 + * zero, unless the thread is {@linkplain Thread#interrupt interrupted}.
16.214 + *
16.215 + * <p>If the current count is zero then this method returns immediately.
16.216 + *
16.217 + * <p>If the current count is greater than zero then the current
16.218 + * thread becomes disabled for thread scheduling purposes and lies
16.219 + * dormant until one of two things happen:
16.220 + * <ul>
16.221 + * <li>The count reaches zero due to invocations of the
16.222 + * {@link #countDown} method; or
16.223 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
16.224 + * the current thread.
16.225 + * </ul>
16.226 + *
16.227 + * <p>If the current thread:
16.228 + * <ul>
16.229 + * <li>has its interrupted status set on entry to this method; or
16.230 + * <li>is {@linkplain Thread#interrupt interrupted} while waiting,
16.231 + * </ul>
16.232 + * then {@link InterruptedException} is thrown and the current thread's
16.233 + * interrupted status is cleared.
16.234 + *
16.235 + * @throws InterruptedException if the current thread is interrupted
16.236 + * while waiting
16.237 + */
16.238 + public void await() throws InterruptedException {
16.239 + sync.acquireSharedInterruptibly(1);
16.240 + }
16.241 +
16.242 + /**
16.243 + * Causes the current thread to wait until the latch has counted down to
16.244 + * zero, unless the thread is {@linkplain Thread#interrupt interrupted},
16.245 + * or the specified waiting time elapses.
16.246 + *
16.247 + * <p>If the current count is zero then this method returns immediately
16.248 + * with the value {@code true}.
16.249 + *
16.250 + * <p>If the current count is greater than zero then the current
16.251 + * thread becomes disabled for thread scheduling purposes and lies
16.252 + * dormant until one of three things happen:
16.253 + * <ul>
16.254 + * <li>The count reaches zero due to invocations of the
16.255 + * {@link #countDown} method; or
16.256 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
16.257 + * the current thread; or
16.258 + * <li>The specified waiting time elapses.
16.259 + * </ul>
16.260 + *
16.261 + * <p>If the count reaches zero then the method returns with the
16.262 + * value {@code true}.
16.263 + *
16.264 + * <p>If the current thread:
16.265 + * <ul>
16.266 + * <li>has its interrupted status set on entry to this method; or
16.267 + * <li>is {@linkplain Thread#interrupt interrupted} while waiting,
16.268 + * </ul>
16.269 + * then {@link InterruptedException} is thrown and the current thread's
16.270 + * interrupted status is cleared.
16.271 + *
16.272 + * <p>If the specified waiting time elapses then the value {@code false}
16.273 + * is returned. If the time is less than or equal to zero, the method
16.274 + * will not wait at all.
16.275 + *
16.276 + * @param timeout the maximum time to wait
16.277 + * @param unit the time unit of the {@code timeout} argument
16.278 + * @return {@code true} if the count reached zero and {@code false}
16.279 + * if the waiting time elapsed before the count reached zero
16.280 + * @throws InterruptedException if the current thread is interrupted
16.281 + * while waiting
16.282 + */
16.283 + public boolean await(long timeout, TimeUnit unit)
16.284 + throws InterruptedException {
16.285 + return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
16.286 + }
16.287 +
16.288 + /**
16.289 + * Decrements the count of the latch, releasing all waiting threads if
16.290 + * the count reaches zero.
16.291 + *
16.292 + * <p>If the current count is greater than zero then it is decremented.
16.293 + * If the new count is zero then all waiting threads are re-enabled for
16.294 + * thread scheduling purposes.
16.295 + *
16.296 + * <p>If the current count equals zero then nothing happens.
16.297 + */
16.298 + public void countDown() {
16.299 + sync.releaseShared(1);
16.300 + }
16.301 +
16.302 + /**
16.303 + * Returns the current count.
16.304 + *
16.305 + * <p>This method is typically used for debugging and testing purposes.
16.306 + *
16.307 + * @return the current count
16.308 + */
16.309 + public long getCount() {
16.310 + return sync.getCount();
16.311 + }
16.312 +
16.313 + /**
16.314 + * Returns a string identifying this latch, as well as its state.
16.315 + * The state, in brackets, includes the String {@code "Count ="}
16.316 + * followed by the current count.
16.317 + *
16.318 + * @return a string identifying this latch, as well as its state
16.319 + */
16.320 + public String toString() {
16.321 + return super.toString() + "[Count = " + sync.getCount() + "]";
16.322 + }
16.323 +}
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
17.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/CyclicBarrier.java Sat Mar 19 10:46:31 2016 +0100
17.3 @@ -0,0 +1,483 @@
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 +package java.util.concurrent;
17.40 +import java.util.concurrent.locks.*;
17.41 +
17.42 +/**
17.43 + * A synchronization aid that allows a set of threads to all wait for
17.44 + * each other to reach a common barrier point. CyclicBarriers are
17.45 + * useful in programs involving a fixed sized party of threads that
17.46 + * must occasionally wait for each other. The barrier is called
17.47 + * <em>cyclic</em> because it can be re-used after the waiting threads
17.48 + * are released.
17.49 + *
17.50 + * <p>A <tt>CyclicBarrier</tt> supports an optional {@link Runnable} command
17.51 + * that is run once per barrier point, after the last thread in the party
17.52 + * arrives, but before any threads are released.
17.53 + * This <em>barrier action</em> is useful
17.54 + * for updating shared-state before any of the parties continue.
17.55 + *
17.56 + * <p><b>Sample usage:</b> Here is an example of
17.57 + * using a barrier in a parallel decomposition design:
17.58 + * <pre>
17.59 + * class Solver {
17.60 + * final int N;
17.61 + * final float[][] data;
17.62 + * final CyclicBarrier barrier;
17.63 + *
17.64 + * class Worker implements Runnable {
17.65 + * int myRow;
17.66 + * Worker(int row) { myRow = row; }
17.67 + * public void run() {
17.68 + * while (!done()) {
17.69 + * processRow(myRow);
17.70 + *
17.71 + * try {
17.72 + * barrier.await();
17.73 + * } catch (InterruptedException ex) {
17.74 + * return;
17.75 + * } catch (BrokenBarrierException ex) {
17.76 + * return;
17.77 + * }
17.78 + * }
17.79 + * }
17.80 + * }
17.81 + *
17.82 + * public Solver(float[][] matrix) {
17.83 + * data = matrix;
17.84 + * N = matrix.length;
17.85 + * barrier = new CyclicBarrier(N,
17.86 + * new Runnable() {
17.87 + * public void run() {
17.88 + * mergeRows(...);
17.89 + * }
17.90 + * });
17.91 + * for (int i = 0; i < N; ++i)
17.92 + * new Thread(new Worker(i)).start();
17.93 + *
17.94 + * waitUntilDone();
17.95 + * }
17.96 + * }
17.97 + * </pre>
17.98 + * Here, each worker thread processes a row of the matrix then waits at the
17.99 + * barrier until all rows have been processed. When all rows are processed
17.100 + * the supplied {@link Runnable} barrier action is executed and merges the
17.101 + * rows. If the merger
17.102 + * determines that a solution has been found then <tt>done()</tt> will return
17.103 + * <tt>true</tt> and each worker will terminate.
17.104 + *
17.105 + * <p>If the barrier action does not rely on the parties being suspended when
17.106 + * it is executed, then any of the threads in the party could execute that
17.107 + * action when it is released. To facilitate this, each invocation of
17.108 + * {@link #await} returns the arrival index of that thread at the barrier.
17.109 + * You can then choose which thread should execute the barrier action, for
17.110 + * example:
17.111 + * <pre> if (barrier.await() == 0) {
17.112 + * // log the completion of this iteration
17.113 + * }</pre>
17.114 + *
17.115 + * <p>The <tt>CyclicBarrier</tt> uses an all-or-none breakage model
17.116 + * for failed synchronization attempts: If a thread leaves a barrier
17.117 + * point prematurely because of interruption, failure, or timeout, all
17.118 + * other threads waiting at that barrier point will also leave
17.119 + * abnormally via {@link BrokenBarrierException} (or
17.120 + * {@link InterruptedException} if they too were interrupted at about
17.121 + * the same time).
17.122 + *
17.123 + * <p>Memory consistency effects: Actions in a thread prior to calling
17.124 + * {@code await()}
17.125 + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
17.126 + * actions that are part of the barrier action, which in turn
17.127 + * <i>happen-before</i> actions following a successful return from the
17.128 + * corresponding {@code await()} in other threads.
17.129 + *
17.130 + * @since 1.5
17.131 + * @see CountDownLatch
17.132 + *
17.133 + * @author Doug Lea
17.134 + */
17.135 +public class CyclicBarrier {
17.136 + /**
17.137 + * Each use of the barrier is represented as a generation instance.
17.138 + * The generation changes whenever the barrier is tripped, or
17.139 + * is reset. There can be many generations associated with threads
17.140 + * using the barrier - due to the non-deterministic way the lock
17.141 + * may be allocated to waiting threads - but only one of these
17.142 + * can be active at a time (the one to which <tt>count</tt> applies)
17.143 + * and all the rest are either broken or tripped.
17.144 + * There need not be an active generation if there has been a break
17.145 + * but no subsequent reset.
17.146 + */
17.147 + private static class Generation {
17.148 + boolean broken = false;
17.149 + }
17.150 +
17.151 + /** The lock for guarding barrier entry */
17.152 + private final ReentrantLock lock = new ReentrantLock();
17.153 + /** Condition to wait on until tripped */
17.154 + private final Condition trip = lock.newCondition();
17.155 + /** The number of parties */
17.156 + private final int parties;
17.157 + /* The command to run when tripped */
17.158 + private final Runnable barrierCommand;
17.159 + /** The current generation */
17.160 + private Generation generation = new Generation();
17.161 +
17.162 + /**
17.163 + * Number of parties still waiting. Counts down from parties to 0
17.164 + * on each generation. It is reset to parties on each new
17.165 + * generation or when broken.
17.166 + */
17.167 + private int count;
17.168 +
17.169 + /**
17.170 + * Updates state on barrier trip and wakes up everyone.
17.171 + * Called only while holding lock.
17.172 + */
17.173 + private void nextGeneration() {
17.174 + // signal completion of last generation
17.175 + trip.signalAll();
17.176 + // set up next generation
17.177 + count = parties;
17.178 + generation = new Generation();
17.179 + }
17.180 +
17.181 + /**
17.182 + * Sets current barrier generation as broken and wakes up everyone.
17.183 + * Called only while holding lock.
17.184 + */
17.185 + private void breakBarrier() {
17.186 + generation.broken = true;
17.187 + count = parties;
17.188 + trip.signalAll();
17.189 + }
17.190 +
17.191 + /**
17.192 + * Main barrier code, covering the various policies.
17.193 + */
17.194 + private int dowait(boolean timed, long nanos)
17.195 + throws InterruptedException, BrokenBarrierException,
17.196 + TimeoutException {
17.197 + final ReentrantLock lock = this.lock;
17.198 + lock.lock();
17.199 + try {
17.200 + final Generation g = generation;
17.201 +
17.202 + if (g.broken)
17.203 + throw new BrokenBarrierException();
17.204 +
17.205 + if (Thread.interrupted()) {
17.206 + breakBarrier();
17.207 + throw new InterruptedException();
17.208 + }
17.209 +
17.210 + int index = --count;
17.211 + if (index == 0) { // tripped
17.212 + boolean ranAction = false;
17.213 + try {
17.214 + final Runnable command = barrierCommand;
17.215 + if (command != null)
17.216 + command.run();
17.217 + ranAction = true;
17.218 + nextGeneration();
17.219 + return 0;
17.220 + } finally {
17.221 + if (!ranAction)
17.222 + breakBarrier();
17.223 + }
17.224 + }
17.225 +
17.226 + // loop until tripped, broken, interrupted, or timed out
17.227 + for (;;) {
17.228 + try {
17.229 + if (!timed)
17.230 + trip.await();
17.231 + else if (nanos > 0L)
17.232 + nanos = trip.awaitNanos(nanos);
17.233 + } catch (InterruptedException ie) {
17.234 + if (g == generation && ! g.broken) {
17.235 + breakBarrier();
17.236 + throw ie;
17.237 + } else {
17.238 + // We're about to finish waiting even if we had not
17.239 + // been interrupted, so this interrupt is deemed to
17.240 + // "belong" to subsequent execution.
17.241 + Thread.currentThread().interrupt();
17.242 + }
17.243 + }
17.244 +
17.245 + if (g.broken)
17.246 + throw new BrokenBarrierException();
17.247 +
17.248 + if (g != generation)
17.249 + return index;
17.250 +
17.251 + if (timed && nanos <= 0L) {
17.252 + breakBarrier();
17.253 + throw new TimeoutException();
17.254 + }
17.255 + }
17.256 + } finally {
17.257 + lock.unlock();
17.258 + }
17.259 + }
17.260 +
17.261 + /**
17.262 + * Creates a new <tt>CyclicBarrier</tt> that will trip when the
17.263 + * given number of parties (threads) are waiting upon it, and which
17.264 + * will execute the given barrier action when the barrier is tripped,
17.265 + * performed by the last thread entering the barrier.
17.266 + *
17.267 + * @param parties the number of threads that must invoke {@link #await}
17.268 + * before the barrier is tripped
17.269 + * @param barrierAction the command to execute when the barrier is
17.270 + * tripped, or {@code null} if there is no action
17.271 + * @throws IllegalArgumentException if {@code parties} is less than 1
17.272 + */
17.273 + public CyclicBarrier(int parties, Runnable barrierAction) {
17.274 + if (parties <= 0) throw new IllegalArgumentException();
17.275 + this.parties = parties;
17.276 + this.count = parties;
17.277 + this.barrierCommand = barrierAction;
17.278 + }
17.279 +
17.280 + /**
17.281 + * Creates a new <tt>CyclicBarrier</tt> that will trip when the
17.282 + * given number of parties (threads) are waiting upon it, and
17.283 + * does not perform a predefined action when the barrier is tripped.
17.284 + *
17.285 + * @param parties the number of threads that must invoke {@link #await}
17.286 + * before the barrier is tripped
17.287 + * @throws IllegalArgumentException if {@code parties} is less than 1
17.288 + */
17.289 + public CyclicBarrier(int parties) {
17.290 + this(parties, null);
17.291 + }
17.292 +
17.293 + /**
17.294 + * Returns the number of parties required to trip this barrier.
17.295 + *
17.296 + * @return the number of parties required to trip this barrier
17.297 + */
17.298 + public int getParties() {
17.299 + return parties;
17.300 + }
17.301 +
17.302 + /**
17.303 + * Waits until all {@linkplain #getParties parties} have invoked
17.304 + * <tt>await</tt> on this barrier.
17.305 + *
17.306 + * <p>If the current thread is not the last to arrive then it is
17.307 + * disabled for thread scheduling purposes and lies dormant until
17.308 + * one of the following things happens:
17.309 + * <ul>
17.310 + * <li>The last thread arrives; or
17.311 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
17.312 + * the current thread; or
17.313 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
17.314 + * one of the other waiting threads; or
17.315 + * <li>Some other thread times out while waiting for barrier; or
17.316 + * <li>Some other thread invokes {@link #reset} on this barrier.
17.317 + * </ul>
17.318 + *
17.319 + * <p>If the current thread:
17.320 + * <ul>
17.321 + * <li>has its interrupted status set on entry to this method; or
17.322 + * <li>is {@linkplain Thread#interrupt interrupted} while waiting
17.323 + * </ul>
17.324 + * then {@link InterruptedException} is thrown and the current thread's
17.325 + * interrupted status is cleared.
17.326 + *
17.327 + * <p>If the barrier is {@link #reset} while any thread is waiting,
17.328 + * or if the barrier {@linkplain #isBroken is broken} when
17.329 + * <tt>await</tt> is invoked, or while any thread is waiting, then
17.330 + * {@link BrokenBarrierException} is thrown.
17.331 + *
17.332 + * <p>If any thread is {@linkplain Thread#interrupt interrupted} while waiting,
17.333 + * then all other waiting threads will throw
17.334 + * {@link BrokenBarrierException} and the barrier is placed in the broken
17.335 + * state.
17.336 + *
17.337 + * <p>If the current thread is the last thread to arrive, and a
17.338 + * non-null barrier action was supplied in the constructor, then the
17.339 + * current thread runs the action before allowing the other threads to
17.340 + * continue.
17.341 + * If an exception occurs during the barrier action then that exception
17.342 + * will be propagated in the current thread and the barrier is placed in
17.343 + * the broken state.
17.344 + *
17.345 + * @return the arrival index of the current thread, where index
17.346 + * <tt>{@link #getParties()} - 1</tt> indicates the first
17.347 + * to arrive and zero indicates the last to arrive
17.348 + * @throws InterruptedException if the current thread was interrupted
17.349 + * while waiting
17.350 + * @throws BrokenBarrierException if <em>another</em> thread was
17.351 + * interrupted or timed out while the current thread was
17.352 + * waiting, or the barrier was reset, or the barrier was
17.353 + * broken when {@code await} was called, or the barrier
17.354 + * action (if present) failed due an exception.
17.355 + */
17.356 + public int await() throws InterruptedException, BrokenBarrierException {
17.357 + try {
17.358 + return dowait(false, 0L);
17.359 + } catch (TimeoutException toe) {
17.360 + throw new Error(toe); // cannot happen;
17.361 + }
17.362 + }
17.363 +
17.364 + /**
17.365 + * Waits until all {@linkplain #getParties parties} have invoked
17.366 + * <tt>await</tt> on this barrier, or the specified waiting time elapses.
17.367 + *
17.368 + * <p>If the current thread is not the last to arrive then it is
17.369 + * disabled for thread scheduling purposes and lies dormant until
17.370 + * one of the following things happens:
17.371 + * <ul>
17.372 + * <li>The last thread arrives; or
17.373 + * <li>The specified timeout elapses; or
17.374 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
17.375 + * the current thread; or
17.376 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
17.377 + * one of the other waiting threads; or
17.378 + * <li>Some other thread times out while waiting for barrier; or
17.379 + * <li>Some other thread invokes {@link #reset} on this barrier.
17.380 + * </ul>
17.381 + *
17.382 + * <p>If the current thread:
17.383 + * <ul>
17.384 + * <li>has its interrupted status set on entry to this method; or
17.385 + * <li>is {@linkplain Thread#interrupt interrupted} while waiting
17.386 + * </ul>
17.387 + * then {@link InterruptedException} is thrown and the current thread's
17.388 + * interrupted status is cleared.
17.389 + *
17.390 + * <p>If the specified waiting time elapses then {@link TimeoutException}
17.391 + * is thrown. If the time is less than or equal to zero, the
17.392 + * method will not wait at all.
17.393 + *
17.394 + * <p>If the barrier is {@link #reset} while any thread is waiting,
17.395 + * or if the barrier {@linkplain #isBroken is broken} when
17.396 + * <tt>await</tt> is invoked, or while any thread is waiting, then
17.397 + * {@link BrokenBarrierException} is thrown.
17.398 + *
17.399 + * <p>If any thread is {@linkplain Thread#interrupt interrupted} while
17.400 + * waiting, then all other waiting threads will throw {@link
17.401 + * BrokenBarrierException} and the barrier is placed in the broken
17.402 + * state.
17.403 + *
17.404 + * <p>If the current thread is the last thread to arrive, and a
17.405 + * non-null barrier action was supplied in the constructor, then the
17.406 + * current thread runs the action before allowing the other threads to
17.407 + * continue.
17.408 + * If an exception occurs during the barrier action then that exception
17.409 + * will be propagated in the current thread and the barrier is placed in
17.410 + * the broken state.
17.411 + *
17.412 + * @param timeout the time to wait for the barrier
17.413 + * @param unit the time unit of the timeout parameter
17.414 + * @return the arrival index of the current thread, where index
17.415 + * <tt>{@link #getParties()} - 1</tt> indicates the first
17.416 + * to arrive and zero indicates the last to arrive
17.417 + * @throws InterruptedException if the current thread was interrupted
17.418 + * while waiting
17.419 + * @throws TimeoutException if the specified timeout elapses
17.420 + * @throws BrokenBarrierException if <em>another</em> thread was
17.421 + * interrupted or timed out while the current thread was
17.422 + * waiting, or the barrier was reset, or the barrier was broken
17.423 + * when {@code await} was called, or the barrier action (if
17.424 + * present) failed due an exception
17.425 + */
17.426 + public int await(long timeout, TimeUnit unit)
17.427 + throws InterruptedException,
17.428 + BrokenBarrierException,
17.429 + TimeoutException {
17.430 + return dowait(true, unit.toNanos(timeout));
17.431 + }
17.432 +
17.433 + /**
17.434 + * Queries if this barrier is in a broken state.
17.435 + *
17.436 + * @return {@code true} if one or more parties broke out of this
17.437 + * barrier due to interruption or timeout since
17.438 + * construction or the last reset, or a barrier action
17.439 + * failed due to an exception; {@code false} otherwise.
17.440 + */
17.441 + public boolean isBroken() {
17.442 + final ReentrantLock lock = this.lock;
17.443 + lock.lock();
17.444 + try {
17.445 + return generation.broken;
17.446 + } finally {
17.447 + lock.unlock();
17.448 + }
17.449 + }
17.450 +
17.451 + /**
17.452 + * Resets the barrier to its initial state. If any parties are
17.453 + * currently waiting at the barrier, they will return with a
17.454 + * {@link BrokenBarrierException}. Note that resets <em>after</em>
17.455 + * a breakage has occurred for other reasons can be complicated to
17.456 + * carry out; threads need to re-synchronize in some other way,
17.457 + * and choose one to perform the reset. It may be preferable to
17.458 + * instead create a new barrier for subsequent use.
17.459 + */
17.460 + public void reset() {
17.461 + final ReentrantLock lock = this.lock;
17.462 + lock.lock();
17.463 + try {
17.464 + breakBarrier(); // break the current generation
17.465 + nextGeneration(); // start a new generation
17.466 + } finally {
17.467 + lock.unlock();
17.468 + }
17.469 + }
17.470 +
17.471 + /**
17.472 + * Returns the number of parties currently waiting at the barrier.
17.473 + * This method is primarily useful for debugging and assertions.
17.474 + *
17.475 + * @return the number of parties currently blocked in {@link #await}
17.476 + */
17.477 + public int getNumberWaiting() {
17.478 + final ReentrantLock lock = this.lock;
17.479 + lock.lock();
17.480 + try {
17.481 + return parties - count;
17.482 + } finally {
17.483 + lock.unlock();
17.484 + }
17.485 + }
17.486 +}
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
18.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/DelayQueue.java Sat Mar 19 10:46:31 2016 +0100
18.3 @@ -0,0 +1,546 @@
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 +
18.40 +package java.util.concurrent;
18.41 +import java.util.concurrent.locks.*;
18.42 +import java.util.*;
18.43 +
18.44 +/**
18.45 + * An unbounded {@linkplain BlockingQueue blocking queue} of
18.46 + * <tt>Delayed</tt> elements, in which an element can only be taken
18.47 + * when its delay has expired. The <em>head</em> of the queue is that
18.48 + * <tt>Delayed</tt> element whose delay expired furthest in the
18.49 + * past. If no delay has expired there is no head and <tt>poll</tt>
18.50 + * will return <tt>null</tt>. Expiration occurs when an element's
18.51 + * <tt>getDelay(TimeUnit.NANOSECONDS)</tt> method returns a value less
18.52 + * than or equal to zero. Even though unexpired elements cannot be
18.53 + * removed using <tt>take</tt> or <tt>poll</tt>, they are otherwise
18.54 + * treated as normal elements. For example, the <tt>size</tt> method
18.55 + * returns the count of both expired and unexpired elements.
18.56 + * This queue does not permit null elements.
18.57 + *
18.58 + * <p>This class and its iterator implement all of the
18.59 + * <em>optional</em> methods of the {@link Collection} and {@link
18.60 + * Iterator} interfaces.
18.61 + *
18.62 + * <p>This class is a member of the
18.63 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
18.64 + * Java Collections Framework</a>.
18.65 + *
18.66 + * @since 1.5
18.67 + * @author Doug Lea
18.68 + * @param <E> the type of elements held in this collection
18.69 + */
18.70 +
18.71 +public class DelayQueue<E extends Delayed> extends AbstractQueue<E>
18.72 + implements BlockingQueue<E> {
18.73 +
18.74 + private transient final ReentrantLock lock = new ReentrantLock();
18.75 + private final PriorityQueue<E> q = new PriorityQueue<E>();
18.76 +
18.77 + /**
18.78 + * Thread designated to wait for the element at the head of
18.79 + * the queue. This variant of the Leader-Follower pattern
18.80 + * (http://www.cs.wustl.edu/~schmidt/POSA/POSA2/) serves to
18.81 + * minimize unnecessary timed waiting. When a thread becomes
18.82 + * the leader, it waits only for the next delay to elapse, but
18.83 + * other threads await indefinitely. The leader thread must
18.84 + * signal some other thread before returning from take() or
18.85 + * poll(...), unless some other thread becomes leader in the
18.86 + * interim. Whenever the head of the queue is replaced with
18.87 + * an element with an earlier expiration time, the leader
18.88 + * field is invalidated by being reset to null, and some
18.89 + * waiting thread, but not necessarily the current leader, is
18.90 + * signalled. So waiting threads must be prepared to acquire
18.91 + * and lose leadership while waiting.
18.92 + */
18.93 + private Thread leader = null;
18.94 +
18.95 + /**
18.96 + * Condition signalled when a newer element becomes available
18.97 + * at the head of the queue or a new thread may need to
18.98 + * become leader.
18.99 + */
18.100 + private final Condition available = lock.newCondition();
18.101 +
18.102 + /**
18.103 + * Creates a new <tt>DelayQueue</tt> that is initially empty.
18.104 + */
18.105 + public DelayQueue() {}
18.106 +
18.107 + /**
18.108 + * Creates a <tt>DelayQueue</tt> initially containing the elements of the
18.109 + * given collection of {@link Delayed} instances.
18.110 + *
18.111 + * @param c the collection of elements to initially contain
18.112 + * @throws NullPointerException if the specified collection or any
18.113 + * of its elements are null
18.114 + */
18.115 + public DelayQueue(Collection<? extends E> c) {
18.116 + this.addAll(c);
18.117 + }
18.118 +
18.119 + /**
18.120 + * Inserts the specified element into this delay queue.
18.121 + *
18.122 + * @param e the element to add
18.123 + * @return <tt>true</tt> (as specified by {@link Collection#add})
18.124 + * @throws NullPointerException if the specified element is null
18.125 + */
18.126 + public boolean add(E e) {
18.127 + return offer(e);
18.128 + }
18.129 +
18.130 + /**
18.131 + * Inserts the specified element into this delay queue.
18.132 + *
18.133 + * @param e the element to add
18.134 + * @return <tt>true</tt>
18.135 + * @throws NullPointerException if the specified element is null
18.136 + */
18.137 + public boolean offer(E e) {
18.138 + final ReentrantLock lock = this.lock;
18.139 + lock.lock();
18.140 + try {
18.141 + q.offer(e);
18.142 + if (q.peek() == e) {
18.143 + leader = null;
18.144 + available.signal();
18.145 + }
18.146 + return true;
18.147 + } finally {
18.148 + lock.unlock();
18.149 + }
18.150 + }
18.151 +
18.152 + /**
18.153 + * Inserts the specified element into this delay queue. As the queue is
18.154 + * unbounded this method will never block.
18.155 + *
18.156 + * @param e the element to add
18.157 + * @throws NullPointerException {@inheritDoc}
18.158 + */
18.159 + public void put(E e) {
18.160 + offer(e);
18.161 + }
18.162 +
18.163 + /**
18.164 + * Inserts the specified element into this delay queue. As the queue is
18.165 + * unbounded this method will never block.
18.166 + *
18.167 + * @param e the element to add
18.168 + * @param timeout This parameter is ignored as the method never blocks
18.169 + * @param unit This parameter is ignored as the method never blocks
18.170 + * @return <tt>true</tt>
18.171 + * @throws NullPointerException {@inheritDoc}
18.172 + */
18.173 + public boolean offer(E e, long timeout, TimeUnit unit) {
18.174 + return offer(e);
18.175 + }
18.176 +
18.177 + /**
18.178 + * Retrieves and removes the head of this queue, or returns <tt>null</tt>
18.179 + * if this queue has no elements with an expired delay.
18.180 + *
18.181 + * @return the head of this queue, or <tt>null</tt> if this
18.182 + * queue has no elements with an expired delay
18.183 + */
18.184 + public E poll() {
18.185 + final ReentrantLock lock = this.lock;
18.186 + lock.lock();
18.187 + try {
18.188 + E first = q.peek();
18.189 + if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
18.190 + return null;
18.191 + else
18.192 + return q.poll();
18.193 + } finally {
18.194 + lock.unlock();
18.195 + }
18.196 + }
18.197 +
18.198 + /**
18.199 + * Retrieves and removes the head of this queue, waiting if necessary
18.200 + * until an element with an expired delay is available on this queue.
18.201 + *
18.202 + * @return the head of this queue
18.203 + * @throws InterruptedException {@inheritDoc}
18.204 + */
18.205 + public E take() throws InterruptedException {
18.206 + final ReentrantLock lock = this.lock;
18.207 + lock.lockInterruptibly();
18.208 + try {
18.209 + for (;;) {
18.210 + E first = q.peek();
18.211 + if (first == null)
18.212 + available.await();
18.213 + else {
18.214 + long delay = first.getDelay(TimeUnit.NANOSECONDS);
18.215 + if (delay <= 0)
18.216 + return q.poll();
18.217 + else if (leader != null)
18.218 + available.await();
18.219 + else {
18.220 + Thread thisThread = Thread.currentThread();
18.221 + leader = thisThread;
18.222 + try {
18.223 + available.awaitNanos(delay);
18.224 + } finally {
18.225 + if (leader == thisThread)
18.226 + leader = null;
18.227 + }
18.228 + }
18.229 + }
18.230 + }
18.231 + } finally {
18.232 + if (leader == null && q.peek() != null)
18.233 + available.signal();
18.234 + lock.unlock();
18.235 + }
18.236 + }
18.237 +
18.238 + /**
18.239 + * Retrieves and removes the head of this queue, waiting if necessary
18.240 + * until an element with an expired delay is available on this queue,
18.241 + * or the specified wait time expires.
18.242 + *
18.243 + * @return the head of this queue, or <tt>null</tt> if the
18.244 + * specified waiting time elapses before an element with
18.245 + * an expired delay becomes available
18.246 + * @throws InterruptedException {@inheritDoc}
18.247 + */
18.248 + public E poll(long timeout, TimeUnit unit) throws InterruptedException {
18.249 + long nanos = unit.toNanos(timeout);
18.250 + final ReentrantLock lock = this.lock;
18.251 + lock.lockInterruptibly();
18.252 + try {
18.253 + for (;;) {
18.254 + E first = q.peek();
18.255 + if (first == null) {
18.256 + if (nanos <= 0)
18.257 + return null;
18.258 + else
18.259 + nanos = available.awaitNanos(nanos);
18.260 + } else {
18.261 + long delay = first.getDelay(TimeUnit.NANOSECONDS);
18.262 + if (delay <= 0)
18.263 + return q.poll();
18.264 + if (nanos <= 0)
18.265 + return null;
18.266 + if (nanos < delay || leader != null)
18.267 + nanos = available.awaitNanos(nanos);
18.268 + else {
18.269 + Thread thisThread = Thread.currentThread();
18.270 + leader = thisThread;
18.271 + try {
18.272 + long timeLeft = available.awaitNanos(delay);
18.273 + nanos -= delay - timeLeft;
18.274 + } finally {
18.275 + if (leader == thisThread)
18.276 + leader = null;
18.277 + }
18.278 + }
18.279 + }
18.280 + }
18.281 + } finally {
18.282 + if (leader == null && q.peek() != null)
18.283 + available.signal();
18.284 + lock.unlock();
18.285 + }
18.286 + }
18.287 +
18.288 + /**
18.289 + * Retrieves, but does not remove, the head of this queue, or
18.290 + * returns <tt>null</tt> if this queue is empty. Unlike
18.291 + * <tt>poll</tt>, if no expired elements are available in the queue,
18.292 + * this method returns the element that will expire next,
18.293 + * if one exists.
18.294 + *
18.295 + * @return the head of this queue, or <tt>null</tt> if this
18.296 + * queue is empty.
18.297 + */
18.298 + public E peek() {
18.299 + final ReentrantLock lock = this.lock;
18.300 + lock.lock();
18.301 + try {
18.302 + return q.peek();
18.303 + } finally {
18.304 + lock.unlock();
18.305 + }
18.306 + }
18.307 +
18.308 + public int size() {
18.309 + final ReentrantLock lock = this.lock;
18.310 + lock.lock();
18.311 + try {
18.312 + return q.size();
18.313 + } finally {
18.314 + lock.unlock();
18.315 + }
18.316 + }
18.317 +
18.318 + /**
18.319 + * @throws UnsupportedOperationException {@inheritDoc}
18.320 + * @throws ClassCastException {@inheritDoc}
18.321 + * @throws NullPointerException {@inheritDoc}
18.322 + * @throws IllegalArgumentException {@inheritDoc}
18.323 + */
18.324 + public int drainTo(Collection<? super E> c) {
18.325 + if (c == null)
18.326 + throw new NullPointerException();
18.327 + if (c == this)
18.328 + throw new IllegalArgumentException();
18.329 + final ReentrantLock lock = this.lock;
18.330 + lock.lock();
18.331 + try {
18.332 + int n = 0;
18.333 + for (;;) {
18.334 + E first = q.peek();
18.335 + if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
18.336 + break;
18.337 + c.add(q.poll());
18.338 + ++n;
18.339 + }
18.340 + return n;
18.341 + } finally {
18.342 + lock.unlock();
18.343 + }
18.344 + }
18.345 +
18.346 + /**
18.347 + * @throws UnsupportedOperationException {@inheritDoc}
18.348 + * @throws ClassCastException {@inheritDoc}
18.349 + * @throws NullPointerException {@inheritDoc}
18.350 + * @throws IllegalArgumentException {@inheritDoc}
18.351 + */
18.352 + public int drainTo(Collection<? super E> c, int maxElements) {
18.353 + if (c == null)
18.354 + throw new NullPointerException();
18.355 + if (c == this)
18.356 + throw new IllegalArgumentException();
18.357 + if (maxElements <= 0)
18.358 + return 0;
18.359 + final ReentrantLock lock = this.lock;
18.360 + lock.lock();
18.361 + try {
18.362 + int n = 0;
18.363 + while (n < maxElements) {
18.364 + E first = q.peek();
18.365 + if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
18.366 + break;
18.367 + c.add(q.poll());
18.368 + ++n;
18.369 + }
18.370 + return n;
18.371 + } finally {
18.372 + lock.unlock();
18.373 + }
18.374 + }
18.375 +
18.376 + /**
18.377 + * Atomically removes all of the elements from this delay queue.
18.378 + * The queue will be empty after this call returns.
18.379 + * Elements with an unexpired delay are not waited for; they are
18.380 + * simply discarded from the queue.
18.381 + */
18.382 + public void clear() {
18.383 + final ReentrantLock lock = this.lock;
18.384 + lock.lock();
18.385 + try {
18.386 + q.clear();
18.387 + } finally {
18.388 + lock.unlock();
18.389 + }
18.390 + }
18.391 +
18.392 + /**
18.393 + * Always returns <tt>Integer.MAX_VALUE</tt> because
18.394 + * a <tt>DelayQueue</tt> is not capacity constrained.
18.395 + *
18.396 + * @return <tt>Integer.MAX_VALUE</tt>
18.397 + */
18.398 + public int remainingCapacity() {
18.399 + return Integer.MAX_VALUE;
18.400 + }
18.401 +
18.402 + /**
18.403 + * Returns an array containing all of the elements in this queue.
18.404 + * The returned array elements are in no particular order.
18.405 + *
18.406 + * <p>The returned array will be "safe" in that no references to it are
18.407 + * maintained by this queue. (In other words, this method must allocate
18.408 + * a new array). The caller is thus free to modify the returned array.
18.409 + *
18.410 + * <p>This method acts as bridge between array-based and collection-based
18.411 + * APIs.
18.412 + *
18.413 + * @return an array containing all of the elements in this queue
18.414 + */
18.415 + public Object[] toArray() {
18.416 + final ReentrantLock lock = this.lock;
18.417 + lock.lock();
18.418 + try {
18.419 + return q.toArray();
18.420 + } finally {
18.421 + lock.unlock();
18.422 + }
18.423 + }
18.424 +
18.425 + /**
18.426 + * Returns an array containing all of the elements in this queue; the
18.427 + * runtime type of the returned array is that of the specified array.
18.428 + * The returned array elements are in no particular order.
18.429 + * If the queue fits in the specified array, it is returned therein.
18.430 + * Otherwise, a new array is allocated with the runtime type of the
18.431 + * specified array and the size of this queue.
18.432 + *
18.433 + * <p>If this queue fits in the specified array with room to spare
18.434 + * (i.e., the array has more elements than this queue), the element in
18.435 + * the array immediately following the end of the queue is set to
18.436 + * <tt>null</tt>.
18.437 + *
18.438 + * <p>Like the {@link #toArray()} method, this method acts as bridge between
18.439 + * array-based and collection-based APIs. Further, this method allows
18.440 + * precise control over the runtime type of the output array, and may,
18.441 + * under certain circumstances, be used to save allocation costs.
18.442 + *
18.443 + * <p>The following code can be used to dump a delay queue into a newly
18.444 + * allocated array of <tt>Delayed</tt>:
18.445 + *
18.446 + * <pre>
18.447 + * Delayed[] a = q.toArray(new Delayed[0]);</pre>
18.448 + *
18.449 + * Note that <tt>toArray(new Object[0])</tt> is identical in function to
18.450 + * <tt>toArray()</tt>.
18.451 + *
18.452 + * @param a the array into which the elements of the queue are to
18.453 + * be stored, if it is big enough; otherwise, a new array of the
18.454 + * same runtime type is allocated for this purpose
18.455 + * @return an array containing all of the elements in this queue
18.456 + * @throws ArrayStoreException if the runtime type of the specified array
18.457 + * is not a supertype of the runtime type of every element in
18.458 + * this queue
18.459 + * @throws NullPointerException if the specified array is null
18.460 + */
18.461 + public <T> T[] toArray(T[] a) {
18.462 + final ReentrantLock lock = this.lock;
18.463 + lock.lock();
18.464 + try {
18.465 + return q.toArray(a);
18.466 + } finally {
18.467 + lock.unlock();
18.468 + }
18.469 + }
18.470 +
18.471 + /**
18.472 + * Removes a single instance of the specified element from this
18.473 + * queue, if it is present, whether or not it has expired.
18.474 + */
18.475 + public boolean remove(Object o) {
18.476 + final ReentrantLock lock = this.lock;
18.477 + lock.lock();
18.478 + try {
18.479 + return q.remove(o);
18.480 + } finally {
18.481 + lock.unlock();
18.482 + }
18.483 + }
18.484 +
18.485 + /**
18.486 + * Returns an iterator over all the elements (both expired and
18.487 + * unexpired) in this queue. The iterator does not return the
18.488 + * elements in any particular order.
18.489 + *
18.490 + * <p>The returned iterator is a "weakly consistent" iterator that
18.491 + * will never throw {@link java.util.ConcurrentModificationException
18.492 + * ConcurrentModificationException}, and guarantees to traverse
18.493 + * elements as they existed upon construction of the iterator, and
18.494 + * may (but is not guaranteed to) reflect any modifications
18.495 + * subsequent to construction.
18.496 + *
18.497 + * @return an iterator over the elements in this queue
18.498 + */
18.499 + public Iterator<E> iterator() {
18.500 + return new Itr(toArray());
18.501 + }
18.502 +
18.503 + /**
18.504 + * Snapshot iterator that works off copy of underlying q array.
18.505 + */
18.506 + private class Itr implements Iterator<E> {
18.507 + final Object[] array; // Array of all elements
18.508 + int cursor; // index of next element to return;
18.509 + int lastRet; // index of last element, or -1 if no such
18.510 +
18.511 + Itr(Object[] array) {
18.512 + lastRet = -1;
18.513 + this.array = array;
18.514 + }
18.515 +
18.516 + public boolean hasNext() {
18.517 + return cursor < array.length;
18.518 + }
18.519 +
18.520 + @SuppressWarnings("unchecked")
18.521 + public E next() {
18.522 + if (cursor >= array.length)
18.523 + throw new NoSuchElementException();
18.524 + lastRet = cursor;
18.525 + return (E)array[cursor++];
18.526 + }
18.527 +
18.528 + public void remove() {
18.529 + if (lastRet < 0)
18.530 + throw new IllegalStateException();
18.531 + Object x = array[lastRet];
18.532 + lastRet = -1;
18.533 + // Traverse underlying queue to find == element,
18.534 + // not just a .equals element.
18.535 + lock.lock();
18.536 + try {
18.537 + for (Iterator it = q.iterator(); it.hasNext(); ) {
18.538 + if (it.next() == x) {
18.539 + it.remove();
18.540 + return;
18.541 + }
18.542 + }
18.543 + } finally {
18.544 + lock.unlock();
18.545 + }
18.546 + }
18.547 + }
18.548 +
18.549 +}
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
19.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/Delayed.java Sat Mar 19 10:46:31 2016 +0100
19.3 @@ -0,0 +1,62 @@
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 with assistance from members of JCP JSR-166
19.35 + * Expert Group and released to the public domain, as explained at
19.36 + * http://creativecommons.org/publicdomain/zero/1.0/
19.37 + */
19.38 +
19.39 +package java.util.concurrent;
19.40 +
19.41 +import java.util.*;
19.42 +
19.43 +/**
19.44 + * A mix-in style interface for marking objects that should be
19.45 + * acted upon after a given delay.
19.46 + *
19.47 + * <p>An implementation of this interface must define a
19.48 + * <tt>compareTo</tt> method that provides an ordering consistent with
19.49 + * its <tt>getDelay</tt> method.
19.50 + *
19.51 + * @since 1.5
19.52 + * @author Doug Lea
19.53 + */
19.54 +public interface Delayed extends Comparable<Delayed> {
19.55 +
19.56 + /**
19.57 + * Returns the remaining delay associated with this object, in the
19.58 + * given time unit.
19.59 + *
19.60 + * @param unit the time unit
19.61 + * @return the remaining delay; zero or negative values indicate
19.62 + * that the delay has already elapsed
19.63 + */
19.64 + long getDelay(TimeUnit unit);
19.65 +}
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
20.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/Exchanger.java Sat Mar 19 10:46:31 2016 +0100
20.3 @@ -0,0 +1,687 @@
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, Bill Scherer, and Michael Scott with
20.35 + * assistance from members of JCP JSR-166 Expert Group and released to
20.36 + * the public domain, as explained at
20.37 + * http://creativecommons.org/publicdomain/zero/1.0/
20.38 + */
20.39 +
20.40 +package java.util.concurrent;
20.41 +import java.util.concurrent.atomic.*;
20.42 +import java.util.concurrent.locks.LockSupport;
20.43 +
20.44 +/**
20.45 + * A synchronization point at which threads can pair and swap elements
20.46 + * within pairs. Each thread presents some object on entry to the
20.47 + * {@link #exchange exchange} method, matches with a partner thread,
20.48 + * and receives its partner's object on return. An Exchanger may be
20.49 + * viewed as a bidirectional form of a {@link SynchronousQueue}.
20.50 + * Exchangers may be useful in applications such as genetic algorithms
20.51 + * and pipeline designs.
20.52 + *
20.53 + * <p><b>Sample Usage:</b>
20.54 + * Here are the highlights of a class that uses an {@code Exchanger}
20.55 + * to swap buffers between threads so that the thread filling the
20.56 + * buffer gets a freshly emptied one when it needs it, handing off the
20.57 + * filled one to the thread emptying the buffer.
20.58 + * <pre>{@code
20.59 + * class FillAndEmpty {
20.60 + * Exchanger<DataBuffer> exchanger = new Exchanger<DataBuffer>();
20.61 + * DataBuffer initialEmptyBuffer = ... a made-up type
20.62 + * DataBuffer initialFullBuffer = ...
20.63 + *
20.64 + * class FillingLoop implements Runnable {
20.65 + * public void run() {
20.66 + * DataBuffer currentBuffer = initialEmptyBuffer;
20.67 + * try {
20.68 + * while (currentBuffer != null) {
20.69 + * addToBuffer(currentBuffer);
20.70 + * if (currentBuffer.isFull())
20.71 + * currentBuffer = exchanger.exchange(currentBuffer);
20.72 + * }
20.73 + * } catch (InterruptedException ex) { ... handle ... }
20.74 + * }
20.75 + * }
20.76 + *
20.77 + * class EmptyingLoop implements Runnable {
20.78 + * public void run() {
20.79 + * DataBuffer currentBuffer = initialFullBuffer;
20.80 + * try {
20.81 + * while (currentBuffer != null) {
20.82 + * takeFromBuffer(currentBuffer);
20.83 + * if (currentBuffer.isEmpty())
20.84 + * currentBuffer = exchanger.exchange(currentBuffer);
20.85 + * }
20.86 + * } catch (InterruptedException ex) { ... handle ...}
20.87 + * }
20.88 + * }
20.89 + *
20.90 + * void start() {
20.91 + * new Thread(new FillingLoop()).start();
20.92 + * new Thread(new EmptyingLoop()).start();
20.93 + * }
20.94 + * }
20.95 + * }</pre>
20.96 + *
20.97 + * <p>Memory consistency effects: For each pair of threads that
20.98 + * successfully exchange objects via an {@code Exchanger}, actions
20.99 + * prior to the {@code exchange()} in each thread
20.100 + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
20.101 + * those subsequent to a return from the corresponding {@code exchange()}
20.102 + * in the other thread.
20.103 + *
20.104 + * @since 1.5
20.105 + * @author Doug Lea and Bill Scherer and Michael Scott
20.106 + * @param <V> The type of objects that may be exchanged
20.107 + */
20.108 +public class Exchanger<V> {
20.109 + /*
20.110 + * Algorithm Description:
20.111 + *
20.112 + * The basic idea is to maintain a "slot", which is a reference to
20.113 + * a Node containing both an Item to offer and a "hole" waiting to
20.114 + * get filled in. If an incoming "occupying" thread sees that the
20.115 + * slot is null, it CAS'es (compareAndSets) a Node there and waits
20.116 + * for another to invoke exchange. That second "fulfilling" thread
20.117 + * sees that the slot is non-null, and so CASes it back to null,
20.118 + * also exchanging items by CASing the hole, plus waking up the
20.119 + * occupying thread if it is blocked. In each case CAS'es may
20.120 + * fail because a slot at first appears non-null but is null upon
20.121 + * CAS, or vice-versa. So threads may need to retry these
20.122 + * actions.
20.123 + *
20.124 + * This simple approach works great when there are only a few
20.125 + * threads using an Exchanger, but performance rapidly
20.126 + * deteriorates due to CAS contention on the single slot when
20.127 + * there are lots of threads using an exchanger. So instead we use
20.128 + * an "arena"; basically a kind of hash table with a dynamically
20.129 + * varying number of slots, any one of which can be used by
20.130 + * threads performing an exchange. Incoming threads pick slots
20.131 + * based on a hash of their Thread ids. If an incoming thread
20.132 + * fails to CAS in its chosen slot, it picks an alternative slot
20.133 + * instead. And similarly from there. If a thread successfully
20.134 + * CASes into a slot but no other thread arrives, it tries
20.135 + * another, heading toward the zero slot, which always exists even
20.136 + * if the table shrinks. The particular mechanics controlling this
20.137 + * are as follows:
20.138 + *
20.139 + * Waiting: Slot zero is special in that it is the only slot that
20.140 + * exists when there is no contention. A thread occupying slot
20.141 + * zero will block if no thread fulfills it after a short spin.
20.142 + * In other cases, occupying threads eventually give up and try
20.143 + * another slot. Waiting threads spin for a while (a period that
20.144 + * should be a little less than a typical context-switch time)
20.145 + * before either blocking (if slot zero) or giving up (if other
20.146 + * slots) and restarting. There is no reason for threads to block
20.147 + * unless there are unlikely to be any other threads present.
20.148 + * Occupants are mainly avoiding memory contention so sit there
20.149 + * quietly polling for a shorter period than it would take to
20.150 + * block and then unblock them. Non-slot-zero waits that elapse
20.151 + * because of lack of other threads waste around one extra
20.152 + * context-switch time per try, which is still on average much
20.153 + * faster than alternative approaches.
20.154 + *
20.155 + * Sizing: Usually, using only a few slots suffices to reduce
20.156 + * contention. Especially with small numbers of threads, using
20.157 + * too many slots can lead to just as poor performance as using
20.158 + * too few of them, and there's not much room for error. The
20.159 + * variable "max" maintains the number of slots actually in
20.160 + * use. It is increased when a thread sees too many CAS
20.161 + * failures. (This is analogous to resizing a regular hash table
20.162 + * based on a target load factor, except here, growth steps are
20.163 + * just one-by-one rather than proportional.) Growth requires
20.164 + * contention failures in each of three tried slots. Requiring
20.165 + * multiple failures for expansion copes with the fact that some
20.166 + * failed CASes are not due to contention but instead to simple
20.167 + * races between two threads or thread pre-emptions occurring
20.168 + * between reading and CASing. Also, very transient peak
20.169 + * contention can be much higher than the average sustainable
20.170 + * levels. An attempt to decrease the max limit is usually made
20.171 + * when a non-slot-zero wait elapses without being fulfilled.
20.172 + * Threads experiencing elapsed waits move closer to zero, so
20.173 + * eventually find existing (or future) threads even if the table
20.174 + * has been shrunk due to inactivity. The chosen mechanics and
20.175 + * thresholds for growing and shrinking are intrinsically
20.176 + * entangled with indexing and hashing inside the exchange code,
20.177 + * and can't be nicely abstracted out.
20.178 + *
20.179 + * Hashing: Each thread picks its initial slot to use in accord
20.180 + * with a simple hashcode. The sequence is the same on each
20.181 + * encounter by any given thread, but effectively random across
20.182 + * threads. Using arenas encounters the classic cost vs quality
20.183 + * tradeoffs of all hash tables. Here, we use a one-step FNV-1a
20.184 + * hash code based on the current thread's Thread.getId(), along
20.185 + * with a cheap approximation to a mod operation to select an
20.186 + * index. The downside of optimizing index selection in this way
20.187 + * is that the code is hardwired to use a maximum table size of
20.188 + * 32. But this value more than suffices for known platforms and
20.189 + * applications.
20.190 + *
20.191 + * Probing: On sensed contention of a selected slot, we probe
20.192 + * sequentially through the table, analogously to linear probing
20.193 + * after collision in a hash table. (We move circularly, in
20.194 + * reverse order, to mesh best with table growth and shrinkage
20.195 + * rules.) Except that to minimize the effects of false-alarms
20.196 + * and cache thrashing, we try the first selected slot twice
20.197 + * before moving.
20.198 + *
20.199 + * Padding: Even with contention management, slots are heavily
20.200 + * contended, so use cache-padding to avoid poor memory
20.201 + * performance. Because of this, slots are lazily constructed
20.202 + * only when used, to avoid wasting this space unnecessarily.
20.203 + * While isolation of locations is not much of an issue at first
20.204 + * in an application, as time goes on and garbage-collectors
20.205 + * perform compaction, slots are very likely to be moved adjacent
20.206 + * to each other, which can cause much thrashing of cache lines on
20.207 + * MPs unless padding is employed.
20.208 + *
20.209 + * This is an improvement of the algorithm described in the paper
20.210 + * "A Scalable Elimination-based Exchange Channel" by William
20.211 + * Scherer, Doug Lea, and Michael Scott in Proceedings of SCOOL05
20.212 + * workshop. Available at: http://hdl.handle.net/1802/2104
20.213 + */
20.214 +
20.215 + /** The number of CPUs, for sizing and spin control */
20.216 + private static final int NCPU = Runtime.getRuntime().availableProcessors();
20.217 +
20.218 + /**
20.219 + * The capacity of the arena. Set to a value that provides more
20.220 + * than enough space to handle contention. On small machines
20.221 + * most slots won't be used, but it is still not wasted because
20.222 + * the extra space provides some machine-level address padding
20.223 + * to minimize interference with heavily CAS'ed Slot locations.
20.224 + * And on very large machines, performance eventually becomes
20.225 + * bounded by memory bandwidth, not numbers of threads/CPUs.
20.226 + * This constant cannot be changed without also modifying
20.227 + * indexing and hashing algorithms.
20.228 + */
20.229 + private static final int CAPACITY = 32;
20.230 +
20.231 + /**
20.232 + * The value of "max" that will hold all threads without
20.233 + * contention. When this value is less than CAPACITY, some
20.234 + * otherwise wasted expansion can be avoided.
20.235 + */
20.236 + private static final int FULL =
20.237 + Math.max(0, Math.min(CAPACITY, NCPU / 2) - 1);
20.238 +
20.239 + /**
20.240 + * The number of times to spin (doing nothing except polling a
20.241 + * memory location) before blocking or giving up while waiting to
20.242 + * be fulfilled. Should be zero on uniprocessors. On
20.243 + * multiprocessors, this value should be large enough so that two
20.244 + * threads exchanging items as fast as possible block only when
20.245 + * one of them is stalled (due to GC or preemption), but not much
20.246 + * longer, to avoid wasting CPU resources. Seen differently, this
20.247 + * value is a little over half the number of cycles of an average
20.248 + * context switch time on most systems. The value here is
20.249 + * approximately the average of those across a range of tested
20.250 + * systems.
20.251 + */
20.252 + private static final int SPINS = (NCPU == 1) ? 0 : 2000;
20.253 +
20.254 + /**
20.255 + * The number of times to spin before blocking in timed waits.
20.256 + * Timed waits spin more slowly because checking the time takes
20.257 + * time. The best value relies mainly on the relative rate of
20.258 + * System.nanoTime vs memory accesses. The value is empirically
20.259 + * derived to work well across a variety of systems.
20.260 + */
20.261 + private static final int TIMED_SPINS = SPINS / 20;
20.262 +
20.263 + /**
20.264 + * Sentinel item representing cancellation of a wait due to
20.265 + * interruption, timeout, or elapsed spin-waits. This value is
20.266 + * placed in holes on cancellation, and used as a return value
20.267 + * from waiting methods to indicate failure to set or get hole.
20.268 + */
20.269 + private static final Object CANCEL = new Object();
20.270 +
20.271 + /**
20.272 + * Value representing null arguments/returns from public
20.273 + * methods. This disambiguates from internal requirement that
20.274 + * holes start out as null to mean they are not yet set.
20.275 + */
20.276 + private static final Object NULL_ITEM = new Object();
20.277 +
20.278 + /**
20.279 + * Nodes hold partially exchanged data. This class
20.280 + * opportunistically subclasses AtomicReference to represent the
20.281 + * hole. So get() returns hole, and compareAndSet CAS'es value
20.282 + * into hole. This class cannot be parameterized as "V" because
20.283 + * of the use of non-V CANCEL sentinels.
20.284 + */
20.285 + private static final class Node extends AtomicReference<Object> {
20.286 + /** The element offered by the Thread creating this node. */
20.287 + public final Object item;
20.288 +
20.289 + /** The Thread waiting to be signalled; null until waiting. */
20.290 + public volatile Thread waiter;
20.291 +
20.292 + /**
20.293 + * Creates node with given item and empty hole.
20.294 + * @param item the item
20.295 + */
20.296 + public Node(Object item) {
20.297 + this.item = item;
20.298 + }
20.299 + }
20.300 +
20.301 + /**
20.302 + * A Slot is an AtomicReference with heuristic padding to lessen
20.303 + * cache effects of this heavily CAS'ed location. While the
20.304 + * padding adds noticeable space, all slots are created only on
20.305 + * demand, and there will be more than one of them only when it
20.306 + * would improve throughput more than enough to outweigh using
20.307 + * extra space.
20.308 + */
20.309 + private static final class Slot extends AtomicReference<Object> {
20.310 + // Improve likelihood of isolation on <= 64 byte cache lines
20.311 + long q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, qa, qb, qc, qd, qe;
20.312 + }
20.313 +
20.314 + /**
20.315 + * Slot array. Elements are lazily initialized when needed.
20.316 + * Declared volatile to enable double-checked lazy construction.
20.317 + */
20.318 + private volatile Slot[] arena = new Slot[CAPACITY];
20.319 +
20.320 + /**
20.321 + * The maximum slot index being used. The value sometimes
20.322 + * increases when a thread experiences too many CAS contentions,
20.323 + * and sometimes decreases when a spin-wait elapses. Changes
20.324 + * are performed only via compareAndSet, to avoid stale values
20.325 + * when a thread happens to stall right before setting.
20.326 + */
20.327 + private final AtomicInteger max = new AtomicInteger();
20.328 +
20.329 + /**
20.330 + * Main exchange function, handling the different policy variants.
20.331 + * Uses Object, not "V" as argument and return value to simplify
20.332 + * handling of sentinel values. Callers from public methods decode
20.333 + * and cast accordingly.
20.334 + *
20.335 + * @param item the (non-null) item to exchange
20.336 + * @param timed true if the wait is timed
20.337 + * @param nanos if timed, the maximum wait time
20.338 + * @return the other thread's item, or CANCEL if interrupted or timed out
20.339 + */
20.340 + private Object doExchange(Object item, boolean timed, long nanos) {
20.341 + Node me = new Node(item); // Create in case occupying
20.342 + int index = hashIndex(); // Index of current slot
20.343 + int fails = 0; // Number of CAS failures
20.344 +
20.345 + for (;;) {
20.346 + Object y; // Contents of current slot
20.347 + Slot slot = arena[index];
20.348 + if (slot == null) // Lazily initialize slots
20.349 + createSlot(index); // Continue loop to reread
20.350 + else if ((y = slot.get()) != null && // Try to fulfill
20.351 + slot.compareAndSet(y, null)) {
20.352 + Node you = (Node)y; // Transfer item
20.353 + if (you.compareAndSet(null, item)) {
20.354 + LockSupport.unpark(you.waiter);
20.355 + return you.item;
20.356 + } // Else cancelled; continue
20.357 + }
20.358 + else if (y == null && // Try to occupy
20.359 + slot.compareAndSet(null, me)) {
20.360 + if (index == 0) // Blocking wait for slot 0
20.361 + return timed ?
20.362 + awaitNanos(me, slot, nanos) :
20.363 + await(me, slot);
20.364 + Object v = spinWait(me, slot); // Spin wait for non-0
20.365 + if (v != CANCEL)
20.366 + return v;
20.367 + me = new Node(item); // Throw away cancelled node
20.368 + int m = max.get();
20.369 + if (m > (index >>>= 1)) // Decrease index
20.370 + max.compareAndSet(m, m - 1); // Maybe shrink table
20.371 + }
20.372 + else if (++fails > 1) { // Allow 2 fails on 1st slot
20.373 + int m = max.get();
20.374 + if (fails > 3 && m < FULL && max.compareAndSet(m, m + 1))
20.375 + index = m + 1; // Grow on 3rd failed slot
20.376 + else if (--index < 0)
20.377 + index = m; // Circularly traverse
20.378 + }
20.379 + }
20.380 + }
20.381 +
20.382 + /**
20.383 + * Returns a hash index for the current thread. Uses a one-step
20.384 + * FNV-1a hash code (http://www.isthe.com/chongo/tech/comp/fnv/)
20.385 + * based on the current thread's Thread.getId(). These hash codes
20.386 + * have more uniform distribution properties with respect to small
20.387 + * moduli (here 1-31) than do other simple hashing functions.
20.388 + *
20.389 + * <p>To return an index between 0 and max, we use a cheap
20.390 + * approximation to a mod operation, that also corrects for bias
20.391 + * due to non-power-of-2 remaindering (see {@link
20.392 + * java.util.Random#nextInt}). Bits of the hashcode are masked
20.393 + * with "nbits", the ceiling power of two of table size (looked up
20.394 + * in a table packed into three ints). If too large, this is
20.395 + * retried after rotating the hash by nbits bits, while forcing new
20.396 + * top bit to 0, which guarantees eventual termination (although
20.397 + * with a non-random-bias). This requires an average of less than
20.398 + * 2 tries for all table sizes, and has a maximum 2% difference
20.399 + * from perfectly uniform slot probabilities when applied to all
20.400 + * possible hash codes for sizes less than 32.
20.401 + *
20.402 + * @return a per-thread-random index, 0 <= index < max
20.403 + */
20.404 + private final int hashIndex() {
20.405 + long id = Thread.currentThread().getId();
20.406 + int hash = (((int)(id ^ (id >>> 32))) ^ 0x811c9dc5) * 0x01000193;
20.407 +
20.408 + int m = max.get();
20.409 + int nbits = (((0xfffffc00 >> m) & 4) | // Compute ceil(log2(m+1))
20.410 + ((0x000001f8 >>> m) & 2) | // The constants hold
20.411 + ((0xffff00f2 >>> m) & 1)); // a lookup table
20.412 + int index;
20.413 + while ((index = hash & ((1 << nbits) - 1)) > m) // May retry on
20.414 + hash = (hash >>> nbits) | (hash << (33 - nbits)); // non-power-2 m
20.415 + return index;
20.416 + }
20.417 +
20.418 + /**
20.419 + * Creates a new slot at given index. Called only when the slot
20.420 + * appears to be null. Relies on double-check using builtin
20.421 + * locks, since they rarely contend. This in turn relies on the
20.422 + * arena array being declared volatile.
20.423 + *
20.424 + * @param index the index to add slot at
20.425 + */
20.426 + private void createSlot(int index) {
20.427 + // Create slot outside of lock to narrow sync region
20.428 + Slot newSlot = new Slot();
20.429 + Slot[] a = arena;
20.430 + synchronized (a) {
20.431 + if (a[index] == null)
20.432 + a[index] = newSlot;
20.433 + }
20.434 + }
20.435 +
20.436 + /**
20.437 + * Tries to cancel a wait for the given node waiting in the given
20.438 + * slot, if so, helping clear the node from its slot to avoid
20.439 + * garbage retention.
20.440 + *
20.441 + * @param node the waiting node
20.442 + * @param the slot it is waiting in
20.443 + * @return true if successfully cancelled
20.444 + */
20.445 + private static boolean tryCancel(Node node, Slot slot) {
20.446 + if (!node.compareAndSet(null, CANCEL))
20.447 + return false;
20.448 + if (slot.get() == node) // pre-check to minimize contention
20.449 + slot.compareAndSet(node, null);
20.450 + return true;
20.451 + }
20.452 +
20.453 + // Three forms of waiting. Each just different enough not to merge
20.454 + // code with others.
20.455 +
20.456 + /**
20.457 + * Spin-waits for hole for a non-0 slot. Fails if spin elapses
20.458 + * before hole filled. Does not check interrupt, relying on check
20.459 + * in public exchange method to abort if interrupted on entry.
20.460 + *
20.461 + * @param node the waiting node
20.462 + * @return on success, the hole; on failure, CANCEL
20.463 + */
20.464 + private static Object spinWait(Node node, Slot slot) {
20.465 + int spins = SPINS;
20.466 + for (;;) {
20.467 + Object v = node.get();
20.468 + if (v != null)
20.469 + return v;
20.470 + else if (spins > 0)
20.471 + --spins;
20.472 + else
20.473 + tryCancel(node, slot);
20.474 + }
20.475 + }
20.476 +
20.477 + /**
20.478 + * Waits for (by spinning and/or blocking) and gets the hole
20.479 + * filled in by another thread. Fails if interrupted before
20.480 + * hole filled.
20.481 + *
20.482 + * When a node/thread is about to block, it sets its waiter field
20.483 + * and then rechecks state at least one more time before actually
20.484 + * parking, thus covering race vs fulfiller noticing that waiter
20.485 + * is non-null so should be woken.
20.486 + *
20.487 + * Thread interruption status is checked only surrounding calls to
20.488 + * park. The caller is assumed to have checked interrupt status
20.489 + * on entry.
20.490 + *
20.491 + * @param node the waiting node
20.492 + * @return on success, the hole; on failure, CANCEL
20.493 + */
20.494 + private static Object await(Node node, Slot slot) {
20.495 + Thread w = Thread.currentThread();
20.496 + int spins = SPINS;
20.497 + for (;;) {
20.498 + Object v = node.get();
20.499 + if (v != null)
20.500 + return v;
20.501 + else if (spins > 0) // Spin-wait phase
20.502 + --spins;
20.503 + else if (node.waiter == null) // Set up to block next
20.504 + node.waiter = w;
20.505 + else if (w.isInterrupted()) // Abort on interrupt
20.506 + tryCancel(node, slot);
20.507 + else // Block
20.508 + LockSupport.park(node);
20.509 + }
20.510 + }
20.511 +
20.512 + /**
20.513 + * Waits for (at index 0) and gets the hole filled in by another
20.514 + * thread. Fails if timed out or interrupted before hole filled.
20.515 + * Same basic logic as untimed version, but a bit messier.
20.516 + *
20.517 + * @param node the waiting node
20.518 + * @param nanos the wait time
20.519 + * @return on success, the hole; on failure, CANCEL
20.520 + */
20.521 + private Object awaitNanos(Node node, Slot slot, long nanos) {
20.522 + int spins = TIMED_SPINS;
20.523 + long lastTime = 0;
20.524 + Thread w = null;
20.525 + for (;;) {
20.526 + Object v = node.get();
20.527 + if (v != null)
20.528 + return v;
20.529 + long now = System.nanoTime();
20.530 + if (w == null)
20.531 + w = Thread.currentThread();
20.532 + else
20.533 + nanos -= now - lastTime;
20.534 + lastTime = now;
20.535 + if (nanos > 0) {
20.536 + if (spins > 0)
20.537 + --spins;
20.538 + else if (node.waiter == null)
20.539 + node.waiter = w;
20.540 + else if (w.isInterrupted())
20.541 + tryCancel(node, slot);
20.542 + else
20.543 + LockSupport.parkNanos(node, nanos);
20.544 + }
20.545 + else if (tryCancel(node, slot) && !w.isInterrupted())
20.546 + return scanOnTimeout(node);
20.547 + }
20.548 + }
20.549 +
20.550 + /**
20.551 + * Sweeps through arena checking for any waiting threads. Called
20.552 + * only upon return from timeout while waiting in slot 0. When a
20.553 + * thread gives up on a timed wait, it is possible that a
20.554 + * previously-entered thread is still waiting in some other
20.555 + * slot. So we scan to check for any. This is almost always
20.556 + * overkill, but decreases the likelihood of timeouts when there
20.557 + * are other threads present to far less than that in lock-based
20.558 + * exchangers in which earlier-arriving threads may still be
20.559 + * waiting on entry locks.
20.560 + *
20.561 + * @param node the waiting node
20.562 + * @return another thread's item, or CANCEL
20.563 + */
20.564 + private Object scanOnTimeout(Node node) {
20.565 + Object y;
20.566 + for (int j = arena.length - 1; j >= 0; --j) {
20.567 + Slot slot = arena[j];
20.568 + if (slot != null) {
20.569 + while ((y = slot.get()) != null) {
20.570 + if (slot.compareAndSet(y, null)) {
20.571 + Node you = (Node)y;
20.572 + if (you.compareAndSet(null, node.item)) {
20.573 + LockSupport.unpark(you.waiter);
20.574 + return you.item;
20.575 + }
20.576 + }
20.577 + }
20.578 + }
20.579 + }
20.580 + return CANCEL;
20.581 + }
20.582 +
20.583 + /**
20.584 + * Creates a new Exchanger.
20.585 + */
20.586 + public Exchanger() {
20.587 + }
20.588 +
20.589 + /**
20.590 + * Waits for another thread to arrive at this exchange point (unless
20.591 + * the current thread is {@linkplain Thread#interrupt interrupted}),
20.592 + * and then transfers the given object to it, receiving its object
20.593 + * in return.
20.594 + *
20.595 + * <p>If another thread is already waiting at the exchange point then
20.596 + * it is resumed for thread scheduling purposes and receives the object
20.597 + * passed in by the current thread. The current thread returns immediately,
20.598 + * receiving the object passed to the exchange by that other thread.
20.599 + *
20.600 + * <p>If no other thread is already waiting at the exchange then the
20.601 + * current thread is disabled for thread scheduling purposes and lies
20.602 + * dormant until one of two things happens:
20.603 + * <ul>
20.604 + * <li>Some other thread enters the exchange; or
20.605 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
20.606 + * the current thread.
20.607 + * </ul>
20.608 + * <p>If the current thread:
20.609 + * <ul>
20.610 + * <li>has its interrupted status set on entry to this method; or
20.611 + * <li>is {@linkplain Thread#interrupt interrupted} while waiting
20.612 + * for the exchange,
20.613 + * </ul>
20.614 + * then {@link InterruptedException} is thrown and the current thread's
20.615 + * interrupted status is cleared.
20.616 + *
20.617 + * @param x the object to exchange
20.618 + * @return the object provided by the other thread
20.619 + * @throws InterruptedException if the current thread was
20.620 + * interrupted while waiting
20.621 + */
20.622 + public V exchange(V x) throws InterruptedException {
20.623 + if (!Thread.interrupted()) {
20.624 + Object v = doExchange((x == null) ? NULL_ITEM : x, false, 0);
20.625 + if (v == NULL_ITEM)
20.626 + return null;
20.627 + if (v != CANCEL)
20.628 + return (V)v;
20.629 + Thread.interrupted(); // Clear interrupt status on IE throw
20.630 + }
20.631 + throw new InterruptedException();
20.632 + }
20.633 +
20.634 + /**
20.635 + * Waits for another thread to arrive at this exchange point (unless
20.636 + * the current thread is {@linkplain Thread#interrupt interrupted} or
20.637 + * the specified waiting time elapses), and then transfers the given
20.638 + * object to it, receiving its object in return.
20.639 + *
20.640 + * <p>If another thread is already waiting at the exchange point then
20.641 + * it is resumed for thread scheduling purposes and receives the object
20.642 + * passed in by the current thread. The current thread returns immediately,
20.643 + * receiving the object passed to the exchange by that other thread.
20.644 + *
20.645 + * <p>If no other thread is already waiting at the exchange then the
20.646 + * current thread is disabled for thread scheduling purposes and lies
20.647 + * dormant until one of three things happens:
20.648 + * <ul>
20.649 + * <li>Some other thread enters the exchange; or
20.650 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
20.651 + * the current thread; or
20.652 + * <li>The specified waiting time elapses.
20.653 + * </ul>
20.654 + * <p>If the current thread:
20.655 + * <ul>
20.656 + * <li>has its interrupted status set on entry to this method; or
20.657 + * <li>is {@linkplain Thread#interrupt interrupted} while waiting
20.658 + * for the exchange,
20.659 + * </ul>
20.660 + * then {@link InterruptedException} is thrown and the current thread's
20.661 + * interrupted status is cleared.
20.662 + *
20.663 + * <p>If the specified waiting time elapses then {@link
20.664 + * TimeoutException} is thrown. If the time is less than or equal
20.665 + * to zero, the method will not wait at all.
20.666 + *
20.667 + * @param x the object to exchange
20.668 + * @param timeout the maximum time to wait
20.669 + * @param unit the time unit of the <tt>timeout</tt> argument
20.670 + * @return the object provided by the other thread
20.671 + * @throws InterruptedException if the current thread was
20.672 + * interrupted while waiting
20.673 + * @throws TimeoutException if the specified waiting time elapses
20.674 + * before another thread enters the exchange
20.675 + */
20.676 + public V exchange(V x, long timeout, TimeUnit unit)
20.677 + throws InterruptedException, TimeoutException {
20.678 + if (!Thread.interrupted()) {
20.679 + Object v = doExchange((x == null) ? NULL_ITEM : x,
20.680 + true, unit.toNanos(timeout));
20.681 + if (v == NULL_ITEM)
20.682 + return null;
20.683 + if (v != CANCEL)
20.684 + return (V)v;
20.685 + if (!Thread.interrupted())
20.686 + throw new TimeoutException();
20.687 + }
20.688 + throw new InterruptedException();
20.689 + }
20.690 +}
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
21.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ExecutionException.java Sat Mar 19 10:46:31 2016 +0100
21.3 @@ -0,0 +1,94 @@
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 + * Exception thrown when attempting to retrieve the result of a task
21.43 + * that aborted by throwing an exception. This exception can be
21.44 + * inspected using the {@link #getCause()} method.
21.45 + *
21.46 + * @see Future
21.47 + * @since 1.5
21.48 + * @author Doug Lea
21.49 + */
21.50 +public class ExecutionException extends Exception {
21.51 + private static final long serialVersionUID = 7830266012832686185L;
21.52 +
21.53 + /**
21.54 + * Constructs an <tt>ExecutionException</tt> with no detail message.
21.55 + * The cause is not initialized, and may subsequently be
21.56 + * initialized by a call to {@link #initCause(Throwable) initCause}.
21.57 + */
21.58 + protected ExecutionException() { }
21.59 +
21.60 + /**
21.61 + * Constructs an <tt>ExecutionException</tt> with the specified detail
21.62 + * message. The cause is not initialized, and may subsequently be
21.63 + * initialized by a call to {@link #initCause(Throwable) initCause}.
21.64 + *
21.65 + * @param message the detail message
21.66 + */
21.67 + protected ExecutionException(String message) {
21.68 + super(message);
21.69 + }
21.70 +
21.71 + /**
21.72 + * Constructs an <tt>ExecutionException</tt> with the specified detail
21.73 + * message and cause.
21.74 + *
21.75 + * @param message the detail message
21.76 + * @param cause the cause (which is saved for later retrieval by the
21.77 + * {@link #getCause()} method)
21.78 + */
21.79 + public ExecutionException(String message, Throwable cause) {
21.80 + super(message, cause);
21.81 + }
21.82 +
21.83 + /**
21.84 + * Constructs an <tt>ExecutionException</tt> with the specified cause.
21.85 + * The detail message is set to:
21.86 + * <pre>
21.87 + * (cause == null ? null : cause.toString())</pre>
21.88 + * (which typically contains the class and detail message of
21.89 + * <tt>cause</tt>).
21.90 + *
21.91 + * @param cause the cause (which is saved for later retrieval by the
21.92 + * {@link #getCause()} method)
21.93 + */
21.94 + public ExecutionException(Throwable cause) {
21.95 + super(cause);
21.96 + }
21.97 +}
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
22.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/Executor.java Sat Mar 19 10:46:31 2016 +0100
22.3 @@ -0,0 +1,141 @@
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 +
22.41 +/**
22.42 + * An object that executes submitted {@link Runnable} tasks. This
22.43 + * interface provides a way of decoupling task submission from the
22.44 + * mechanics of how each task will be run, including details of thread
22.45 + * use, scheduling, etc. An <tt>Executor</tt> is normally used
22.46 + * instead of explicitly creating threads. For example, rather than
22.47 + * invoking <tt>new Thread(new(RunnableTask())).start()</tt> for each
22.48 + * of a set of tasks, you might use:
22.49 + *
22.50 + * <pre>
22.51 + * Executor executor = <em>anExecutor</em>;
22.52 + * executor.execute(new RunnableTask1());
22.53 + * executor.execute(new RunnableTask2());
22.54 + * ...
22.55 + * </pre>
22.56 + *
22.57 + * However, the <tt>Executor</tt> interface does not strictly
22.58 + * require that execution be asynchronous. In the simplest case, an
22.59 + * executor can run the submitted task immediately in the caller's
22.60 + * thread:
22.61 + *
22.62 + * <pre>
22.63 + * class DirectExecutor implements Executor {
22.64 + * public void execute(Runnable r) {
22.65 + * r.run();
22.66 + * }
22.67 + * }</pre>
22.68 + *
22.69 + * More typically, tasks are executed in some thread other
22.70 + * than the caller's thread. The executor below spawns a new thread
22.71 + * for each task.
22.72 + *
22.73 + * <pre>
22.74 + * class ThreadPerTaskExecutor implements Executor {
22.75 + * public void execute(Runnable r) {
22.76 + * new Thread(r).start();
22.77 + * }
22.78 + * }</pre>
22.79 + *
22.80 + * Many <tt>Executor</tt> implementations impose some sort of
22.81 + * limitation on how and when tasks are scheduled. The executor below
22.82 + * serializes the submission of tasks to a second executor,
22.83 + * illustrating a composite executor.
22.84 + *
22.85 + * <pre> {@code
22.86 + * class SerialExecutor implements Executor {
22.87 + * final Queue<Runnable> tasks = new ArrayDeque<Runnable>();
22.88 + * final Executor executor;
22.89 + * Runnable active;
22.90 + *
22.91 + * SerialExecutor(Executor executor) {
22.92 + * this.executor = executor;
22.93 + * }
22.94 + *
22.95 + * public synchronized void execute(final Runnable r) {
22.96 + * tasks.offer(new Runnable() {
22.97 + * public void run() {
22.98 + * try {
22.99 + * r.run();
22.100 + * } finally {
22.101 + * scheduleNext();
22.102 + * }
22.103 + * }
22.104 + * });
22.105 + * if (active == null) {
22.106 + * scheduleNext();
22.107 + * }
22.108 + * }
22.109 + *
22.110 + * protected synchronized void scheduleNext() {
22.111 + * if ((active = tasks.poll()) != null) {
22.112 + * executor.execute(active);
22.113 + * }
22.114 + * }
22.115 + * }}</pre>
22.116 + *
22.117 + * The <tt>Executor</tt> implementations provided in this package
22.118 + * implement {@link ExecutorService}, which is a more extensive
22.119 + * interface. The {@link ThreadPoolExecutor} class provides an
22.120 + * extensible thread pool implementation. The {@link Executors} class
22.121 + * provides convenient factory methods for these Executors.
22.122 + *
22.123 + * <p>Memory consistency effects: Actions in a thread prior to
22.124 + * submitting a {@code Runnable} object to an {@code Executor}
22.125 + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
22.126 + * its execution begins, perhaps in another thread.
22.127 + *
22.128 + * @since 1.5
22.129 + * @author Doug Lea
22.130 + */
22.131 +public interface Executor {
22.132 +
22.133 + /**
22.134 + * Executes the given command at some time in the future. The command
22.135 + * may execute in a new thread, in a pooled thread, or in the calling
22.136 + * thread, at the discretion of the <tt>Executor</tt> implementation.
22.137 + *
22.138 + * @param command the runnable task
22.139 + * @throws RejectedExecutionException if this task cannot be
22.140 + * accepted for execution.
22.141 + * @throws NullPointerException if command is null
22.142 + */
22.143 + void execute(Runnable command);
22.144 +}
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
23.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ExecutorCompletionService.java Sat Mar 19 10:46:31 2016 +0100
23.3 @@ -0,0 +1,205 @@
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 +
23.41 +/**
23.42 + * A {@link CompletionService} that uses a supplied {@link Executor}
23.43 + * to execute tasks. This class arranges that submitted tasks are,
23.44 + * upon completion, placed on a queue accessible using {@code take}.
23.45 + * The class is lightweight enough to be suitable for transient use
23.46 + * when processing groups of tasks.
23.47 + *
23.48 + * <p>
23.49 + *
23.50 + * <b>Usage Examples.</b>
23.51 + *
23.52 + * Suppose you have a set of solvers for a certain problem, each
23.53 + * returning a value of some type {@code Result}, and would like to
23.54 + * run them concurrently, processing the results of each of them that
23.55 + * return a non-null value, in some method {@code use(Result r)}. You
23.56 + * could write this as:
23.57 + *
23.58 + * <pre> {@code
23.59 + * void solve(Executor e,
23.60 + * Collection<Callable<Result>> solvers)
23.61 + * throws InterruptedException, ExecutionException {
23.62 + * CompletionService<Result> ecs
23.63 + * = new ExecutorCompletionService<Result>(e);
23.64 + * for (Callable<Result> s : solvers)
23.65 + * ecs.submit(s);
23.66 + * int n = solvers.size();
23.67 + * for (int i = 0; i < n; ++i) {
23.68 + * Result r = ecs.take().get();
23.69 + * if (r != null)
23.70 + * use(r);
23.71 + * }
23.72 + * }}</pre>
23.73 + *
23.74 + * Suppose instead that you would like to use the first non-null result
23.75 + * of the set of tasks, ignoring any that encounter exceptions,
23.76 + * and cancelling all other tasks when the first one is ready:
23.77 + *
23.78 + * <pre> {@code
23.79 + * void solve(Executor e,
23.80 + * Collection<Callable<Result>> solvers)
23.81 + * throws InterruptedException {
23.82 + * CompletionService<Result> ecs
23.83 + * = new ExecutorCompletionService<Result>(e);
23.84 + * int n = solvers.size();
23.85 + * List<Future<Result>> futures
23.86 + * = new ArrayList<Future<Result>>(n);
23.87 + * Result result = null;
23.88 + * try {
23.89 + * for (Callable<Result> s : solvers)
23.90 + * futures.add(ecs.submit(s));
23.91 + * for (int i = 0; i < n; ++i) {
23.92 + * try {
23.93 + * Result r = ecs.take().get();
23.94 + * if (r != null) {
23.95 + * result = r;
23.96 + * break;
23.97 + * }
23.98 + * } catch (ExecutionException ignore) {}
23.99 + * }
23.100 + * }
23.101 + * finally {
23.102 + * for (Future<Result> f : futures)
23.103 + * f.cancel(true);
23.104 + * }
23.105 + *
23.106 + * if (result != null)
23.107 + * use(result);
23.108 + * }}</pre>
23.109 + */
23.110 +public class ExecutorCompletionService<V> implements CompletionService<V> {
23.111 + private final Executor executor;
23.112 + private final AbstractExecutorService aes;
23.113 + private final BlockingQueue<Future<V>> completionQueue;
23.114 +
23.115 + /**
23.116 + * FutureTask extension to enqueue upon completion
23.117 + */
23.118 + private class QueueingFuture extends FutureTask<Void> {
23.119 + QueueingFuture(RunnableFuture<V> task) {
23.120 + super(task, null);
23.121 + this.task = task;
23.122 + }
23.123 + protected void done() { completionQueue.add(task); }
23.124 + private final Future<V> task;
23.125 + }
23.126 +
23.127 + private RunnableFuture<V> newTaskFor(Callable<V> task) {
23.128 + if (aes == null)
23.129 + return new FutureTask<V>(task);
23.130 + else
23.131 + return aes.newTaskFor(task);
23.132 + }
23.133 +
23.134 + private RunnableFuture<V> newTaskFor(Runnable task, V result) {
23.135 + if (aes == null)
23.136 + return new FutureTask<V>(task, result);
23.137 + else
23.138 + return aes.newTaskFor(task, result);
23.139 + }
23.140 +
23.141 + /**
23.142 + * Creates an ExecutorCompletionService using the supplied
23.143 + * executor for base task execution and a
23.144 + * {@link LinkedBlockingQueue} as a completion queue.
23.145 + *
23.146 + * @param executor the executor to use
23.147 + * @throws NullPointerException if executor is {@code null}
23.148 + */
23.149 + public ExecutorCompletionService(Executor executor) {
23.150 + if (executor == null)
23.151 + throw new NullPointerException();
23.152 + this.executor = executor;
23.153 + this.aes = (executor instanceof AbstractExecutorService) ?
23.154 + (AbstractExecutorService) executor : null;
23.155 + this.completionQueue = new LinkedBlockingQueue<Future<V>>();
23.156 + }
23.157 +
23.158 + /**
23.159 + * Creates an ExecutorCompletionService using the supplied
23.160 + * executor for base task execution and the supplied queue as its
23.161 + * completion queue.
23.162 + *
23.163 + * @param executor the executor to use
23.164 + * @param completionQueue the queue to use as the completion queue
23.165 + * normally one dedicated for use by this service. This
23.166 + * queue is treated as unbounded -- failed attempted
23.167 + * {@code Queue.add} operations for completed taskes cause
23.168 + * them not to be retrievable.
23.169 + * @throws NullPointerException if executor or completionQueue are {@code null}
23.170 + */
23.171 + public ExecutorCompletionService(Executor executor,
23.172 + BlockingQueue<Future<V>> completionQueue) {
23.173 + if (executor == null || completionQueue == null)
23.174 + throw new NullPointerException();
23.175 + this.executor = executor;
23.176 + this.aes = (executor instanceof AbstractExecutorService) ?
23.177 + (AbstractExecutorService) executor : null;
23.178 + this.completionQueue = completionQueue;
23.179 + }
23.180 +
23.181 + public Future<V> submit(Callable<V> task) {
23.182 + if (task == null) throw new NullPointerException();
23.183 + RunnableFuture<V> f = newTaskFor(task);
23.184 + executor.execute(new QueueingFuture(f));
23.185 + return f;
23.186 + }
23.187 +
23.188 + public Future<V> submit(Runnable task, V result) {
23.189 + if (task == null) throw new NullPointerException();
23.190 + RunnableFuture<V> f = newTaskFor(task, result);
23.191 + executor.execute(new QueueingFuture(f));
23.192 + return f;
23.193 + }
23.194 +
23.195 + public Future<V> take() throws InterruptedException {
23.196 + return completionQueue.take();
23.197 + }
23.198 +
23.199 + public Future<V> poll() {
23.200 + return completionQueue.poll();
23.201 + }
23.202 +
23.203 + public Future<V> poll(long timeout, TimeUnit unit)
23.204 + throws InterruptedException {
23.205 + return completionQueue.poll(timeout, unit);
23.206 + }
23.207 +
23.208 +}
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
24.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ExecutorService.java Sat Mar 19 10:46:31 2016 +0100
24.3 @@ -0,0 +1,370 @@
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 +import java.util.List;
24.41 +import java.util.Collection;
24.42 +import java.security.PrivilegedAction;
24.43 +import java.security.PrivilegedExceptionAction;
24.44 +
24.45 +/**
24.46 + * An {@link Executor} that provides methods to manage termination and
24.47 + * methods that can produce a {@link Future} for tracking progress of
24.48 + * one or more asynchronous tasks.
24.49 + *
24.50 + * <p> An <tt>ExecutorService</tt> can be shut down, which will cause
24.51 + * it to reject new tasks. Two different methods are provided for
24.52 + * shutting down an <tt>ExecutorService</tt>. The {@link #shutdown}
24.53 + * method will allow previously submitted tasks to execute before
24.54 + * terminating, while the {@link #shutdownNow} method prevents waiting
24.55 + * tasks from starting and attempts to stop currently executing tasks.
24.56 + * Upon termination, an executor has no tasks actively executing, no
24.57 + * tasks awaiting execution, and no new tasks can be submitted. An
24.58 + * unused <tt>ExecutorService</tt> should be shut down to allow
24.59 + * reclamation of its resources.
24.60 + *
24.61 + * <p> Method <tt>submit</tt> extends base method {@link
24.62 + * Executor#execute} by creating and returning a {@link Future} that
24.63 + * can be used to cancel execution and/or wait for completion.
24.64 + * Methods <tt>invokeAny</tt> and <tt>invokeAll</tt> perform the most
24.65 + * commonly useful forms of bulk execution, executing a collection of
24.66 + * tasks and then waiting for at least one, or all, to
24.67 + * complete. (Class {@link ExecutorCompletionService} can be used to
24.68 + * write customized variants of these methods.)
24.69 + *
24.70 + * <p>The {@link Executors} class provides factory methods for the
24.71 + * executor services provided in this package.
24.72 + *
24.73 + * <h3>Usage Examples</h3>
24.74 + *
24.75 + * Here is a sketch of a network service in which threads in a thread
24.76 + * pool service incoming requests. It uses the preconfigured {@link
24.77 + * Executors#newFixedThreadPool} factory method:
24.78 + *
24.79 + * <pre>
24.80 + * class NetworkService implements Runnable {
24.81 + * private final ServerSocket serverSocket;
24.82 + * private final ExecutorService pool;
24.83 + *
24.84 + * public NetworkService(int port, int poolSize)
24.85 + * throws IOException {
24.86 + * serverSocket = new ServerSocket(port);
24.87 + * pool = Executors.newFixedThreadPool(poolSize);
24.88 + * }
24.89 + *
24.90 + * public void run() { // run the service
24.91 + * try {
24.92 + * for (;;) {
24.93 + * pool.execute(new Handler(serverSocket.accept()));
24.94 + * }
24.95 + * } catch (IOException ex) {
24.96 + * pool.shutdown();
24.97 + * }
24.98 + * }
24.99 + * }
24.100 + *
24.101 + * class Handler implements Runnable {
24.102 + * private final Socket socket;
24.103 + * Handler(Socket socket) { this.socket = socket; }
24.104 + * public void run() {
24.105 + * // read and service request on socket
24.106 + * }
24.107 + * }
24.108 + * </pre>
24.109 + *
24.110 + * The following method shuts down an <tt>ExecutorService</tt> in two phases,
24.111 + * first by calling <tt>shutdown</tt> to reject incoming tasks, and then
24.112 + * calling <tt>shutdownNow</tt>, if necessary, to cancel any lingering tasks:
24.113 + *
24.114 + * <pre>
24.115 + * void shutdownAndAwaitTermination(ExecutorService pool) {
24.116 + * pool.shutdown(); // Disable new tasks from being submitted
24.117 + * try {
24.118 + * // Wait a while for existing tasks to terminate
24.119 + * if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
24.120 + * pool.shutdownNow(); // Cancel currently executing tasks
24.121 + * // Wait a while for tasks to respond to being cancelled
24.122 + * if (!pool.awaitTermination(60, TimeUnit.SECONDS))
24.123 + * System.err.println("Pool did not terminate");
24.124 + * }
24.125 + * } catch (InterruptedException ie) {
24.126 + * // (Re-)Cancel if current thread also interrupted
24.127 + * pool.shutdownNow();
24.128 + * // Preserve interrupt status
24.129 + * Thread.currentThread().interrupt();
24.130 + * }
24.131 + * }
24.132 + * </pre>
24.133 + *
24.134 + * <p>Memory consistency effects: Actions in a thread prior to the
24.135 + * submission of a {@code Runnable} or {@code Callable} task to an
24.136 + * {@code ExecutorService}
24.137 + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
24.138 + * any actions taken by that task, which in turn <i>happen-before</i> the
24.139 + * result is retrieved via {@code Future.get()}.
24.140 + *
24.141 + * @since 1.5
24.142 + * @author Doug Lea
24.143 + */
24.144 +public interface ExecutorService extends Executor {
24.145 +
24.146 + /**
24.147 + * Initiates an orderly shutdown in which previously submitted
24.148 + * tasks are executed, but no new tasks will be accepted.
24.149 + * Invocation has no additional effect if already shut down.
24.150 + *
24.151 + * <p>This method does not wait for previously submitted tasks to
24.152 + * complete execution. Use {@link #awaitTermination awaitTermination}
24.153 + * to do that.
24.154 + *
24.155 + * @throws SecurityException if a security manager exists and
24.156 + * shutting down this ExecutorService may manipulate
24.157 + * threads that the caller is not permitted to modify
24.158 + * because it does not hold {@link
24.159 + * java.lang.RuntimePermission}<tt>("modifyThread")</tt>,
24.160 + * or the security manager's <tt>checkAccess</tt> method
24.161 + * denies access.
24.162 + */
24.163 + void shutdown();
24.164 +
24.165 + /**
24.166 + * Attempts to stop all actively executing tasks, halts the
24.167 + * processing of waiting tasks, and returns a list of the tasks
24.168 + * that were awaiting execution.
24.169 + *
24.170 + * <p>This method does not wait for actively executing tasks to
24.171 + * terminate. Use {@link #awaitTermination awaitTermination} to
24.172 + * do that.
24.173 + *
24.174 + * <p>There are no guarantees beyond best-effort attempts to stop
24.175 + * processing actively executing tasks. For example, typical
24.176 + * implementations will cancel via {@link Thread#interrupt}, so any
24.177 + * task that fails to respond to interrupts may never terminate.
24.178 + *
24.179 + * @return list of tasks that never commenced execution
24.180 + * @throws SecurityException if a security manager exists and
24.181 + * shutting down this ExecutorService may manipulate
24.182 + * threads that the caller is not permitted to modify
24.183 + * because it does not hold {@link
24.184 + * java.lang.RuntimePermission}<tt>("modifyThread")</tt>,
24.185 + * or the security manager's <tt>checkAccess</tt> method
24.186 + * denies access.
24.187 + */
24.188 + List<Runnable> shutdownNow();
24.189 +
24.190 + /**
24.191 + * Returns <tt>true</tt> if this executor has been shut down.
24.192 + *
24.193 + * @return <tt>true</tt> if this executor has been shut down
24.194 + */
24.195 + boolean isShutdown();
24.196 +
24.197 + /**
24.198 + * Returns <tt>true</tt> if all tasks have completed following shut down.
24.199 + * Note that <tt>isTerminated</tt> is never <tt>true</tt> unless
24.200 + * either <tt>shutdown</tt> or <tt>shutdownNow</tt> was called first.
24.201 + *
24.202 + * @return <tt>true</tt> if all tasks have completed following shut down
24.203 + */
24.204 + boolean isTerminated();
24.205 +
24.206 + /**
24.207 + * Blocks until all tasks have completed execution after a shutdown
24.208 + * request, or the timeout occurs, or the current thread is
24.209 + * interrupted, whichever happens first.
24.210 + *
24.211 + * @param timeout the maximum time to wait
24.212 + * @param unit the time unit of the timeout argument
24.213 + * @return <tt>true</tt> if this executor terminated and
24.214 + * <tt>false</tt> if the timeout elapsed before termination
24.215 + * @throws InterruptedException if interrupted while waiting
24.216 + */
24.217 + boolean awaitTermination(long timeout, TimeUnit unit)
24.218 + throws InterruptedException;
24.219 +
24.220 +
24.221 + /**
24.222 + * Submits a value-returning task for execution and returns a
24.223 + * Future representing the pending results of the task. The
24.224 + * Future's <tt>get</tt> method will return the task's result upon
24.225 + * successful completion.
24.226 + *
24.227 + * <p>
24.228 + * If you would like to immediately block waiting
24.229 + * for a task, you can use constructions of the form
24.230 + * <tt>result = exec.submit(aCallable).get();</tt>
24.231 + *
24.232 + * <p> Note: The {@link Executors} class includes a set of methods
24.233 + * that can convert some other common closure-like objects,
24.234 + * for example, {@link java.security.PrivilegedAction} to
24.235 + * {@link Callable} form so they can be submitted.
24.236 + *
24.237 + * @param task the task to submit
24.238 + * @return a Future representing pending completion of the task
24.239 + * @throws RejectedExecutionException if the task cannot be
24.240 + * scheduled for execution
24.241 + * @throws NullPointerException if the task is null
24.242 + */
24.243 + <T> Future<T> submit(Callable<T> task);
24.244 +
24.245 + /**
24.246 + * Submits a Runnable task for execution and returns a Future
24.247 + * representing that task. The Future's <tt>get</tt> method will
24.248 + * return the given result upon successful completion.
24.249 + *
24.250 + * @param task the task to submit
24.251 + * @param result the result to return
24.252 + * @return a Future representing pending completion of the task
24.253 + * @throws RejectedExecutionException if the task cannot be
24.254 + * scheduled for execution
24.255 + * @throws NullPointerException if the task is null
24.256 + */
24.257 + <T> Future<T> submit(Runnable task, T result);
24.258 +
24.259 + /**
24.260 + * Submits a Runnable task for execution and returns a Future
24.261 + * representing that task. The Future's <tt>get</tt> method will
24.262 + * return <tt>null</tt> upon <em>successful</em> completion.
24.263 + *
24.264 + * @param task the task to submit
24.265 + * @return a Future representing pending completion of the task
24.266 + * @throws RejectedExecutionException if the task cannot be
24.267 + * scheduled for execution
24.268 + * @throws NullPointerException if the task is null
24.269 + */
24.270 + Future<?> submit(Runnable task);
24.271 +
24.272 + /**
24.273 + * Executes the given tasks, returning a list of Futures holding
24.274 + * their status and results when all complete.
24.275 + * {@link Future#isDone} is <tt>true</tt> for each
24.276 + * element of the returned list.
24.277 + * Note that a <em>completed</em> task could have
24.278 + * terminated either normally or by throwing an exception.
24.279 + * The results of this method are undefined if the given
24.280 + * collection is modified while this operation is in progress.
24.281 + *
24.282 + * @param tasks the collection of tasks
24.283 + * @return A list of Futures representing the tasks, in the same
24.284 + * sequential order as produced by the iterator for the
24.285 + * given task list, each of which has completed.
24.286 + * @throws InterruptedException if interrupted while waiting, in
24.287 + * which case unfinished tasks are cancelled.
24.288 + * @throws NullPointerException if tasks or any of its elements are <tt>null</tt>
24.289 + * @throws RejectedExecutionException if any task cannot be
24.290 + * scheduled for execution
24.291 + */
24.292 +
24.293 + <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
24.294 + throws InterruptedException;
24.295 +
24.296 + /**
24.297 + * Executes the given tasks, returning a list of Futures holding
24.298 + * their status and results
24.299 + * when all complete or the timeout expires, whichever happens first.
24.300 + * {@link Future#isDone} is <tt>true</tt> for each
24.301 + * element of the returned list.
24.302 + * Upon return, tasks that have not completed are cancelled.
24.303 + * Note that a <em>completed</em> task could have
24.304 + * terminated either normally or by throwing an exception.
24.305 + * The results of this method are undefined if the given
24.306 + * collection is modified while this operation is in progress.
24.307 + *
24.308 + * @param tasks the collection of tasks
24.309 + * @param timeout the maximum time to wait
24.310 + * @param unit the time unit of the timeout argument
24.311 + * @return a list of Futures representing the tasks, in the same
24.312 + * sequential order as produced by the iterator for the
24.313 + * given task list. If the operation did not time out,
24.314 + * each task will have completed. If it did time out, some
24.315 + * of these tasks will not have completed.
24.316 + * @throws InterruptedException if interrupted while waiting, in
24.317 + * which case unfinished tasks are cancelled
24.318 + * @throws NullPointerException if tasks, any of its elements, or
24.319 + * unit are <tt>null</tt>
24.320 + * @throws RejectedExecutionException if any task cannot be scheduled
24.321 + * for execution
24.322 + */
24.323 + <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
24.324 + long timeout, TimeUnit unit)
24.325 + throws InterruptedException;
24.326 +
24.327 + /**
24.328 + * Executes the given tasks, returning the result
24.329 + * of one that has completed successfully (i.e., without throwing
24.330 + * an exception), if any do. Upon normal or exceptional return,
24.331 + * tasks that have not completed are cancelled.
24.332 + * The results of this method are undefined if the given
24.333 + * collection is modified while this operation is in progress.
24.334 + *
24.335 + * @param tasks the collection of tasks
24.336 + * @return the result returned by one of the tasks
24.337 + * @throws InterruptedException if interrupted while waiting
24.338 + * @throws NullPointerException if tasks or any element task
24.339 + * subject to execution is <tt>null</tt>
24.340 + * @throws IllegalArgumentException if tasks is empty
24.341 + * @throws ExecutionException if no task successfully completes
24.342 + * @throws RejectedExecutionException if tasks cannot be scheduled
24.343 + * for execution
24.344 + */
24.345 + <T> T invokeAny(Collection<? extends Callable<T>> tasks)
24.346 + throws InterruptedException, ExecutionException;
24.347 +
24.348 + /**
24.349 + * Executes the given tasks, returning the result
24.350 + * of one that has completed successfully (i.e., without throwing
24.351 + * an exception), if any do before the given timeout elapses.
24.352 + * Upon normal or exceptional return, tasks that have not
24.353 + * completed are cancelled.
24.354 + * The results of this method are undefined if the given
24.355 + * collection is modified while this operation is in progress.
24.356 + *
24.357 + * @param tasks the collection of tasks
24.358 + * @param timeout the maximum time to wait
24.359 + * @param unit the time unit of the timeout argument
24.360 + * @return the result returned by one of the tasks.
24.361 + * @throws InterruptedException if interrupted while waiting
24.362 + * @throws NullPointerException if tasks, or unit, or any element
24.363 + * task subject to execution is <tt>null</tt>
24.364 + * @throws TimeoutException if the given timeout elapses before
24.365 + * any task successfully completes
24.366 + * @throws ExecutionException if no task successfully completes
24.367 + * @throws RejectedExecutionException if tasks cannot be scheduled
24.368 + * for execution
24.369 + */
24.370 + <T> T invokeAny(Collection<? extends Callable<T>> tasks,
24.371 + long timeout, TimeUnit unit)
24.372 + throws InterruptedException, ExecutionException, TimeoutException;
24.373 +}
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
25.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/Executors.java Sat Mar 19 10:46:31 2016 +0100
25.3 @@ -0,0 +1,706 @@
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 +import java.util.*;
25.41 +import java.util.concurrent.atomic.AtomicInteger;
25.42 +import java.security.AccessControlContext;
25.43 +import java.security.AccessController;
25.44 +import java.security.PrivilegedAction;
25.45 +import java.security.PrivilegedExceptionAction;
25.46 +import java.security.PrivilegedActionException;
25.47 +import java.security.AccessControlException;
25.48 +import sun.security.util.SecurityConstants;
25.49 +
25.50 +/**
25.51 + * Factory and utility methods for {@link Executor}, {@link
25.52 + * ExecutorService}, {@link ScheduledExecutorService}, {@link
25.53 + * ThreadFactory}, and {@link Callable} classes defined in this
25.54 + * package. This class supports the following kinds of methods:
25.55 + *
25.56 + * <ul>
25.57 + * <li> Methods that create and return an {@link ExecutorService}
25.58 + * set up with commonly useful configuration settings.
25.59 + * <li> Methods that create and return a {@link ScheduledExecutorService}
25.60 + * set up with commonly useful configuration settings.
25.61 + * <li> Methods that create and return a "wrapped" ExecutorService, that
25.62 + * disables reconfiguration by making implementation-specific methods
25.63 + * inaccessible.
25.64 + * <li> Methods that create and return a {@link ThreadFactory}
25.65 + * that sets newly created threads to a known state.
25.66 + * <li> Methods that create and return a {@link Callable}
25.67 + * out of other closure-like forms, so they can be used
25.68 + * in execution methods requiring <tt>Callable</tt>.
25.69 + * </ul>
25.70 + *
25.71 + * @since 1.5
25.72 + * @author Doug Lea
25.73 + */
25.74 +public class Executors {
25.75 +
25.76 + /**
25.77 + * Creates a thread pool that reuses a fixed number of threads
25.78 + * operating off a shared unbounded queue. At any point, at most
25.79 + * <tt>nThreads</tt> threads will be active processing tasks.
25.80 + * If additional tasks are submitted when all threads are active,
25.81 + * they will wait in the queue until a thread is available.
25.82 + * If any thread terminates due to a failure during execution
25.83 + * prior to shutdown, a new one will take its place if needed to
25.84 + * execute subsequent tasks. The threads in the pool will exist
25.85 + * until it is explicitly {@link ExecutorService#shutdown shutdown}.
25.86 + *
25.87 + * @param nThreads the number of threads in the pool
25.88 + * @return the newly created thread pool
25.89 + * @throws IllegalArgumentException if {@code nThreads <= 0}
25.90 + */
25.91 + public static ExecutorService newFixedThreadPool(int nThreads) {
25.92 + return new ThreadPoolExecutor(nThreads, nThreads,
25.93 + 0L, TimeUnit.MILLISECONDS,
25.94 + new LinkedBlockingQueue<Runnable>());
25.95 + }
25.96 +
25.97 + /**
25.98 + * Creates a thread pool that reuses a fixed number of threads
25.99 + * operating off a shared unbounded queue, using the provided
25.100 + * ThreadFactory to create new threads when needed. At any point,
25.101 + * at most <tt>nThreads</tt> threads will be active processing
25.102 + * tasks. If additional tasks are submitted when all threads are
25.103 + * active, they will wait in the queue until a thread is
25.104 + * available. If any thread terminates due to a failure during
25.105 + * execution prior to shutdown, a new one will take its place if
25.106 + * needed to execute subsequent tasks. The threads in the pool will
25.107 + * exist until it is explicitly {@link ExecutorService#shutdown
25.108 + * shutdown}.
25.109 + *
25.110 + * @param nThreads the number of threads in the pool
25.111 + * @param threadFactory the factory to use when creating new threads
25.112 + * @return the newly created thread pool
25.113 + * @throws NullPointerException if threadFactory is null
25.114 + * @throws IllegalArgumentException if {@code nThreads <= 0}
25.115 + */
25.116 + public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
25.117 + return new ThreadPoolExecutor(nThreads, nThreads,
25.118 + 0L, TimeUnit.MILLISECONDS,
25.119 + new LinkedBlockingQueue<Runnable>(),
25.120 + threadFactory);
25.121 + }
25.122 +
25.123 + /**
25.124 + * Creates an Executor that uses a single worker thread operating
25.125 + * off an unbounded queue. (Note however that if this single
25.126 + * thread terminates due to a failure during execution prior to
25.127 + * shutdown, a new one will take its place if needed to execute
25.128 + * subsequent tasks.) Tasks are guaranteed to execute
25.129 + * sequentially, and no more than one task will be active at any
25.130 + * given time. Unlike the otherwise equivalent
25.131 + * <tt>newFixedThreadPool(1)</tt> the returned executor is
25.132 + * guaranteed not to be reconfigurable to use additional threads.
25.133 + *
25.134 + * @return the newly created single-threaded Executor
25.135 + */
25.136 + public static ExecutorService newSingleThreadExecutor() {
25.137 + return new FinalizableDelegatedExecutorService
25.138 + (new ThreadPoolExecutor(1, 1,
25.139 + 0L, TimeUnit.MILLISECONDS,
25.140 + new LinkedBlockingQueue<Runnable>()));
25.141 + }
25.142 +
25.143 + /**
25.144 + * Creates an Executor that uses a single worker thread operating
25.145 + * off an unbounded queue, and uses the provided ThreadFactory to
25.146 + * create a new thread when needed. Unlike the otherwise
25.147 + * equivalent <tt>newFixedThreadPool(1, threadFactory)</tt> the
25.148 + * returned executor is guaranteed not to be reconfigurable to use
25.149 + * additional threads.
25.150 + *
25.151 + * @param threadFactory the factory to use when creating new
25.152 + * threads
25.153 + *
25.154 + * @return the newly created single-threaded Executor
25.155 + * @throws NullPointerException if threadFactory is null
25.156 + */
25.157 + public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
25.158 + return new FinalizableDelegatedExecutorService
25.159 + (new ThreadPoolExecutor(1, 1,
25.160 + 0L, TimeUnit.MILLISECONDS,
25.161 + new LinkedBlockingQueue<Runnable>(),
25.162 + threadFactory));
25.163 + }
25.164 +
25.165 + /**
25.166 + * Creates a thread pool that creates new threads as needed, but
25.167 + * will reuse previously constructed threads when they are
25.168 + * available. These pools will typically improve the performance
25.169 + * of programs that execute many short-lived asynchronous tasks.
25.170 + * Calls to <tt>execute</tt> will reuse previously constructed
25.171 + * threads if available. If no existing thread is available, a new
25.172 + * thread will be created and added to the pool. Threads that have
25.173 + * not been used for sixty seconds are terminated and removed from
25.174 + * the cache. Thus, a pool that remains idle for long enough will
25.175 + * not consume any resources. Note that pools with similar
25.176 + * properties but different details (for example, timeout parameters)
25.177 + * may be created using {@link ThreadPoolExecutor} constructors.
25.178 + *
25.179 + * @return the newly created thread pool
25.180 + */
25.181 + public static ExecutorService newCachedThreadPool() {
25.182 + return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
25.183 + 60L, TimeUnit.SECONDS,
25.184 + new SynchronousQueue<Runnable>());
25.185 + }
25.186 +
25.187 + /**
25.188 + * Creates a thread pool that creates new threads as needed, but
25.189 + * will reuse previously constructed threads when they are
25.190 + * available, and uses the provided
25.191 + * ThreadFactory to create new threads when needed.
25.192 + * @param threadFactory the factory to use when creating new threads
25.193 + * @return the newly created thread pool
25.194 + * @throws NullPointerException if threadFactory is null
25.195 + */
25.196 + public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
25.197 + return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
25.198 + 60L, TimeUnit.SECONDS,
25.199 + new SynchronousQueue<Runnable>(),
25.200 + threadFactory);
25.201 + }
25.202 +
25.203 + /**
25.204 + * Creates a single-threaded executor that can schedule commands
25.205 + * to run after a given delay, or to execute periodically.
25.206 + * (Note however that if this single
25.207 + * thread terminates due to a failure during execution prior to
25.208 + * shutdown, a new one will take its place if needed to execute
25.209 + * subsequent tasks.) Tasks are guaranteed to execute
25.210 + * sequentially, and no more than one task will be active at any
25.211 + * given time. Unlike the otherwise equivalent
25.212 + * <tt>newScheduledThreadPool(1)</tt> the returned executor is
25.213 + * guaranteed not to be reconfigurable to use additional threads.
25.214 + * @return the newly created scheduled executor
25.215 + */
25.216 + public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
25.217 + return new DelegatedScheduledExecutorService
25.218 + (new ScheduledThreadPoolExecutor(1));
25.219 + }
25.220 +
25.221 + /**
25.222 + * Creates a single-threaded executor that can schedule commands
25.223 + * to run after a given delay, or to execute periodically. (Note
25.224 + * however that if this single thread terminates due to a failure
25.225 + * during execution prior to shutdown, a new one will take its
25.226 + * place if needed to execute subsequent tasks.) Tasks are
25.227 + * guaranteed to execute sequentially, and no more than one task
25.228 + * will be active at any given time. Unlike the otherwise
25.229 + * equivalent <tt>newScheduledThreadPool(1, threadFactory)</tt>
25.230 + * the returned executor is guaranteed not to be reconfigurable to
25.231 + * use additional threads.
25.232 + * @param threadFactory the factory to use when creating new
25.233 + * threads
25.234 + * @return a newly created scheduled executor
25.235 + * @throws NullPointerException if threadFactory is null
25.236 + */
25.237 + public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) {
25.238 + return new DelegatedScheduledExecutorService
25.239 + (new ScheduledThreadPoolExecutor(1, threadFactory));
25.240 + }
25.241 +
25.242 + /**
25.243 + * Creates a thread pool that can schedule commands to run after a
25.244 + * given delay, or to execute periodically.
25.245 + * @param corePoolSize the number of threads to keep in the pool,
25.246 + * even if they are idle.
25.247 + * @return a newly created scheduled thread pool
25.248 + * @throws IllegalArgumentException if {@code corePoolSize < 0}
25.249 + */
25.250 + public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
25.251 + return new ScheduledThreadPoolExecutor(corePoolSize);
25.252 + }
25.253 +
25.254 + /**
25.255 + * Creates a thread pool that can schedule commands to run after a
25.256 + * given delay, or to execute periodically.
25.257 + * @param corePoolSize the number of threads to keep in the pool,
25.258 + * even if they are idle.
25.259 + * @param threadFactory the factory to use when the executor
25.260 + * creates a new thread.
25.261 + * @return a newly created scheduled thread pool
25.262 + * @throws IllegalArgumentException if {@code corePoolSize < 0}
25.263 + * @throws NullPointerException if threadFactory is null
25.264 + */
25.265 + public static ScheduledExecutorService newScheduledThreadPool(
25.266 + int corePoolSize, ThreadFactory threadFactory) {
25.267 + return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
25.268 + }
25.269 +
25.270 +
25.271 + /**
25.272 + * Returns an object that delegates all defined {@link
25.273 + * ExecutorService} methods to the given executor, but not any
25.274 + * other methods that might otherwise be accessible using
25.275 + * casts. This provides a way to safely "freeze" configuration and
25.276 + * disallow tuning of a given concrete implementation.
25.277 + * @param executor the underlying implementation
25.278 + * @return an <tt>ExecutorService</tt> instance
25.279 + * @throws NullPointerException if executor null
25.280 + */
25.281 + public static ExecutorService unconfigurableExecutorService(ExecutorService executor) {
25.282 + if (executor == null)
25.283 + throw new NullPointerException();
25.284 + return new DelegatedExecutorService(executor);
25.285 + }
25.286 +
25.287 + /**
25.288 + * Returns an object that delegates all defined {@link
25.289 + * ScheduledExecutorService} methods to the given executor, but
25.290 + * not any other methods that might otherwise be accessible using
25.291 + * casts. This provides a way to safely "freeze" configuration and
25.292 + * disallow tuning of a given concrete implementation.
25.293 + * @param executor the underlying implementation
25.294 + * @return a <tt>ScheduledExecutorService</tt> instance
25.295 + * @throws NullPointerException if executor null
25.296 + */
25.297 + public static ScheduledExecutorService unconfigurableScheduledExecutorService(ScheduledExecutorService executor) {
25.298 + if (executor == null)
25.299 + throw new NullPointerException();
25.300 + return new DelegatedScheduledExecutorService(executor);
25.301 + }
25.302 +
25.303 + /**
25.304 + * Returns a default thread factory used to create new threads.
25.305 + * This factory creates all new threads used by an Executor in the
25.306 + * same {@link ThreadGroup}. If there is a {@link
25.307 + * java.lang.SecurityManager}, it uses the group of {@link
25.308 + * System#getSecurityManager}, else the group of the thread
25.309 + * invoking this <tt>defaultThreadFactory</tt> method. Each new
25.310 + * thread is created as a non-daemon thread with priority set to
25.311 + * the smaller of <tt>Thread.NORM_PRIORITY</tt> and the maximum
25.312 + * priority permitted in the thread group. New threads have names
25.313 + * accessible via {@link Thread#getName} of
25.314 + * <em>pool-N-thread-M</em>, where <em>N</em> is the sequence
25.315 + * number of this factory, and <em>M</em> is the sequence number
25.316 + * of the thread created by this factory.
25.317 + * @return a thread factory
25.318 + */
25.319 + public static ThreadFactory defaultThreadFactory() {
25.320 + return new DefaultThreadFactory();
25.321 + }
25.322 +
25.323 + /**
25.324 + * Returns a thread factory used to create new threads that
25.325 + * have the same permissions as the current thread.
25.326 + * This factory creates threads with the same settings as {@link
25.327 + * Executors#defaultThreadFactory}, additionally setting the
25.328 + * AccessControlContext and contextClassLoader of new threads to
25.329 + * be the same as the thread invoking this
25.330 + * <tt>privilegedThreadFactory</tt> method. A new
25.331 + * <tt>privilegedThreadFactory</tt> can be created within an
25.332 + * {@link AccessController#doPrivileged} action setting the
25.333 + * current thread's access control context to create threads with
25.334 + * the selected permission settings holding within that action.
25.335 + *
25.336 + * <p> Note that while tasks running within such threads will have
25.337 + * the same access control and class loader settings as the
25.338 + * current thread, they need not have the same {@link
25.339 + * java.lang.ThreadLocal} or {@link
25.340 + * java.lang.InheritableThreadLocal} values. If necessary,
25.341 + * particular values of thread locals can be set or reset before
25.342 + * any task runs in {@link ThreadPoolExecutor} subclasses using
25.343 + * {@link ThreadPoolExecutor#beforeExecute}. Also, if it is
25.344 + * necessary to initialize worker threads to have the same
25.345 + * InheritableThreadLocal settings as some other designated
25.346 + * thread, you can create a custom ThreadFactory in which that
25.347 + * thread waits for and services requests to create others that
25.348 + * will inherit its values.
25.349 + *
25.350 + * @return a thread factory
25.351 + * @throws AccessControlException if the current access control
25.352 + * context does not have permission to both get and set context
25.353 + * class loader.
25.354 + */
25.355 + public static ThreadFactory privilegedThreadFactory() {
25.356 + return new PrivilegedThreadFactory();
25.357 + }
25.358 +
25.359 + /**
25.360 + * Returns a {@link Callable} object that, when
25.361 + * called, runs the given task and returns the given result. This
25.362 + * can be useful when applying methods requiring a
25.363 + * <tt>Callable</tt> to an otherwise resultless action.
25.364 + * @param task the task to run
25.365 + * @param result the result to return
25.366 + * @return a callable object
25.367 + * @throws NullPointerException if task null
25.368 + */
25.369 + public static <T> Callable<T> callable(Runnable task, T result) {
25.370 + if (task == null)
25.371 + throw new NullPointerException();
25.372 + return new RunnableAdapter<T>(task, result);
25.373 + }
25.374 +
25.375 + /**
25.376 + * Returns a {@link Callable} object that, when
25.377 + * called, runs the given task and returns <tt>null</tt>.
25.378 + * @param task the task to run
25.379 + * @return a callable object
25.380 + * @throws NullPointerException if task null
25.381 + */
25.382 + public static Callable<Object> callable(Runnable task) {
25.383 + if (task == null)
25.384 + throw new NullPointerException();
25.385 + return new RunnableAdapter<Object>(task, null);
25.386 + }
25.387 +
25.388 + /**
25.389 + * Returns a {@link Callable} object that, when
25.390 + * called, runs the given privileged action and returns its result.
25.391 + * @param action the privileged action to run
25.392 + * @return a callable object
25.393 + * @throws NullPointerException if action null
25.394 + */
25.395 + public static Callable<Object> callable(final PrivilegedAction<?> action) {
25.396 + if (action == null)
25.397 + throw new NullPointerException();
25.398 + return new Callable<Object>() {
25.399 + public Object call() { return action.run(); }};
25.400 + }
25.401 +
25.402 + /**
25.403 + * Returns a {@link Callable} object that, when
25.404 + * called, runs the given privileged exception action and returns
25.405 + * its result.
25.406 + * @param action the privileged exception action to run
25.407 + * @return a callable object
25.408 + * @throws NullPointerException if action null
25.409 + */
25.410 + public static Callable<Object> callable(final PrivilegedExceptionAction<?> action) {
25.411 + if (action == null)
25.412 + throw new NullPointerException();
25.413 + return new Callable<Object>() {
25.414 + public Object call() throws Exception { return action.run(); }};
25.415 + }
25.416 +
25.417 + /**
25.418 + * Returns a {@link Callable} object that will, when
25.419 + * called, execute the given <tt>callable</tt> under the current
25.420 + * access control context. This method should normally be
25.421 + * invoked within an {@link AccessController#doPrivileged} action
25.422 + * to create callables that will, if possible, execute under the
25.423 + * selected permission settings holding within that action; or if
25.424 + * not possible, throw an associated {@link
25.425 + * AccessControlException}.
25.426 + * @param callable the underlying task
25.427 + * @return a callable object
25.428 + * @throws NullPointerException if callable null
25.429 + *
25.430 + */
25.431 + public static <T> Callable<T> privilegedCallable(Callable<T> callable) {
25.432 + if (callable == null)
25.433 + throw new NullPointerException();
25.434 + return new PrivilegedCallable<T>(callable);
25.435 + }
25.436 +
25.437 + /**
25.438 + * Returns a {@link Callable} object that will, when
25.439 + * called, execute the given <tt>callable</tt> under the current
25.440 + * access control context, with the current context class loader
25.441 + * as the context class loader. This method should normally be
25.442 + * invoked within an {@link AccessController#doPrivileged} action
25.443 + * to create callables that will, if possible, execute under the
25.444 + * selected permission settings holding within that action; or if
25.445 + * not possible, throw an associated {@link
25.446 + * AccessControlException}.
25.447 + * @param callable the underlying task
25.448 + *
25.449 + * @return a callable object
25.450 + * @throws NullPointerException if callable null
25.451 + * @throws AccessControlException if the current access control
25.452 + * context does not have permission to both set and get context
25.453 + * class loader.
25.454 + */
25.455 + public static <T> Callable<T> privilegedCallableUsingCurrentClassLoader(Callable<T> callable) {
25.456 + if (callable == null)
25.457 + throw new NullPointerException();
25.458 + return new PrivilegedCallableUsingCurrentClassLoader<T>(callable);
25.459 + }
25.460 +
25.461 + // Non-public classes supporting the public methods
25.462 +
25.463 + /**
25.464 + * A callable that runs given task and returns given result
25.465 + */
25.466 + static final class RunnableAdapter<T> implements Callable<T> {
25.467 + final Runnable task;
25.468 + final T result;
25.469 + RunnableAdapter(Runnable task, T result) {
25.470 + this.task = task;
25.471 + this.result = result;
25.472 + }
25.473 + public T call() {
25.474 + task.run();
25.475 + return result;
25.476 + }
25.477 + }
25.478 +
25.479 + /**
25.480 + * A callable that runs under established access control settings
25.481 + */
25.482 + static final class PrivilegedCallable<T> implements Callable<T> {
25.483 + private final Callable<T> task;
25.484 + private final AccessControlContext acc;
25.485 +
25.486 + PrivilegedCallable(Callable<T> task) {
25.487 + this.task = task;
25.488 + this.acc = AccessController.getContext();
25.489 + }
25.490 +
25.491 + public T call() throws Exception {
25.492 + try {
25.493 + return AccessController.doPrivileged(
25.494 + new PrivilegedExceptionAction<T>() {
25.495 + public T run() throws Exception {
25.496 + return task.call();
25.497 + }
25.498 + }, acc);
25.499 + } catch (PrivilegedActionException e) {
25.500 + throw e.getException();
25.501 + }
25.502 + }
25.503 + }
25.504 +
25.505 + /**
25.506 + * A callable that runs under established access control settings and
25.507 + * current ClassLoader
25.508 + */
25.509 + static final class PrivilegedCallableUsingCurrentClassLoader<T> implements Callable<T> {
25.510 + private final Callable<T> task;
25.511 + private final AccessControlContext acc;
25.512 + private final ClassLoader ccl;
25.513 +
25.514 + PrivilegedCallableUsingCurrentClassLoader(Callable<T> task) {
25.515 + SecurityManager sm = System.getSecurityManager();
25.516 + if (sm != null) {
25.517 + // Calls to getContextClassLoader from this class
25.518 + // never trigger a security check, but we check
25.519 + // whether our callers have this permission anyways.
25.520 + sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
25.521 +
25.522 + // Whether setContextClassLoader turns out to be necessary
25.523 + // or not, we fail fast if permission is not available.
25.524 + sm.checkPermission(new RuntimePermission("setContextClassLoader"));
25.525 + }
25.526 + this.task = task;
25.527 + this.acc = AccessController.getContext();
25.528 + this.ccl = Thread.currentThread().getContextClassLoader();
25.529 + }
25.530 +
25.531 + public T call() throws Exception {
25.532 + try {
25.533 + return AccessController.doPrivileged(
25.534 + new PrivilegedExceptionAction<T>() {
25.535 + public T run() throws Exception {
25.536 + ClassLoader savedcl = null;
25.537 + Thread t = Thread.currentThread();
25.538 + try {
25.539 + ClassLoader cl = t.getContextClassLoader();
25.540 + if (ccl != cl) {
25.541 + t.setContextClassLoader(ccl);
25.542 + savedcl = cl;
25.543 + }
25.544 + return task.call();
25.545 + } finally {
25.546 + if (savedcl != null)
25.547 + t.setContextClassLoader(savedcl);
25.548 + }
25.549 + }
25.550 + }, acc);
25.551 + } catch (PrivilegedActionException e) {
25.552 + throw e.getException();
25.553 + }
25.554 + }
25.555 + }
25.556 +
25.557 + /**
25.558 + * The default thread factory
25.559 + */
25.560 + static class DefaultThreadFactory implements ThreadFactory {
25.561 + private static final AtomicInteger poolNumber = new AtomicInteger(1);
25.562 + private final ThreadGroup group;
25.563 + private final AtomicInteger threadNumber = new AtomicInteger(1);
25.564 + private final String namePrefix;
25.565 +
25.566 + DefaultThreadFactory() {
25.567 + SecurityManager s = System.getSecurityManager();
25.568 + group = (s != null) ? s.getThreadGroup() :
25.569 + Thread.currentThread().getThreadGroup();
25.570 + namePrefix = "pool-" +
25.571 + poolNumber.getAndIncrement() +
25.572 + "-thread-";
25.573 + }
25.574 +
25.575 + public Thread newThread(Runnable r) {
25.576 + Thread t = new Thread(group, r,
25.577 + namePrefix + threadNumber.getAndIncrement(),
25.578 + 0);
25.579 + if (t.isDaemon())
25.580 + t.setDaemon(false);
25.581 + if (t.getPriority() != Thread.NORM_PRIORITY)
25.582 + t.setPriority(Thread.NORM_PRIORITY);
25.583 + return t;
25.584 + }
25.585 + }
25.586 +
25.587 + /**
25.588 + * Thread factory capturing access control context and class loader
25.589 + */
25.590 + static class PrivilegedThreadFactory extends DefaultThreadFactory {
25.591 + private final AccessControlContext acc;
25.592 + private final ClassLoader ccl;
25.593 +
25.594 + PrivilegedThreadFactory() {
25.595 + super();
25.596 + SecurityManager sm = System.getSecurityManager();
25.597 + if (sm != null) {
25.598 + // Calls to getContextClassLoader from this class
25.599 + // never trigger a security check, but we check
25.600 + // whether our callers have this permission anyways.
25.601 + sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
25.602 +
25.603 + // Fail fast
25.604 + sm.checkPermission(new RuntimePermission("setContextClassLoader"));
25.605 + }
25.606 + this.acc = AccessController.getContext();
25.607 + this.ccl = Thread.currentThread().getContextClassLoader();
25.608 + }
25.609 +
25.610 + public Thread newThread(final Runnable r) {
25.611 + return super.newThread(new Runnable() {
25.612 + public void run() {
25.613 + AccessController.doPrivileged(new PrivilegedAction<Void>() {
25.614 + public Void run() {
25.615 + Thread.currentThread().setContextClassLoader(ccl);
25.616 + r.run();
25.617 + return null;
25.618 + }
25.619 + }, acc);
25.620 + }
25.621 + });
25.622 + }
25.623 + }
25.624 +
25.625 + /**
25.626 + * A wrapper class that exposes only the ExecutorService methods
25.627 + * of an ExecutorService implementation.
25.628 + */
25.629 + static class DelegatedExecutorService extends AbstractExecutorService {
25.630 + private final ExecutorService e;
25.631 + DelegatedExecutorService(ExecutorService executor) { e = executor; }
25.632 + public void execute(Runnable command) { e.execute(command); }
25.633 + public void shutdown() { e.shutdown(); }
25.634 + public List<Runnable> shutdownNow() { return e.shutdownNow(); }
25.635 + public boolean isShutdown() { return e.isShutdown(); }
25.636 + public boolean isTerminated() { return e.isTerminated(); }
25.637 + public boolean awaitTermination(long timeout, TimeUnit unit)
25.638 + throws InterruptedException {
25.639 + return e.awaitTermination(timeout, unit);
25.640 + }
25.641 + public Future<?> submit(Runnable task) {
25.642 + return e.submit(task);
25.643 + }
25.644 + public <T> Future<T> submit(Callable<T> task) {
25.645 + return e.submit(task);
25.646 + }
25.647 + public <T> Future<T> submit(Runnable task, T result) {
25.648 + return e.submit(task, result);
25.649 + }
25.650 + public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
25.651 + throws InterruptedException {
25.652 + return e.invokeAll(tasks);
25.653 + }
25.654 + public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
25.655 + long timeout, TimeUnit unit)
25.656 + throws InterruptedException {
25.657 + return e.invokeAll(tasks, timeout, unit);
25.658 + }
25.659 + public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
25.660 + throws InterruptedException, ExecutionException {
25.661 + return e.invokeAny(tasks);
25.662 + }
25.663 + public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
25.664 + long timeout, TimeUnit unit)
25.665 + throws InterruptedException, ExecutionException, TimeoutException {
25.666 + return e.invokeAny(tasks, timeout, unit);
25.667 + }
25.668 + }
25.669 +
25.670 + static class FinalizableDelegatedExecutorService
25.671 + extends DelegatedExecutorService {
25.672 + FinalizableDelegatedExecutorService(ExecutorService executor) {
25.673 + super(executor);
25.674 + }
25.675 + protected void finalize() {
25.676 + super.shutdown();
25.677 + }
25.678 + }
25.679 +
25.680 + /**
25.681 + * A wrapper class that exposes only the ScheduledExecutorService
25.682 + * methods of a ScheduledExecutorService implementation.
25.683 + */
25.684 + static class DelegatedScheduledExecutorService
25.685 + extends DelegatedExecutorService
25.686 + implements ScheduledExecutorService {
25.687 + private final ScheduledExecutorService e;
25.688 + DelegatedScheduledExecutorService(ScheduledExecutorService executor) {
25.689 + super(executor);
25.690 + e = executor;
25.691 + }
25.692 + public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
25.693 + return e.schedule(command, delay, unit);
25.694 + }
25.695 + public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) {
25.696 + return e.schedule(callable, delay, unit);
25.697 + }
25.698 + public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) {
25.699 + return e.scheduleAtFixedRate(command, initialDelay, period, unit);
25.700 + }
25.701 + public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) {
25.702 + return e.scheduleWithFixedDelay(command, initialDelay, delay, unit);
25.703 + }
25.704 + }
25.705 +
25.706 +
25.707 + /** Cannot instantiate. */
25.708 + private Executors() {}
25.709 +}
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
26.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ForkJoinPool.java Sat Mar 19 10:46:31 2016 +0100
26.3 @@ -0,0 +1,2177 @@
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.ArrayList;
26.42 +import java.util.Arrays;
26.43 +import java.util.Collection;
26.44 +import java.util.Collections;
26.45 +import java.util.List;
26.46 +import java.util.Random;
26.47 +import java.util.concurrent.AbstractExecutorService;
26.48 +import java.util.concurrent.Callable;
26.49 +import java.util.concurrent.ExecutorService;
26.50 +import java.util.concurrent.Future;
26.51 +import java.util.concurrent.RejectedExecutionException;
26.52 +import java.util.concurrent.RunnableFuture;
26.53 +import java.util.concurrent.TimeUnit;
26.54 +import java.util.concurrent.TimeoutException;
26.55 +import java.util.concurrent.atomic.AtomicInteger;
26.56 +import java.util.concurrent.locks.LockSupport;
26.57 +import java.util.concurrent.locks.ReentrantLock;
26.58 +import java.util.concurrent.locks.Condition;
26.59 +
26.60 +/**
26.61 + * An {@link ExecutorService} for running {@link ForkJoinTask}s.
26.62 + * A {@code ForkJoinPool} provides the entry point for submissions
26.63 + * from non-{@code ForkJoinTask} clients, as well as management and
26.64 + * monitoring operations.
26.65 + *
26.66 + * <p>A {@code ForkJoinPool} differs from other kinds of {@link
26.67 + * ExecutorService} mainly by virtue of employing
26.68 + * <em>work-stealing</em>: all threads in the pool attempt to find and
26.69 + * execute subtasks created by other active tasks (eventually blocking
26.70 + * waiting for work if none exist). This enables efficient processing
26.71 + * when most tasks spawn other subtasks (as do most {@code
26.72 + * ForkJoinTask}s). When setting <em>asyncMode</em> to true in
26.73 + * constructors, {@code ForkJoinPool}s may also be appropriate for use
26.74 + * with event-style tasks that are never joined.
26.75 + *
26.76 + * <p>A {@code ForkJoinPool} is constructed with a given target
26.77 + * parallelism level; by default, equal to the number of available
26.78 + * processors. The pool attempts to maintain enough active (or
26.79 + * available) threads by dynamically adding, suspending, or resuming
26.80 + * internal worker threads, even if some tasks are stalled waiting to
26.81 + * join others. However, no such adjustments are guaranteed in the
26.82 + * face of blocked IO or other unmanaged synchronization. The nested
26.83 + * {@link ManagedBlocker} interface enables extension of the kinds of
26.84 + * synchronization accommodated.
26.85 + *
26.86 + * <p>In addition to execution and lifecycle control methods, this
26.87 + * class provides status check methods (for example
26.88 + * {@link #getStealCount}) that are intended to aid in developing,
26.89 + * tuning, and monitoring fork/join applications. Also, method
26.90 + * {@link #toString} returns indications of pool state in a
26.91 + * convenient form for informal monitoring.
26.92 + *
26.93 + * <p> As is the case with other ExecutorServices, there are three
26.94 + * main task execution methods summarized in the following
26.95 + * table. These are designed to be used by clients not already engaged
26.96 + * in fork/join computations in the current pool. The main forms of
26.97 + * these methods accept instances of {@code ForkJoinTask}, but
26.98 + * overloaded forms also allow mixed execution of plain {@code
26.99 + * Runnable}- or {@code Callable}- based activities as well. However,
26.100 + * tasks that are already executing in a pool should normally
26.101 + * <em>NOT</em> use these pool execution methods, but instead use the
26.102 + * within-computation forms listed in the table.
26.103 + *
26.104 + * <table BORDER CELLPADDING=3 CELLSPACING=1>
26.105 + * <tr>
26.106 + * <td></td>
26.107 + * <td ALIGN=CENTER> <b>Call from non-fork/join clients</b></td>
26.108 + * <td ALIGN=CENTER> <b>Call from within fork/join computations</b></td>
26.109 + * </tr>
26.110 + * <tr>
26.111 + * <td> <b>Arrange async execution</td>
26.112 + * <td> {@link #execute(ForkJoinTask)}</td>
26.113 + * <td> {@link ForkJoinTask#fork}</td>
26.114 + * </tr>
26.115 + * <tr>
26.116 + * <td> <b>Await and obtain result</td>
26.117 + * <td> {@link #invoke(ForkJoinTask)}</td>
26.118 + * <td> {@link ForkJoinTask#invoke}</td>
26.119 + * </tr>
26.120 + * <tr>
26.121 + * <td> <b>Arrange exec and obtain Future</td>
26.122 + * <td> {@link #submit(ForkJoinTask)}</td>
26.123 + * <td> {@link ForkJoinTask#fork} (ForkJoinTasks <em>are</em> Futures)</td>
26.124 + * </tr>
26.125 + * </table>
26.126 + *
26.127 + * <p><b>Sample Usage.</b> Normally a single {@code ForkJoinPool} is
26.128 + * used for all parallel task execution in a program or subsystem.
26.129 + * Otherwise, use would not usually outweigh the construction and
26.130 + * bookkeeping overhead of creating a large set of threads. For
26.131 + * example, a common pool could be used for the {@code SortTasks}
26.132 + * illustrated in {@link RecursiveAction}. Because {@code
26.133 + * ForkJoinPool} uses threads in {@linkplain java.lang.Thread#isDaemon
26.134 + * daemon} mode, there is typically no need to explicitly {@link
26.135 + * #shutdown} such a pool upon program exit.
26.136 + *
26.137 + * <pre>
26.138 + * static final ForkJoinPool mainPool = new ForkJoinPool();
26.139 + * ...
26.140 + * public void sort(long[] array) {
26.141 + * mainPool.invoke(new SortTask(array, 0, array.length));
26.142 + * }
26.143 + * </pre>
26.144 + *
26.145 + * <p><b>Implementation notes</b>: This implementation restricts the
26.146 + * maximum number of running threads to 32767. Attempts to create
26.147 + * pools with greater than the maximum number result in
26.148 + * {@code IllegalArgumentException}.
26.149 + *
26.150 + * <p>This implementation rejects submitted tasks (that is, by throwing
26.151 + * {@link RejectedExecutionException}) only when the pool is shut down
26.152 + * or internal resources have been exhausted.
26.153 + *
26.154 + * @since 1.7
26.155 + * @author Doug Lea
26.156 + */
26.157 +public class ForkJoinPool extends AbstractExecutorService {
26.158 +
26.159 + /*
26.160 + * Implementation Overview
26.161 + *
26.162 + * This class provides the central bookkeeping and control for a
26.163 + * set of worker threads: Submissions from non-FJ threads enter
26.164 + * into a submission queue. Workers take these tasks and typically
26.165 + * split them into subtasks that may be stolen by other workers.
26.166 + * Preference rules give first priority to processing tasks from
26.167 + * their own queues (LIFO or FIFO, depending on mode), then to
26.168 + * randomized FIFO steals of tasks in other worker queues, and
26.169 + * lastly to new submissions.
26.170 + *
26.171 + * The main throughput advantages of work-stealing stem from
26.172 + * decentralized control -- workers mostly take tasks from
26.173 + * themselves or each other. We cannot negate this in the
26.174 + * implementation of other management responsibilities. The main
26.175 + * tactic for avoiding bottlenecks is packing nearly all
26.176 + * essentially atomic control state into a single 64bit volatile
26.177 + * variable ("ctl"). This variable is read on the order of 10-100
26.178 + * times as often as it is modified (always via CAS). (There is
26.179 + * some additional control state, for example variable "shutdown"
26.180 + * for which we can cope with uncoordinated updates.) This
26.181 + * streamlines synchronization and control at the expense of messy
26.182 + * constructions needed to repack status bits upon updates.
26.183 + * Updates tend not to contend with each other except during
26.184 + * bursts while submitted tasks begin or end. In some cases when
26.185 + * they do contend, threads can instead do something else
26.186 + * (usually, scan for tasks) until contention subsides.
26.187 + *
26.188 + * To enable packing, we restrict maximum parallelism to (1<<15)-1
26.189 + * (which is far in excess of normal operating range) to allow
26.190 + * ids, counts, and their negations (used for thresholding) to fit
26.191 + * into 16bit fields.
26.192 + *
26.193 + * Recording Workers. Workers are recorded in the "workers" array
26.194 + * that is created upon pool construction and expanded if (rarely)
26.195 + * necessary. This is an array as opposed to some other data
26.196 + * structure to support index-based random steals by workers.
26.197 + * Updates to the array recording new workers and unrecording
26.198 + * terminated ones are protected from each other by a seqLock
26.199 + * (scanGuard) but the array is otherwise concurrently readable,
26.200 + * and accessed directly by workers. To simplify index-based
26.201 + * operations, the array size is always a power of two, and all
26.202 + * readers must tolerate null slots. To avoid flailing during
26.203 + * start-up, the array is presized to hold twice #parallelism
26.204 + * workers (which is unlikely to need further resizing during
26.205 + * execution). But to avoid dealing with so many null slots,
26.206 + * variable scanGuard includes a mask for the nearest power of two
26.207 + * that contains all current workers. All worker thread creation
26.208 + * is on-demand, triggered by task submissions, replacement of
26.209 + * terminated workers, and/or compensation for blocked
26.210 + * workers. However, all other support code is set up to work with
26.211 + * other policies. To ensure that we do not hold on to worker
26.212 + * references that would prevent GC, ALL accesses to workers are
26.213 + * via indices into the workers array (which is one source of some
26.214 + * of the messy code constructions here). In essence, the workers
26.215 + * array serves as a weak reference mechanism. Thus for example
26.216 + * the wait queue field of ctl stores worker indices, not worker
26.217 + * references. Access to the workers in associated methods (for
26.218 + * example signalWork) must both index-check and null-check the
26.219 + * IDs. All such accesses ignore bad IDs by returning out early
26.220 + * from what they are doing, since this can only be associated
26.221 + * with termination, in which case it is OK to give up.
26.222 + *
26.223 + * All uses of the workers array, as well as queue arrays, check
26.224 + * that the array is non-null (even if previously non-null). This
26.225 + * allows nulling during termination, which is currently not
26.226 + * necessary, but remains an option for resource-revocation-based
26.227 + * shutdown schemes.
26.228 + *
26.229 + * Wait Queuing. Unlike HPC work-stealing frameworks, we cannot
26.230 + * let workers spin indefinitely scanning for tasks when none can
26.231 + * be found immediately, and we cannot start/resume workers unless
26.232 + * there appear to be tasks available. On the other hand, we must
26.233 + * quickly prod them into action when new tasks are submitted or
26.234 + * generated. We park/unpark workers after placing in an event
26.235 + * wait queue when they cannot find work. This "queue" is actually
26.236 + * a simple Treiber stack, headed by the "id" field of ctl, plus a
26.237 + * 15bit counter value to both wake up waiters (by advancing their
26.238 + * count) and avoid ABA effects. Successors are held in worker
26.239 + * field "nextWait". Queuing deals with several intrinsic races,
26.240 + * mainly that a task-producing thread can miss seeing (and
26.241 + * signalling) another thread that gave up looking for work but
26.242 + * has not yet entered the wait queue. We solve this by requiring
26.243 + * a full sweep of all workers both before (in scan()) and after
26.244 + * (in tryAwaitWork()) a newly waiting worker is added to the wait
26.245 + * queue. During a rescan, the worker might release some other
26.246 + * queued worker rather than itself, which has the same net
26.247 + * effect. Because enqueued workers may actually be rescanning
26.248 + * rather than waiting, we set and clear the "parked" field of
26.249 + * ForkJoinWorkerThread to reduce unnecessary calls to unpark.
26.250 + * (Use of the parked field requires a secondary recheck to avoid
26.251 + * missed signals.)
26.252 + *
26.253 + * Signalling. We create or wake up workers only when there
26.254 + * appears to be at least one task they might be able to find and
26.255 + * execute. When a submission is added or another worker adds a
26.256 + * task to a queue that previously had two or fewer tasks, they
26.257 + * signal waiting workers (or trigger creation of new ones if
26.258 + * fewer than the given parallelism level -- see signalWork).
26.259 + * These primary signals are buttressed by signals during rescans
26.260 + * as well as those performed when a worker steals a task and
26.261 + * notices that there are more tasks too; together these cover the
26.262 + * signals needed in cases when more than two tasks are pushed
26.263 + * but untaken.
26.264 + *
26.265 + * Trimming workers. To release resources after periods of lack of
26.266 + * use, a worker starting to wait when the pool is quiescent will
26.267 + * time out and terminate if the pool has remained quiescent for
26.268 + * SHRINK_RATE nanosecs. This will slowly propagate, eventually
26.269 + * terminating all workers after long periods of non-use.
26.270 + *
26.271 + * Submissions. External submissions are maintained in an
26.272 + * array-based queue that is structured identically to
26.273 + * ForkJoinWorkerThread queues except for the use of
26.274 + * submissionLock in method addSubmission. Unlike the case for
26.275 + * worker queues, multiple external threads can add new
26.276 + * submissions, so adding requires a lock.
26.277 + *
26.278 + * Compensation. Beyond work-stealing support and lifecycle
26.279 + * control, the main responsibility of this framework is to take
26.280 + * actions when one worker is waiting to join a task stolen (or
26.281 + * always held by) another. Because we are multiplexing many
26.282 + * tasks on to a pool of workers, we can't just let them block (as
26.283 + * in Thread.join). We also cannot just reassign the joiner's
26.284 + * run-time stack with another and replace it later, which would
26.285 + * be a form of "continuation", that even if possible is not
26.286 + * necessarily a good idea since we sometimes need both an
26.287 + * unblocked task and its continuation to progress. Instead we
26.288 + * combine two tactics:
26.289 + *
26.290 + * Helping: Arranging for the joiner to execute some task that it
26.291 + * would be running if the steal had not occurred. Method
26.292 + * ForkJoinWorkerThread.joinTask tracks joining->stealing
26.293 + * links to try to find such a task.
26.294 + *
26.295 + * Compensating: Unless there are already enough live threads,
26.296 + * method tryPreBlock() may create or re-activate a spare
26.297 + * thread to compensate for blocked joiners until they
26.298 + * unblock.
26.299 + *
26.300 + * The ManagedBlocker extension API can't use helping so relies
26.301 + * only on compensation in method awaitBlocker.
26.302 + *
26.303 + * It is impossible to keep exactly the target parallelism number
26.304 + * of threads running at any given time. Determining the
26.305 + * existence of conservatively safe helping targets, the
26.306 + * availability of already-created spares, and the apparent need
26.307 + * to create new spares are all racy and require heuristic
26.308 + * guidance, so we rely on multiple retries of each. Currently,
26.309 + * in keeping with on-demand signalling policy, we compensate only
26.310 + * if blocking would leave less than one active (non-waiting,
26.311 + * non-blocked) worker. Additionally, to avoid some false alarms
26.312 + * due to GC, lagging counters, system activity, etc, compensated
26.313 + * blocking for joins is only attempted after rechecks stabilize
26.314 + * (retries are interspersed with Thread.yield, for good
26.315 + * citizenship). The variable blockedCount, incremented before
26.316 + * blocking and decremented after, is sometimes needed to
26.317 + * distinguish cases of waiting for work vs blocking on joins or
26.318 + * other managed sync. Both cases are equivalent for most pool
26.319 + * control, so we can update non-atomically. (Additionally,
26.320 + * contention on blockedCount alleviates some contention on ctl).
26.321 + *
26.322 + * Shutdown and Termination. A call to shutdownNow atomically sets
26.323 + * the ctl stop bit and then (non-atomically) sets each workers
26.324 + * "terminate" status, cancels all unprocessed tasks, and wakes up
26.325 + * all waiting workers. Detecting whether termination should
26.326 + * commence after a non-abrupt shutdown() call requires more work
26.327 + * and bookkeeping. We need consensus about quiesence (i.e., that
26.328 + * there is no more work) which is reflected in active counts so
26.329 + * long as there are no current blockers, as well as possible
26.330 + * re-evaluations during independent changes in blocking or
26.331 + * quiescing workers.
26.332 + *
26.333 + * Style notes: There is a lot of representation-level coupling
26.334 + * among classes ForkJoinPool, ForkJoinWorkerThread, and
26.335 + * ForkJoinTask. Most fields of ForkJoinWorkerThread maintain
26.336 + * data structures managed by ForkJoinPool, so are directly
26.337 + * accessed. Conversely we allow access to "workers" array by
26.338 + * workers, and direct access to ForkJoinTask.status by both
26.339 + * ForkJoinPool and ForkJoinWorkerThread. There is little point
26.340 + * trying to reduce this, since any associated future changes in
26.341 + * representations will need to be accompanied by algorithmic
26.342 + * changes anyway. All together, these low-level implementation
26.343 + * choices produce as much as a factor of 4 performance
26.344 + * improvement compared to naive implementations, and enable the
26.345 + * processing of billions of tasks per second, at the expense of
26.346 + * some ugliness.
26.347 + *
26.348 + * Methods signalWork() and scan() are the main bottlenecks so are
26.349 + * especially heavily micro-optimized/mangled. There are lots of
26.350 + * inline assignments (of form "while ((local = field) != 0)")
26.351 + * which are usually the simplest way to ensure the required read
26.352 + * orderings (which are sometimes critical). This leads to a
26.353 + * "C"-like style of listing declarations of these locals at the
26.354 + * heads of methods or blocks. There are several occurrences of
26.355 + * the unusual "do {} while (!cas...)" which is the simplest way
26.356 + * to force an update of a CAS'ed variable. There are also other
26.357 + * coding oddities that help some methods perform reasonably even
26.358 + * when interpreted (not compiled).
26.359 + *
26.360 + * The order of declarations in this file is: (1) declarations of
26.361 + * statics (2) fields (along with constants used when unpacking
26.362 + * some of them), listed in an order that tends to reduce
26.363 + * contention among them a bit under most JVMs. (3) internal
26.364 + * control methods (4) callbacks and other support for
26.365 + * ForkJoinTask and ForkJoinWorkerThread classes, (5) exported
26.366 + * methods (plus a few little helpers). (6) static block
26.367 + * initializing all statics in a minimally dependent order.
26.368 + */
26.369 +
26.370 + /**
26.371 + * Factory for creating new {@link ForkJoinWorkerThread}s.
26.372 + * A {@code ForkJoinWorkerThreadFactory} must be defined and used
26.373 + * for {@code ForkJoinWorkerThread} subclasses that extend base
26.374 + * functionality or initialize threads with different contexts.
26.375 + */
26.376 + public static interface ForkJoinWorkerThreadFactory {
26.377 + /**
26.378 + * Returns a new worker thread operating in the given pool.
26.379 + *
26.380 + * @param pool the pool this thread works in
26.381 + * @throws NullPointerException if the pool is null
26.382 + */
26.383 + public ForkJoinWorkerThread newThread(ForkJoinPool pool);
26.384 + }
26.385 +
26.386 + /**
26.387 + * Default ForkJoinWorkerThreadFactory implementation; creates a
26.388 + * new ForkJoinWorkerThread.
26.389 + */
26.390 + static class DefaultForkJoinWorkerThreadFactory
26.391 + implements ForkJoinWorkerThreadFactory {
26.392 + public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
26.393 + return new ForkJoinWorkerThread(pool);
26.394 + }
26.395 + }
26.396 +
26.397 + /**
26.398 + * Creates a new ForkJoinWorkerThread. This factory is used unless
26.399 + * overridden in ForkJoinPool constructors.
26.400 + */
26.401 + public static final ForkJoinWorkerThreadFactory
26.402 + defaultForkJoinWorkerThreadFactory;
26.403 +
26.404 + /**
26.405 + * Permission required for callers of methods that may start or
26.406 + * kill threads.
26.407 + */
26.408 + private static final RuntimePermission modifyThreadPermission;
26.409 +
26.410 + /**
26.411 + * If there is a security manager, makes sure caller has
26.412 + * permission to modify threads.
26.413 + */
26.414 + private static void checkPermission() {
26.415 + SecurityManager security = System.getSecurityManager();
26.416 + if (security != null)
26.417 + security.checkPermission(modifyThreadPermission);
26.418 + }
26.419 +
26.420 + /**
26.421 + * Generator for assigning sequence numbers as pool names.
26.422 + */
26.423 + private static final AtomicInteger poolNumberGenerator;
26.424 +
26.425 + /**
26.426 + * Generator for initial random seeds for worker victim
26.427 + * selection. This is used only to create initial seeds. Random
26.428 + * steals use a cheaper xorshift generator per steal attempt. We
26.429 + * don't expect much contention on seedGenerator, so just use a
26.430 + * plain Random.
26.431 + */
26.432 + static final Random workerSeedGenerator;
26.433 +
26.434 + /**
26.435 + * Array holding all worker threads in the pool. Initialized upon
26.436 + * construction. Array size must be a power of two. Updates and
26.437 + * replacements are protected by scanGuard, but the array is
26.438 + * always kept in a consistent enough state to be randomly
26.439 + * accessed without locking by workers performing work-stealing,
26.440 + * as well as other traversal-based methods in this class, so long
26.441 + * as reads memory-acquire by first reading ctl. All readers must
26.442 + * tolerate that some array slots may be null.
26.443 + */
26.444 + ForkJoinWorkerThread[] workers;
26.445 +
26.446 + /**
26.447 + * Initial size for submission queue array. Must be a power of
26.448 + * two. In many applications, these always stay small so we use a
26.449 + * small initial cap.
26.450 + */
26.451 + private static final int INITIAL_QUEUE_CAPACITY = 8;
26.452 +
26.453 + /**
26.454 + * Maximum size for submission queue array. Must be a power of two
26.455 + * less than or equal to 1 << (31 - width of array entry) to
26.456 + * ensure lack of index wraparound, but is capped at a lower
26.457 + * value to help users trap runaway computations.
26.458 + */
26.459 + private static final int MAXIMUM_QUEUE_CAPACITY = 1 << 24; // 16M
26.460 +
26.461 + /**
26.462 + * Array serving as submission queue. Initialized upon construction.
26.463 + */
26.464 + private ForkJoinTask<?>[] submissionQueue;
26.465 +
26.466 + /**
26.467 + * Lock protecting submissions array for addSubmission
26.468 + */
26.469 + private final ReentrantLock submissionLock;
26.470 +
26.471 + /**
26.472 + * Condition for awaitTermination, using submissionLock for
26.473 + * convenience.
26.474 + */
26.475 + private final Condition termination;
26.476 +
26.477 + /**
26.478 + * Creation factory for worker threads.
26.479 + */
26.480 + private final ForkJoinWorkerThreadFactory factory;
26.481 +
26.482 + /**
26.483 + * The uncaught exception handler used when any worker abruptly
26.484 + * terminates.
26.485 + */
26.486 + final Thread.UncaughtExceptionHandler ueh;
26.487 +
26.488 + /**
26.489 + * Prefix for assigning names to worker threads
26.490 + */
26.491 + private final String workerNamePrefix;
26.492 +
26.493 + /**
26.494 + * Sum of per-thread steal counts, updated only when threads are
26.495 + * idle or terminating.
26.496 + */
26.497 + private volatile long stealCount;
26.498 +
26.499 + /**
26.500 + * Main pool control -- a long packed with:
26.501 + * AC: Number of active running workers minus target parallelism (16 bits)
26.502 + * TC: Number of total workers minus target parallelism (16bits)
26.503 + * ST: true if pool is terminating (1 bit)
26.504 + * EC: the wait count of top waiting thread (15 bits)
26.505 + * ID: ~poolIndex of top of Treiber stack of waiting threads (16 bits)
26.506 + *
26.507 + * When convenient, we can extract the upper 32 bits of counts and
26.508 + * the lower 32 bits of queue state, u = (int)(ctl >>> 32) and e =
26.509 + * (int)ctl. The ec field is never accessed alone, but always
26.510 + * together with id and st. The offsets of counts by the target
26.511 + * parallelism and the positionings of fields makes it possible to
26.512 + * perform the most common checks via sign tests of fields: When
26.513 + * ac is negative, there are not enough active workers, when tc is
26.514 + * negative, there are not enough total workers, when id is
26.515 + * negative, there is at least one waiting worker, and when e is
26.516 + * negative, the pool is terminating. To deal with these possibly
26.517 + * negative fields, we use casts in and out of "short" and/or
26.518 + * signed shifts to maintain signedness.
26.519 + */
26.520 + volatile long ctl;
26.521 +
26.522 + // bit positions/shifts for fields
26.523 + private static final int AC_SHIFT = 48;
26.524 + private static final int TC_SHIFT = 32;
26.525 + private static final int ST_SHIFT = 31;
26.526 + private static final int EC_SHIFT = 16;
26.527 +
26.528 + // bounds
26.529 + private static final int MAX_ID = 0x7fff; // max poolIndex
26.530 + private static final int SMASK = 0xffff; // mask short bits
26.531 + private static final int SHORT_SIGN = 1 << 15;
26.532 + private static final int INT_SIGN = 1 << 31;
26.533 +
26.534 + // masks
26.535 + private static final long STOP_BIT = 0x0001L << ST_SHIFT;
26.536 + private static final long AC_MASK = ((long)SMASK) << AC_SHIFT;
26.537 + private static final long TC_MASK = ((long)SMASK) << TC_SHIFT;
26.538 +
26.539 + // units for incrementing and decrementing
26.540 + private static final long TC_UNIT = 1L << TC_SHIFT;
26.541 + private static final long AC_UNIT = 1L << AC_SHIFT;
26.542 +
26.543 + // masks and units for dealing with u = (int)(ctl >>> 32)
26.544 + private static final int UAC_SHIFT = AC_SHIFT - 32;
26.545 + private static final int UTC_SHIFT = TC_SHIFT - 32;
26.546 + private static final int UAC_MASK = SMASK << UAC_SHIFT;
26.547 + private static final int UTC_MASK = SMASK << UTC_SHIFT;
26.548 + private static final int UAC_UNIT = 1 << UAC_SHIFT;
26.549 + private static final int UTC_UNIT = 1 << UTC_SHIFT;
26.550 +
26.551 + // masks and units for dealing with e = (int)ctl
26.552 + private static final int E_MASK = 0x7fffffff; // no STOP_BIT
26.553 + private static final int EC_UNIT = 1 << EC_SHIFT;
26.554 +
26.555 + /**
26.556 + * The target parallelism level.
26.557 + */
26.558 + final int parallelism;
26.559 +
26.560 + /**
26.561 + * Index (mod submission queue length) of next element to take
26.562 + * from submission queue. Usage is identical to that for
26.563 + * per-worker queues -- see ForkJoinWorkerThread internal
26.564 + * documentation.
26.565 + */
26.566 + volatile int queueBase;
26.567 +
26.568 + /**
26.569 + * Index (mod submission queue length) of next element to add
26.570 + * in submission queue. Usage is identical to that for
26.571 + * per-worker queues -- see ForkJoinWorkerThread internal
26.572 + * documentation.
26.573 + */
26.574 + int queueTop;
26.575 +
26.576 + /**
26.577 + * True when shutdown() has been called.
26.578 + */
26.579 + volatile boolean shutdown;
26.580 +
26.581 + /**
26.582 + * True if use local fifo, not default lifo, for local polling
26.583 + * Read by, and replicated by ForkJoinWorkerThreads
26.584 + */
26.585 + final boolean locallyFifo;
26.586 +
26.587 + /**
26.588 + * The number of threads in ForkJoinWorkerThreads.helpQuiescePool.
26.589 + * When non-zero, suppresses automatic shutdown when active
26.590 + * counts become zero.
26.591 + */
26.592 + volatile int quiescerCount;
26.593 +
26.594 + /**
26.595 + * The number of threads blocked in join.
26.596 + */
26.597 + volatile int blockedCount;
26.598 +
26.599 + /**
26.600 + * Counter for worker Thread names (unrelated to their poolIndex)
26.601 + */
26.602 + private volatile int nextWorkerNumber;
26.603 +
26.604 + /**
26.605 + * The index for the next created worker. Accessed under scanGuard.
26.606 + */
26.607 + private int nextWorkerIndex;
26.608 +
26.609 + /**
26.610 + * SeqLock and index masking for updates to workers array. Locked
26.611 + * when SG_UNIT is set. Unlocking clears bit by adding
26.612 + * SG_UNIT. Staleness of read-only operations can be checked by
26.613 + * comparing scanGuard to value before the reads. The low 16 bits
26.614 + * (i.e, anding with SMASK) hold (the smallest power of two
26.615 + * covering all worker indices, minus one, and is used to avoid
26.616 + * dealing with large numbers of null slots when the workers array
26.617 + * is overallocated.
26.618 + */
26.619 + volatile int scanGuard;
26.620 +
26.621 + private static final int SG_UNIT = 1 << 16;
26.622 +
26.623 + /**
26.624 + * The wakeup interval (in nanoseconds) for a worker waiting for a
26.625 + * task when the pool is quiescent to instead try to shrink the
26.626 + * number of workers. The exact value does not matter too
26.627 + * much. It must be short enough to release resources during
26.628 + * sustained periods of idleness, but not so short that threads
26.629 + * are continually re-created.
26.630 + */
26.631 + private static final long SHRINK_RATE =
26.632 + 4L * 1000L * 1000L * 1000L; // 4 seconds
26.633 +
26.634 + /**
26.635 + * Top-level loop for worker threads: On each step: if the
26.636 + * previous step swept through all queues and found no tasks, or
26.637 + * there are excess threads, then possibly blocks. Otherwise,
26.638 + * scans for and, if found, executes a task. Returns when pool
26.639 + * and/or worker terminate.
26.640 + *
26.641 + * @param w the worker
26.642 + */
26.643 + final void work(ForkJoinWorkerThread w) {
26.644 + boolean swept = false; // true on empty scans
26.645 + long c;
26.646 + while (!w.terminate && (int)(c = ctl) >= 0) {
26.647 + int a; // active count
26.648 + if (!swept && (a = (int)(c >> AC_SHIFT)) <= 0)
26.649 + swept = scan(w, a);
26.650 + else if (tryAwaitWork(w, c))
26.651 + swept = false;
26.652 + }
26.653 + }
26.654 +
26.655 + // Signalling
26.656 +
26.657 + /**
26.658 + * Wakes up or creates a worker.
26.659 + */
26.660 + final void signalWork() {
26.661 + /*
26.662 + * The while condition is true if: (there is are too few total
26.663 + * workers OR there is at least one waiter) AND (there are too
26.664 + * few active workers OR the pool is terminating). The value
26.665 + * of e distinguishes the remaining cases: zero (no waiters)
26.666 + * for create, negative if terminating (in which case do
26.667 + * nothing), else release a waiter. The secondary checks for
26.668 + * release (non-null array etc) can fail if the pool begins
26.669 + * terminating after the test, and don't impose any added cost
26.670 + * because JVMs must perform null and bounds checks anyway.
26.671 + */
26.672 + long c; int e, u;
26.673 + while ((((e = (int)(c = ctl)) | (u = (int)(c >>> 32))) &
26.674 + (INT_SIGN|SHORT_SIGN)) == (INT_SIGN|SHORT_SIGN) && e >= 0) {
26.675 + if (e > 0) { // release a waiting worker
26.676 + int i; ForkJoinWorkerThread w; ForkJoinWorkerThread[] ws;
26.677 + if ((ws = workers) == null ||
26.678 + (i = ~e & SMASK) >= ws.length ||
26.679 + (w = ws[i]) == null)
26.680 + break;
26.681 + long nc = (((long)(w.nextWait & E_MASK)) |
26.682 + ((long)(u + UAC_UNIT) << 32));
26.683 + if (w.eventCount == e &&
26.684 + UNSAFE.compareAndSwapLong(this, ctlOffset, c, nc)) {
26.685 + w.eventCount = (e + EC_UNIT) & E_MASK;
26.686 + if (w.parked)
26.687 + UNSAFE.unpark(w);
26.688 + break;
26.689 + }
26.690 + }
26.691 + else if (UNSAFE.compareAndSwapLong
26.692 + (this, ctlOffset, c,
26.693 + (long)(((u + UTC_UNIT) & UTC_MASK) |
26.694 + ((u + UAC_UNIT) & UAC_MASK)) << 32)) {
26.695 + addWorker();
26.696 + break;
26.697 + }
26.698 + }
26.699 + }
26.700 +
26.701 + /**
26.702 + * Variant of signalWork to help release waiters on rescans.
26.703 + * Tries once to release a waiter if active count < 0.
26.704 + *
26.705 + * @return false if failed due to contention, else true
26.706 + */
26.707 + private boolean tryReleaseWaiter() {
26.708 + long c; int e, i; ForkJoinWorkerThread w; ForkJoinWorkerThread[] ws;
26.709 + if ((e = (int)(c = ctl)) > 0 &&
26.710 + (int)(c >> AC_SHIFT) < 0 &&
26.711 + (ws = workers) != null &&
26.712 + (i = ~e & SMASK) < ws.length &&
26.713 + (w = ws[i]) != null) {
26.714 + long nc = ((long)(w.nextWait & E_MASK) |
26.715 + ((c + AC_UNIT) & (AC_MASK|TC_MASK)));
26.716 + if (w.eventCount != e ||
26.717 + !UNSAFE.compareAndSwapLong(this, ctlOffset, c, nc))
26.718 + return false;
26.719 + w.eventCount = (e + EC_UNIT) & E_MASK;
26.720 + if (w.parked)
26.721 + UNSAFE.unpark(w);
26.722 + }
26.723 + return true;
26.724 + }
26.725 +
26.726 + // Scanning for tasks
26.727 +
26.728 + /**
26.729 + * Scans for and, if found, executes one task. Scans start at a
26.730 + * random index of workers array, and randomly select the first
26.731 + * (2*#workers)-1 probes, and then, if all empty, resort to 2
26.732 + * circular sweeps, which is necessary to check quiescence. and
26.733 + * taking a submission only if no stealable tasks were found. The
26.734 + * steal code inside the loop is a specialized form of
26.735 + * ForkJoinWorkerThread.deqTask, followed bookkeeping to support
26.736 + * helpJoinTask and signal propagation. The code for submission
26.737 + * queues is almost identical. On each steal, the worker completes
26.738 + * not only the task, but also all local tasks that this task may
26.739 + * have generated. On detecting staleness or contention when
26.740 + * trying to take a task, this method returns without finishing
26.741 + * sweep, which allows global state rechecks before retry.
26.742 + *
26.743 + * @param w the worker
26.744 + * @param a the number of active workers
26.745 + * @return true if swept all queues without finding a task
26.746 + */
26.747 + private boolean scan(ForkJoinWorkerThread w, int a) {
26.748 + int g = scanGuard; // mask 0 avoids useless scans if only one active
26.749 + int m = (parallelism == 1 - a && blockedCount == 0) ? 0 : g & SMASK;
26.750 + ForkJoinWorkerThread[] ws = workers;
26.751 + if (ws == null || ws.length <= m) // staleness check
26.752 + return false;
26.753 + for (int r = w.seed, k = r, j = -(m + m); j <= m + m; ++j) {
26.754 + ForkJoinTask<?> t; ForkJoinTask<?>[] q; int b, i;
26.755 + ForkJoinWorkerThread v = ws[k & m];
26.756 + if (v != null && (b = v.queueBase) != v.queueTop &&
26.757 + (q = v.queue) != null && (i = (q.length - 1) & b) >= 0) {
26.758 + long u = (i << ASHIFT) + ABASE;
26.759 + if ((t = q[i]) != null && v.queueBase == b &&
26.760 + UNSAFE.compareAndSwapObject(q, u, t, null)) {
26.761 + int d = (v.queueBase = b + 1) - v.queueTop;
26.762 + v.stealHint = w.poolIndex;
26.763 + if (d != 0)
26.764 + signalWork(); // propagate if nonempty
26.765 + w.execTask(t);
26.766 + }
26.767 + r ^= r << 13; r ^= r >>> 17; w.seed = r ^ (r << 5);
26.768 + return false; // store next seed
26.769 + }
26.770 + else if (j < 0) { // xorshift
26.771 + r ^= r << 13; r ^= r >>> 17; k = r ^= r << 5;
26.772 + }
26.773 + else
26.774 + ++k;
26.775 + }
26.776 + if (scanGuard != g) // staleness check
26.777 + return false;
26.778 + else { // try to take submission
26.779 + ForkJoinTask<?> t; ForkJoinTask<?>[] q; int b, i;
26.780 + if ((b = queueBase) != queueTop &&
26.781 + (q = submissionQueue) != null &&
26.782 + (i = (q.length - 1) & b) >= 0) {
26.783 + long u = (i << ASHIFT) + ABASE;
26.784 + if ((t = q[i]) != null && queueBase == b &&
26.785 + UNSAFE.compareAndSwapObject(q, u, t, null)) {
26.786 + queueBase = b + 1;
26.787 + w.execTask(t);
26.788 + }
26.789 + return false;
26.790 + }
26.791 + return true; // all queues empty
26.792 + }
26.793 + }
26.794 +
26.795 + /**
26.796 + * Tries to enqueue worker w in wait queue and await change in
26.797 + * worker's eventCount. If the pool is quiescent and there is
26.798 + * more than one worker, possibly terminates worker upon exit.
26.799 + * Otherwise, before blocking, rescans queues to avoid missed
26.800 + * signals. Upon finding work, releases at least one worker
26.801 + * (which may be the current worker). Rescans restart upon
26.802 + * detected staleness or failure to release due to
26.803 + * contention. Note the unusual conventions about Thread.interrupt
26.804 + * here and elsewhere: Because interrupts are used solely to alert
26.805 + * threads to check termination, which is checked here anyway, we
26.806 + * clear status (using Thread.interrupted) before any call to
26.807 + * park, so that park does not immediately return due to status
26.808 + * being set via some other unrelated call to interrupt in user
26.809 + * code.
26.810 + *
26.811 + * @param w the calling worker
26.812 + * @param c the ctl value on entry
26.813 + * @return true if waited or another thread was released upon enq
26.814 + */
26.815 + private boolean tryAwaitWork(ForkJoinWorkerThread w, long c) {
26.816 + int v = w.eventCount;
26.817 + w.nextWait = (int)c; // w's successor record
26.818 + long nc = (long)(v & E_MASK) | ((c - AC_UNIT) & (AC_MASK|TC_MASK));
26.819 + if (ctl != c || !UNSAFE.compareAndSwapLong(this, ctlOffset, c, nc)) {
26.820 + long d = ctl; // return true if lost to a deq, to force scan
26.821 + return (int)d != (int)c && ((d - c) & AC_MASK) >= 0L;
26.822 + }
26.823 + for (int sc = w.stealCount; sc != 0;) { // accumulate stealCount
26.824 + long s = stealCount;
26.825 + if (UNSAFE.compareAndSwapLong(this, stealCountOffset, s, s + sc))
26.826 + sc = w.stealCount = 0;
26.827 + else if (w.eventCount != v)
26.828 + return true; // update next time
26.829 + }
26.830 + if ((!shutdown || !tryTerminate(false)) &&
26.831 + (int)c != 0 && parallelism + (int)(nc >> AC_SHIFT) == 0 &&
26.832 + blockedCount == 0 && quiescerCount == 0)
26.833 + idleAwaitWork(w, nc, c, v); // quiescent
26.834 + for (boolean rescanned = false;;) {
26.835 + if (w.eventCount != v)
26.836 + return true;
26.837 + if (!rescanned) {
26.838 + int g = scanGuard, m = g & SMASK;
26.839 + ForkJoinWorkerThread[] ws = workers;
26.840 + if (ws != null && m < ws.length) {
26.841 + rescanned = true;
26.842 + for (int i = 0; i <= m; ++i) {
26.843 + ForkJoinWorkerThread u = ws[i];
26.844 + if (u != null) {
26.845 + if (u.queueBase != u.queueTop &&
26.846 + !tryReleaseWaiter())
26.847 + rescanned = false; // contended
26.848 + if (w.eventCount != v)
26.849 + return true;
26.850 + }
26.851 + }
26.852 + }
26.853 + if (scanGuard != g || // stale
26.854 + (queueBase != queueTop && !tryReleaseWaiter()))
26.855 + rescanned = false;
26.856 + if (!rescanned)
26.857 + Thread.yield(); // reduce contention
26.858 + else
26.859 + Thread.interrupted(); // clear before park
26.860 + }
26.861 + else {
26.862 + w.parked = true; // must recheck
26.863 + if (w.eventCount != v) {
26.864 + w.parked = false;
26.865 + return true;
26.866 + }
26.867 + LockSupport.park(this);
26.868 + rescanned = w.parked = false;
26.869 + }
26.870 + }
26.871 + }
26.872 +
26.873 + /**
26.874 + * If inactivating worker w has caused pool to become
26.875 + * quiescent, check for pool termination, and wait for event
26.876 + * for up to SHRINK_RATE nanosecs (rescans are unnecessary in
26.877 + * this case because quiescence reflects consensus about lack
26.878 + * of work). On timeout, if ctl has not changed, terminate the
26.879 + * worker. Upon its termination (see deregisterWorker), it may
26.880 + * wake up another worker to possibly repeat this process.
26.881 + *
26.882 + * @param w the calling worker
26.883 + * @param currentCtl the ctl value after enqueuing w
26.884 + * @param prevCtl the ctl value if w terminated
26.885 + * @param v the eventCount w awaits change
26.886 + */
26.887 + private void idleAwaitWork(ForkJoinWorkerThread w, long currentCtl,
26.888 + long prevCtl, int v) {
26.889 + if (w.eventCount == v) {
26.890 + if (shutdown)
26.891 + tryTerminate(false);
26.892 + ForkJoinTask.helpExpungeStaleExceptions(); // help clean weak refs
26.893 + while (ctl == currentCtl) {
26.894 + long startTime = System.nanoTime();
26.895 + w.parked = true;
26.896 + if (w.eventCount == v) // must recheck
26.897 + LockSupport.parkNanos(this, SHRINK_RATE);
26.898 + w.parked = false;
26.899 + if (w.eventCount != v)
26.900 + break;
26.901 + else if (System.nanoTime() - startTime <
26.902 + SHRINK_RATE - (SHRINK_RATE / 10)) // timing slop
26.903 + Thread.interrupted(); // spurious wakeup
26.904 + else if (UNSAFE.compareAndSwapLong(this, ctlOffset,
26.905 + currentCtl, prevCtl)) {
26.906 + w.terminate = true; // restore previous
26.907 + w.eventCount = ((int)currentCtl + EC_UNIT) & E_MASK;
26.908 + break;
26.909 + }
26.910 + }
26.911 + }
26.912 + }
26.913 +
26.914 + // Submissions
26.915 +
26.916 + /**
26.917 + * Enqueues the given task in the submissionQueue. Same idea as
26.918 + * ForkJoinWorkerThread.pushTask except for use of submissionLock.
26.919 + *
26.920 + * @param t the task
26.921 + */
26.922 + private void addSubmission(ForkJoinTask<?> t) {
26.923 + final ReentrantLock lock = this.submissionLock;
26.924 + lock.lock();
26.925 + try {
26.926 + ForkJoinTask<?>[] q; int s, m;
26.927 + if ((q = submissionQueue) != null) { // ignore if queue removed
26.928 + long u = (((s = queueTop) & (m = q.length-1)) << ASHIFT)+ABASE;
26.929 + UNSAFE.putOrderedObject(q, u, t);
26.930 + queueTop = s + 1;
26.931 + if (s - queueBase == m)
26.932 + growSubmissionQueue();
26.933 + }
26.934 + } finally {
26.935 + lock.unlock();
26.936 + }
26.937 + signalWork();
26.938 + }
26.939 +
26.940 + // (pollSubmission is defined below with exported methods)
26.941 +
26.942 + /**
26.943 + * Creates or doubles submissionQueue array.
26.944 + * Basically identical to ForkJoinWorkerThread version.
26.945 + */
26.946 + private void growSubmissionQueue() {
26.947 + ForkJoinTask<?>[] oldQ = submissionQueue;
26.948 + int size = oldQ != null ? oldQ.length << 1 : INITIAL_QUEUE_CAPACITY;
26.949 + if (size > MAXIMUM_QUEUE_CAPACITY)
26.950 + throw new RejectedExecutionException("Queue capacity exceeded");
26.951 + if (size < INITIAL_QUEUE_CAPACITY)
26.952 + size = INITIAL_QUEUE_CAPACITY;
26.953 + ForkJoinTask<?>[] q = submissionQueue = new ForkJoinTask<?>[size];
26.954 + int mask = size - 1;
26.955 + int top = queueTop;
26.956 + int oldMask;
26.957 + if (oldQ != null && (oldMask = oldQ.length - 1) >= 0) {
26.958 + for (int b = queueBase; b != top; ++b) {
26.959 + long u = ((b & oldMask) << ASHIFT) + ABASE;
26.960 + Object x = UNSAFE.getObjectVolatile(oldQ, u);
26.961 + if (x != null && UNSAFE.compareAndSwapObject(oldQ, u, x, null))
26.962 + UNSAFE.putObjectVolatile
26.963 + (q, ((b & mask) << ASHIFT) + ABASE, x);
26.964 + }
26.965 + }
26.966 + }
26.967 +
26.968 + // Blocking support
26.969 +
26.970 + /**
26.971 + * Tries to increment blockedCount, decrement active count
26.972 + * (sometimes implicitly) and possibly release or create a
26.973 + * compensating worker in preparation for blocking. Fails
26.974 + * on contention or termination.
26.975 + *
26.976 + * @return true if the caller can block, else should recheck and retry
26.977 + */
26.978 + private boolean tryPreBlock() {
26.979 + int b = blockedCount;
26.980 + if (UNSAFE.compareAndSwapInt(this, blockedCountOffset, b, b + 1)) {
26.981 + int pc = parallelism;
26.982 + do {
26.983 + ForkJoinWorkerThread[] ws; ForkJoinWorkerThread w;
26.984 + int e, ac, tc, rc, i;
26.985 + long c = ctl;
26.986 + int u = (int)(c >>> 32);
26.987 + if ((e = (int)c) < 0) {
26.988 + // skip -- terminating
26.989 + }
26.990 + else if ((ac = (u >> UAC_SHIFT)) <= 0 && e != 0 &&
26.991 + (ws = workers) != null &&
26.992 + (i = ~e & SMASK) < ws.length &&
26.993 + (w = ws[i]) != null) {
26.994 + long nc = ((long)(w.nextWait & E_MASK) |
26.995 + (c & (AC_MASK|TC_MASK)));
26.996 + if (w.eventCount == e &&
26.997 + UNSAFE.compareAndSwapLong(this, ctlOffset, c, nc)) {
26.998 + w.eventCount = (e + EC_UNIT) & E_MASK;
26.999 + if (w.parked)
26.1000 + UNSAFE.unpark(w);
26.1001 + return true; // release an idle worker
26.1002 + }
26.1003 + }
26.1004 + else if ((tc = (short)(u >>> UTC_SHIFT)) >= 0 && ac + pc > 1) {
26.1005 + long nc = ((c - AC_UNIT) & AC_MASK) | (c & ~AC_MASK);
26.1006 + if (UNSAFE.compareAndSwapLong(this, ctlOffset, c, nc))
26.1007 + return true; // no compensation needed
26.1008 + }
26.1009 + else if (tc + pc < MAX_ID) {
26.1010 + long nc = ((c + TC_UNIT) & TC_MASK) | (c & ~TC_MASK);
26.1011 + if (UNSAFE.compareAndSwapLong(this, ctlOffset, c, nc)) {
26.1012 + addWorker();
26.1013 + return true; // create a replacement
26.1014 + }
26.1015 + }
26.1016 + // try to back out on any failure and let caller retry
26.1017 + } while (!UNSAFE.compareAndSwapInt(this, blockedCountOffset,
26.1018 + b = blockedCount, b - 1));
26.1019 + }
26.1020 + return false;
26.1021 + }
26.1022 +
26.1023 + /**
26.1024 + * Decrements blockedCount and increments active count
26.1025 + */
26.1026 + private void postBlock() {
26.1027 + long c;
26.1028 + do {} while (!UNSAFE.compareAndSwapLong(this, ctlOffset, // no mask
26.1029 + c = ctl, c + AC_UNIT));
26.1030 + int b;
26.1031 + do {} while (!UNSAFE.compareAndSwapInt(this, blockedCountOffset,
26.1032 + b = blockedCount, b - 1));
26.1033 + }
26.1034 +
26.1035 + /**
26.1036 + * Possibly blocks waiting for the given task to complete, or
26.1037 + * cancels the task if terminating. Fails to wait if contended.
26.1038 + *
26.1039 + * @param joinMe the task
26.1040 + */
26.1041 + final void tryAwaitJoin(ForkJoinTask<?> joinMe) {
26.1042 + int s;
26.1043 + Thread.interrupted(); // clear interrupts before checking termination
26.1044 + if (joinMe.status >= 0) {
26.1045 + if (tryPreBlock()) {
26.1046 + joinMe.tryAwaitDone(0L);
26.1047 + postBlock();
26.1048 + }
26.1049 + else if ((ctl & STOP_BIT) != 0L)
26.1050 + joinMe.cancelIgnoringExceptions();
26.1051 + }
26.1052 + }
26.1053 +
26.1054 + /**
26.1055 + * Possibly blocks the given worker waiting for joinMe to
26.1056 + * complete or timeout
26.1057 + *
26.1058 + * @param joinMe the task
26.1059 + * @param millis the wait time for underlying Object.wait
26.1060 + */
26.1061 + final void timedAwaitJoin(ForkJoinTask<?> joinMe, long nanos) {
26.1062 + while (joinMe.status >= 0) {
26.1063 + Thread.interrupted();
26.1064 + if ((ctl & STOP_BIT) != 0L) {
26.1065 + joinMe.cancelIgnoringExceptions();
26.1066 + break;
26.1067 + }
26.1068 + if (tryPreBlock()) {
26.1069 + long last = System.nanoTime();
26.1070 + while (joinMe.status >= 0) {
26.1071 + long millis = TimeUnit.NANOSECONDS.toMillis(nanos);
26.1072 + if (millis <= 0)
26.1073 + break;
26.1074 + joinMe.tryAwaitDone(millis);
26.1075 + if (joinMe.status < 0)
26.1076 + break;
26.1077 + if ((ctl & STOP_BIT) != 0L) {
26.1078 + joinMe.cancelIgnoringExceptions();
26.1079 + break;
26.1080 + }
26.1081 + long now = System.nanoTime();
26.1082 + nanos -= now - last;
26.1083 + last = now;
26.1084 + }
26.1085 + postBlock();
26.1086 + break;
26.1087 + }
26.1088 + }
26.1089 + }
26.1090 +
26.1091 + /**
26.1092 + * If necessary, compensates for blocker, and blocks
26.1093 + */
26.1094 + private void awaitBlocker(ManagedBlocker blocker)
26.1095 + throws InterruptedException {
26.1096 + while (!blocker.isReleasable()) {
26.1097 + if (tryPreBlock()) {
26.1098 + try {
26.1099 + do {} while (!blocker.isReleasable() && !blocker.block());
26.1100 + } finally {
26.1101 + postBlock();
26.1102 + }
26.1103 + break;
26.1104 + }
26.1105 + }
26.1106 + }
26.1107 +
26.1108 + // Creating, registering and deregistring workers
26.1109 +
26.1110 + /**
26.1111 + * Tries to create and start a worker; minimally rolls back counts
26.1112 + * on failure.
26.1113 + */
26.1114 + private void addWorker() {
26.1115 + Throwable ex = null;
26.1116 + ForkJoinWorkerThread t = null;
26.1117 + try {
26.1118 + t = factory.newThread(this);
26.1119 + } catch (Throwable e) {
26.1120 + ex = e;
26.1121 + }
26.1122 + if (t == null) { // null or exceptional factory return
26.1123 + long c; // adjust counts
26.1124 + do {} while (!UNSAFE.compareAndSwapLong
26.1125 + (this, ctlOffset, c = ctl,
26.1126 + (((c - AC_UNIT) & AC_MASK) |
26.1127 + ((c - TC_UNIT) & TC_MASK) |
26.1128 + (c & ~(AC_MASK|TC_MASK)))));
26.1129 + // Propagate exception if originating from an external caller
26.1130 + if (!tryTerminate(false) && ex != null &&
26.1131 + !(Thread.currentThread() instanceof ForkJoinWorkerThread))
26.1132 + UNSAFE.throwException(ex);
26.1133 + }
26.1134 + else
26.1135 + t.start();
26.1136 + }
26.1137 +
26.1138 + /**
26.1139 + * Callback from ForkJoinWorkerThread constructor to assign a
26.1140 + * public name
26.1141 + */
26.1142 + final String nextWorkerName() {
26.1143 + for (int n;;) {
26.1144 + if (UNSAFE.compareAndSwapInt(this, nextWorkerNumberOffset,
26.1145 + n = nextWorkerNumber, ++n))
26.1146 + return workerNamePrefix + n;
26.1147 + }
26.1148 + }
26.1149 +
26.1150 + /**
26.1151 + * Callback from ForkJoinWorkerThread constructor to
26.1152 + * determine its poolIndex and record in workers array.
26.1153 + *
26.1154 + * @param w the worker
26.1155 + * @return the worker's pool index
26.1156 + */
26.1157 + final int registerWorker(ForkJoinWorkerThread w) {
26.1158 + /*
26.1159 + * In the typical case, a new worker acquires the lock, uses
26.1160 + * next available index and returns quickly. Since we should
26.1161 + * not block callers (ultimately from signalWork or
26.1162 + * tryPreBlock) waiting for the lock needed to do this, we
26.1163 + * instead help release other workers while waiting for the
26.1164 + * lock.
26.1165 + */
26.1166 + for (int g;;) {
26.1167 + ForkJoinWorkerThread[] ws;
26.1168 + if (((g = scanGuard) & SG_UNIT) == 0 &&
26.1169 + UNSAFE.compareAndSwapInt(this, scanGuardOffset,
26.1170 + g, g | SG_UNIT)) {
26.1171 + int k = nextWorkerIndex;
26.1172 + try {
26.1173 + if ((ws = workers) != null) { // ignore on shutdown
26.1174 + int n = ws.length;
26.1175 + if (k < 0 || k >= n || ws[k] != null) {
26.1176 + for (k = 0; k < n && ws[k] != null; ++k)
26.1177 + ;
26.1178 + if (k == n)
26.1179 + ws = workers = Arrays.copyOf(ws, n << 1);
26.1180 + }
26.1181 + ws[k] = w;
26.1182 + nextWorkerIndex = k + 1;
26.1183 + int m = g & SMASK;
26.1184 + g = (k > m) ? ((m << 1) + 1) & SMASK : g + (SG_UNIT<<1);
26.1185 + }
26.1186 + } finally {
26.1187 + scanGuard = g;
26.1188 + }
26.1189 + return k;
26.1190 + }
26.1191 + else if ((ws = workers) != null) { // help release others
26.1192 + for (ForkJoinWorkerThread u : ws) {
26.1193 + if (u != null && u.queueBase != u.queueTop) {
26.1194 + if (tryReleaseWaiter())
26.1195 + break;
26.1196 + }
26.1197 + }
26.1198 + }
26.1199 + }
26.1200 + }
26.1201 +
26.1202 + /**
26.1203 + * Final callback from terminating worker. Removes record of
26.1204 + * worker from array, and adjusts counts. If pool is shutting
26.1205 + * down, tries to complete termination.
26.1206 + *
26.1207 + * @param w the worker
26.1208 + */
26.1209 + final void deregisterWorker(ForkJoinWorkerThread w, Throwable ex) {
26.1210 + int idx = w.poolIndex;
26.1211 + int sc = w.stealCount;
26.1212 + int steps = 0;
26.1213 + // Remove from array, adjust worker counts and collect steal count.
26.1214 + // We can intermix failed removes or adjusts with steal updates
26.1215 + do {
26.1216 + long s, c;
26.1217 + int g;
26.1218 + if (steps == 0 && ((g = scanGuard) & SG_UNIT) == 0 &&
26.1219 + UNSAFE.compareAndSwapInt(this, scanGuardOffset,
26.1220 + g, g |= SG_UNIT)) {
26.1221 + ForkJoinWorkerThread[] ws = workers;
26.1222 + if (ws != null && idx >= 0 &&
26.1223 + idx < ws.length && ws[idx] == w)
26.1224 + ws[idx] = null; // verify
26.1225 + nextWorkerIndex = idx;
26.1226 + scanGuard = g + SG_UNIT;
26.1227 + steps = 1;
26.1228 + }
26.1229 + if (steps == 1 &&
26.1230 + UNSAFE.compareAndSwapLong(this, ctlOffset, c = ctl,
26.1231 + (((c - AC_UNIT) & AC_MASK) |
26.1232 + ((c - TC_UNIT) & TC_MASK) |
26.1233 + (c & ~(AC_MASK|TC_MASK)))))
26.1234 + steps = 2;
26.1235 + if (sc != 0 &&
26.1236 + UNSAFE.compareAndSwapLong(this, stealCountOffset,
26.1237 + s = stealCount, s + sc))
26.1238 + sc = 0;
26.1239 + } while (steps != 2 || sc != 0);
26.1240 + if (!tryTerminate(false)) {
26.1241 + if (ex != null) // possibly replace if died abnormally
26.1242 + signalWork();
26.1243 + else
26.1244 + tryReleaseWaiter();
26.1245 + }
26.1246 + }
26.1247 +
26.1248 + // Shutdown and termination
26.1249 +
26.1250 + /**
26.1251 + * Possibly initiates and/or completes termination.
26.1252 + *
26.1253 + * @param now if true, unconditionally terminate, else only
26.1254 + * if shutdown and empty queue and no active workers
26.1255 + * @return true if now terminating or terminated
26.1256 + */
26.1257 + private boolean tryTerminate(boolean now) {
26.1258 + long c;
26.1259 + while (((c = ctl) & STOP_BIT) == 0) {
26.1260 + if (!now) {
26.1261 + if ((int)(c >> AC_SHIFT) != -parallelism)
26.1262 + return false;
26.1263 + if (!shutdown || blockedCount != 0 || quiescerCount != 0 ||
26.1264 + queueBase != queueTop) {
26.1265 + if (ctl == c) // staleness check
26.1266 + return false;
26.1267 + continue;
26.1268 + }
26.1269 + }
26.1270 + if (UNSAFE.compareAndSwapLong(this, ctlOffset, c, c | STOP_BIT))
26.1271 + startTerminating();
26.1272 + }
26.1273 + if ((short)(c >>> TC_SHIFT) == -parallelism) { // signal when 0 workers
26.1274 + final ReentrantLock lock = this.submissionLock;
26.1275 + lock.lock();
26.1276 + try {
26.1277 + termination.signalAll();
26.1278 + } finally {
26.1279 + lock.unlock();
26.1280 + }
26.1281 + }
26.1282 + return true;
26.1283 + }
26.1284 +
26.1285 + /**
26.1286 + * Runs up to three passes through workers: (0) Setting
26.1287 + * termination status for each worker, followed by wakeups up to
26.1288 + * queued workers; (1) helping cancel tasks; (2) interrupting
26.1289 + * lagging threads (likely in external tasks, but possibly also
26.1290 + * blocked in joins). Each pass repeats previous steps because of
26.1291 + * potential lagging thread creation.
26.1292 + */
26.1293 + private void startTerminating() {
26.1294 + cancelSubmissions();
26.1295 + for (int pass = 0; pass < 3; ++pass) {
26.1296 + ForkJoinWorkerThread[] ws = workers;
26.1297 + if (ws != null) {
26.1298 + for (ForkJoinWorkerThread w : ws) {
26.1299 + if (w != null) {
26.1300 + w.terminate = true;
26.1301 + if (pass > 0) {
26.1302 + w.cancelTasks();
26.1303 + if (pass > 1 && !w.isInterrupted()) {
26.1304 + try {
26.1305 + w.interrupt();
26.1306 + } catch (SecurityException ignore) {
26.1307 + }
26.1308 + }
26.1309 + }
26.1310 + }
26.1311 + }
26.1312 + terminateWaiters();
26.1313 + }
26.1314 + }
26.1315 + }
26.1316 +
26.1317 + /**
26.1318 + * Polls and cancels all submissions. Called only during termination.
26.1319 + */
26.1320 + private void cancelSubmissions() {
26.1321 + while (queueBase != queueTop) {
26.1322 + ForkJoinTask<?> task = pollSubmission();
26.1323 + if (task != null) {
26.1324 + try {
26.1325 + task.cancel(false);
26.1326 + } catch (Throwable ignore) {
26.1327 + }
26.1328 + }
26.1329 + }
26.1330 + }
26.1331 +
26.1332 + /**
26.1333 + * Tries to set the termination status of waiting workers, and
26.1334 + * then wakes them up (after which they will terminate).
26.1335 + */
26.1336 + private void terminateWaiters() {
26.1337 + ForkJoinWorkerThread[] ws = workers;
26.1338 + if (ws != null) {
26.1339 + ForkJoinWorkerThread w; long c; int i, e;
26.1340 + int n = ws.length;
26.1341 + while ((i = ~(e = (int)(c = ctl)) & SMASK) < n &&
26.1342 + (w = ws[i]) != null && w.eventCount == (e & E_MASK)) {
26.1343 + if (UNSAFE.compareAndSwapLong(this, ctlOffset, c,
26.1344 + (long)(w.nextWait & E_MASK) |
26.1345 + ((c + AC_UNIT) & AC_MASK) |
26.1346 + (c & (TC_MASK|STOP_BIT)))) {
26.1347 + w.terminate = true;
26.1348 + w.eventCount = e + EC_UNIT;
26.1349 + if (w.parked)
26.1350 + UNSAFE.unpark(w);
26.1351 + }
26.1352 + }
26.1353 + }
26.1354 + }
26.1355 +
26.1356 + // misc ForkJoinWorkerThread support
26.1357 +
26.1358 + /**
26.1359 + * Increment or decrement quiescerCount. Needed only to prevent
26.1360 + * triggering shutdown if a worker is transiently inactive while
26.1361 + * checking quiescence.
26.1362 + *
26.1363 + * @param delta 1 for increment, -1 for decrement
26.1364 + */
26.1365 + final void addQuiescerCount(int delta) {
26.1366 + int c;
26.1367 + do {} while (!UNSAFE.compareAndSwapInt(this, quiescerCountOffset,
26.1368 + c = quiescerCount, c + delta));
26.1369 + }
26.1370 +
26.1371 + /**
26.1372 + * Directly increment or decrement active count without
26.1373 + * queuing. This method is used to transiently assert inactivation
26.1374 + * while checking quiescence.
26.1375 + *
26.1376 + * @param delta 1 for increment, -1 for decrement
26.1377 + */
26.1378 + final void addActiveCount(int delta) {
26.1379 + long d = delta < 0 ? -AC_UNIT : AC_UNIT;
26.1380 + long c;
26.1381 + do {} while (!UNSAFE.compareAndSwapLong(this, ctlOffset, c = ctl,
26.1382 + ((c + d) & AC_MASK) |
26.1383 + (c & ~AC_MASK)));
26.1384 + }
26.1385 +
26.1386 + /**
26.1387 + * Returns the approximate (non-atomic) number of idle threads per
26.1388 + * active thread.
26.1389 + */
26.1390 + final int idlePerActive() {
26.1391 + // Approximate at powers of two for small values, saturate past 4
26.1392 + int p = parallelism;
26.1393 + int a = p + (int)(ctl >> AC_SHIFT);
26.1394 + return (a > (p >>>= 1) ? 0 :
26.1395 + a > (p >>>= 1) ? 1 :
26.1396 + a > (p >>>= 1) ? 2 :
26.1397 + a > (p >>>= 1) ? 4 :
26.1398 + 8);
26.1399 + }
26.1400 +
26.1401 + // Exported methods
26.1402 +
26.1403 + // Constructors
26.1404 +
26.1405 + /**
26.1406 + * Creates a {@code ForkJoinPool} with parallelism equal to {@link
26.1407 + * java.lang.Runtime#availableProcessors}, using the {@linkplain
26.1408 + * #defaultForkJoinWorkerThreadFactory default thread factory},
26.1409 + * no UncaughtExceptionHandler, and non-async LIFO processing mode.
26.1410 + *
26.1411 + * @throws SecurityException if a security manager exists and
26.1412 + * the caller is not permitted to modify threads
26.1413 + * because it does not hold {@link
26.1414 + * java.lang.RuntimePermission}{@code ("modifyThread")}
26.1415 + */
26.1416 + public ForkJoinPool() {
26.1417 + this(Runtime.getRuntime().availableProcessors(),
26.1418 + defaultForkJoinWorkerThreadFactory, null, false);
26.1419 + }
26.1420 +
26.1421 + /**
26.1422 + * Creates a {@code ForkJoinPool} with the indicated parallelism
26.1423 + * level, the {@linkplain
26.1424 + * #defaultForkJoinWorkerThreadFactory default thread factory},
26.1425 + * no UncaughtExceptionHandler, and non-async LIFO processing mode.
26.1426 + *
26.1427 + * @param parallelism the parallelism level
26.1428 + * @throws IllegalArgumentException if parallelism less than or
26.1429 + * equal to zero, or greater than implementation limit
26.1430 + * @throws SecurityException if a security manager exists and
26.1431 + * the caller is not permitted to modify threads
26.1432 + * because it does not hold {@link
26.1433 + * java.lang.RuntimePermission}{@code ("modifyThread")}
26.1434 + */
26.1435 + public ForkJoinPool(int parallelism) {
26.1436 + this(parallelism, defaultForkJoinWorkerThreadFactory, null, false);
26.1437 + }
26.1438 +
26.1439 + /**
26.1440 + * Creates a {@code ForkJoinPool} with the given parameters.
26.1441 + *
26.1442 + * @param parallelism the parallelism level. For default value,
26.1443 + * use {@link java.lang.Runtime#availableProcessors}.
26.1444 + * @param factory the factory for creating new threads. For default value,
26.1445 + * use {@link #defaultForkJoinWorkerThreadFactory}.
26.1446 + * @param handler the handler for internal worker threads that
26.1447 + * terminate due to unrecoverable errors encountered while executing
26.1448 + * tasks. For default value, use {@code null}.
26.1449 + * @param asyncMode if true,
26.1450 + * establishes local first-in-first-out scheduling mode for forked
26.1451 + * tasks that are never joined. This mode may be more appropriate
26.1452 + * than default locally stack-based mode in applications in which
26.1453 + * worker threads only process event-style asynchronous tasks.
26.1454 + * For default value, use {@code false}.
26.1455 + * @throws IllegalArgumentException if parallelism less than or
26.1456 + * equal to zero, or greater than implementation limit
26.1457 + * @throws NullPointerException if the factory is null
26.1458 + * @throws SecurityException if a security manager exists and
26.1459 + * the caller is not permitted to modify threads
26.1460 + * because it does not hold {@link
26.1461 + * java.lang.RuntimePermission}{@code ("modifyThread")}
26.1462 + */
26.1463 + public ForkJoinPool(int parallelism,
26.1464 + ForkJoinWorkerThreadFactory factory,
26.1465 + Thread.UncaughtExceptionHandler handler,
26.1466 + boolean asyncMode) {
26.1467 + checkPermission();
26.1468 + if (factory == null)
26.1469 + throw new NullPointerException();
26.1470 + if (parallelism <= 0 || parallelism > MAX_ID)
26.1471 + throw new IllegalArgumentException();
26.1472 + this.parallelism = parallelism;
26.1473 + this.factory = factory;
26.1474 + this.ueh = handler;
26.1475 + this.locallyFifo = asyncMode;
26.1476 + long np = (long)(-parallelism); // offset ctl counts
26.1477 + this.ctl = ((np << AC_SHIFT) & AC_MASK) | ((np << TC_SHIFT) & TC_MASK);
26.1478 + this.submissionQueue = new ForkJoinTask<?>[INITIAL_QUEUE_CAPACITY];
26.1479 + // initialize workers array with room for 2*parallelism if possible
26.1480 + int n = parallelism << 1;
26.1481 + if (n >= MAX_ID)
26.1482 + n = MAX_ID;
26.1483 + else { // See Hackers Delight, sec 3.2, where n < (1 << 16)
26.1484 + n |= n >>> 1; n |= n >>> 2; n |= n >>> 4; n |= n >>> 8;
26.1485 + }
26.1486 + workers = new ForkJoinWorkerThread[n + 1];
26.1487 + this.submissionLock = new ReentrantLock();
26.1488 + this.termination = submissionLock.newCondition();
26.1489 + StringBuilder sb = new StringBuilder("ForkJoinPool-");
26.1490 + sb.append(poolNumberGenerator.incrementAndGet());
26.1491 + sb.append("-worker-");
26.1492 + this.workerNamePrefix = sb.toString();
26.1493 + }
26.1494 +
26.1495 + // Execution methods
26.1496 +
26.1497 + /**
26.1498 + * Performs the given task, returning its result upon completion.
26.1499 + * If the computation encounters an unchecked Exception or Error,
26.1500 + * it is rethrown as the outcome of this invocation. Rethrown
26.1501 + * exceptions behave in the same way as regular exceptions, but,
26.1502 + * when possible, contain stack traces (as displayed for example
26.1503 + * using {@code ex.printStackTrace()}) of both the current thread
26.1504 + * as well as the thread actually encountering the exception;
26.1505 + * minimally only the latter.
26.1506 + *
26.1507 + * @param task the task
26.1508 + * @return the task's result
26.1509 + * @throws NullPointerException if the task is null
26.1510 + * @throws RejectedExecutionException if the task cannot be
26.1511 + * scheduled for execution
26.1512 + */
26.1513 + public <T> T invoke(ForkJoinTask<T> task) {
26.1514 + Thread t = Thread.currentThread();
26.1515 + if (task == null)
26.1516 + throw new NullPointerException();
26.1517 + if (shutdown)
26.1518 + throw new RejectedExecutionException();
26.1519 + if ((t instanceof ForkJoinWorkerThread) &&
26.1520 + ((ForkJoinWorkerThread)t).pool == this)
26.1521 + return task.invoke(); // bypass submit if in same pool
26.1522 + else {
26.1523 + addSubmission(task);
26.1524 + return task.join();
26.1525 + }
26.1526 + }
26.1527 +
26.1528 + /**
26.1529 + * Unless terminating, forks task if within an ongoing FJ
26.1530 + * computation in the current pool, else submits as external task.
26.1531 + */
26.1532 + private <T> void forkOrSubmit(ForkJoinTask<T> task) {
26.1533 + ForkJoinWorkerThread w;
26.1534 + Thread t = Thread.currentThread();
26.1535 + if (shutdown)
26.1536 + throw new RejectedExecutionException();
26.1537 + if ((t instanceof ForkJoinWorkerThread) &&
26.1538 + (w = (ForkJoinWorkerThread)t).pool == this)
26.1539 + w.pushTask(task);
26.1540 + else
26.1541 + addSubmission(task);
26.1542 + }
26.1543 +
26.1544 + /**
26.1545 + * Arranges for (asynchronous) execution of the given task.
26.1546 + *
26.1547 + * @param task the task
26.1548 + * @throws NullPointerException if the task is null
26.1549 + * @throws RejectedExecutionException if the task cannot be
26.1550 + * scheduled for execution
26.1551 + */
26.1552 + public void execute(ForkJoinTask<?> task) {
26.1553 + if (task == null)
26.1554 + throw new NullPointerException();
26.1555 + forkOrSubmit(task);
26.1556 + }
26.1557 +
26.1558 + // AbstractExecutorService methods
26.1559 +
26.1560 + /**
26.1561 + * @throws NullPointerException if the task is null
26.1562 + * @throws RejectedExecutionException if the task cannot be
26.1563 + * scheduled for execution
26.1564 + */
26.1565 + public void execute(Runnable task) {
26.1566 + if (task == null)
26.1567 + throw new NullPointerException();
26.1568 + ForkJoinTask<?> job;
26.1569 + if (task instanceof ForkJoinTask<?>) // avoid re-wrap
26.1570 + job = (ForkJoinTask<?>) task;
26.1571 + else
26.1572 + job = ForkJoinTask.adapt(task, null);
26.1573 + forkOrSubmit(job);
26.1574 + }
26.1575 +
26.1576 + /**
26.1577 + * Submits a ForkJoinTask for execution.
26.1578 + *
26.1579 + * @param task the task to submit
26.1580 + * @return the task
26.1581 + * @throws NullPointerException if the task is null
26.1582 + * @throws RejectedExecutionException if the task cannot be
26.1583 + * scheduled for execution
26.1584 + */
26.1585 + public <T> ForkJoinTask<T> submit(ForkJoinTask<T> task) {
26.1586 + if (task == null)
26.1587 + throw new NullPointerException();
26.1588 + forkOrSubmit(task);
26.1589 + return task;
26.1590 + }
26.1591 +
26.1592 + /**
26.1593 + * @throws NullPointerException if the task is null
26.1594 + * @throws RejectedExecutionException if the task cannot be
26.1595 + * scheduled for execution
26.1596 + */
26.1597 + public <T> ForkJoinTask<T> submit(Callable<T> task) {
26.1598 + if (task == null)
26.1599 + throw new NullPointerException();
26.1600 + ForkJoinTask<T> job = ForkJoinTask.adapt(task);
26.1601 + forkOrSubmit(job);
26.1602 + return job;
26.1603 + }
26.1604 +
26.1605 + /**
26.1606 + * @throws NullPointerException if the task is null
26.1607 + * @throws RejectedExecutionException if the task cannot be
26.1608 + * scheduled for execution
26.1609 + */
26.1610 + public <T> ForkJoinTask<T> submit(Runnable task, T result) {
26.1611 + if (task == null)
26.1612 + throw new NullPointerException();
26.1613 + ForkJoinTask<T> job = ForkJoinTask.adapt(task, result);
26.1614 + forkOrSubmit(job);
26.1615 + return job;
26.1616 + }
26.1617 +
26.1618 + /**
26.1619 + * @throws NullPointerException if the task is null
26.1620 + * @throws RejectedExecutionException if the task cannot be
26.1621 + * scheduled for execution
26.1622 + */
26.1623 + public ForkJoinTask<?> submit(Runnable task) {
26.1624 + if (task == null)
26.1625 + throw new NullPointerException();
26.1626 + ForkJoinTask<?> job;
26.1627 + if (task instanceof ForkJoinTask<?>) // avoid re-wrap
26.1628 + job = (ForkJoinTask<?>) task;
26.1629 + else
26.1630 + job = ForkJoinTask.adapt(task, null);
26.1631 + forkOrSubmit(job);
26.1632 + return job;
26.1633 + }
26.1634 +
26.1635 + /**
26.1636 + * @throws NullPointerException {@inheritDoc}
26.1637 + * @throws RejectedExecutionException {@inheritDoc}
26.1638 + */
26.1639 + public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) {
26.1640 + ArrayList<ForkJoinTask<T>> forkJoinTasks =
26.1641 + new ArrayList<ForkJoinTask<T>>(tasks.size());
26.1642 + for (Callable<T> task : tasks)
26.1643 + forkJoinTasks.add(ForkJoinTask.adapt(task));
26.1644 + invoke(new InvokeAll<T>(forkJoinTasks));
26.1645 +
26.1646 + @SuppressWarnings({"unchecked", "rawtypes"})
26.1647 + List<Future<T>> futures = (List<Future<T>>) (List) forkJoinTasks;
26.1648 + return futures;
26.1649 + }
26.1650 +
26.1651 + static final class InvokeAll<T> extends RecursiveAction {
26.1652 + final ArrayList<ForkJoinTask<T>> tasks;
26.1653 + InvokeAll(ArrayList<ForkJoinTask<T>> tasks) { this.tasks = tasks; }
26.1654 + public void compute() {
26.1655 + try { invokeAll(tasks); }
26.1656 + catch (Exception ignore) {}
26.1657 + }
26.1658 + private static final long serialVersionUID = -7914297376763021607L;
26.1659 + }
26.1660 +
26.1661 + /**
26.1662 + * Returns the factory used for constructing new workers.
26.1663 + *
26.1664 + * @return the factory used for constructing new workers
26.1665 + */
26.1666 + public ForkJoinWorkerThreadFactory getFactory() {
26.1667 + return factory;
26.1668 + }
26.1669 +
26.1670 + /**
26.1671 + * Returns the handler for internal worker threads that terminate
26.1672 + * due to unrecoverable errors encountered while executing tasks.
26.1673 + *
26.1674 + * @return the handler, or {@code null} if none
26.1675 + */
26.1676 + public Thread.UncaughtExceptionHandler getUncaughtExceptionHandler() {
26.1677 + return ueh;
26.1678 + }
26.1679 +
26.1680 + /**
26.1681 + * Returns the targeted parallelism level of this pool.
26.1682 + *
26.1683 + * @return the targeted parallelism level of this pool
26.1684 + */
26.1685 + public int getParallelism() {
26.1686 + return parallelism;
26.1687 + }
26.1688 +
26.1689 + /**
26.1690 + * Returns the number of worker threads that have started but not
26.1691 + * yet terminated. The result returned by this method may differ
26.1692 + * from {@link #getParallelism} when threads are created to
26.1693 + * maintain parallelism when others are cooperatively blocked.
26.1694 + *
26.1695 + * @return the number of worker threads
26.1696 + */
26.1697 + public int getPoolSize() {
26.1698 + return parallelism + (short)(ctl >>> TC_SHIFT);
26.1699 + }
26.1700 +
26.1701 + /**
26.1702 + * Returns {@code true} if this pool uses local first-in-first-out
26.1703 + * scheduling mode for forked tasks that are never joined.
26.1704 + *
26.1705 + * @return {@code true} if this pool uses async mode
26.1706 + */
26.1707 + public boolean getAsyncMode() {
26.1708 + return locallyFifo;
26.1709 + }
26.1710 +
26.1711 + /**
26.1712 + * Returns an estimate of the number of worker threads that are
26.1713 + * not blocked waiting to join tasks or for other managed
26.1714 + * synchronization. This method may overestimate the
26.1715 + * number of running threads.
26.1716 + *
26.1717 + * @return the number of worker threads
26.1718 + */
26.1719 + public int getRunningThreadCount() {
26.1720 + int r = parallelism + (int)(ctl >> AC_SHIFT);
26.1721 + return (r <= 0) ? 0 : r; // suppress momentarily negative values
26.1722 + }
26.1723 +
26.1724 + /**
26.1725 + * Returns an estimate of the number of threads that are currently
26.1726 + * stealing or executing tasks. This method may overestimate the
26.1727 + * number of active threads.
26.1728 + *
26.1729 + * @return the number of active threads
26.1730 + */
26.1731 + public int getActiveThreadCount() {
26.1732 + int r = parallelism + (int)(ctl >> AC_SHIFT) + blockedCount;
26.1733 + return (r <= 0) ? 0 : r; // suppress momentarily negative values
26.1734 + }
26.1735 +
26.1736 + /**
26.1737 + * Returns {@code true} if all worker threads are currently idle.
26.1738 + * An idle worker is one that cannot obtain a task to execute
26.1739 + * because none are available to steal from other threads, and
26.1740 + * there are no pending submissions to the pool. This method is
26.1741 + * conservative; it might not return {@code true} immediately upon
26.1742 + * idleness of all threads, but will eventually become true if
26.1743 + * threads remain inactive.
26.1744 + *
26.1745 + * @return {@code true} if all threads are currently idle
26.1746 + */
26.1747 + public boolean isQuiescent() {
26.1748 + return parallelism + (int)(ctl >> AC_SHIFT) + blockedCount == 0;
26.1749 + }
26.1750 +
26.1751 + /**
26.1752 + * Returns an estimate of the total number of tasks stolen from
26.1753 + * one thread's work queue by another. The reported value
26.1754 + * underestimates the actual total number of steals when the pool
26.1755 + * is not quiescent. This value may be useful for monitoring and
26.1756 + * tuning fork/join programs: in general, steal counts should be
26.1757 + * high enough to keep threads busy, but low enough to avoid
26.1758 + * overhead and contention across threads.
26.1759 + *
26.1760 + * @return the number of steals
26.1761 + */
26.1762 + public long getStealCount() {
26.1763 + return stealCount;
26.1764 + }
26.1765 +
26.1766 + /**
26.1767 + * Returns an estimate of the total number of tasks currently held
26.1768 + * in queues by worker threads (but not including tasks submitted
26.1769 + * to the pool that have not begun executing). This value is only
26.1770 + * an approximation, obtained by iterating across all threads in
26.1771 + * the pool. This method may be useful for tuning task
26.1772 + * granularities.
26.1773 + *
26.1774 + * @return the number of queued tasks
26.1775 + */
26.1776 + public long getQueuedTaskCount() {
26.1777 + long count = 0;
26.1778 + ForkJoinWorkerThread[] ws;
26.1779 + if ((short)(ctl >>> TC_SHIFT) > -parallelism &&
26.1780 + (ws = workers) != null) {
26.1781 + for (ForkJoinWorkerThread w : ws)
26.1782 + if (w != null)
26.1783 + count -= w.queueBase - w.queueTop; // must read base first
26.1784 + }
26.1785 + return count;
26.1786 + }
26.1787 +
26.1788 + /**
26.1789 + * Returns an estimate of the number of tasks submitted to this
26.1790 + * pool that have not yet begun executing. This method may take
26.1791 + * time proportional to the number of submissions.
26.1792 + *
26.1793 + * @return the number of queued submissions
26.1794 + */
26.1795 + public int getQueuedSubmissionCount() {
26.1796 + return -queueBase + queueTop;
26.1797 + }
26.1798 +
26.1799 + /**
26.1800 + * Returns {@code true} if there are any tasks submitted to this
26.1801 + * pool that have not yet begun executing.
26.1802 + *
26.1803 + * @return {@code true} if there are any queued submissions
26.1804 + */
26.1805 + public boolean hasQueuedSubmissions() {
26.1806 + return queueBase != queueTop;
26.1807 + }
26.1808 +
26.1809 + /**
26.1810 + * Removes and returns the next unexecuted submission if one is
26.1811 + * available. This method may be useful in extensions to this
26.1812 + * class that re-assign work in systems with multiple pools.
26.1813 + *
26.1814 + * @return the next submission, or {@code null} if none
26.1815 + */
26.1816 + protected ForkJoinTask<?> pollSubmission() {
26.1817 + ForkJoinTask<?> t; ForkJoinTask<?>[] q; int b, i;
26.1818 + while ((b = queueBase) != queueTop &&
26.1819 + (q = submissionQueue) != null &&
26.1820 + (i = (q.length - 1) & b) >= 0) {
26.1821 + long u = (i << ASHIFT) + ABASE;
26.1822 + if ((t = q[i]) != null &&
26.1823 + queueBase == b &&
26.1824 + UNSAFE.compareAndSwapObject(q, u, t, null)) {
26.1825 + queueBase = b + 1;
26.1826 + return t;
26.1827 + }
26.1828 + }
26.1829 + return null;
26.1830 + }
26.1831 +
26.1832 + /**
26.1833 + * Removes all available unexecuted submitted and forked tasks
26.1834 + * from scheduling queues and adds them to the given collection,
26.1835 + * without altering their execution status. These may include
26.1836 + * artificially generated or wrapped tasks. This method is
26.1837 + * designed to be invoked only when the pool is known to be
26.1838 + * quiescent. Invocations at other times may not remove all
26.1839 + * tasks. A failure encountered while attempting to add elements
26.1840 + * to collection {@code c} may result in elements being in
26.1841 + * neither, either or both collections when the associated
26.1842 + * exception is thrown. The behavior of this operation is
26.1843 + * undefined if the specified collection is modified while the
26.1844 + * operation is in progress.
26.1845 + *
26.1846 + * @param c the collection to transfer elements into
26.1847 + * @return the number of elements transferred
26.1848 + */
26.1849 + protected int drainTasksTo(Collection<? super ForkJoinTask<?>> c) {
26.1850 + int count = 0;
26.1851 + while (queueBase != queueTop) {
26.1852 + ForkJoinTask<?> t = pollSubmission();
26.1853 + if (t != null) {
26.1854 + c.add(t);
26.1855 + ++count;
26.1856 + }
26.1857 + }
26.1858 + ForkJoinWorkerThread[] ws;
26.1859 + if ((short)(ctl >>> TC_SHIFT) > -parallelism &&
26.1860 + (ws = workers) != null) {
26.1861 + for (ForkJoinWorkerThread w : ws)
26.1862 + if (w != null)
26.1863 + count += w.drainTasksTo(c);
26.1864 + }
26.1865 + return count;
26.1866 + }
26.1867 +
26.1868 + /**
26.1869 + * Returns a string identifying this pool, as well as its state,
26.1870 + * including indications of run state, parallelism level, and
26.1871 + * worker and task counts.
26.1872 + *
26.1873 + * @return a string identifying this pool, as well as its state
26.1874 + */
26.1875 + public String toString() {
26.1876 + long st = getStealCount();
26.1877 + long qt = getQueuedTaskCount();
26.1878 + long qs = getQueuedSubmissionCount();
26.1879 + int pc = parallelism;
26.1880 + long c = ctl;
26.1881 + int tc = pc + (short)(c >>> TC_SHIFT);
26.1882 + int rc = pc + (int)(c >> AC_SHIFT);
26.1883 + if (rc < 0) // ignore transient negative
26.1884 + rc = 0;
26.1885 + int ac = rc + blockedCount;
26.1886 + String level;
26.1887 + if ((c & STOP_BIT) != 0)
26.1888 + level = (tc == 0) ? "Terminated" : "Terminating";
26.1889 + else
26.1890 + level = shutdown ? "Shutting down" : "Running";
26.1891 + return super.toString() +
26.1892 + "[" + level +
26.1893 + ", parallelism = " + pc +
26.1894 + ", size = " + tc +
26.1895 + ", active = " + ac +
26.1896 + ", running = " + rc +
26.1897 + ", steals = " + st +
26.1898 + ", tasks = " + qt +
26.1899 + ", submissions = " + qs +
26.1900 + "]";
26.1901 + }
26.1902 +
26.1903 + /**
26.1904 + * Initiates an orderly shutdown in which previously submitted
26.1905 + * tasks are executed, but no new tasks will be accepted.
26.1906 + * Invocation has no additional effect if already shut down.
26.1907 + * Tasks that are in the process of being submitted concurrently
26.1908 + * during the course of this method may or may not be rejected.
26.1909 + *
26.1910 + * @throws SecurityException if a security manager exists and
26.1911 + * the caller is not permitted to modify threads
26.1912 + * because it does not hold {@link
26.1913 + * java.lang.RuntimePermission}{@code ("modifyThread")}
26.1914 + */
26.1915 + public void shutdown() {
26.1916 + checkPermission();
26.1917 + shutdown = true;
26.1918 + tryTerminate(false);
26.1919 + }
26.1920 +
26.1921 + /**
26.1922 + * Attempts to cancel and/or stop all tasks, and reject all
26.1923 + * subsequently submitted tasks. Tasks that are in the process of
26.1924 + * being submitted or executed concurrently during the course of
26.1925 + * this method may or may not be rejected. This method cancels
26.1926 + * both existing and unexecuted tasks, in order to permit
26.1927 + * termination in the presence of task dependencies. So the method
26.1928 + * always returns an empty list (unlike the case for some other
26.1929 + * Executors).
26.1930 + *
26.1931 + * @return an empty list
26.1932 + * @throws SecurityException if a security manager exists and
26.1933 + * the caller is not permitted to modify threads
26.1934 + * because it does not hold {@link
26.1935 + * java.lang.RuntimePermission}{@code ("modifyThread")}
26.1936 + */
26.1937 + public List<Runnable> shutdownNow() {
26.1938 + checkPermission();
26.1939 + shutdown = true;
26.1940 + tryTerminate(true);
26.1941 + return Collections.emptyList();
26.1942 + }
26.1943 +
26.1944 + /**
26.1945 + * Returns {@code true} if all tasks have completed following shut down.
26.1946 + *
26.1947 + * @return {@code true} if all tasks have completed following shut down
26.1948 + */
26.1949 + public boolean isTerminated() {
26.1950 + long c = ctl;
26.1951 + return ((c & STOP_BIT) != 0L &&
26.1952 + (short)(c >>> TC_SHIFT) == -parallelism);
26.1953 + }
26.1954 +
26.1955 + /**
26.1956 + * Returns {@code true} if the process of termination has
26.1957 + * commenced but not yet completed. This method may be useful for
26.1958 + * debugging. A return of {@code true} reported a sufficient
26.1959 + * period after shutdown may indicate that submitted tasks have
26.1960 + * ignored or suppressed interruption, or are waiting for IO,
26.1961 + * causing this executor not to properly terminate. (See the
26.1962 + * advisory notes for class {@link ForkJoinTask} stating that
26.1963 + * tasks should not normally entail blocking operations. But if
26.1964 + * they do, they must abort them on interrupt.)
26.1965 + *
26.1966 + * @return {@code true} if terminating but not yet terminated
26.1967 + */
26.1968 + public boolean isTerminating() {
26.1969 + long c = ctl;
26.1970 + return ((c & STOP_BIT) != 0L &&
26.1971 + (short)(c >>> TC_SHIFT) != -parallelism);
26.1972 + }
26.1973 +
26.1974 + /**
26.1975 + * Returns true if terminating or terminated. Used by ForkJoinWorkerThread.
26.1976 + */
26.1977 + final boolean isAtLeastTerminating() {
26.1978 + return (ctl & STOP_BIT) != 0L;
26.1979 + }
26.1980 +
26.1981 + /**
26.1982 + * Returns {@code true} if this pool has been shut down.
26.1983 + *
26.1984 + * @return {@code true} if this pool has been shut down
26.1985 + */
26.1986 + public boolean isShutdown() {
26.1987 + return shutdown;
26.1988 + }
26.1989 +
26.1990 + /**
26.1991 + * Blocks until all tasks have completed execution after a shutdown
26.1992 + * request, or the timeout occurs, or the current thread is
26.1993 + * interrupted, whichever happens first.
26.1994 + *
26.1995 + * @param timeout the maximum time to wait
26.1996 + * @param unit the time unit of the timeout argument
26.1997 + * @return {@code true} if this executor terminated and
26.1998 + * {@code false} if the timeout elapsed before termination
26.1999 + * @throws InterruptedException if interrupted while waiting
26.2000 + */
26.2001 + public boolean awaitTermination(long timeout, TimeUnit unit)
26.2002 + throws InterruptedException {
26.2003 + long nanos = unit.toNanos(timeout);
26.2004 + final ReentrantLock lock = this.submissionLock;
26.2005 + lock.lock();
26.2006 + try {
26.2007 + for (;;) {
26.2008 + if (isTerminated())
26.2009 + return true;
26.2010 + if (nanos <= 0)
26.2011 + return false;
26.2012 + nanos = termination.awaitNanos(nanos);
26.2013 + }
26.2014 + } finally {
26.2015 + lock.unlock();
26.2016 + }
26.2017 + }
26.2018 +
26.2019 + /**
26.2020 + * Interface for extending managed parallelism for tasks running
26.2021 + * in {@link ForkJoinPool}s.
26.2022 + *
26.2023 + * <p>A {@code ManagedBlocker} provides two methods. Method
26.2024 + * {@code isReleasable} must return {@code true} if blocking is
26.2025 + * not necessary. Method {@code block} blocks the current thread
26.2026 + * if necessary (perhaps internally invoking {@code isReleasable}
26.2027 + * before actually blocking). These actions are performed by any
26.2028 + * thread invoking {@link ForkJoinPool#managedBlock}. The
26.2029 + * unusual methods in this API accommodate synchronizers that may,
26.2030 + * but don't usually, block for long periods. Similarly, they
26.2031 + * allow more efficient internal handling of cases in which
26.2032 + * additional workers may be, but usually are not, needed to
26.2033 + * ensure sufficient parallelism. Toward this end,
26.2034 + * implementations of method {@code isReleasable} must be amenable
26.2035 + * to repeated invocation.
26.2036 + *
26.2037 + * <p>For example, here is a ManagedBlocker based on a
26.2038 + * ReentrantLock:
26.2039 + * <pre> {@code
26.2040 + * class ManagedLocker implements ManagedBlocker {
26.2041 + * final ReentrantLock lock;
26.2042 + * boolean hasLock = false;
26.2043 + * ManagedLocker(ReentrantLock lock) { this.lock = lock; }
26.2044 + * public boolean block() {
26.2045 + * if (!hasLock)
26.2046 + * lock.lock();
26.2047 + * return true;
26.2048 + * }
26.2049 + * public boolean isReleasable() {
26.2050 + * return hasLock || (hasLock = lock.tryLock());
26.2051 + * }
26.2052 + * }}</pre>
26.2053 + *
26.2054 + * <p>Here is a class that possibly blocks waiting for an
26.2055 + * item on a given queue:
26.2056 + * <pre> {@code
26.2057 + * class QueueTaker<E> implements ManagedBlocker {
26.2058 + * final BlockingQueue<E> queue;
26.2059 + * volatile E item = null;
26.2060 + * QueueTaker(BlockingQueue<E> q) { this.queue = q; }
26.2061 + * public boolean block() throws InterruptedException {
26.2062 + * if (item == null)
26.2063 + * item = queue.take();
26.2064 + * return true;
26.2065 + * }
26.2066 + * public boolean isReleasable() {
26.2067 + * return item != null || (item = queue.poll()) != null;
26.2068 + * }
26.2069 + * public E getItem() { // call after pool.managedBlock completes
26.2070 + * return item;
26.2071 + * }
26.2072 + * }}</pre>
26.2073 + */
26.2074 + public static interface ManagedBlocker {
26.2075 + /**
26.2076 + * Possibly blocks the current thread, for example waiting for
26.2077 + * a lock or condition.
26.2078 + *
26.2079 + * @return {@code true} if no additional blocking is necessary
26.2080 + * (i.e., if isReleasable would return true)
26.2081 + * @throws InterruptedException if interrupted while waiting
26.2082 + * (the method is not required to do so, but is allowed to)
26.2083 + */
26.2084 + boolean block() throws InterruptedException;
26.2085 +
26.2086 + /**
26.2087 + * Returns {@code true} if blocking is unnecessary.
26.2088 + */
26.2089 + boolean isReleasable();
26.2090 + }
26.2091 +
26.2092 + /**
26.2093 + * Blocks in accord with the given blocker. If the current thread
26.2094 + * is a {@link ForkJoinWorkerThread}, this method possibly
26.2095 + * arranges for a spare thread to be activated if necessary to
26.2096 + * ensure sufficient parallelism while the current thread is blocked.
26.2097 + *
26.2098 + * <p>If the caller is not a {@link ForkJoinTask}, this method is
26.2099 + * behaviorally equivalent to
26.2100 + * <pre> {@code
26.2101 + * while (!blocker.isReleasable())
26.2102 + * if (blocker.block())
26.2103 + * return;
26.2104 + * }</pre>
26.2105 + *
26.2106 + * If the caller is a {@code ForkJoinTask}, then the pool may
26.2107 + * first be expanded to ensure parallelism, and later adjusted.
26.2108 + *
26.2109 + * @param blocker the blocker
26.2110 + * @throws InterruptedException if blocker.block did so
26.2111 + */
26.2112 + public static void managedBlock(ManagedBlocker blocker)
26.2113 + throws InterruptedException {
26.2114 + Thread t = Thread.currentThread();
26.2115 + if (t instanceof ForkJoinWorkerThread) {
26.2116 + ForkJoinWorkerThread w = (ForkJoinWorkerThread) t;
26.2117 + w.pool.awaitBlocker(blocker);
26.2118 + }
26.2119 + else {
26.2120 + do {} while (!blocker.isReleasable() && !blocker.block());
26.2121 + }
26.2122 + }
26.2123 +
26.2124 + // AbstractExecutorService overrides. These rely on undocumented
26.2125 + // fact that ForkJoinTask.adapt returns ForkJoinTasks that also
26.2126 + // implement RunnableFuture.
26.2127 +
26.2128 + protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
26.2129 + return (RunnableFuture<T>) ForkJoinTask.adapt(runnable, value);
26.2130 + }
26.2131 +
26.2132 + protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
26.2133 + return (RunnableFuture<T>) ForkJoinTask.adapt(callable);
26.2134 + }
26.2135 +
26.2136 + // Unsafe mechanics
26.2137 + private static final sun.misc.Unsafe UNSAFE;
26.2138 + private static final long ctlOffset;
26.2139 + private static final long stealCountOffset;
26.2140 + private static final long blockedCountOffset;
26.2141 + private static final long quiescerCountOffset;
26.2142 + private static final long scanGuardOffset;
26.2143 + private static final long nextWorkerNumberOffset;
26.2144 + private static final long ABASE;
26.2145 + private static final int ASHIFT;
26.2146 +
26.2147 + static {
26.2148 + poolNumberGenerator = new AtomicInteger();
26.2149 + workerSeedGenerator = new Random();
26.2150 + modifyThreadPermission = new RuntimePermission("modifyThread");
26.2151 + defaultForkJoinWorkerThreadFactory =
26.2152 + new DefaultForkJoinWorkerThreadFactory();
26.2153 + int s;
26.2154 + try {
26.2155 + UNSAFE = sun.misc.Unsafe.getUnsafe();
26.2156 + Class k = ForkJoinPool.class;
26.2157 + ctlOffset = UNSAFE.objectFieldOffset
26.2158 + (k.getDeclaredField("ctl"));
26.2159 + stealCountOffset = UNSAFE.objectFieldOffset
26.2160 + (k.getDeclaredField("stealCount"));
26.2161 + blockedCountOffset = UNSAFE.objectFieldOffset
26.2162 + (k.getDeclaredField("blockedCount"));
26.2163 + quiescerCountOffset = UNSAFE.objectFieldOffset
26.2164 + (k.getDeclaredField("quiescerCount"));
26.2165 + scanGuardOffset = UNSAFE.objectFieldOffset
26.2166 + (k.getDeclaredField("scanGuard"));
26.2167 + nextWorkerNumberOffset = UNSAFE.objectFieldOffset
26.2168 + (k.getDeclaredField("nextWorkerNumber"));
26.2169 + Class a = ForkJoinTask[].class;
26.2170 + ABASE = UNSAFE.arrayBaseOffset(a);
26.2171 + s = UNSAFE.arrayIndexScale(a);
26.2172 + } catch (Exception e) {
26.2173 + throw new Error(e);
26.2174 + }
26.2175 + if ((s & (s-1)) != 0)
26.2176 + throw new Error("data type scale not a power of two");
26.2177 + ASHIFT = 31 - Integer.numberOfLeadingZeros(s);
26.2178 + }
26.2179 +
26.2180 +}
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
27.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ForkJoinTask.java Sat Mar 19 10:46:31 2016 +0100
27.3 @@ -0,0 +1,1386 @@
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 +import java.io.Serializable;
27.42 +import java.util.Collection;
27.43 +import java.util.Collections;
27.44 +import java.util.List;
27.45 +import java.util.RandomAccess;
27.46 +import java.util.Map;
27.47 +import java.lang.ref.WeakReference;
27.48 +import java.lang.ref.ReferenceQueue;
27.49 +import java.util.concurrent.Callable;
27.50 +import java.util.concurrent.CancellationException;
27.51 +import java.util.concurrent.ExecutionException;
27.52 +import java.util.concurrent.Executor;
27.53 +import java.util.concurrent.ExecutorService;
27.54 +import java.util.concurrent.Future;
27.55 +import java.util.concurrent.RejectedExecutionException;
27.56 +import java.util.concurrent.RunnableFuture;
27.57 +import java.util.concurrent.TimeUnit;
27.58 +import java.util.concurrent.TimeoutException;
27.59 +import java.util.concurrent.locks.ReentrantLock;
27.60 +import java.lang.reflect.Constructor;
27.61 +
27.62 +/**
27.63 + * Abstract base class for tasks that run within a {@link ForkJoinPool}.
27.64 + * A {@code ForkJoinTask} is a thread-like entity that is much
27.65 + * lighter weight than a normal thread. Huge numbers of tasks and
27.66 + * subtasks may be hosted by a small number of actual threads in a
27.67 + * ForkJoinPool, at the price of some usage limitations.
27.68 + *
27.69 + * <p>A "main" {@code ForkJoinTask} begins execution when submitted
27.70 + * to a {@link ForkJoinPool}. Once started, it will usually in turn
27.71 + * start other subtasks. As indicated by the name of this class,
27.72 + * many programs using {@code ForkJoinTask} employ only methods
27.73 + * {@link #fork} and {@link #join}, or derivatives such as {@link
27.74 + * #invokeAll(ForkJoinTask...) invokeAll}. However, this class also
27.75 + * provides a number of other methods that can come into play in
27.76 + * advanced usages, as well as extension mechanics that allow
27.77 + * support of new forms of fork/join processing.
27.78 + *
27.79 + * <p>A {@code ForkJoinTask} is a lightweight form of {@link Future}.
27.80 + * The efficiency of {@code ForkJoinTask}s stems from a set of
27.81 + * restrictions (that are only partially statically enforceable)
27.82 + * reflecting their intended use as computational tasks calculating
27.83 + * pure functions or operating on purely isolated objects. The
27.84 + * primary coordination mechanisms are {@link #fork}, that arranges
27.85 + * asynchronous execution, and {@link #join}, that doesn't proceed
27.86 + * until the task's result has been computed. Computations should
27.87 + * avoid {@code synchronized} methods or blocks, and should minimize
27.88 + * other blocking synchronization apart from joining other tasks or
27.89 + * using synchronizers such as Phasers that are advertised to
27.90 + * cooperate with fork/join scheduling. Tasks should also not perform
27.91 + * blocking IO, and should ideally access variables that are
27.92 + * completely independent of those accessed by other running
27.93 + * tasks. Minor breaches of these restrictions, for example using
27.94 + * shared output streams, may be tolerable in practice, but frequent
27.95 + * use may result in poor performance, and the potential to
27.96 + * indefinitely stall if the number of threads not waiting for IO or
27.97 + * other external synchronization becomes exhausted. This usage
27.98 + * restriction is in part enforced by not permitting checked
27.99 + * exceptions such as {@code IOExceptions} to be thrown. However,
27.100 + * computations may still encounter unchecked exceptions, that are
27.101 + * rethrown to callers attempting to join them. These exceptions may
27.102 + * additionally include {@link RejectedExecutionException} stemming
27.103 + * from internal resource exhaustion, such as failure to allocate
27.104 + * internal task queues. Rethrown exceptions behave in the same way as
27.105 + * regular exceptions, but, when possible, contain stack traces (as
27.106 + * displayed for example using {@code ex.printStackTrace()}) of both
27.107 + * the thread that initiated the computation as well as the thread
27.108 + * actually encountering the exception; minimally only the latter.
27.109 + *
27.110 + * <p>The primary method for awaiting completion and extracting
27.111 + * results of a task is {@link #join}, but there are several variants:
27.112 + * The {@link Future#get} methods support interruptible and/or timed
27.113 + * waits for completion and report results using {@code Future}
27.114 + * conventions. Method {@link #invoke} is semantically
27.115 + * equivalent to {@code fork(); join()} but always attempts to begin
27.116 + * execution in the current thread. The "<em>quiet</em>" forms of
27.117 + * these methods do not extract results or report exceptions. These
27.118 + * may be useful when a set of tasks are being executed, and you need
27.119 + * to delay processing of results or exceptions until all complete.
27.120 + * Method {@code invokeAll} (available in multiple versions)
27.121 + * performs the most common form of parallel invocation: forking a set
27.122 + * of tasks and joining them all.
27.123 + *
27.124 + * <p>The execution status of tasks may be queried at several levels
27.125 + * of detail: {@link #isDone} is true if a task completed in any way
27.126 + * (including the case where a task was cancelled without executing);
27.127 + * {@link #isCompletedNormally} is true if a task completed without
27.128 + * cancellation or encountering an exception; {@link #isCancelled} is
27.129 + * true if the task was cancelled (in which case {@link #getException}
27.130 + * returns a {@link java.util.concurrent.CancellationException}); and
27.131 + * {@link #isCompletedAbnormally} is true if a task was either
27.132 + * cancelled or encountered an exception, in which case {@link
27.133 + * #getException} will return either the encountered exception or
27.134 + * {@link java.util.concurrent.CancellationException}.
27.135 + *
27.136 + * <p>The ForkJoinTask class is not usually directly subclassed.
27.137 + * Instead, you subclass one of the abstract classes that support a
27.138 + * particular style of fork/join processing, typically {@link
27.139 + * RecursiveAction} for computations that do not return results, or
27.140 + * {@link RecursiveTask} for those that do. Normally, a concrete
27.141 + * ForkJoinTask subclass declares fields comprising its parameters,
27.142 + * established in a constructor, and then defines a {@code compute}
27.143 + * method that somehow uses the control methods supplied by this base
27.144 + * class. While these methods have {@code public} access (to allow
27.145 + * instances of different task subclasses to call each other's
27.146 + * methods), some of them may only be called from within other
27.147 + * ForkJoinTasks (as may be determined using method {@link
27.148 + * #inForkJoinPool}). Attempts to invoke them in other contexts
27.149 + * result in exceptions or errors, possibly including
27.150 + * {@code ClassCastException}.
27.151 + *
27.152 + * <p>Method {@link #join} and its variants are appropriate for use
27.153 + * only when completion dependencies are acyclic; that is, the
27.154 + * parallel computation can be described as a directed acyclic graph
27.155 + * (DAG). Otherwise, executions may encounter a form of deadlock as
27.156 + * tasks cyclically wait for each other. However, this framework
27.157 + * supports other methods and techniques (for example the use of
27.158 + * {@link Phaser}, {@link #helpQuiesce}, and {@link #complete}) that
27.159 + * may be of use in constructing custom subclasses for problems that
27.160 + * are not statically structured as DAGs.
27.161 + *
27.162 + * <p>Most base support methods are {@code final}, to prevent
27.163 + * overriding of implementations that are intrinsically tied to the
27.164 + * underlying lightweight task scheduling framework. Developers
27.165 + * creating new basic styles of fork/join processing should minimally
27.166 + * implement {@code protected} methods {@link #exec}, {@link
27.167 + * #setRawResult}, and {@link #getRawResult}, while also introducing
27.168 + * an abstract computational method that can be implemented in its
27.169 + * subclasses, possibly relying on other {@code protected} methods
27.170 + * provided by this class.
27.171 + *
27.172 + * <p>ForkJoinTasks should perform relatively small amounts of
27.173 + * computation. Large tasks should be split into smaller subtasks,
27.174 + * usually via recursive decomposition. As a very rough rule of thumb,
27.175 + * a task should perform more than 100 and less than 10000 basic
27.176 + * computational steps, and should avoid indefinite looping. If tasks
27.177 + * are too big, then parallelism cannot improve throughput. If too
27.178 + * small, then memory and internal task maintenance overhead may
27.179 + * overwhelm processing.
27.180 + *
27.181 + * <p>This class provides {@code adapt} methods for {@link Runnable}
27.182 + * and {@link Callable}, that may be of use when mixing execution of
27.183 + * {@code ForkJoinTasks} with other kinds of tasks. When all tasks are
27.184 + * of this form, consider using a pool constructed in <em>asyncMode</em>.
27.185 + *
27.186 + * <p>ForkJoinTasks are {@code Serializable}, which enables them to be
27.187 + * used in extensions such as remote execution frameworks. It is
27.188 + * sensible to serialize tasks only before or after, but not during,
27.189 + * execution. Serialization is not relied on during execution itself.
27.190 + *
27.191 + * @since 1.7
27.192 + * @author Doug Lea
27.193 + */
27.194 +public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
27.195 +
27.196 + /*
27.197 + * See the internal documentation of class ForkJoinPool for a
27.198 + * general implementation overview. ForkJoinTasks are mainly
27.199 + * responsible for maintaining their "status" field amidst relays
27.200 + * to methods in ForkJoinWorkerThread and ForkJoinPool. The
27.201 + * methods of this class are more-or-less layered into (1) basic
27.202 + * status maintenance (2) execution and awaiting completion (3)
27.203 + * user-level methods that additionally report results. This is
27.204 + * sometimes hard to see because this file orders exported methods
27.205 + * in a way that flows well in javadocs.
27.206 + */
27.207 +
27.208 + /*
27.209 + * The status field holds run control status bits packed into a
27.210 + * single int to minimize footprint and to ensure atomicity (via
27.211 + * CAS). Status is initially zero, and takes on nonnegative
27.212 + * values until completed, upon which status holds value
27.213 + * NORMAL, CANCELLED, or EXCEPTIONAL. Tasks undergoing blocking
27.214 + * waits by other threads have the SIGNAL bit set. Completion of
27.215 + * a stolen task with SIGNAL set awakens any waiters via
27.216 + * notifyAll. Even though suboptimal for some purposes, we use
27.217 + * basic builtin wait/notify to take advantage of "monitor
27.218 + * inflation" in JVMs that we would otherwise need to emulate to
27.219 + * avoid adding further per-task bookkeeping overhead. We want
27.220 + * these monitors to be "fat", i.e., not use biasing or thin-lock
27.221 + * techniques, so use some odd coding idioms that tend to avoid
27.222 + * them.
27.223 + */
27.224 +
27.225 + /** The run status of this task */
27.226 + volatile int status; // accessed directly by pool and workers
27.227 + private static final int NORMAL = -1;
27.228 + private static final int CANCELLED = -2;
27.229 + private static final int EXCEPTIONAL = -3;
27.230 + private static final int SIGNAL = 1;
27.231 +
27.232 + /**
27.233 + * Marks completion and wakes up threads waiting to join this task,
27.234 + * also clearing signal request bits.
27.235 + *
27.236 + * @param completion one of NORMAL, CANCELLED, EXCEPTIONAL
27.237 + * @return completion status on exit
27.238 + */
27.239 + private int setCompletion(int completion) {
27.240 + for (int s;;) {
27.241 + if ((s = status) < 0)
27.242 + return s;
27.243 + if (UNSAFE.compareAndSwapInt(this, statusOffset, s, completion)) {
27.244 + if (s != 0)
27.245 + synchronized (this) { notifyAll(); }
27.246 + return completion;
27.247 + }
27.248 + }
27.249 + }
27.250 +
27.251 + /**
27.252 + * Tries to block a worker thread until completed or timed out.
27.253 + * Uses Object.wait time argument conventions.
27.254 + * May fail on contention or interrupt.
27.255 + *
27.256 + * @param millis if > 0, wait time.
27.257 + */
27.258 + final void tryAwaitDone(long millis) {
27.259 + int s;
27.260 + try {
27.261 + if (((s = status) > 0 ||
27.262 + (s == 0 &&
27.263 + UNSAFE.compareAndSwapInt(this, statusOffset, 0, SIGNAL))) &&
27.264 + status > 0) {
27.265 + synchronized (this) {
27.266 + if (status > 0)
27.267 + wait(millis);
27.268 + }
27.269 + }
27.270 + } catch (InterruptedException ie) {
27.271 + // caller must check termination
27.272 + }
27.273 + }
27.274 +
27.275 + /**
27.276 + * Blocks a non-worker-thread until completion.
27.277 + * @return status upon completion
27.278 + */
27.279 + private int externalAwaitDone() {
27.280 + int s;
27.281 + if ((s = status) >= 0) {
27.282 + boolean interrupted = false;
27.283 + synchronized (this) {
27.284 + while ((s = status) >= 0) {
27.285 + if (s == 0)
27.286 + UNSAFE.compareAndSwapInt(this, statusOffset,
27.287 + 0, SIGNAL);
27.288 + else {
27.289 + try {
27.290 + wait();
27.291 + } catch (InterruptedException ie) {
27.292 + interrupted = true;
27.293 + }
27.294 + }
27.295 + }
27.296 + }
27.297 + if (interrupted)
27.298 + Thread.currentThread().interrupt();
27.299 + }
27.300 + return s;
27.301 + }
27.302 +
27.303 + /**
27.304 + * Blocks a non-worker-thread until completion or interruption or timeout.
27.305 + */
27.306 + private int externalInterruptibleAwaitDone(long millis)
27.307 + throws InterruptedException {
27.308 + int s;
27.309 + if (Thread.interrupted())
27.310 + throw new InterruptedException();
27.311 + if ((s = status) >= 0) {
27.312 + synchronized (this) {
27.313 + while ((s = status) >= 0) {
27.314 + if (s == 0)
27.315 + UNSAFE.compareAndSwapInt(this, statusOffset,
27.316 + 0, SIGNAL);
27.317 + else {
27.318 + wait(millis);
27.319 + if (millis > 0L)
27.320 + break;
27.321 + }
27.322 + }
27.323 + }
27.324 + }
27.325 + return s;
27.326 + }
27.327 +
27.328 + /**
27.329 + * Primary execution method for stolen tasks. Unless done, calls
27.330 + * exec and records status if completed, but doesn't wait for
27.331 + * completion otherwise.
27.332 + */
27.333 + final void doExec() {
27.334 + if (status >= 0) {
27.335 + boolean completed;
27.336 + try {
27.337 + completed = exec();
27.338 + } catch (Throwable rex) {
27.339 + setExceptionalCompletion(rex);
27.340 + return;
27.341 + }
27.342 + if (completed)
27.343 + setCompletion(NORMAL); // must be outside try block
27.344 + }
27.345 + }
27.346 +
27.347 + /**
27.348 + * Primary mechanics for join, get, quietlyJoin.
27.349 + * @return status upon completion
27.350 + */
27.351 + private int doJoin() {
27.352 + Thread t; ForkJoinWorkerThread w; int s; boolean completed;
27.353 + if ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) {
27.354 + if ((s = status) < 0)
27.355 + return s;
27.356 + if ((w = (ForkJoinWorkerThread)t).unpushTask(this)) {
27.357 + try {
27.358 + completed = exec();
27.359 + } catch (Throwable rex) {
27.360 + return setExceptionalCompletion(rex);
27.361 + }
27.362 + if (completed)
27.363 + return setCompletion(NORMAL);
27.364 + }
27.365 + return w.joinTask(this);
27.366 + }
27.367 + else
27.368 + return externalAwaitDone();
27.369 + }
27.370 +
27.371 + /**
27.372 + * Primary mechanics for invoke, quietlyInvoke.
27.373 + * @return status upon completion
27.374 + */
27.375 + private int doInvoke() {
27.376 + int s; boolean completed;
27.377 + if ((s = status) < 0)
27.378 + return s;
27.379 + try {
27.380 + completed = exec();
27.381 + } catch (Throwable rex) {
27.382 + return setExceptionalCompletion(rex);
27.383 + }
27.384 + if (completed)
27.385 + return setCompletion(NORMAL);
27.386 + else
27.387 + return doJoin();
27.388 + }
27.389 +
27.390 + // Exception table support
27.391 +
27.392 + /**
27.393 + * Table of exceptions thrown by tasks, to enable reporting by
27.394 + * callers. Because exceptions are rare, we don't directly keep
27.395 + * them with task objects, but instead use a weak ref table. Note
27.396 + * that cancellation exceptions don't appear in the table, but are
27.397 + * instead recorded as status values.
27.398 + *
27.399 + * Note: These statics are initialized below in static block.
27.400 + */
27.401 + private static final ExceptionNode[] exceptionTable;
27.402 + private static final ReentrantLock exceptionTableLock;
27.403 + private static final ReferenceQueue<Object> exceptionTableRefQueue;
27.404 +
27.405 + /**
27.406 + * Fixed capacity for exceptionTable.
27.407 + */
27.408 + private static final int EXCEPTION_MAP_CAPACITY = 32;
27.409 +
27.410 + /**
27.411 + * Key-value nodes for exception table. The chained hash table
27.412 + * uses identity comparisons, full locking, and weak references
27.413 + * for keys. The table has a fixed capacity because it only
27.414 + * maintains task exceptions long enough for joiners to access
27.415 + * them, so should never become very large for sustained
27.416 + * periods. However, since we do not know when the last joiner
27.417 + * completes, we must use weak references and expunge them. We do
27.418 + * so on each operation (hence full locking). Also, some thread in
27.419 + * any ForkJoinPool will call helpExpungeStaleExceptions when its
27.420 + * pool becomes isQuiescent.
27.421 + */
27.422 + static final class ExceptionNode extends WeakReference<ForkJoinTask<?>>{
27.423 + final Throwable ex;
27.424 + ExceptionNode next;
27.425 + final long thrower; // use id not ref to avoid weak cycles
27.426 + ExceptionNode(ForkJoinTask<?> task, Throwable ex, ExceptionNode next) {
27.427 + super(task, exceptionTableRefQueue);
27.428 + this.ex = ex;
27.429 + this.next = next;
27.430 + this.thrower = Thread.currentThread().getId();
27.431 + }
27.432 + }
27.433 +
27.434 + /**
27.435 + * Records exception and sets exceptional completion.
27.436 + *
27.437 + * @return status on exit
27.438 + */
27.439 + private int setExceptionalCompletion(Throwable ex) {
27.440 + int h = System.identityHashCode(this);
27.441 + final ReentrantLock lock = exceptionTableLock;
27.442 + lock.lock();
27.443 + try {
27.444 + expungeStaleExceptions();
27.445 + ExceptionNode[] t = exceptionTable;
27.446 + int i = h & (t.length - 1);
27.447 + for (ExceptionNode e = t[i]; ; e = e.next) {
27.448 + if (e == null) {
27.449 + t[i] = new ExceptionNode(this, ex, t[i]);
27.450 + break;
27.451 + }
27.452 + if (e.get() == this) // already present
27.453 + break;
27.454 + }
27.455 + } finally {
27.456 + lock.unlock();
27.457 + }
27.458 + return setCompletion(EXCEPTIONAL);
27.459 + }
27.460 +
27.461 + /**
27.462 + * Removes exception node and clears status
27.463 + */
27.464 + private void clearExceptionalCompletion() {
27.465 + int h = System.identityHashCode(this);
27.466 + final ReentrantLock lock = exceptionTableLock;
27.467 + lock.lock();
27.468 + try {
27.469 + ExceptionNode[] t = exceptionTable;
27.470 + int i = h & (t.length - 1);
27.471 + ExceptionNode e = t[i];
27.472 + ExceptionNode pred = null;
27.473 + while (e != null) {
27.474 + ExceptionNode next = e.next;
27.475 + if (e.get() == this) {
27.476 + if (pred == null)
27.477 + t[i] = next;
27.478 + else
27.479 + pred.next = next;
27.480 + break;
27.481 + }
27.482 + pred = e;
27.483 + e = next;
27.484 + }
27.485 + expungeStaleExceptions();
27.486 + status = 0;
27.487 + } finally {
27.488 + lock.unlock();
27.489 + }
27.490 + }
27.491 +
27.492 + /**
27.493 + * Returns a rethrowable exception for the given task, if
27.494 + * available. To provide accurate stack traces, if the exception
27.495 + * was not thrown by the current thread, we try to create a new
27.496 + * exception of the same type as the one thrown, but with the
27.497 + * recorded exception as its cause. If there is no such
27.498 + * constructor, we instead try to use a no-arg constructor,
27.499 + * followed by initCause, to the same effect. If none of these
27.500 + * apply, or any fail due to other exceptions, we return the
27.501 + * recorded exception, which is still correct, although it may
27.502 + * contain a misleading stack trace.
27.503 + *
27.504 + * @return the exception, or null if none
27.505 + */
27.506 + private Throwable getThrowableException() {
27.507 + if (status != EXCEPTIONAL)
27.508 + return null;
27.509 + int h = System.identityHashCode(this);
27.510 + ExceptionNode e;
27.511 + final ReentrantLock lock = exceptionTableLock;
27.512 + lock.lock();
27.513 + try {
27.514 + expungeStaleExceptions();
27.515 + ExceptionNode[] t = exceptionTable;
27.516 + e = t[h & (t.length - 1)];
27.517 + while (e != null && e.get() != this)
27.518 + e = e.next;
27.519 + } finally {
27.520 + lock.unlock();
27.521 + }
27.522 + Throwable ex;
27.523 + if (e == null || (ex = e.ex) == null)
27.524 + return null;
27.525 + if (e.thrower != Thread.currentThread().getId()) {
27.526 + Class ec = ex.getClass();
27.527 + try {
27.528 + Constructor<?> noArgCtor = null;
27.529 + Constructor<?>[] cs = ec.getConstructors();// public ctors only
27.530 + for (int i = 0; i < cs.length; ++i) {
27.531 + Constructor<?> c = cs[i];
27.532 + Class<?>[] ps = c.getParameterTypes();
27.533 + if (ps.length == 0)
27.534 + noArgCtor = c;
27.535 + else if (ps.length == 1 && ps[0] == Throwable.class)
27.536 + return (Throwable)(c.newInstance(ex));
27.537 + }
27.538 + if (noArgCtor != null) {
27.539 + Throwable wx = (Throwable)(noArgCtor.newInstance());
27.540 + wx.initCause(ex);
27.541 + return wx;
27.542 + }
27.543 + } catch (Exception ignore) {
27.544 + }
27.545 + }
27.546 + return ex;
27.547 + }
27.548 +
27.549 + /**
27.550 + * Poll stale refs and remove them. Call only while holding lock.
27.551 + */
27.552 + private static void expungeStaleExceptions() {
27.553 + for (Object x; (x = exceptionTableRefQueue.poll()) != null;) {
27.554 + if (x instanceof ExceptionNode) {
27.555 + ForkJoinTask<?> key = ((ExceptionNode)x).get();
27.556 + ExceptionNode[] t = exceptionTable;
27.557 + int i = System.identityHashCode(key) & (t.length - 1);
27.558 + ExceptionNode e = t[i];
27.559 + ExceptionNode pred = null;
27.560 + while (e != null) {
27.561 + ExceptionNode next = e.next;
27.562 + if (e == x) {
27.563 + if (pred == null)
27.564 + t[i] = next;
27.565 + else
27.566 + pred.next = next;
27.567 + break;
27.568 + }
27.569 + pred = e;
27.570 + e = next;
27.571 + }
27.572 + }
27.573 + }
27.574 + }
27.575 +
27.576 + /**
27.577 + * If lock is available, poll stale refs and remove them.
27.578 + * Called from ForkJoinPool when pools become quiescent.
27.579 + */
27.580 + static final void helpExpungeStaleExceptions() {
27.581 + final ReentrantLock lock = exceptionTableLock;
27.582 + if (lock.tryLock()) {
27.583 + try {
27.584 + expungeStaleExceptions();
27.585 + } finally {
27.586 + lock.unlock();
27.587 + }
27.588 + }
27.589 + }
27.590 +
27.591 + /**
27.592 + * Report the result of invoke or join; called only upon
27.593 + * non-normal return of internal versions.
27.594 + */
27.595 + private V reportResult() {
27.596 + int s; Throwable ex;
27.597 + if ((s = status) == CANCELLED)
27.598 + throw new CancellationException();
27.599 + if (s == EXCEPTIONAL && (ex = getThrowableException()) != null)
27.600 + UNSAFE.throwException(ex);
27.601 + return getRawResult();
27.602 + }
27.603 +
27.604 + // public methods
27.605 +
27.606 + /**
27.607 + * Arranges to asynchronously execute this task. While it is not
27.608 + * necessarily enforced, it is a usage error to fork a task more
27.609 + * than once unless it has completed and been reinitialized.
27.610 + * Subsequent modifications to the state of this task or any data
27.611 + * it operates on are not necessarily consistently observable by
27.612 + * any thread other than the one executing it unless preceded by a
27.613 + * call to {@link #join} or related methods, or a call to {@link
27.614 + * #isDone} returning {@code true}.
27.615 + *
27.616 + * <p>This method may be invoked only from within {@code
27.617 + * ForkJoinPool} computations (as may be determined using method
27.618 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
27.619 + * result in exceptions or errors, possibly including {@code
27.620 + * ClassCastException}.
27.621 + *
27.622 + * @return {@code this}, to simplify usage
27.623 + */
27.624 + public final ForkJoinTask<V> fork() {
27.625 + ((ForkJoinWorkerThread) Thread.currentThread())
27.626 + .pushTask(this);
27.627 + return this;
27.628 + }
27.629 +
27.630 + /**
27.631 + * Returns the result of the computation when it {@link #isDone is
27.632 + * done}. This method differs from {@link #get()} in that
27.633 + * abnormal completion results in {@code RuntimeException} or
27.634 + * {@code Error}, not {@code ExecutionException}, and that
27.635 + * interrupts of the calling thread do <em>not</em> cause the
27.636 + * method to abruptly return by throwing {@code
27.637 + * InterruptedException}.
27.638 + *
27.639 + * @return the computed result
27.640 + */
27.641 + public final V join() {
27.642 + if (doJoin() != NORMAL)
27.643 + return reportResult();
27.644 + else
27.645 + return getRawResult();
27.646 + }
27.647 +
27.648 + /**
27.649 + * Commences performing this task, awaits its completion if
27.650 + * necessary, and returns its result, or throws an (unchecked)
27.651 + * {@code RuntimeException} or {@code Error} if the underlying
27.652 + * computation did so.
27.653 + *
27.654 + * @return the computed result
27.655 + */
27.656 + public final V invoke() {
27.657 + if (doInvoke() != NORMAL)
27.658 + return reportResult();
27.659 + else
27.660 + return getRawResult();
27.661 + }
27.662 +
27.663 + /**
27.664 + * Forks the given tasks, returning when {@code isDone} holds for
27.665 + * each task or an (unchecked) exception is encountered, in which
27.666 + * case the exception is rethrown. If more than one task
27.667 + * encounters an exception, then this method throws any one of
27.668 + * these exceptions. If any task encounters an exception, the
27.669 + * other may be cancelled. However, the execution status of
27.670 + * individual tasks is not guaranteed upon exceptional return. The
27.671 + * status of each task may be obtained using {@link
27.672 + * #getException()} and related methods to check if they have been
27.673 + * cancelled, completed normally or exceptionally, or left
27.674 + * unprocessed.
27.675 + *
27.676 + * <p>This method may be invoked only from within {@code
27.677 + * ForkJoinPool} computations (as may be determined using method
27.678 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
27.679 + * result in exceptions or errors, possibly including {@code
27.680 + * ClassCastException}.
27.681 + *
27.682 + * @param t1 the first task
27.683 + * @param t2 the second task
27.684 + * @throws NullPointerException if any task is null
27.685 + */
27.686 + public static void invokeAll(ForkJoinTask<?> t1, ForkJoinTask<?> t2) {
27.687 + t2.fork();
27.688 + t1.invoke();
27.689 + t2.join();
27.690 + }
27.691 +
27.692 + /**
27.693 + * Forks the given tasks, returning when {@code isDone} holds for
27.694 + * each task or an (unchecked) exception is encountered, in which
27.695 + * case the exception is rethrown. If more than one task
27.696 + * encounters an exception, then this method throws any one of
27.697 + * these exceptions. If any task encounters an exception, others
27.698 + * may be cancelled. However, the execution status of individual
27.699 + * tasks is not guaranteed upon exceptional return. The status of
27.700 + * each task may be obtained using {@link #getException()} and
27.701 + * related methods to check if they have been cancelled, completed
27.702 + * normally or exceptionally, or left unprocessed.
27.703 + *
27.704 + * <p>This method may be invoked only from within {@code
27.705 + * ForkJoinPool} computations (as may be determined using method
27.706 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
27.707 + * result in exceptions or errors, possibly including {@code
27.708 + * ClassCastException}.
27.709 + *
27.710 + * @param tasks the tasks
27.711 + * @throws NullPointerException if any task is null
27.712 + */
27.713 + public static void invokeAll(ForkJoinTask<?>... tasks) {
27.714 + Throwable ex = null;
27.715 + int last = tasks.length - 1;
27.716 + for (int i = last; i >= 0; --i) {
27.717 + ForkJoinTask<?> t = tasks[i];
27.718 + if (t == null) {
27.719 + if (ex == null)
27.720 + ex = new NullPointerException();
27.721 + }
27.722 + else if (i != 0)
27.723 + t.fork();
27.724 + else if (t.doInvoke() < NORMAL && ex == null)
27.725 + ex = t.getException();
27.726 + }
27.727 + for (int i = 1; i <= last; ++i) {
27.728 + ForkJoinTask<?> t = tasks[i];
27.729 + if (t != null) {
27.730 + if (ex != null)
27.731 + t.cancel(false);
27.732 + else if (t.doJoin() < NORMAL && ex == null)
27.733 + ex = t.getException();
27.734 + }
27.735 + }
27.736 + if (ex != null)
27.737 + UNSAFE.throwException(ex);
27.738 + }
27.739 +
27.740 + /**
27.741 + * Forks all tasks in the specified collection, returning when
27.742 + * {@code isDone} holds for each task or an (unchecked) exception
27.743 + * is encountered, in which case the exception is rethrown. If
27.744 + * more than one task encounters an exception, then this method
27.745 + * throws any one of these exceptions. If any task encounters an
27.746 + * exception, others may be cancelled. However, the execution
27.747 + * status of individual tasks is not guaranteed upon exceptional
27.748 + * return. The status of each task may be obtained using {@link
27.749 + * #getException()} and related methods to check if they have been
27.750 + * cancelled, completed normally or exceptionally, or left
27.751 + * unprocessed.
27.752 + *
27.753 + * <p>This method may be invoked only from within {@code
27.754 + * ForkJoinPool} computations (as may be determined using method
27.755 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
27.756 + * result in exceptions or errors, possibly including {@code
27.757 + * ClassCastException}.
27.758 + *
27.759 + * @param tasks the collection of tasks
27.760 + * @return the tasks argument, to simplify usage
27.761 + * @throws NullPointerException if tasks or any element are null
27.762 + */
27.763 + public static <T extends ForkJoinTask<?>> Collection<T> invokeAll(Collection<T> tasks) {
27.764 + if (!(tasks instanceof RandomAccess) || !(tasks instanceof List<?>)) {
27.765 + invokeAll(tasks.toArray(new ForkJoinTask<?>[tasks.size()]));
27.766 + return tasks;
27.767 + }
27.768 + @SuppressWarnings("unchecked")
27.769 + List<? extends ForkJoinTask<?>> ts =
27.770 + (List<? extends ForkJoinTask<?>>) tasks;
27.771 + Throwable ex = null;
27.772 + int last = ts.size() - 1;
27.773 + for (int i = last; i >= 0; --i) {
27.774 + ForkJoinTask<?> t = ts.get(i);
27.775 + if (t == null) {
27.776 + if (ex == null)
27.777 + ex = new NullPointerException();
27.778 + }
27.779 + else if (i != 0)
27.780 + t.fork();
27.781 + else if (t.doInvoke() < NORMAL && ex == null)
27.782 + ex = t.getException();
27.783 + }
27.784 + for (int i = 1; i <= last; ++i) {
27.785 + ForkJoinTask<?> t = ts.get(i);
27.786 + if (t != null) {
27.787 + if (ex != null)
27.788 + t.cancel(false);
27.789 + else if (t.doJoin() < NORMAL && ex == null)
27.790 + ex = t.getException();
27.791 + }
27.792 + }
27.793 + if (ex != null)
27.794 + UNSAFE.throwException(ex);
27.795 + return tasks;
27.796 + }
27.797 +
27.798 + /**
27.799 + * Attempts to cancel execution of this task. This attempt will
27.800 + * fail if the task has already completed or could not be
27.801 + * cancelled for some other reason. If successful, and this task
27.802 + * has not started when {@code cancel} is called, execution of
27.803 + * this task is suppressed. After this method returns
27.804 + * successfully, unless there is an intervening call to {@link
27.805 + * #reinitialize}, subsequent calls to {@link #isCancelled},
27.806 + * {@link #isDone}, and {@code cancel} will return {@code true}
27.807 + * and calls to {@link #join} and related methods will result in
27.808 + * {@code CancellationException}.
27.809 + *
27.810 + * <p>This method may be overridden in subclasses, but if so, must
27.811 + * still ensure that these properties hold. In particular, the
27.812 + * {@code cancel} method itself must not throw exceptions.
27.813 + *
27.814 + * <p>This method is designed to be invoked by <em>other</em>
27.815 + * tasks. To terminate the current task, you can just return or
27.816 + * throw an unchecked exception from its computation method, or
27.817 + * invoke {@link #completeExceptionally}.
27.818 + *
27.819 + * @param mayInterruptIfRunning this value has no effect in the
27.820 + * default implementation because interrupts are not used to
27.821 + * control cancellation.
27.822 + *
27.823 + * @return {@code true} if this task is now cancelled
27.824 + */
27.825 + public boolean cancel(boolean mayInterruptIfRunning) {
27.826 + return setCompletion(CANCELLED) == CANCELLED;
27.827 + }
27.828 +
27.829 + /**
27.830 + * Cancels, ignoring any exceptions thrown by cancel. Used during
27.831 + * worker and pool shutdown. Cancel is spec'ed not to throw any
27.832 + * exceptions, but if it does anyway, we have no recourse during
27.833 + * shutdown, so guard against this case.
27.834 + */
27.835 + final void cancelIgnoringExceptions() {
27.836 + try {
27.837 + cancel(false);
27.838 + } catch (Throwable ignore) {
27.839 + }
27.840 + }
27.841 +
27.842 + public final boolean isDone() {
27.843 + return status < 0;
27.844 + }
27.845 +
27.846 + public final boolean isCancelled() {
27.847 + return status == CANCELLED;
27.848 + }
27.849 +
27.850 + /**
27.851 + * Returns {@code true} if this task threw an exception or was cancelled.
27.852 + *
27.853 + * @return {@code true} if this task threw an exception or was cancelled
27.854 + */
27.855 + public final boolean isCompletedAbnormally() {
27.856 + return status < NORMAL;
27.857 + }
27.858 +
27.859 + /**
27.860 + * Returns {@code true} if this task completed without throwing an
27.861 + * exception and was not cancelled.
27.862 + *
27.863 + * @return {@code true} if this task completed without throwing an
27.864 + * exception and was not cancelled
27.865 + */
27.866 + public final boolean isCompletedNormally() {
27.867 + return status == NORMAL;
27.868 + }
27.869 +
27.870 + /**
27.871 + * Returns the exception thrown by the base computation, or a
27.872 + * {@code CancellationException} if cancelled, or {@code null} if
27.873 + * none or if the method has not yet completed.
27.874 + *
27.875 + * @return the exception, or {@code null} if none
27.876 + */
27.877 + public final Throwable getException() {
27.878 + int s = status;
27.879 + return ((s >= NORMAL) ? null :
27.880 + (s == CANCELLED) ? new CancellationException() :
27.881 + getThrowableException());
27.882 + }
27.883 +
27.884 + /**
27.885 + * Completes this task abnormally, and if not already aborted or
27.886 + * cancelled, causes it to throw the given exception upon
27.887 + * {@code join} and related operations. This method may be used
27.888 + * to induce exceptions in asynchronous tasks, or to force
27.889 + * completion of tasks that would not otherwise complete. Its use
27.890 + * in other situations is discouraged. This method is
27.891 + * overridable, but overridden versions must invoke {@code super}
27.892 + * implementation to maintain guarantees.
27.893 + *
27.894 + * @param ex the exception to throw. If this exception is not a
27.895 + * {@code RuntimeException} or {@code Error}, the actual exception
27.896 + * thrown will be a {@code RuntimeException} with cause {@code ex}.
27.897 + */
27.898 + public void completeExceptionally(Throwable ex) {
27.899 + setExceptionalCompletion((ex instanceof RuntimeException) ||
27.900 + (ex instanceof Error) ? ex :
27.901 + new RuntimeException(ex));
27.902 + }
27.903 +
27.904 + /**
27.905 + * Completes this task, and if not already aborted or cancelled,
27.906 + * returning the given value as the result of subsequent
27.907 + * invocations of {@code join} and related operations. This method
27.908 + * may be used to provide results for asynchronous tasks, or to
27.909 + * provide alternative handling for tasks that would not otherwise
27.910 + * complete normally. Its use in other situations is
27.911 + * discouraged. This method is overridable, but overridden
27.912 + * versions must invoke {@code super} implementation to maintain
27.913 + * guarantees.
27.914 + *
27.915 + * @param value the result value for this task
27.916 + */
27.917 + public void complete(V value) {
27.918 + try {
27.919 + setRawResult(value);
27.920 + } catch (Throwable rex) {
27.921 + setExceptionalCompletion(rex);
27.922 + return;
27.923 + }
27.924 + setCompletion(NORMAL);
27.925 + }
27.926 +
27.927 + /**
27.928 + * Waits if necessary for the computation to complete, and then
27.929 + * retrieves its result.
27.930 + *
27.931 + * @return the computed result
27.932 + * @throws CancellationException if the computation was cancelled
27.933 + * @throws ExecutionException if the computation threw an
27.934 + * exception
27.935 + * @throws InterruptedException if the current thread is not a
27.936 + * member of a ForkJoinPool and was interrupted while waiting
27.937 + */
27.938 + public final V get() throws InterruptedException, ExecutionException {
27.939 + int s = (Thread.currentThread() instanceof ForkJoinWorkerThread) ?
27.940 + doJoin() : externalInterruptibleAwaitDone(0L);
27.941 + Throwable ex;
27.942 + if (s == CANCELLED)
27.943 + throw new CancellationException();
27.944 + if (s == EXCEPTIONAL && (ex = getThrowableException()) != null)
27.945 + throw new ExecutionException(ex);
27.946 + return getRawResult();
27.947 + }
27.948 +
27.949 + /**
27.950 + * Waits if necessary for at most the given time for the computation
27.951 + * to complete, and then retrieves its result, if available.
27.952 + *
27.953 + * @param timeout the maximum time to wait
27.954 + * @param unit the time unit of the timeout argument
27.955 + * @return the computed result
27.956 + * @throws CancellationException if the computation was cancelled
27.957 + * @throws ExecutionException if the computation threw an
27.958 + * exception
27.959 + * @throws InterruptedException if the current thread is not a
27.960 + * member of a ForkJoinPool and was interrupted while waiting
27.961 + * @throws TimeoutException if the wait timed out
27.962 + */
27.963 + public final V get(long timeout, TimeUnit unit)
27.964 + throws InterruptedException, ExecutionException, TimeoutException {
27.965 + Thread t = Thread.currentThread();
27.966 + if (t instanceof ForkJoinWorkerThread) {
27.967 + ForkJoinWorkerThread w = (ForkJoinWorkerThread) t;
27.968 + long nanos = unit.toNanos(timeout);
27.969 + if (status >= 0) {
27.970 + boolean completed = false;
27.971 + if (w.unpushTask(this)) {
27.972 + try {
27.973 + completed = exec();
27.974 + } catch (Throwable rex) {
27.975 + setExceptionalCompletion(rex);
27.976 + }
27.977 + }
27.978 + if (completed)
27.979 + setCompletion(NORMAL);
27.980 + else if (status >= 0 && nanos > 0)
27.981 + w.pool.timedAwaitJoin(this, nanos);
27.982 + }
27.983 + }
27.984 + else {
27.985 + long millis = unit.toMillis(timeout);
27.986 + if (millis > 0)
27.987 + externalInterruptibleAwaitDone(millis);
27.988 + }
27.989 + int s = status;
27.990 + if (s != NORMAL) {
27.991 + Throwable ex;
27.992 + if (s == CANCELLED)
27.993 + throw new CancellationException();
27.994 + if (s != EXCEPTIONAL)
27.995 + throw new TimeoutException();
27.996 + if ((ex = getThrowableException()) != null)
27.997 + throw new ExecutionException(ex);
27.998 + }
27.999 + return getRawResult();
27.1000 + }
27.1001 +
27.1002 + /**
27.1003 + * Joins this task, without returning its result or throwing its
27.1004 + * exception. This method may be useful when processing
27.1005 + * collections of tasks when some have been cancelled or otherwise
27.1006 + * known to have aborted.
27.1007 + */
27.1008 + public final void quietlyJoin() {
27.1009 + doJoin();
27.1010 + }
27.1011 +
27.1012 + /**
27.1013 + * Commences performing this task and awaits its completion if
27.1014 + * necessary, without returning its result or throwing its
27.1015 + * exception.
27.1016 + */
27.1017 + public final void quietlyInvoke() {
27.1018 + doInvoke();
27.1019 + }
27.1020 +
27.1021 + /**
27.1022 + * Possibly executes tasks until the pool hosting the current task
27.1023 + * {@link ForkJoinPool#isQuiescent is quiescent}. This method may
27.1024 + * be of use in designs in which many tasks are forked, but none
27.1025 + * are explicitly joined, instead executing them until all are
27.1026 + * processed.
27.1027 + *
27.1028 + * <p>This method may be invoked only from within {@code
27.1029 + * ForkJoinPool} computations (as may be determined using method
27.1030 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
27.1031 + * result in exceptions or errors, possibly including {@code
27.1032 + * ClassCastException}.
27.1033 + */
27.1034 + public static void helpQuiesce() {
27.1035 + ((ForkJoinWorkerThread) Thread.currentThread())
27.1036 + .helpQuiescePool();
27.1037 + }
27.1038 +
27.1039 + /**
27.1040 + * Resets the internal bookkeeping state of this task, allowing a
27.1041 + * subsequent {@code fork}. This method allows repeated reuse of
27.1042 + * this task, but only if reuse occurs when this task has either
27.1043 + * never been forked, or has been forked, then completed and all
27.1044 + * outstanding joins of this task have also completed. Effects
27.1045 + * under any other usage conditions are not guaranteed.
27.1046 + * This method may be useful when executing
27.1047 + * pre-constructed trees of subtasks in loops.
27.1048 + *
27.1049 + * <p>Upon completion of this method, {@code isDone()} reports
27.1050 + * {@code false}, and {@code getException()} reports {@code
27.1051 + * null}. However, the value returned by {@code getRawResult} is
27.1052 + * unaffected. To clear this value, you can invoke {@code
27.1053 + * setRawResult(null)}.
27.1054 + */
27.1055 + public void reinitialize() {
27.1056 + if (status == EXCEPTIONAL)
27.1057 + clearExceptionalCompletion();
27.1058 + else
27.1059 + status = 0;
27.1060 + }
27.1061 +
27.1062 + /**
27.1063 + * Returns the pool hosting the current task execution, or null
27.1064 + * if this task is executing outside of any ForkJoinPool.
27.1065 + *
27.1066 + * @see #inForkJoinPool
27.1067 + * @return the pool, or {@code null} if none
27.1068 + */
27.1069 + public static ForkJoinPool getPool() {
27.1070 + Thread t = Thread.currentThread();
27.1071 + return (t instanceof ForkJoinWorkerThread) ?
27.1072 + ((ForkJoinWorkerThread) t).pool : null;
27.1073 + }
27.1074 +
27.1075 + /**
27.1076 + * Returns {@code true} if the current thread is a {@link
27.1077 + * ForkJoinWorkerThread} executing as a ForkJoinPool computation.
27.1078 + *
27.1079 + * @return {@code true} if the current thread is a {@link
27.1080 + * ForkJoinWorkerThread} executing as a ForkJoinPool computation,
27.1081 + * or {@code false} otherwise
27.1082 + */
27.1083 + public static boolean inForkJoinPool() {
27.1084 + return Thread.currentThread() instanceof ForkJoinWorkerThread;
27.1085 + }
27.1086 +
27.1087 + /**
27.1088 + * Tries to unschedule this task for execution. This method will
27.1089 + * typically succeed if this task is the most recently forked task
27.1090 + * by the current thread, and has not commenced executing in
27.1091 + * another thread. This method may be useful when arranging
27.1092 + * alternative local processing of tasks that could have been, but
27.1093 + * were not, stolen.
27.1094 + *
27.1095 + * <p>This method may be invoked only from within {@code
27.1096 + * ForkJoinPool} computations (as may be determined using method
27.1097 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
27.1098 + * result in exceptions or errors, possibly including {@code
27.1099 + * ClassCastException}.
27.1100 + *
27.1101 + * @return {@code true} if unforked
27.1102 + */
27.1103 + public boolean tryUnfork() {
27.1104 + return ((ForkJoinWorkerThread) Thread.currentThread())
27.1105 + .unpushTask(this);
27.1106 + }
27.1107 +
27.1108 + /**
27.1109 + * Returns an estimate of the number of tasks that have been
27.1110 + * forked by the current worker thread but not yet executed. This
27.1111 + * value may be useful for heuristic decisions about whether to
27.1112 + * fork other tasks.
27.1113 + *
27.1114 + * <p>This method may be invoked only from within {@code
27.1115 + * ForkJoinPool} computations (as may be determined using method
27.1116 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
27.1117 + * result in exceptions or errors, possibly including {@code
27.1118 + * ClassCastException}.
27.1119 + *
27.1120 + * @return the number of tasks
27.1121 + */
27.1122 + public static int getQueuedTaskCount() {
27.1123 + return ((ForkJoinWorkerThread) Thread.currentThread())
27.1124 + .getQueueSize();
27.1125 + }
27.1126 +
27.1127 + /**
27.1128 + * Returns an estimate of how many more locally queued tasks are
27.1129 + * held by the current worker thread than there are other worker
27.1130 + * threads that might steal them. This value may be useful for
27.1131 + * heuristic decisions about whether to fork other tasks. In many
27.1132 + * usages of ForkJoinTasks, at steady state, each worker should
27.1133 + * aim to maintain a small constant surplus (for example, 3) of
27.1134 + * tasks, and to process computations locally if this threshold is
27.1135 + * exceeded.
27.1136 + *
27.1137 + * <p>This method may be invoked only from within {@code
27.1138 + * ForkJoinPool} computations (as may be determined using method
27.1139 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
27.1140 + * result in exceptions or errors, possibly including {@code
27.1141 + * ClassCastException}.
27.1142 + *
27.1143 + * @return the surplus number of tasks, which may be negative
27.1144 + */
27.1145 + public static int getSurplusQueuedTaskCount() {
27.1146 + return ((ForkJoinWorkerThread) Thread.currentThread())
27.1147 + .getEstimatedSurplusTaskCount();
27.1148 + }
27.1149 +
27.1150 + // Extension methods
27.1151 +
27.1152 + /**
27.1153 + * Returns the result that would be returned by {@link #join}, even
27.1154 + * if this task completed abnormally, or {@code null} if this task
27.1155 + * is not known to have been completed. This method is designed
27.1156 + * to aid debugging, as well as to support extensions. Its use in
27.1157 + * any other context is discouraged.
27.1158 + *
27.1159 + * @return the result, or {@code null} if not completed
27.1160 + */
27.1161 + public abstract V getRawResult();
27.1162 +
27.1163 + /**
27.1164 + * Forces the given value to be returned as a result. This method
27.1165 + * is designed to support extensions, and should not in general be
27.1166 + * called otherwise.
27.1167 + *
27.1168 + * @param value the value
27.1169 + */
27.1170 + protected abstract void setRawResult(V value);
27.1171 +
27.1172 + /**
27.1173 + * Immediately performs the base action of this task. This method
27.1174 + * is designed to support extensions, and should not in general be
27.1175 + * called otherwise. The return value controls whether this task
27.1176 + * is considered to be done normally. It may return false in
27.1177 + * asynchronous actions that require explicit invocations of
27.1178 + * {@link #complete} to become joinable. It may also throw an
27.1179 + * (unchecked) exception to indicate abnormal exit.
27.1180 + *
27.1181 + * @return {@code true} if completed normally
27.1182 + */
27.1183 + protected abstract boolean exec();
27.1184 +
27.1185 + /**
27.1186 + * Returns, but does not unschedule or execute, a task queued by
27.1187 + * the current thread but not yet executed, if one is immediately
27.1188 + * available. There is no guarantee that this task will actually
27.1189 + * be polled or executed next. Conversely, this method may return
27.1190 + * null even if a task exists but cannot be accessed without
27.1191 + * contention with other threads. This method is designed
27.1192 + * primarily to support extensions, and is unlikely to be useful
27.1193 + * otherwise.
27.1194 + *
27.1195 + * <p>This method may be invoked only from within {@code
27.1196 + * ForkJoinPool} computations (as may be determined using method
27.1197 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
27.1198 + * result in exceptions or errors, possibly including {@code
27.1199 + * ClassCastException}.
27.1200 + *
27.1201 + * @return the next task, or {@code null} if none are available
27.1202 + */
27.1203 + protected static ForkJoinTask<?> peekNextLocalTask() {
27.1204 + return ((ForkJoinWorkerThread) Thread.currentThread())
27.1205 + .peekTask();
27.1206 + }
27.1207 +
27.1208 + /**
27.1209 + * Unschedules and returns, without executing, the next task
27.1210 + * queued by the current thread but not yet executed. This method
27.1211 + * is designed primarily to support extensions, and is unlikely to
27.1212 + * be useful otherwise.
27.1213 + *
27.1214 + * <p>This method may be invoked only from within {@code
27.1215 + * ForkJoinPool} computations (as may be determined using method
27.1216 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
27.1217 + * result in exceptions or errors, possibly including {@code
27.1218 + * ClassCastException}.
27.1219 + *
27.1220 + * @return the next task, or {@code null} if none are available
27.1221 + */
27.1222 + protected static ForkJoinTask<?> pollNextLocalTask() {
27.1223 + return ((ForkJoinWorkerThread) Thread.currentThread())
27.1224 + .pollLocalTask();
27.1225 + }
27.1226 +
27.1227 + /**
27.1228 + * Unschedules and returns, without executing, the next task
27.1229 + * queued by the current thread but not yet executed, if one is
27.1230 + * available, or if not available, a task that was forked by some
27.1231 + * other thread, if available. Availability may be transient, so a
27.1232 + * {@code null} result does not necessarily imply quiescence
27.1233 + * of the pool this task is operating in. This method is designed
27.1234 + * primarily to support extensions, and is unlikely to be useful
27.1235 + * otherwise.
27.1236 + *
27.1237 + * <p>This method may be invoked only from within {@code
27.1238 + * ForkJoinPool} computations (as may be determined using method
27.1239 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
27.1240 + * result in exceptions or errors, possibly including {@code
27.1241 + * ClassCastException}.
27.1242 + *
27.1243 + * @return a task, or {@code null} if none are available
27.1244 + */
27.1245 + protected static ForkJoinTask<?> pollTask() {
27.1246 + return ((ForkJoinWorkerThread) Thread.currentThread())
27.1247 + .pollTask();
27.1248 + }
27.1249 +
27.1250 + /**
27.1251 + * Adaptor for Runnables. This implements RunnableFuture
27.1252 + * to be compliant with AbstractExecutorService constraints
27.1253 + * when used in ForkJoinPool.
27.1254 + */
27.1255 + static final class AdaptedRunnable<T> extends ForkJoinTask<T>
27.1256 + implements RunnableFuture<T> {
27.1257 + final Runnable runnable;
27.1258 + final T resultOnCompletion;
27.1259 + T result;
27.1260 + AdaptedRunnable(Runnable runnable, T result) {
27.1261 + if (runnable == null) throw new NullPointerException();
27.1262 + this.runnable = runnable;
27.1263 + this.resultOnCompletion = result;
27.1264 + }
27.1265 + public T getRawResult() { return result; }
27.1266 + public void setRawResult(T v) { result = v; }
27.1267 + public boolean exec() {
27.1268 + runnable.run();
27.1269 + result = resultOnCompletion;
27.1270 + return true;
27.1271 + }
27.1272 + public void run() { invoke(); }
27.1273 + private static final long serialVersionUID = 5232453952276885070L;
27.1274 + }
27.1275 +
27.1276 + /**
27.1277 + * Adaptor for Callables
27.1278 + */
27.1279 + static final class AdaptedCallable<T> extends ForkJoinTask<T>
27.1280 + implements RunnableFuture<T> {
27.1281 + final Callable<? extends T> callable;
27.1282 + T result;
27.1283 + AdaptedCallable(Callable<? extends T> callable) {
27.1284 + if (callable == null) throw new NullPointerException();
27.1285 + this.callable = callable;
27.1286 + }
27.1287 + public T getRawResult() { return result; }
27.1288 + public void setRawResult(T v) { result = v; }
27.1289 + public boolean exec() {
27.1290 + try {
27.1291 + result = callable.call();
27.1292 + return true;
27.1293 + } catch (Error err) {
27.1294 + throw err;
27.1295 + } catch (RuntimeException rex) {
27.1296 + throw rex;
27.1297 + } catch (Exception ex) {
27.1298 + throw new RuntimeException(ex);
27.1299 + }
27.1300 + }
27.1301 + public void run() { invoke(); }
27.1302 + private static final long serialVersionUID = 2838392045355241008L;
27.1303 + }
27.1304 +
27.1305 + /**
27.1306 + * Returns a new {@code ForkJoinTask} that performs the {@code run}
27.1307 + * method of the given {@code Runnable} as its action, and returns
27.1308 + * a null result upon {@link #join}.
27.1309 + *
27.1310 + * @param runnable the runnable action
27.1311 + * @return the task
27.1312 + */
27.1313 + public static ForkJoinTask<?> adapt(Runnable runnable) {
27.1314 + return new AdaptedRunnable<Void>(runnable, null);
27.1315 + }
27.1316 +
27.1317 + /**
27.1318 + * Returns a new {@code ForkJoinTask} that performs the {@code run}
27.1319 + * method of the given {@code Runnable} as its action, and returns
27.1320 + * the given result upon {@link #join}.
27.1321 + *
27.1322 + * @param runnable the runnable action
27.1323 + * @param result the result upon completion
27.1324 + * @return the task
27.1325 + */
27.1326 + public static <T> ForkJoinTask<T> adapt(Runnable runnable, T result) {
27.1327 + return new AdaptedRunnable<T>(runnable, result);
27.1328 + }
27.1329 +
27.1330 + /**
27.1331 + * Returns a new {@code ForkJoinTask} that performs the {@code call}
27.1332 + * method of the given {@code Callable} as its action, and returns
27.1333 + * its result upon {@link #join}, translating any checked exceptions
27.1334 + * encountered into {@code RuntimeException}.
27.1335 + *
27.1336 + * @param callable the callable action
27.1337 + * @return the task
27.1338 + */
27.1339 + public static <T> ForkJoinTask<T> adapt(Callable<? extends T> callable) {
27.1340 + return new AdaptedCallable<T>(callable);
27.1341 + }
27.1342 +
27.1343 + // Serialization support
27.1344 +
27.1345 + private static final long serialVersionUID = -7721805057305804111L;
27.1346 +
27.1347 + /**
27.1348 + * Saves the state to a stream (that is, serializes it).
27.1349 + *
27.1350 + * @serialData the current run status and the exception thrown
27.1351 + * during execution, or {@code null} if none
27.1352 + * @param s the stream
27.1353 + */
27.1354 + private void writeObject(java.io.ObjectOutputStream s)
27.1355 + throws java.io.IOException {
27.1356 + s.defaultWriteObject();
27.1357 + s.writeObject(getException());
27.1358 + }
27.1359 +
27.1360 + /**
27.1361 + * Reconstitutes the instance from a stream (that is, deserializes it).
27.1362 + *
27.1363 + * @param s the stream
27.1364 + */
27.1365 + private void readObject(java.io.ObjectInputStream s)
27.1366 + throws java.io.IOException, ClassNotFoundException {
27.1367 + s.defaultReadObject();
27.1368 + Object ex = s.readObject();
27.1369 + if (ex != null)
27.1370 + setExceptionalCompletion((Throwable)ex);
27.1371 + }
27.1372 +
27.1373 + // Unsafe mechanics
27.1374 + private static final sun.misc.Unsafe UNSAFE;
27.1375 + private static final long statusOffset;
27.1376 + static {
27.1377 + exceptionTableLock = new ReentrantLock();
27.1378 + exceptionTableRefQueue = new ReferenceQueue<Object>();
27.1379 + exceptionTable = new ExceptionNode[EXCEPTION_MAP_CAPACITY];
27.1380 + try {
27.1381 + UNSAFE = sun.misc.Unsafe.getUnsafe();
27.1382 + statusOffset = UNSAFE.objectFieldOffset
27.1383 + (ForkJoinTask.class.getDeclaredField("status"));
27.1384 + } catch (Exception e) {
27.1385 + throw new Error(e);
27.1386 + }
27.1387 + }
27.1388 +
27.1389 +}
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
28.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ForkJoinWorkerThread.java Sat Mar 19 10:46:31 2016 +0100
28.3 @@ -0,0 +1,998 @@
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 +
28.41 +import java.util.Collection;
28.42 +import java.util.concurrent.RejectedExecutionException;
28.43 +
28.44 +/**
28.45 + * A thread managed by a {@link ForkJoinPool}, which executes
28.46 + * {@link ForkJoinTask}s.
28.47 + * This class is subclassable solely for the sake of adding
28.48 + * functionality -- there are no overridable methods dealing with
28.49 + * scheduling or execution. However, you can override initialization
28.50 + * and termination methods surrounding the main task processing loop.
28.51 + * If you do create such a subclass, you will also need to supply a
28.52 + * custom {@link ForkJoinPool.ForkJoinWorkerThreadFactory} to use it
28.53 + * in a {@code ForkJoinPool}.
28.54 + *
28.55 + * @since 1.7
28.56 + * @author Doug Lea
28.57 + */
28.58 +public class ForkJoinWorkerThread extends Thread {
28.59 + /*
28.60 + * Overview:
28.61 + *
28.62 + * ForkJoinWorkerThreads are managed by ForkJoinPools and perform
28.63 + * ForkJoinTasks. This class includes bookkeeping in support of
28.64 + * worker activation, suspension, and lifecycle control described
28.65 + * in more detail in the internal documentation of class
28.66 + * ForkJoinPool. And as described further below, this class also
28.67 + * includes special-cased support for some ForkJoinTask
28.68 + * methods. But the main mechanics involve work-stealing:
28.69 + *
28.70 + * Work-stealing queues are special forms of Deques that support
28.71 + * only three of the four possible end-operations -- push, pop,
28.72 + * and deq (aka steal), under the further constraints that push
28.73 + * and pop are called only from the owning thread, while deq may
28.74 + * be called from other threads. (If you are unfamiliar with
28.75 + * them, you probably want to read Herlihy and Shavit's book "The
28.76 + * Art of Multiprocessor programming", chapter 16 describing these
28.77 + * in more detail before proceeding.) The main work-stealing
28.78 + * queue design is roughly similar to those in the papers "Dynamic
28.79 + * Circular Work-Stealing Deque" by Chase and Lev, SPAA 2005
28.80 + * (http://research.sun.com/scalable/pubs/index.html) and
28.81 + * "Idempotent work stealing" by Michael, Saraswat, and Vechev,
28.82 + * PPoPP 2009 (http://portal.acm.org/citation.cfm?id=1504186).
28.83 + * The main differences ultimately stem from gc requirements that
28.84 + * we null out taken slots as soon as we can, to maintain as small
28.85 + * a footprint as possible even in programs generating huge
28.86 + * numbers of tasks. To accomplish this, we shift the CAS
28.87 + * arbitrating pop vs deq (steal) from being on the indices
28.88 + * ("queueBase" and "queueTop") to the slots themselves (mainly
28.89 + * via method "casSlotNull()"). So, both a successful pop and deq
28.90 + * mainly entail a CAS of a slot from non-null to null. Because
28.91 + * we rely on CASes of references, we do not need tag bits on
28.92 + * queueBase or queueTop. They are simple ints as used in any
28.93 + * circular array-based queue (see for example ArrayDeque).
28.94 + * Updates to the indices must still be ordered in a way that
28.95 + * guarantees that queueTop == queueBase means the queue is empty,
28.96 + * but otherwise may err on the side of possibly making the queue
28.97 + * appear nonempty when a push, pop, or deq have not fully
28.98 + * committed. Note that this means that the deq operation,
28.99 + * considered individually, is not wait-free. One thief cannot
28.100 + * successfully continue until another in-progress one (or, if
28.101 + * previously empty, a push) completes. However, in the
28.102 + * aggregate, we ensure at least probabilistic non-blockingness.
28.103 + * If an attempted steal fails, a thief always chooses a different
28.104 + * random victim target to try next. So, in order for one thief to
28.105 + * progress, it suffices for any in-progress deq or new push on
28.106 + * any empty queue to complete.
28.107 + *
28.108 + * This approach also enables support for "async mode" where local
28.109 + * task processing is in FIFO, not LIFO order; simply by using a
28.110 + * version of deq rather than pop when locallyFifo is true (as set
28.111 + * by the ForkJoinPool). This allows use in message-passing
28.112 + * frameworks in which tasks are never joined. However neither
28.113 + * mode considers affinities, loads, cache localities, etc, so
28.114 + * rarely provide the best possible performance on a given
28.115 + * machine, but portably provide good throughput by averaging over
28.116 + * these factors. (Further, even if we did try to use such
28.117 + * information, we do not usually have a basis for exploiting
28.118 + * it. For example, some sets of tasks profit from cache
28.119 + * affinities, but others are harmed by cache pollution effects.)
28.120 + *
28.121 + * When a worker would otherwise be blocked waiting to join a
28.122 + * task, it first tries a form of linear helping: Each worker
28.123 + * records (in field currentSteal) the most recent task it stole
28.124 + * from some other worker. Plus, it records (in field currentJoin)
28.125 + * the task it is currently actively joining. Method joinTask uses
28.126 + * these markers to try to find a worker to help (i.e., steal back
28.127 + * a task from and execute it) that could hasten completion of the
28.128 + * actively joined task. In essence, the joiner executes a task
28.129 + * that would be on its own local deque had the to-be-joined task
28.130 + * not been stolen. This may be seen as a conservative variant of
28.131 + * the approach in Wagner & Calder "Leapfrogging: a portable
28.132 + * technique for implementing efficient futures" SIGPLAN Notices,
28.133 + * 1993 (http://portal.acm.org/citation.cfm?id=155354). It differs
28.134 + * in that: (1) We only maintain dependency links across workers
28.135 + * upon steals, rather than use per-task bookkeeping. This may
28.136 + * require a linear scan of workers array to locate stealers, but
28.137 + * usually doesn't because stealers leave hints (that may become
28.138 + * stale/wrong) of where to locate them. This isolates cost to
28.139 + * when it is needed, rather than adding to per-task overhead.
28.140 + * (2) It is "shallow", ignoring nesting and potentially cyclic
28.141 + * mutual steals. (3) It is intentionally racy: field currentJoin
28.142 + * is updated only while actively joining, which means that we
28.143 + * miss links in the chain during long-lived tasks, GC stalls etc
28.144 + * (which is OK since blocking in such cases is usually a good
28.145 + * idea). (4) We bound the number of attempts to find work (see
28.146 + * MAX_HELP) and fall back to suspending the worker and if
28.147 + * necessary replacing it with another.
28.148 + *
28.149 + * Efficient implementation of these algorithms currently relies
28.150 + * on an uncomfortable amount of "Unsafe" mechanics. To maintain
28.151 + * correct orderings, reads and writes of variable queueBase
28.152 + * require volatile ordering. Variable queueTop need not be
28.153 + * volatile because non-local reads always follow those of
28.154 + * queueBase. Similarly, because they are protected by volatile
28.155 + * queueBase reads, reads of the queue array and its slots by
28.156 + * other threads do not need volatile load semantics, but writes
28.157 + * (in push) require store order and CASes (in pop and deq)
28.158 + * require (volatile) CAS semantics. (Michael, Saraswat, and
28.159 + * Vechev's algorithm has similar properties, but without support
28.160 + * for nulling slots.) Since these combinations aren't supported
28.161 + * using ordinary volatiles, the only way to accomplish these
28.162 + * efficiently is to use direct Unsafe calls. (Using external
28.163 + * AtomicIntegers and AtomicReferenceArrays for the indices and
28.164 + * array is significantly slower because of memory locality and
28.165 + * indirection effects.)
28.166 + *
28.167 + * Further, performance on most platforms is very sensitive to
28.168 + * placement and sizing of the (resizable) queue array. Even
28.169 + * though these queues don't usually become all that big, the
28.170 + * initial size must be large enough to counteract cache
28.171 + * contention effects across multiple queues (especially in the
28.172 + * presence of GC cardmarking). Also, to improve thread-locality,
28.173 + * queues are initialized after starting.
28.174 + */
28.175 +
28.176 + /**
28.177 + * Mask for pool indices encoded as shorts
28.178 + */
28.179 + private static final int SMASK = 0xffff;
28.180 +
28.181 + /**
28.182 + * Capacity of work-stealing queue array upon initialization.
28.183 + * Must be a power of two. Initial size must be at least 4, but is
28.184 + * padded to minimize cache effects.
28.185 + */
28.186 + private static final int INITIAL_QUEUE_CAPACITY = 1 << 13;
28.187 +
28.188 + /**
28.189 + * Maximum size for queue array. Must be a power of two
28.190 + * less than or equal to 1 << (31 - width of array entry) to
28.191 + * ensure lack of index wraparound, but is capped at a lower
28.192 + * value to help users trap runaway computations.
28.193 + */
28.194 + private static final int MAXIMUM_QUEUE_CAPACITY = 1 << 24; // 16M
28.195 +
28.196 + /**
28.197 + * The work-stealing queue array. Size must be a power of two.
28.198 + * Initialized when started (as oposed to when constructed), to
28.199 + * improve memory locality.
28.200 + */
28.201 + ForkJoinTask<?>[] queue;
28.202 +
28.203 + /**
28.204 + * The pool this thread works in. Accessed directly by ForkJoinTask.
28.205 + */
28.206 + final ForkJoinPool pool;
28.207 +
28.208 + /**
28.209 + * Index (mod queue.length) of next queue slot to push to or pop
28.210 + * from. It is written only by owner thread, and accessed by other
28.211 + * threads only after reading (volatile) queueBase. Both queueTop
28.212 + * and queueBase are allowed to wrap around on overflow, but
28.213 + * (queueTop - queueBase) still estimates size.
28.214 + */
28.215 + int queueTop;
28.216 +
28.217 + /**
28.218 + * Index (mod queue.length) of least valid queue slot, which is
28.219 + * always the next position to steal from if nonempty.
28.220 + */
28.221 + volatile int queueBase;
28.222 +
28.223 + /**
28.224 + * The index of most recent stealer, used as a hint to avoid
28.225 + * traversal in method helpJoinTask. This is only a hint because a
28.226 + * worker might have had multiple steals and this only holds one
28.227 + * of them (usually the most current). Declared non-volatile,
28.228 + * relying on other prevailing sync to keep reasonably current.
28.229 + */
28.230 + int stealHint;
28.231 +
28.232 + /**
28.233 + * Index of this worker in pool array. Set once by pool before
28.234 + * running, and accessed directly by pool to locate this worker in
28.235 + * its workers array.
28.236 + */
28.237 + final int poolIndex;
28.238 +
28.239 + /**
28.240 + * Encoded record for pool task waits. Usages are always
28.241 + * surrounded by volatile reads/writes
28.242 + */
28.243 + int nextWait;
28.244 +
28.245 + /**
28.246 + * Complement of poolIndex, offset by count of entries of task
28.247 + * waits. Accessed by ForkJoinPool to manage event waiters.
28.248 + */
28.249 + volatile int eventCount;
28.250 +
28.251 + /**
28.252 + * Seed for random number generator for choosing steal victims.
28.253 + * Uses Marsaglia xorshift. Must be initialized as nonzero.
28.254 + */
28.255 + int seed;
28.256 +
28.257 + /**
28.258 + * Number of steals. Directly accessed (and reset) by pool when
28.259 + * idle.
28.260 + */
28.261 + int stealCount;
28.262 +
28.263 + /**
28.264 + * True if this worker should or did terminate
28.265 + */
28.266 + volatile boolean terminate;
28.267 +
28.268 + /**
28.269 + * Set to true before LockSupport.park; false on return
28.270 + */
28.271 + volatile boolean parked;
28.272 +
28.273 + /**
28.274 + * True if use local fifo, not default lifo, for local polling.
28.275 + * Shadows value from ForkJoinPool.
28.276 + */
28.277 + final boolean locallyFifo;
28.278 +
28.279 + /**
28.280 + * The task most recently stolen from another worker (or
28.281 + * submission queue). All uses are surrounded by enough volatile
28.282 + * reads/writes to maintain as non-volatile.
28.283 + */
28.284 + ForkJoinTask<?> currentSteal;
28.285 +
28.286 + /**
28.287 + * The task currently being joined, set only when actively trying
28.288 + * to help other stealers in helpJoinTask. All uses are surrounded
28.289 + * by enough volatile reads/writes to maintain as non-volatile.
28.290 + */
28.291 + ForkJoinTask<?> currentJoin;
28.292 +
28.293 + /**
28.294 + * Creates a ForkJoinWorkerThread operating in the given pool.
28.295 + *
28.296 + * @param pool the pool this thread works in
28.297 + * @throws NullPointerException if pool is null
28.298 + */
28.299 + protected ForkJoinWorkerThread(ForkJoinPool pool) {
28.300 + super(pool.nextWorkerName());
28.301 + this.pool = pool;
28.302 + int k = pool.registerWorker(this);
28.303 + poolIndex = k;
28.304 + eventCount = ~k & SMASK; // clear wait count
28.305 + locallyFifo = pool.locallyFifo;
28.306 + Thread.UncaughtExceptionHandler ueh = pool.ueh;
28.307 + if (ueh != null)
28.308 + setUncaughtExceptionHandler(ueh);
28.309 + setDaemon(true);
28.310 + }
28.311 +
28.312 + // Public methods
28.313 +
28.314 + /**
28.315 + * Returns the pool hosting this thread.
28.316 + *
28.317 + * @return the pool
28.318 + */
28.319 + public ForkJoinPool getPool() {
28.320 + return pool;
28.321 + }
28.322 +
28.323 + /**
28.324 + * Returns the index number of this thread in its pool. The
28.325 + * returned value ranges from zero to the maximum number of
28.326 + * threads (minus one) that have ever been created in the pool.
28.327 + * This method may be useful for applications that track status or
28.328 + * collect results per-worker rather than per-task.
28.329 + *
28.330 + * @return the index number
28.331 + */
28.332 + public int getPoolIndex() {
28.333 + return poolIndex;
28.334 + }
28.335 +
28.336 + // Randomization
28.337 +
28.338 + /**
28.339 + * Computes next value for random victim probes and backoffs.
28.340 + * Scans don't require a very high quality generator, but also not
28.341 + * a crummy one. Marsaglia xor-shift is cheap and works well
28.342 + * enough. Note: This is manually inlined in FJP.scan() to avoid
28.343 + * writes inside busy loops.
28.344 + */
28.345 + private int nextSeed() {
28.346 + int r = seed;
28.347 + r ^= r << 13;
28.348 + r ^= r >>> 17;
28.349 + r ^= r << 5;
28.350 + return seed = r;
28.351 + }
28.352 +
28.353 + // Run State management
28.354 +
28.355 + /**
28.356 + * Initializes internal state after construction but before
28.357 + * processing any tasks. If you override this method, you must
28.358 + * invoke {@code super.onStart()} at the beginning of the method.
28.359 + * Initialization requires care: Most fields must have legal
28.360 + * default values, to ensure that attempted accesses from other
28.361 + * threads work correctly even before this thread starts
28.362 + * processing tasks.
28.363 + */
28.364 + protected void onStart() {
28.365 + queue = new ForkJoinTask<?>[INITIAL_QUEUE_CAPACITY];
28.366 + int r = pool.workerSeedGenerator.nextInt();
28.367 + seed = (r == 0) ? 1 : r; // must be nonzero
28.368 + }
28.369 +
28.370 + /**
28.371 + * Performs cleanup associated with termination of this worker
28.372 + * thread. If you override this method, you must invoke
28.373 + * {@code super.onTermination} at the end of the overridden method.
28.374 + *
28.375 + * @param exception the exception causing this thread to abort due
28.376 + * to an unrecoverable error, or {@code null} if completed normally
28.377 + */
28.378 + protected void onTermination(Throwable exception) {
28.379 + try {
28.380 + terminate = true;
28.381 + cancelTasks();
28.382 + pool.deregisterWorker(this, exception);
28.383 + } catch (Throwable ex) { // Shouldn't ever happen
28.384 + if (exception == null) // but if so, at least rethrown
28.385 + exception = ex;
28.386 + } finally {
28.387 + if (exception != null)
28.388 + UNSAFE.throwException(exception);
28.389 + }
28.390 + }
28.391 +
28.392 + /**
28.393 + * This method is required to be public, but should never be
28.394 + * called explicitly. It performs the main run loop to execute
28.395 + * {@link ForkJoinTask}s.
28.396 + */
28.397 + public void run() {
28.398 + Throwable exception = null;
28.399 + try {
28.400 + onStart();
28.401 + pool.work(this);
28.402 + } catch (Throwable ex) {
28.403 + exception = ex;
28.404 + } finally {
28.405 + onTermination(exception);
28.406 + }
28.407 + }
28.408 +
28.409 + /*
28.410 + * Intrinsics-based atomic writes for queue slots. These are
28.411 + * basically the same as methods in AtomicReferenceArray, but
28.412 + * specialized for (1) ForkJoinTask elements (2) requirement that
28.413 + * nullness and bounds checks have already been performed by
28.414 + * callers and (3) effective offsets are known not to overflow
28.415 + * from int to long (because of MAXIMUM_QUEUE_CAPACITY). We don't
28.416 + * need corresponding version for reads: plain array reads are OK
28.417 + * because they are protected by other volatile reads and are
28.418 + * confirmed by CASes.
28.419 + *
28.420 + * Most uses don't actually call these methods, but instead
28.421 + * contain inlined forms that enable more predictable
28.422 + * optimization. We don't define the version of write used in
28.423 + * pushTask at all, but instead inline there a store-fenced array
28.424 + * slot write.
28.425 + *
28.426 + * Also in most methods, as a performance (not correctness) issue,
28.427 + * we'd like to encourage compilers not to arbitrarily postpone
28.428 + * setting queueTop after writing slot. Currently there is no
28.429 + * intrinsic for arranging this, but using Unsafe putOrderedInt
28.430 + * may be a preferable strategy on some compilers even though its
28.431 + * main effect is a pre-, not post- fence. To simplify possible
28.432 + * changes, the option is left in comments next to the associated
28.433 + * assignments.
28.434 + */
28.435 +
28.436 + /**
28.437 + * CASes slot i of array q from t to null. Caller must ensure q is
28.438 + * non-null and index is in range.
28.439 + */
28.440 + private static final boolean casSlotNull(ForkJoinTask<?>[] q, int i,
28.441 + ForkJoinTask<?> t) {
28.442 + return UNSAFE.compareAndSwapObject(q, (i << ASHIFT) + ABASE, t, null);
28.443 + }
28.444 +
28.445 + /**
28.446 + * Performs a volatile write of the given task at given slot of
28.447 + * array q. Caller must ensure q is non-null and index is in
28.448 + * range. This method is used only during resets and backouts.
28.449 + */
28.450 + private static final void writeSlot(ForkJoinTask<?>[] q, int i,
28.451 + ForkJoinTask<?> t) {
28.452 + UNSAFE.putObjectVolatile(q, (i << ASHIFT) + ABASE, t);
28.453 + }
28.454 +
28.455 + // queue methods
28.456 +
28.457 + /**
28.458 + * Pushes a task. Call only from this thread.
28.459 + *
28.460 + * @param t the task. Caller must ensure non-null.
28.461 + */
28.462 + final void pushTask(ForkJoinTask<?> t) {
28.463 + ForkJoinTask<?>[] q; int s, m;
28.464 + if ((q = queue) != null) { // ignore if queue removed
28.465 + long u = (((s = queueTop) & (m = q.length - 1)) << ASHIFT) + ABASE;
28.466 + UNSAFE.putOrderedObject(q, u, t);
28.467 + queueTop = s + 1; // or use putOrderedInt
28.468 + if ((s -= queueBase) <= 2)
28.469 + pool.signalWork();
28.470 + else if (s == m)
28.471 + growQueue();
28.472 + }
28.473 + }
28.474 +
28.475 + /**
28.476 + * Creates or doubles queue array. Transfers elements by
28.477 + * emulating steals (deqs) from old array and placing, oldest
28.478 + * first, into new array.
28.479 + */
28.480 + private void growQueue() {
28.481 + ForkJoinTask<?>[] oldQ = queue;
28.482 + int size = oldQ != null ? oldQ.length << 1 : INITIAL_QUEUE_CAPACITY;
28.483 + if (size > MAXIMUM_QUEUE_CAPACITY)
28.484 + throw new RejectedExecutionException("Queue capacity exceeded");
28.485 + if (size < INITIAL_QUEUE_CAPACITY)
28.486 + size = INITIAL_QUEUE_CAPACITY;
28.487 + ForkJoinTask<?>[] q = queue = new ForkJoinTask<?>[size];
28.488 + int mask = size - 1;
28.489 + int top = queueTop;
28.490 + int oldMask;
28.491 + if (oldQ != null && (oldMask = oldQ.length - 1) >= 0) {
28.492 + for (int b = queueBase; b != top; ++b) {
28.493 + long u = ((b & oldMask) << ASHIFT) + ABASE;
28.494 + Object x = UNSAFE.getObjectVolatile(oldQ, u);
28.495 + if (x != null && UNSAFE.compareAndSwapObject(oldQ, u, x, null))
28.496 + UNSAFE.putObjectVolatile
28.497 + (q, ((b & mask) << ASHIFT) + ABASE, x);
28.498 + }
28.499 + }
28.500 + }
28.501 +
28.502 + /**
28.503 + * Tries to take a task from the base of the queue, failing if
28.504 + * empty or contended. Note: Specializations of this code appear
28.505 + * in locallyDeqTask and elsewhere.
28.506 + *
28.507 + * @return a task, or null if none or contended
28.508 + */
28.509 + final ForkJoinTask<?> deqTask() {
28.510 + ForkJoinTask<?> t; ForkJoinTask<?>[] q; int b, i;
28.511 + if (queueTop != (b = queueBase) &&
28.512 + (q = queue) != null && // must read q after b
28.513 + (i = (q.length - 1) & b) >= 0 &&
28.514 + (t = q[i]) != null && queueBase == b &&
28.515 + UNSAFE.compareAndSwapObject(q, (i << ASHIFT) + ABASE, t, null)) {
28.516 + queueBase = b + 1;
28.517 + return t;
28.518 + }
28.519 + return null;
28.520 + }
28.521 +
28.522 + /**
28.523 + * Tries to take a task from the base of own queue. Called only
28.524 + * by this thread.
28.525 + *
28.526 + * @return a task, or null if none
28.527 + */
28.528 + final ForkJoinTask<?> locallyDeqTask() {
28.529 + ForkJoinTask<?> t; int m, b, i;
28.530 + ForkJoinTask<?>[] q = queue;
28.531 + if (q != null && (m = q.length - 1) >= 0) {
28.532 + while (queueTop != (b = queueBase)) {
28.533 + if ((t = q[i = m & b]) != null &&
28.534 + queueBase == b &&
28.535 + UNSAFE.compareAndSwapObject(q, (i << ASHIFT) + ABASE,
28.536 + t, null)) {
28.537 + queueBase = b + 1;
28.538 + return t;
28.539 + }
28.540 + }
28.541 + }
28.542 + return null;
28.543 + }
28.544 +
28.545 + /**
28.546 + * Returns a popped task, or null if empty.
28.547 + * Called only by this thread.
28.548 + */
28.549 + private ForkJoinTask<?> popTask() {
28.550 + int m;
28.551 + ForkJoinTask<?>[] q = queue;
28.552 + if (q != null && (m = q.length - 1) >= 0) {
28.553 + for (int s; (s = queueTop) != queueBase;) {
28.554 + int i = m & --s;
28.555 + long u = (i << ASHIFT) + ABASE; // raw offset
28.556 + ForkJoinTask<?> t = q[i];
28.557 + if (t == null) // lost to stealer
28.558 + break;
28.559 + if (UNSAFE.compareAndSwapObject(q, u, t, null)) {
28.560 + queueTop = s; // or putOrderedInt
28.561 + return t;
28.562 + }
28.563 + }
28.564 + }
28.565 + return null;
28.566 + }
28.567 +
28.568 + /**
28.569 + * Specialized version of popTask to pop only if topmost element
28.570 + * is the given task. Called only by this thread.
28.571 + *
28.572 + * @param t the task. Caller must ensure non-null.
28.573 + */
28.574 + final boolean unpushTask(ForkJoinTask<?> t) {
28.575 + ForkJoinTask<?>[] q;
28.576 + int s;
28.577 + if ((q = queue) != null && (s = queueTop) != queueBase &&
28.578 + UNSAFE.compareAndSwapObject
28.579 + (q, (((q.length - 1) & --s) << ASHIFT) + ABASE, t, null)) {
28.580 + queueTop = s; // or putOrderedInt
28.581 + return true;
28.582 + }
28.583 + return false;
28.584 + }
28.585 +
28.586 + /**
28.587 + * Returns next task, or null if empty or contended.
28.588 + */
28.589 + final ForkJoinTask<?> peekTask() {
28.590 + int m;
28.591 + ForkJoinTask<?>[] q = queue;
28.592 + if (q == null || (m = q.length - 1) < 0)
28.593 + return null;
28.594 + int i = locallyFifo ? queueBase : (queueTop - 1);
28.595 + return q[i & m];
28.596 + }
28.597 +
28.598 + // Support methods for ForkJoinPool
28.599 +
28.600 + /**
28.601 + * Runs the given task, plus any local tasks until queue is empty
28.602 + */
28.603 + final void execTask(ForkJoinTask<?> t) {
28.604 + currentSteal = t;
28.605 + for (;;) {
28.606 + if (t != null)
28.607 + t.doExec();
28.608 + if (queueTop == queueBase)
28.609 + break;
28.610 + t = locallyFifo ? locallyDeqTask() : popTask();
28.611 + }
28.612 + ++stealCount;
28.613 + currentSteal = null;
28.614 + }
28.615 +
28.616 + /**
28.617 + * Removes and cancels all tasks in queue. Can be called from any
28.618 + * thread.
28.619 + */
28.620 + final void cancelTasks() {
28.621 + ForkJoinTask<?> cj = currentJoin; // try to cancel ongoing tasks
28.622 + if (cj != null && cj.status >= 0)
28.623 + cj.cancelIgnoringExceptions();
28.624 + ForkJoinTask<?> cs = currentSteal;
28.625 + if (cs != null && cs.status >= 0)
28.626 + cs.cancelIgnoringExceptions();
28.627 + while (queueBase != queueTop) {
28.628 + ForkJoinTask<?> t = deqTask();
28.629 + if (t != null)
28.630 + t.cancelIgnoringExceptions();
28.631 + }
28.632 + }
28.633 +
28.634 + /**
28.635 + * Drains tasks to given collection c.
28.636 + *
28.637 + * @return the number of tasks drained
28.638 + */
28.639 + final int drainTasksTo(Collection<? super ForkJoinTask<?>> c) {
28.640 + int n = 0;
28.641 + while (queueBase != queueTop) {
28.642 + ForkJoinTask<?> t = deqTask();
28.643 + if (t != null) {
28.644 + c.add(t);
28.645 + ++n;
28.646 + }
28.647 + }
28.648 + return n;
28.649 + }
28.650 +
28.651 + // Support methods for ForkJoinTask
28.652 +
28.653 + /**
28.654 + * Returns an estimate of the number of tasks in the queue.
28.655 + */
28.656 + final int getQueueSize() {
28.657 + return queueTop - queueBase;
28.658 + }
28.659 +
28.660 + /**
28.661 + * Gets and removes a local task.
28.662 + *
28.663 + * @return a task, if available
28.664 + */
28.665 + final ForkJoinTask<?> pollLocalTask() {
28.666 + return locallyFifo ? locallyDeqTask() : popTask();
28.667 + }
28.668 +
28.669 + /**
28.670 + * Gets and removes a local or stolen task.
28.671 + *
28.672 + * @return a task, if available
28.673 + */
28.674 + final ForkJoinTask<?> pollTask() {
28.675 + ForkJoinWorkerThread[] ws;
28.676 + ForkJoinTask<?> t = pollLocalTask();
28.677 + if (t != null || (ws = pool.workers) == null)
28.678 + return t;
28.679 + int n = ws.length; // cheap version of FJP.scan
28.680 + int steps = n << 1;
28.681 + int r = nextSeed();
28.682 + int i = 0;
28.683 + while (i < steps) {
28.684 + ForkJoinWorkerThread w = ws[(i++ + r) & (n - 1)];
28.685 + if (w != null && w.queueBase != w.queueTop && w.queue != null) {
28.686 + if ((t = w.deqTask()) != null)
28.687 + return t;
28.688 + i = 0;
28.689 + }
28.690 + }
28.691 + return null;
28.692 + }
28.693 +
28.694 + /**
28.695 + * The maximum stolen->joining link depth allowed in helpJoinTask,
28.696 + * as well as the maximum number of retries (allowing on average
28.697 + * one staleness retry per level) per attempt to instead try
28.698 + * compensation. Depths for legitimate chains are unbounded, but
28.699 + * we use a fixed constant to avoid (otherwise unchecked) cycles
28.700 + * and bound staleness of traversal parameters at the expense of
28.701 + * sometimes blocking when we could be helping.
28.702 + */
28.703 + private static final int MAX_HELP = 16;
28.704 +
28.705 + /**
28.706 + * Possibly runs some tasks and/or blocks, until joinMe is done.
28.707 + *
28.708 + * @param joinMe the task to join
28.709 + * @return completion status on exit
28.710 + */
28.711 + final int joinTask(ForkJoinTask<?> joinMe) {
28.712 + ForkJoinTask<?> prevJoin = currentJoin;
28.713 + currentJoin = joinMe;
28.714 + for (int s, retries = MAX_HELP;;) {
28.715 + if ((s = joinMe.status) < 0) {
28.716 + currentJoin = prevJoin;
28.717 + return s;
28.718 + }
28.719 + if (retries > 0) {
28.720 + if (queueTop != queueBase) {
28.721 + if (!localHelpJoinTask(joinMe))
28.722 + retries = 0; // cannot help
28.723 + }
28.724 + else if (retries == MAX_HELP >>> 1) {
28.725 + --retries; // check uncommon case
28.726 + if (tryDeqAndExec(joinMe) >= 0)
28.727 + Thread.yield(); // for politeness
28.728 + }
28.729 + else
28.730 + retries = helpJoinTask(joinMe) ? MAX_HELP : retries - 1;
28.731 + }
28.732 + else {
28.733 + retries = MAX_HELP; // restart if not done
28.734 + pool.tryAwaitJoin(joinMe);
28.735 + }
28.736 + }
28.737 + }
28.738 +
28.739 + /**
28.740 + * If present, pops and executes the given task, or any other
28.741 + * cancelled task
28.742 + *
28.743 + * @return false if any other non-cancelled task exists in local queue
28.744 + */
28.745 + private boolean localHelpJoinTask(ForkJoinTask<?> joinMe) {
28.746 + int s, i; ForkJoinTask<?>[] q; ForkJoinTask<?> t;
28.747 + if ((s = queueTop) != queueBase && (q = queue) != null &&
28.748 + (i = (q.length - 1) & --s) >= 0 &&
28.749 + (t = q[i]) != null) {
28.750 + if (t != joinMe && t.status >= 0)
28.751 + return false;
28.752 + if (UNSAFE.compareAndSwapObject
28.753 + (q, (i << ASHIFT) + ABASE, t, null)) {
28.754 + queueTop = s; // or putOrderedInt
28.755 + t.doExec();
28.756 + }
28.757 + }
28.758 + return true;
28.759 + }
28.760 +
28.761 + /**
28.762 + * Tries to locate and execute tasks for a stealer of the given
28.763 + * task, or in turn one of its stealers, Traces
28.764 + * currentSteal->currentJoin links looking for a thread working on
28.765 + * a descendant of the given task and with a non-empty queue to
28.766 + * steal back and execute tasks from. The implementation is very
28.767 + * branchy to cope with potential inconsistencies or loops
28.768 + * encountering chains that are stale, unknown, or of length
28.769 + * greater than MAX_HELP links. All of these cases are dealt with
28.770 + * by just retrying by caller.
28.771 + *
28.772 + * @param joinMe the task to join
28.773 + * @param canSteal true if local queue is empty
28.774 + * @return true if ran a task
28.775 + */
28.776 + private boolean helpJoinTask(ForkJoinTask<?> joinMe) {
28.777 + boolean helped = false;
28.778 + int m = pool.scanGuard & SMASK;
28.779 + ForkJoinWorkerThread[] ws = pool.workers;
28.780 + if (ws != null && ws.length > m && joinMe.status >= 0) {
28.781 + int levels = MAX_HELP; // remaining chain length
28.782 + ForkJoinTask<?> task = joinMe; // base of chain
28.783 + outer:for (ForkJoinWorkerThread thread = this;;) {
28.784 + // Try to find v, the stealer of task, by first using hint
28.785 + ForkJoinWorkerThread v = ws[thread.stealHint & m];
28.786 + if (v == null || v.currentSteal != task) {
28.787 + for (int j = 0; ;) { // search array
28.788 + if ((v = ws[j]) != null && v.currentSteal == task) {
28.789 + thread.stealHint = j;
28.790 + break; // save hint for next time
28.791 + }
28.792 + if (++j > m)
28.793 + break outer; // can't find stealer
28.794 + }
28.795 + }
28.796 + // Try to help v, using specialized form of deqTask
28.797 + for (;;) {
28.798 + ForkJoinTask<?>[] q; int b, i;
28.799 + if (joinMe.status < 0)
28.800 + break outer;
28.801 + if ((b = v.queueBase) == v.queueTop ||
28.802 + (q = v.queue) == null ||
28.803 + (i = (q.length-1) & b) < 0)
28.804 + break; // empty
28.805 + long u = (i << ASHIFT) + ABASE;
28.806 + ForkJoinTask<?> t = q[i];
28.807 + if (task.status < 0)
28.808 + break outer; // stale
28.809 + if (t != null && v.queueBase == b &&
28.810 + UNSAFE.compareAndSwapObject(q, u, t, null)) {
28.811 + v.queueBase = b + 1;
28.812 + v.stealHint = poolIndex;
28.813 + ForkJoinTask<?> ps = currentSteal;
28.814 + currentSteal = t;
28.815 + t.doExec();
28.816 + currentSteal = ps;
28.817 + helped = true;
28.818 + }
28.819 + }
28.820 + // Try to descend to find v's stealer
28.821 + ForkJoinTask<?> next = v.currentJoin;
28.822 + if (--levels > 0 && task.status >= 0 &&
28.823 + next != null && next != task) {
28.824 + task = next;
28.825 + thread = v;
28.826 + }
28.827 + else
28.828 + break; // max levels, stale, dead-end, or cyclic
28.829 + }
28.830 + }
28.831 + return helped;
28.832 + }
28.833 +
28.834 + /**
28.835 + * Performs an uncommon case for joinTask: If task t is at base of
28.836 + * some workers queue, steals and executes it.
28.837 + *
28.838 + * @param t the task
28.839 + * @return t's status
28.840 + */
28.841 + private int tryDeqAndExec(ForkJoinTask<?> t) {
28.842 + int m = pool.scanGuard & SMASK;
28.843 + ForkJoinWorkerThread[] ws = pool.workers;
28.844 + if (ws != null && ws.length > m && t.status >= 0) {
28.845 + for (int j = 0; j <= m; ++j) {
28.846 + ForkJoinTask<?>[] q; int b, i;
28.847 + ForkJoinWorkerThread v = ws[j];
28.848 + if (v != null &&
28.849 + (b = v.queueBase) != v.queueTop &&
28.850 + (q = v.queue) != null &&
28.851 + (i = (q.length - 1) & b) >= 0 &&
28.852 + q[i] == t) {
28.853 + long u = (i << ASHIFT) + ABASE;
28.854 + if (v.queueBase == b &&
28.855 + UNSAFE.compareAndSwapObject(q, u, t, null)) {
28.856 + v.queueBase = b + 1;
28.857 + v.stealHint = poolIndex;
28.858 + ForkJoinTask<?> ps = currentSteal;
28.859 + currentSteal = t;
28.860 + t.doExec();
28.861 + currentSteal = ps;
28.862 + }
28.863 + break;
28.864 + }
28.865 + }
28.866 + }
28.867 + return t.status;
28.868 + }
28.869 +
28.870 + /**
28.871 + * Implements ForkJoinTask.getSurplusQueuedTaskCount(). Returns
28.872 + * an estimate of the number of tasks, offset by a function of
28.873 + * number of idle workers.
28.874 + *
28.875 + * This method provides a cheap heuristic guide for task
28.876 + * partitioning when programmers, frameworks, tools, or languages
28.877 + * have little or no idea about task granularity. In essence by
28.878 + * offering this method, we ask users only about tradeoffs in
28.879 + * overhead vs expected throughput and its variance, rather than
28.880 + * how finely to partition tasks.
28.881 + *
28.882 + * In a steady state strict (tree-structured) computation, each
28.883 + * thread makes available for stealing enough tasks for other
28.884 + * threads to remain active. Inductively, if all threads play by
28.885 + * the same rules, each thread should make available only a
28.886 + * constant number of tasks.
28.887 + *
28.888 + * The minimum useful constant is just 1. But using a value of 1
28.889 + * would require immediate replenishment upon each steal to
28.890 + * maintain enough tasks, which is infeasible. Further,
28.891 + * partitionings/granularities of offered tasks should minimize
28.892 + * steal rates, which in general means that threads nearer the top
28.893 + * of computation tree should generate more than those nearer the
28.894 + * bottom. In perfect steady state, each thread is at
28.895 + * approximately the same level of computation tree. However,
28.896 + * producing extra tasks amortizes the uncertainty of progress and
28.897 + * diffusion assumptions.
28.898 + *
28.899 + * So, users will want to use values larger, but not much larger
28.900 + * than 1 to both smooth over transient shortages and hedge
28.901 + * against uneven progress; as traded off against the cost of
28.902 + * extra task overhead. We leave the user to pick a threshold
28.903 + * value to compare with the results of this call to guide
28.904 + * decisions, but recommend values such as 3.
28.905 + *
28.906 + * When all threads are active, it is on average OK to estimate
28.907 + * surplus strictly locally. In steady-state, if one thread is
28.908 + * maintaining say 2 surplus tasks, then so are others. So we can
28.909 + * just use estimated queue length (although note that (queueTop -
28.910 + * queueBase) can be an overestimate because of stealers lagging
28.911 + * increments of queueBase). However, this strategy alone leads
28.912 + * to serious mis-estimates in some non-steady-state conditions
28.913 + * (ramp-up, ramp-down, other stalls). We can detect many of these
28.914 + * by further considering the number of "idle" threads, that are
28.915 + * known to have zero queued tasks, so compensate by a factor of
28.916 + * (#idle/#active) threads.
28.917 + */
28.918 + final int getEstimatedSurplusTaskCount() {
28.919 + return queueTop - queueBase - pool.idlePerActive();
28.920 + }
28.921 +
28.922 + /**
28.923 + * Runs tasks until {@code pool.isQuiescent()}. We piggyback on
28.924 + * pool's active count ctl maintenance, but rather than blocking
28.925 + * when tasks cannot be found, we rescan until all others cannot
28.926 + * find tasks either. The bracketing by pool quiescerCounts
28.927 + * updates suppresses pool auto-shutdown mechanics that could
28.928 + * otherwise prematurely terminate the pool because all threads
28.929 + * appear to be inactive.
28.930 + */
28.931 + final void helpQuiescePool() {
28.932 + boolean active = true;
28.933 + ForkJoinTask<?> ps = currentSteal; // to restore below
28.934 + ForkJoinPool p = pool;
28.935 + p.addQuiescerCount(1);
28.936 + for (;;) {
28.937 + ForkJoinWorkerThread[] ws = p.workers;
28.938 + ForkJoinWorkerThread v = null;
28.939 + int n;
28.940 + if (queueTop != queueBase)
28.941 + v = this;
28.942 + else if (ws != null && (n = ws.length) > 1) {
28.943 + ForkJoinWorkerThread w;
28.944 + int r = nextSeed(); // cheap version of FJP.scan
28.945 + int steps = n << 1;
28.946 + for (int i = 0; i < steps; ++i) {
28.947 + if ((w = ws[(i + r) & (n - 1)]) != null &&
28.948 + w.queueBase != w.queueTop) {
28.949 + v = w;
28.950 + break;
28.951 + }
28.952 + }
28.953 + }
28.954 + if (v != null) {
28.955 + ForkJoinTask<?> t;
28.956 + if (!active) {
28.957 + active = true;
28.958 + p.addActiveCount(1);
28.959 + }
28.960 + if ((t = (v != this) ? v.deqTask() :
28.961 + locallyFifo ? locallyDeqTask() : popTask()) != null) {
28.962 + currentSteal = t;
28.963 + t.doExec();
28.964 + currentSteal = ps;
28.965 + }
28.966 + }
28.967 + else {
28.968 + if (active) {
28.969 + active = false;
28.970 + p.addActiveCount(-1);
28.971 + }
28.972 + if (p.isQuiescent()) {
28.973 + p.addActiveCount(1);
28.974 + p.addQuiescerCount(-1);
28.975 + break;
28.976 + }
28.977 + }
28.978 + }
28.979 + }
28.980 +
28.981 + // Unsafe mechanics
28.982 + private static final sun.misc.Unsafe UNSAFE;
28.983 + private static final long ABASE;
28.984 + private static final int ASHIFT;
28.985 +
28.986 + static {
28.987 + int s;
28.988 + try {
28.989 + UNSAFE = sun.misc.Unsafe.getUnsafe();
28.990 + Class a = ForkJoinTask[].class;
28.991 + ABASE = UNSAFE.arrayBaseOffset(a);
28.992 + s = UNSAFE.arrayIndexScale(a);
28.993 + } catch (Exception e) {
28.994 + throw new Error(e);
28.995 + }
28.996 + if ((s & (s-1)) != 0)
28.997 + throw new Error("data type scale not a power of two");
28.998 + ASHIFT = 31 - Integer.numberOfLeadingZeros(s);
28.999 + }
28.1000 +
28.1001 +}
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
29.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/Future.java Sat Mar 19 10:46:31 2016 +0100
29.3 @@ -0,0 +1,169 @@
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 +/**
29.42 + * A <tt>Future</tt> represents the result of an asynchronous
29.43 + * computation. Methods are provided to check if the computation is
29.44 + * complete, to wait for its completion, and to retrieve the result of
29.45 + * the computation. The result can only be retrieved using method
29.46 + * <tt>get</tt> when the computation has completed, blocking if
29.47 + * necessary until it is ready. Cancellation is performed by the
29.48 + * <tt>cancel</tt> method. Additional methods are provided to
29.49 + * determine if the task completed normally or was cancelled. Once a
29.50 + * computation has completed, the computation cannot be cancelled.
29.51 + * If you would like to use a <tt>Future</tt> for the sake
29.52 + * of cancellability but not provide a usable result, you can
29.53 + * declare types of the form {@code Future<?>} and
29.54 + * return <tt>null</tt> as a result of the underlying task.
29.55 + *
29.56 + * <p>
29.57 + * <b>Sample Usage</b> (Note that the following classes are all
29.58 + * made-up.) <p>
29.59 + * <pre> {@code
29.60 + * interface ArchiveSearcher { String search(String target); }
29.61 + * class App {
29.62 + * ExecutorService executor = ...
29.63 + * ArchiveSearcher searcher = ...
29.64 + * void showSearch(final String target)
29.65 + * throws InterruptedException {
29.66 + * Future<String> future
29.67 + * = executor.submit(new Callable<String>() {
29.68 + * public String call() {
29.69 + * return searcher.search(target);
29.70 + * }});
29.71 + * displayOtherThings(); // do other things while searching
29.72 + * try {
29.73 + * displayText(future.get()); // use future
29.74 + * } catch (ExecutionException ex) { cleanup(); return; }
29.75 + * }
29.76 + * }}</pre>
29.77 + *
29.78 + * The {@link FutureTask} class is an implementation of <tt>Future</tt> that
29.79 + * implements <tt>Runnable</tt>, and so may be executed by an <tt>Executor</tt>.
29.80 + * For example, the above construction with <tt>submit</tt> could be replaced by:
29.81 + * <pre> {@code
29.82 + * FutureTask<String> future =
29.83 + * new FutureTask<String>(new Callable<String>() {
29.84 + * public String call() {
29.85 + * return searcher.search(target);
29.86 + * }});
29.87 + * executor.execute(future);}</pre>
29.88 + *
29.89 + * <p>Memory consistency effects: Actions taken by the asynchronous computation
29.90 + * <a href="package-summary.html#MemoryVisibility"> <i>happen-before</i></a>
29.91 + * actions following the corresponding {@code Future.get()} in another thread.
29.92 + *
29.93 + * @see FutureTask
29.94 + * @see Executor
29.95 + * @since 1.5
29.96 + * @author Doug Lea
29.97 + * @param <V> The result type returned by this Future's <tt>get</tt> method
29.98 + */
29.99 +public interface Future<V> {
29.100 +
29.101 + /**
29.102 + * Attempts to cancel execution of this task. This attempt will
29.103 + * fail if the task has already completed, has already been cancelled,
29.104 + * or could not be cancelled for some other reason. If successful,
29.105 + * and this task has not started when <tt>cancel</tt> is called,
29.106 + * this task should never run. If the task has already started,
29.107 + * then the <tt>mayInterruptIfRunning</tt> parameter determines
29.108 + * whether the thread executing this task should be interrupted in
29.109 + * an attempt to stop the task.
29.110 + *
29.111 + * <p>After this method returns, subsequent calls to {@link #isDone} will
29.112 + * always return <tt>true</tt>. Subsequent calls to {@link #isCancelled}
29.113 + * will always return <tt>true</tt> if this method returned <tt>true</tt>.
29.114 + *
29.115 + * @param mayInterruptIfRunning <tt>true</tt> if the thread executing this
29.116 + * task should be interrupted; otherwise, in-progress tasks are allowed
29.117 + * to complete
29.118 + * @return <tt>false</tt> if the task could not be cancelled,
29.119 + * typically because it has already completed normally;
29.120 + * <tt>true</tt> otherwise
29.121 + */
29.122 + boolean cancel(boolean mayInterruptIfRunning);
29.123 +
29.124 + /**
29.125 + * Returns <tt>true</tt> if this task was cancelled before it completed
29.126 + * normally.
29.127 + *
29.128 + * @return <tt>true</tt> if this task was cancelled before it completed
29.129 + */
29.130 + boolean isCancelled();
29.131 +
29.132 + /**
29.133 + * Returns <tt>true</tt> if this task completed.
29.134 + *
29.135 + * Completion may be due to normal termination, an exception, or
29.136 + * cancellation -- in all of these cases, this method will return
29.137 + * <tt>true</tt>.
29.138 + *
29.139 + * @return <tt>true</tt> if this task completed
29.140 + */
29.141 + boolean isDone();
29.142 +
29.143 + /**
29.144 + * Waits if necessary for the computation to complete, and then
29.145 + * retrieves its result.
29.146 + *
29.147 + * @return the computed result
29.148 + * @throws CancellationException if the computation was cancelled
29.149 + * @throws ExecutionException if the computation threw an
29.150 + * exception
29.151 + * @throws InterruptedException if the current thread was interrupted
29.152 + * while waiting
29.153 + */
29.154 + V get() throws InterruptedException, ExecutionException;
29.155 +
29.156 + /**
29.157 + * Waits if necessary for at most the given time for the computation
29.158 + * to complete, and then retrieves its result, if available.
29.159 + *
29.160 + * @param timeout the maximum time to wait
29.161 + * @param unit the time unit of the timeout argument
29.162 + * @return the computed result
29.163 + * @throws CancellationException if the computation was cancelled
29.164 + * @throws ExecutionException if the computation threw an
29.165 + * exception
29.166 + * @throws InterruptedException if the current thread was interrupted
29.167 + * while waiting
29.168 + * @throws TimeoutException if the wait timed out
29.169 + */
29.170 + V get(long timeout, TimeUnit unit)
29.171 + throws InterruptedException, ExecutionException, TimeoutException;
29.172 +}
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
30.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/FutureTask.java Sat Mar 19 10:46:31 2016 +0100
30.3 @@ -0,0 +1,360 @@
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 +import java.util.concurrent.locks.*;
30.41 +
30.42 +/**
30.43 + * A cancellable asynchronous computation. This class provides a base
30.44 + * implementation of {@link Future}, with methods to start and cancel
30.45 + * a computation, query to see if the computation is complete, and
30.46 + * retrieve the result of the computation. The result can only be
30.47 + * retrieved when the computation has completed; the <tt>get</tt>
30.48 + * method will block if the computation has not yet completed. Once
30.49 + * the computation has completed, the computation cannot be restarted
30.50 + * or cancelled.
30.51 + *
30.52 + * <p>A <tt>FutureTask</tt> can be used to wrap a {@link Callable} or
30.53 + * {@link java.lang.Runnable} object. Because <tt>FutureTask</tt>
30.54 + * implements <tt>Runnable</tt>, a <tt>FutureTask</tt> can be
30.55 + * submitted to an {@link Executor} for execution.
30.56 + *
30.57 + * <p>In addition to serving as a standalone class, this class provides
30.58 + * <tt>protected</tt> functionality that may be useful when creating
30.59 + * customized task classes.
30.60 + *
30.61 + * @since 1.5
30.62 + * @author Doug Lea
30.63 + * @param <V> The result type returned by this FutureTask's <tt>get</tt> method
30.64 + */
30.65 +public class FutureTask<V> implements RunnableFuture<V> {
30.66 + /** Synchronization control for FutureTask */
30.67 + private final Sync sync;
30.68 +
30.69 + /**
30.70 + * Creates a <tt>FutureTask</tt> that will, upon running, execute the
30.71 + * given <tt>Callable</tt>.
30.72 + *
30.73 + * @param callable the callable task
30.74 + * @throws NullPointerException if callable is null
30.75 + */
30.76 + public FutureTask(Callable<V> callable) {
30.77 + if (callable == null)
30.78 + throw new NullPointerException();
30.79 + sync = new Sync(callable);
30.80 + }
30.81 +
30.82 + /**
30.83 + * Creates a <tt>FutureTask</tt> that will, upon running, execute the
30.84 + * given <tt>Runnable</tt>, and arrange that <tt>get</tt> will return the
30.85 + * given result on successful completion.
30.86 + *
30.87 + * @param runnable the runnable task
30.88 + * @param result the result to return on successful completion. If
30.89 + * you don't need a particular result, consider using
30.90 + * constructions of the form:
30.91 + * {@code Future<?> f = new FutureTask<Void>(runnable, null)}
30.92 + * @throws NullPointerException if runnable is null
30.93 + */
30.94 + public FutureTask(Runnable runnable, V result) {
30.95 + sync = new Sync(Executors.callable(runnable, result));
30.96 + }
30.97 +
30.98 + public boolean isCancelled() {
30.99 + return sync.innerIsCancelled();
30.100 + }
30.101 +
30.102 + public boolean isDone() {
30.103 + return sync.innerIsDone();
30.104 + }
30.105 +
30.106 + public boolean cancel(boolean mayInterruptIfRunning) {
30.107 + return sync.innerCancel(mayInterruptIfRunning);
30.108 + }
30.109 +
30.110 + /**
30.111 + * @throws CancellationException {@inheritDoc}
30.112 + */
30.113 + public V get() throws InterruptedException, ExecutionException {
30.114 + return sync.innerGet();
30.115 + }
30.116 +
30.117 + /**
30.118 + * @throws CancellationException {@inheritDoc}
30.119 + */
30.120 + public V get(long timeout, TimeUnit unit)
30.121 + throws InterruptedException, ExecutionException, TimeoutException {
30.122 + return sync.innerGet(unit.toNanos(timeout));
30.123 + }
30.124 +
30.125 + /**
30.126 + * Protected method invoked when this task transitions to state
30.127 + * <tt>isDone</tt> (whether normally or via cancellation). The
30.128 + * default implementation does nothing. Subclasses may override
30.129 + * this method to invoke completion callbacks or perform
30.130 + * bookkeeping. Note that you can query status inside the
30.131 + * implementation of this method to determine whether this task
30.132 + * has been cancelled.
30.133 + */
30.134 + protected void done() { }
30.135 +
30.136 + /**
30.137 + * Sets the result of this Future to the given value unless
30.138 + * this future has already been set or has been cancelled.
30.139 + * This method is invoked internally by the <tt>run</tt> method
30.140 + * upon successful completion of the computation.
30.141 + * @param v the value
30.142 + */
30.143 + protected void set(V v) {
30.144 + sync.innerSet(v);
30.145 + }
30.146 +
30.147 + /**
30.148 + * Causes this future to report an <tt>ExecutionException</tt>
30.149 + * with the given throwable as its cause, unless this Future has
30.150 + * already been set or has been cancelled.
30.151 + * This method is invoked internally by the <tt>run</tt> method
30.152 + * upon failure of the computation.
30.153 + * @param t the cause of failure
30.154 + */
30.155 + protected void setException(Throwable t) {
30.156 + sync.innerSetException(t);
30.157 + }
30.158 +
30.159 + // The following (duplicated) doc comment can be removed once
30.160 + //
30.161 + // 6270645: Javadoc comments should be inherited from most derived
30.162 + // superinterface or superclass
30.163 + // is fixed.
30.164 + /**
30.165 + * Sets this Future to the result of its computation
30.166 + * unless it has been cancelled.
30.167 + */
30.168 + public void run() {
30.169 + sync.innerRun();
30.170 + }
30.171 +
30.172 + /**
30.173 + * Executes the computation without setting its result, and then
30.174 + * resets this Future to initial state, failing to do so if the
30.175 + * computation encounters an exception or is cancelled. This is
30.176 + * designed for use with tasks that intrinsically execute more
30.177 + * than once.
30.178 + * @return true if successfully run and reset
30.179 + */
30.180 + protected boolean runAndReset() {
30.181 + return sync.innerRunAndReset();
30.182 + }
30.183 +
30.184 + /**
30.185 + * Synchronization control for FutureTask. Note that this must be
30.186 + * a non-static inner class in order to invoke the protected
30.187 + * <tt>done</tt> method. For clarity, all inner class support
30.188 + * methods are same as outer, prefixed with "inner".
30.189 + *
30.190 + * Uses AQS sync state to represent run status
30.191 + */
30.192 + private final class Sync extends AbstractQueuedSynchronizer {
30.193 + private static final long serialVersionUID = -7828117401763700385L;
30.194 +
30.195 + /** State value representing that task is ready to run */
30.196 + private static final int READY = 0;
30.197 + /** State value representing that task is running */
30.198 + private static final int RUNNING = 1;
30.199 + /** State value representing that task ran */
30.200 + private static final int RAN = 2;
30.201 + /** State value representing that task was cancelled */
30.202 + private static final int CANCELLED = 4;
30.203 +
30.204 + /** The underlying callable */
30.205 + private final Callable<V> callable;
30.206 + /** The result to return from get() */
30.207 + private V result;
30.208 + /** The exception to throw from get() */
30.209 + private Throwable exception;
30.210 +
30.211 + /**
30.212 + * The thread running task. When nulled after set/cancel, this
30.213 + * indicates that the results are accessible. Must be
30.214 + * volatile, to ensure visibility upon completion.
30.215 + */
30.216 + private volatile Thread runner;
30.217 +
30.218 + Sync(Callable<V> callable) {
30.219 + this.callable = callable;
30.220 + }
30.221 +
30.222 + private boolean ranOrCancelled(int state) {
30.223 + return (state & (RAN | CANCELLED)) != 0;
30.224 + }
30.225 +
30.226 + /**
30.227 + * Implements AQS base acquire to succeed if ran or cancelled
30.228 + */
30.229 + protected int tryAcquireShared(int ignore) {
30.230 + return innerIsDone() ? 1 : -1;
30.231 + }
30.232 +
30.233 + /**
30.234 + * Implements AQS base release to always signal after setting
30.235 + * final done status by nulling runner thread.
30.236 + */
30.237 + protected boolean tryReleaseShared(int ignore) {
30.238 + runner = null;
30.239 + return true;
30.240 + }
30.241 +
30.242 + boolean innerIsCancelled() {
30.243 + return getState() == CANCELLED;
30.244 + }
30.245 +
30.246 + boolean innerIsDone() {
30.247 + return ranOrCancelled(getState()) && runner == null;
30.248 + }
30.249 +
30.250 + V innerGet() throws InterruptedException, ExecutionException {
30.251 + acquireSharedInterruptibly(0);
30.252 + if (getState() == CANCELLED)
30.253 + throw new CancellationException();
30.254 + if (exception != null)
30.255 + throw new ExecutionException(exception);
30.256 + return result;
30.257 + }
30.258 +
30.259 + V innerGet(long nanosTimeout) throws InterruptedException, ExecutionException, TimeoutException {
30.260 + if (!tryAcquireSharedNanos(0, nanosTimeout))
30.261 + throw new TimeoutException();
30.262 + if (getState() == CANCELLED)
30.263 + throw new CancellationException();
30.264 + if (exception != null)
30.265 + throw new ExecutionException(exception);
30.266 + return result;
30.267 + }
30.268 +
30.269 + void innerSet(V v) {
30.270 + for (;;) {
30.271 + int s = getState();
30.272 + if (s == RAN)
30.273 + return;
30.274 + if (s == CANCELLED) {
30.275 + // aggressively release to set runner to null,
30.276 + // in case we are racing with a cancel request
30.277 + // that will try to interrupt runner
30.278 + releaseShared(0);
30.279 + return;
30.280 + }
30.281 + if (compareAndSetState(s, RAN)) {
30.282 + result = v;
30.283 + releaseShared(0);
30.284 + done();
30.285 + return;
30.286 + }
30.287 + }
30.288 + }
30.289 +
30.290 + void innerSetException(Throwable t) {
30.291 + for (;;) {
30.292 + int s = getState();
30.293 + if (s == RAN)
30.294 + return;
30.295 + if (s == CANCELLED) {
30.296 + // aggressively release to set runner to null,
30.297 + // in case we are racing with a cancel request
30.298 + // that will try to interrupt runner
30.299 + releaseShared(0);
30.300 + return;
30.301 + }
30.302 + if (compareAndSetState(s, RAN)) {
30.303 + exception = t;
30.304 + releaseShared(0);
30.305 + done();
30.306 + return;
30.307 + }
30.308 + }
30.309 + }
30.310 +
30.311 + boolean innerCancel(boolean mayInterruptIfRunning) {
30.312 + for (;;) {
30.313 + int s = getState();
30.314 + if (ranOrCancelled(s))
30.315 + return false;
30.316 + if (compareAndSetState(s, CANCELLED))
30.317 + break;
30.318 + }
30.319 + if (mayInterruptIfRunning) {
30.320 + Thread r = runner;
30.321 + if (r != null)
30.322 + r.interrupt();
30.323 + }
30.324 + releaseShared(0);
30.325 + done();
30.326 + return true;
30.327 + }
30.328 +
30.329 + void innerRun() {
30.330 + if (!compareAndSetState(READY, RUNNING))
30.331 + return;
30.332 +
30.333 + runner = Thread.currentThread();
30.334 + if (getState() == RUNNING) { // recheck after setting thread
30.335 + V result;
30.336 + try {
30.337 + result = callable.call();
30.338 + } catch (Throwable ex) {
30.339 + setException(ex);
30.340 + return;
30.341 + }
30.342 + set(result);
30.343 + } else {
30.344 + releaseShared(0); // cancel
30.345 + }
30.346 + }
30.347 +
30.348 + boolean innerRunAndReset() {
30.349 + if (!compareAndSetState(READY, RUNNING))
30.350 + return false;
30.351 + try {
30.352 + runner = Thread.currentThread();
30.353 + if (getState() == RUNNING)
30.354 + callable.call(); // don't set result
30.355 + runner = null;
30.356 + return compareAndSetState(RUNNING, READY);
30.357 + } catch (Throwable ex) {
30.358 + setException(ex);
30.359 + return false;
30.360 + }
30.361 + }
30.362 + }
30.363 +}
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
31.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/LinkedBlockingDeque.java Sat Mar 19 10:46:31 2016 +0100
31.3 @@ -0,0 +1,1198 @@
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.concurrent.locks.Condition;
31.46 +import java.util.concurrent.locks.ReentrantLock;
31.47 +
31.48 +/**
31.49 + * An optionally-bounded {@linkplain BlockingDeque blocking deque} based on
31.50 + * linked nodes.
31.51 + *
31.52 + * <p> The optional capacity bound constructor argument serves as a
31.53 + * way to prevent excessive expansion. The capacity, if unspecified,
31.54 + * is equal to {@link Integer#MAX_VALUE}. Linked nodes are
31.55 + * dynamically created upon each insertion unless this would bring the
31.56 + * deque above capacity.
31.57 + *
31.58 + * <p>Most operations run in constant time (ignoring time spent
31.59 + * blocking). Exceptions include {@link #remove(Object) remove},
31.60 + * {@link #removeFirstOccurrence removeFirstOccurrence}, {@link
31.61 + * #removeLastOccurrence removeLastOccurrence}, {@link #contains
31.62 + * contains}, {@link #iterator iterator.remove()}, and the bulk
31.63 + * operations, all of which run in linear time.
31.64 + *
31.65 + * <p>This class and its iterator implement all of the
31.66 + * <em>optional</em> methods of the {@link Collection} and {@link
31.67 + * Iterator} interfaces.
31.68 + *
31.69 + * <p>This class is a member of the
31.70 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
31.71 + * Java Collections Framework</a>.
31.72 + *
31.73 + * @since 1.6
31.74 + * @author Doug Lea
31.75 + * @param <E> the type of elements held in this collection
31.76 + */
31.77 +public class LinkedBlockingDeque<E>
31.78 + extends AbstractQueue<E>
31.79 + implements BlockingDeque<E>, java.io.Serializable {
31.80 +
31.81 + /*
31.82 + * Implemented as a simple doubly-linked list protected by a
31.83 + * single lock and using conditions to manage blocking.
31.84 + *
31.85 + * To implement weakly consistent iterators, it appears we need to
31.86 + * keep all Nodes GC-reachable from a predecessor dequeued Node.
31.87 + * That would cause two problems:
31.88 + * - allow a rogue Iterator to cause unbounded memory retention
31.89 + * - cause cross-generational linking of old Nodes to new Nodes if
31.90 + * a Node was tenured while live, which generational GCs have a
31.91 + * hard time dealing with, causing repeated major collections.
31.92 + * However, only non-deleted Nodes need to be reachable from
31.93 + * dequeued Nodes, and reachability does not necessarily have to
31.94 + * be of the kind understood by the GC. We use the trick of
31.95 + * linking a Node that has just been dequeued to itself. Such a
31.96 + * self-link implicitly means to jump to "first" (for next links)
31.97 + * or "last" (for prev links).
31.98 + */
31.99 +
31.100 + /*
31.101 + * We have "diamond" multiple interface/abstract class inheritance
31.102 + * here, and that introduces ambiguities. Often we want the
31.103 + * BlockingDeque javadoc combined with the AbstractQueue
31.104 + * implementation, so a lot of method specs are duplicated here.
31.105 + */
31.106 +
31.107 + private static final long serialVersionUID = -387911632671998426L;
31.108 +
31.109 + /** Doubly-linked list node class */
31.110 + static final class Node<E> {
31.111 + /**
31.112 + * The item, or null if this node has been removed.
31.113 + */
31.114 + E item;
31.115 +
31.116 + /**
31.117 + * One of:
31.118 + * - the real predecessor Node
31.119 + * - this Node, meaning the predecessor is tail
31.120 + * - null, meaning there is no predecessor
31.121 + */
31.122 + Node<E> prev;
31.123 +
31.124 + /**
31.125 + * One of:
31.126 + * - the real successor Node
31.127 + * - this Node, meaning the successor is head
31.128 + * - null, meaning there is no successor
31.129 + */
31.130 + Node<E> next;
31.131 +
31.132 + Node(E x) {
31.133 + item = x;
31.134 + }
31.135 + }
31.136 +
31.137 + /**
31.138 + * Pointer to first node.
31.139 + * Invariant: (first == null && last == null) ||
31.140 + * (first.prev == null && first.item != null)
31.141 + */
31.142 + transient Node<E> first;
31.143 +
31.144 + /**
31.145 + * Pointer to last node.
31.146 + * Invariant: (first == null && last == null) ||
31.147 + * (last.next == null && last.item != null)
31.148 + */
31.149 + transient Node<E> last;
31.150 +
31.151 + /** Number of items in the deque */
31.152 + private transient int count;
31.153 +
31.154 + /** Maximum number of items in the deque */
31.155 + private final int capacity;
31.156 +
31.157 + /** Main lock guarding all access */
31.158 + final ReentrantLock lock = new ReentrantLock();
31.159 +
31.160 + /** Condition for waiting takes */
31.161 + private final Condition notEmpty = lock.newCondition();
31.162 +
31.163 + /** Condition for waiting puts */
31.164 + private final Condition notFull = lock.newCondition();
31.165 +
31.166 + /**
31.167 + * Creates a {@code LinkedBlockingDeque} with a capacity of
31.168 + * {@link Integer#MAX_VALUE}.
31.169 + */
31.170 + public LinkedBlockingDeque() {
31.171 + this(Integer.MAX_VALUE);
31.172 + }
31.173 +
31.174 + /**
31.175 + * Creates a {@code LinkedBlockingDeque} with the given (fixed) capacity.
31.176 + *
31.177 + * @param capacity the capacity of this deque
31.178 + * @throws IllegalArgumentException if {@code capacity} is less than 1
31.179 + */
31.180 + public LinkedBlockingDeque(int capacity) {
31.181 + if (capacity <= 0) throw new IllegalArgumentException();
31.182 + this.capacity = capacity;
31.183 + }
31.184 +
31.185 + /**
31.186 + * Creates a {@code LinkedBlockingDeque} with a capacity of
31.187 + * {@link Integer#MAX_VALUE}, initially containing the elements of
31.188 + * the given collection, added in traversal order of the
31.189 + * collection's iterator.
31.190 + *
31.191 + * @param c the collection of elements to initially contain
31.192 + * @throws NullPointerException if the specified collection or any
31.193 + * of its elements are null
31.194 + */
31.195 + public LinkedBlockingDeque(Collection<? extends E> c) {
31.196 + this(Integer.MAX_VALUE);
31.197 + final ReentrantLock lock = this.lock;
31.198 + lock.lock(); // Never contended, but necessary for visibility
31.199 + try {
31.200 + for (E e : c) {
31.201 + if (e == null)
31.202 + throw new NullPointerException();
31.203 + if (!linkLast(new Node<E>(e)))
31.204 + throw new IllegalStateException("Deque full");
31.205 + }
31.206 + } finally {
31.207 + lock.unlock();
31.208 + }
31.209 + }
31.210 +
31.211 +
31.212 + // Basic linking and unlinking operations, called only while holding lock
31.213 +
31.214 + /**
31.215 + * Links node as first element, or returns false if full.
31.216 + */
31.217 + private boolean linkFirst(Node<E> node) {
31.218 + // assert lock.isHeldByCurrentThread();
31.219 + if (count >= capacity)
31.220 + return false;
31.221 + Node<E> f = first;
31.222 + node.next = f;
31.223 + first = node;
31.224 + if (last == null)
31.225 + last = node;
31.226 + else
31.227 + f.prev = node;
31.228 + ++count;
31.229 + notEmpty.signal();
31.230 + return true;
31.231 + }
31.232 +
31.233 + /**
31.234 + * Links node as last element, or returns false if full.
31.235 + */
31.236 + private boolean linkLast(Node<E> node) {
31.237 + // assert lock.isHeldByCurrentThread();
31.238 + if (count >= capacity)
31.239 + return false;
31.240 + Node<E> l = last;
31.241 + node.prev = l;
31.242 + last = node;
31.243 + if (first == null)
31.244 + first = node;
31.245 + else
31.246 + l.next = node;
31.247 + ++count;
31.248 + notEmpty.signal();
31.249 + return true;
31.250 + }
31.251 +
31.252 + /**
31.253 + * Removes and returns first element, or null if empty.
31.254 + */
31.255 + private E unlinkFirst() {
31.256 + // assert lock.isHeldByCurrentThread();
31.257 + Node<E> f = first;
31.258 + if (f == null)
31.259 + return null;
31.260 + Node<E> n = f.next;
31.261 + E item = f.item;
31.262 + f.item = null;
31.263 + f.next = f; // help GC
31.264 + first = n;
31.265 + if (n == null)
31.266 + last = null;
31.267 + else
31.268 + n.prev = null;
31.269 + --count;
31.270 + notFull.signal();
31.271 + return item;
31.272 + }
31.273 +
31.274 + /**
31.275 + * Removes and returns last element, or null if empty.
31.276 + */
31.277 + private E unlinkLast() {
31.278 + // assert lock.isHeldByCurrentThread();
31.279 + Node<E> l = last;
31.280 + if (l == null)
31.281 + return null;
31.282 + Node<E> p = l.prev;
31.283 + E item = l.item;
31.284 + l.item = null;
31.285 + l.prev = l; // help GC
31.286 + last = p;
31.287 + if (p == null)
31.288 + first = null;
31.289 + else
31.290 + p.next = null;
31.291 + --count;
31.292 + notFull.signal();
31.293 + return item;
31.294 + }
31.295 +
31.296 + /**
31.297 + * Unlinks x.
31.298 + */
31.299 + void unlink(Node<E> x) {
31.300 + // assert lock.isHeldByCurrentThread();
31.301 + Node<E> p = x.prev;
31.302 + Node<E> n = x.next;
31.303 + if (p == null) {
31.304 + unlinkFirst();
31.305 + } else if (n == null) {
31.306 + unlinkLast();
31.307 + } else {
31.308 + p.next = n;
31.309 + n.prev = p;
31.310 + x.item = null;
31.311 + // Don't mess with x's links. They may still be in use by
31.312 + // an iterator.
31.313 + --count;
31.314 + notFull.signal();
31.315 + }
31.316 + }
31.317 +
31.318 + // BlockingDeque methods
31.319 +
31.320 + /**
31.321 + * @throws IllegalStateException {@inheritDoc}
31.322 + * @throws NullPointerException {@inheritDoc}
31.323 + */
31.324 + public void addFirst(E e) {
31.325 + if (!offerFirst(e))
31.326 + throw new IllegalStateException("Deque full");
31.327 + }
31.328 +
31.329 + /**
31.330 + * @throws IllegalStateException {@inheritDoc}
31.331 + * @throws NullPointerException {@inheritDoc}
31.332 + */
31.333 + public void addLast(E e) {
31.334 + if (!offerLast(e))
31.335 + throw new IllegalStateException("Deque full");
31.336 + }
31.337 +
31.338 + /**
31.339 + * @throws NullPointerException {@inheritDoc}
31.340 + */
31.341 + public boolean offerFirst(E e) {
31.342 + if (e == null) throw new NullPointerException();
31.343 + Node<E> node = new Node<E>(e);
31.344 + final ReentrantLock lock = this.lock;
31.345 + lock.lock();
31.346 + try {
31.347 + return linkFirst(node);
31.348 + } finally {
31.349 + lock.unlock();
31.350 + }
31.351 + }
31.352 +
31.353 + /**
31.354 + * @throws NullPointerException {@inheritDoc}
31.355 + */
31.356 + public boolean offerLast(E e) {
31.357 + if (e == null) throw new NullPointerException();
31.358 + Node<E> node = new Node<E>(e);
31.359 + final ReentrantLock lock = this.lock;
31.360 + lock.lock();
31.361 + try {
31.362 + return linkLast(node);
31.363 + } finally {
31.364 + lock.unlock();
31.365 + }
31.366 + }
31.367 +
31.368 + /**
31.369 + * @throws NullPointerException {@inheritDoc}
31.370 + * @throws InterruptedException {@inheritDoc}
31.371 + */
31.372 + public void putFirst(E e) throws InterruptedException {
31.373 + if (e == null) throw new NullPointerException();
31.374 + Node<E> node = new Node<E>(e);
31.375 + final ReentrantLock lock = this.lock;
31.376 + lock.lock();
31.377 + try {
31.378 + while (!linkFirst(node))
31.379 + notFull.await();
31.380 + } finally {
31.381 + lock.unlock();
31.382 + }
31.383 + }
31.384 +
31.385 + /**
31.386 + * @throws NullPointerException {@inheritDoc}
31.387 + * @throws InterruptedException {@inheritDoc}
31.388 + */
31.389 + public void putLast(E e) throws InterruptedException {
31.390 + if (e == null) throw new NullPointerException();
31.391 + Node<E> node = new Node<E>(e);
31.392 + final ReentrantLock lock = this.lock;
31.393 + lock.lock();
31.394 + try {
31.395 + while (!linkLast(node))
31.396 + notFull.await();
31.397 + } finally {
31.398 + lock.unlock();
31.399 + }
31.400 + }
31.401 +
31.402 + /**
31.403 + * @throws NullPointerException {@inheritDoc}
31.404 + * @throws InterruptedException {@inheritDoc}
31.405 + */
31.406 + public boolean offerFirst(E e, long timeout, TimeUnit unit)
31.407 + throws InterruptedException {
31.408 + if (e == null) throw new NullPointerException();
31.409 + Node<E> node = new Node<E>(e);
31.410 + long nanos = unit.toNanos(timeout);
31.411 + final ReentrantLock lock = this.lock;
31.412 + lock.lockInterruptibly();
31.413 + try {
31.414 + while (!linkFirst(node)) {
31.415 + if (nanos <= 0)
31.416 + return false;
31.417 + nanos = notFull.awaitNanos(nanos);
31.418 + }
31.419 + return true;
31.420 + } finally {
31.421 + lock.unlock();
31.422 + }
31.423 + }
31.424 +
31.425 + /**
31.426 + * @throws NullPointerException {@inheritDoc}
31.427 + * @throws InterruptedException {@inheritDoc}
31.428 + */
31.429 + public boolean offerLast(E e, long timeout, TimeUnit unit)
31.430 + throws InterruptedException {
31.431 + if (e == null) throw new NullPointerException();
31.432 + Node<E> node = new Node<E>(e);
31.433 + long nanos = unit.toNanos(timeout);
31.434 + final ReentrantLock lock = this.lock;
31.435 + lock.lockInterruptibly();
31.436 + try {
31.437 + while (!linkLast(node)) {
31.438 + if (nanos <= 0)
31.439 + return false;
31.440 + nanos = notFull.awaitNanos(nanos);
31.441 + }
31.442 + return true;
31.443 + } finally {
31.444 + lock.unlock();
31.445 + }
31.446 + }
31.447 +
31.448 + /**
31.449 + * @throws NoSuchElementException {@inheritDoc}
31.450 + */
31.451 + public E removeFirst() {
31.452 + E x = pollFirst();
31.453 + if (x == null) throw new NoSuchElementException();
31.454 + return x;
31.455 + }
31.456 +
31.457 + /**
31.458 + * @throws NoSuchElementException {@inheritDoc}
31.459 + */
31.460 + public E removeLast() {
31.461 + E x = pollLast();
31.462 + if (x == null) throw new NoSuchElementException();
31.463 + return x;
31.464 + }
31.465 +
31.466 + public E pollFirst() {
31.467 + final ReentrantLock lock = this.lock;
31.468 + lock.lock();
31.469 + try {
31.470 + return unlinkFirst();
31.471 + } finally {
31.472 + lock.unlock();
31.473 + }
31.474 + }
31.475 +
31.476 + public E pollLast() {
31.477 + final ReentrantLock lock = this.lock;
31.478 + lock.lock();
31.479 + try {
31.480 + return unlinkLast();
31.481 + } finally {
31.482 + lock.unlock();
31.483 + }
31.484 + }
31.485 +
31.486 + public E takeFirst() throws InterruptedException {
31.487 + final ReentrantLock lock = this.lock;
31.488 + lock.lock();
31.489 + try {
31.490 + E x;
31.491 + while ( (x = unlinkFirst()) == null)
31.492 + notEmpty.await();
31.493 + return x;
31.494 + } finally {
31.495 + lock.unlock();
31.496 + }
31.497 + }
31.498 +
31.499 + public E takeLast() throws InterruptedException {
31.500 + final ReentrantLock lock = this.lock;
31.501 + lock.lock();
31.502 + try {
31.503 + E x;
31.504 + while ( (x = unlinkLast()) == null)
31.505 + notEmpty.await();
31.506 + return x;
31.507 + } finally {
31.508 + lock.unlock();
31.509 + }
31.510 + }
31.511 +
31.512 + public E pollFirst(long timeout, TimeUnit unit)
31.513 + throws InterruptedException {
31.514 + long nanos = unit.toNanos(timeout);
31.515 + final ReentrantLock lock = this.lock;
31.516 + lock.lockInterruptibly();
31.517 + try {
31.518 + E x;
31.519 + while ( (x = unlinkFirst()) == null) {
31.520 + if (nanos <= 0)
31.521 + return null;
31.522 + nanos = notEmpty.awaitNanos(nanos);
31.523 + }
31.524 + return x;
31.525 + } finally {
31.526 + lock.unlock();
31.527 + }
31.528 + }
31.529 +
31.530 + public E pollLast(long timeout, TimeUnit unit)
31.531 + throws InterruptedException {
31.532 + long nanos = unit.toNanos(timeout);
31.533 + final ReentrantLock lock = this.lock;
31.534 + lock.lockInterruptibly();
31.535 + try {
31.536 + E x;
31.537 + while ( (x = unlinkLast()) == null) {
31.538 + if (nanos <= 0)
31.539 + return null;
31.540 + nanos = notEmpty.awaitNanos(nanos);
31.541 + }
31.542 + return x;
31.543 + } finally {
31.544 + lock.unlock();
31.545 + }
31.546 + }
31.547 +
31.548 + /**
31.549 + * @throws NoSuchElementException {@inheritDoc}
31.550 + */
31.551 + public E getFirst() {
31.552 + E x = peekFirst();
31.553 + if (x == null) throw new NoSuchElementException();
31.554 + return x;
31.555 + }
31.556 +
31.557 + /**
31.558 + * @throws NoSuchElementException {@inheritDoc}
31.559 + */
31.560 + public E getLast() {
31.561 + E x = peekLast();
31.562 + if (x == null) throw new NoSuchElementException();
31.563 + return x;
31.564 + }
31.565 +
31.566 + public E peekFirst() {
31.567 + final ReentrantLock lock = this.lock;
31.568 + lock.lock();
31.569 + try {
31.570 + return (first == null) ? null : first.item;
31.571 + } finally {
31.572 + lock.unlock();
31.573 + }
31.574 + }
31.575 +
31.576 + public E peekLast() {
31.577 + final ReentrantLock lock = this.lock;
31.578 + lock.lock();
31.579 + try {
31.580 + return (last == null) ? null : last.item;
31.581 + } finally {
31.582 + lock.unlock();
31.583 + }
31.584 + }
31.585 +
31.586 + public boolean removeFirstOccurrence(Object o) {
31.587 + if (o == null) return false;
31.588 + final ReentrantLock lock = this.lock;
31.589 + lock.lock();
31.590 + try {
31.591 + for (Node<E> p = first; p != null; p = p.next) {
31.592 + if (o.equals(p.item)) {
31.593 + unlink(p);
31.594 + return true;
31.595 + }
31.596 + }
31.597 + return false;
31.598 + } finally {
31.599 + lock.unlock();
31.600 + }
31.601 + }
31.602 +
31.603 + public boolean removeLastOccurrence(Object o) {
31.604 + if (o == null) return false;
31.605 + final ReentrantLock lock = this.lock;
31.606 + lock.lock();
31.607 + try {
31.608 + for (Node<E> p = last; p != null; p = p.prev) {
31.609 + if (o.equals(p.item)) {
31.610 + unlink(p);
31.611 + return true;
31.612 + }
31.613 + }
31.614 + return false;
31.615 + } finally {
31.616 + lock.unlock();
31.617 + }
31.618 + }
31.619 +
31.620 + // BlockingQueue methods
31.621 +
31.622 + /**
31.623 + * Inserts the specified element at the end of this deque unless it would
31.624 + * violate capacity restrictions. When using a capacity-restricted deque,
31.625 + * it is generally preferable to use method {@link #offer(Object) offer}.
31.626 + *
31.627 + * <p>This method is equivalent to {@link #addLast}.
31.628 + *
31.629 + * @throws IllegalStateException if the element cannot be added at this
31.630 + * time due to capacity restrictions
31.631 + * @throws NullPointerException if the specified element is null
31.632 + */
31.633 + public boolean add(E e) {
31.634 + addLast(e);
31.635 + return true;
31.636 + }
31.637 +
31.638 + /**
31.639 + * @throws NullPointerException if the specified element is null
31.640 + */
31.641 + public boolean offer(E e) {
31.642 + return offerLast(e);
31.643 + }
31.644 +
31.645 + /**
31.646 + * @throws NullPointerException {@inheritDoc}
31.647 + * @throws InterruptedException {@inheritDoc}
31.648 + */
31.649 + public void put(E e) throws InterruptedException {
31.650 + putLast(e);
31.651 + }
31.652 +
31.653 + /**
31.654 + * @throws NullPointerException {@inheritDoc}
31.655 + * @throws InterruptedException {@inheritDoc}
31.656 + */
31.657 + public boolean offer(E e, long timeout, TimeUnit unit)
31.658 + throws InterruptedException {
31.659 + return offerLast(e, timeout, unit);
31.660 + }
31.661 +
31.662 + /**
31.663 + * Retrieves and removes the head of the queue represented by this deque.
31.664 + * This method differs from {@link #poll poll} only in that it throws an
31.665 + * exception if this deque is empty.
31.666 + *
31.667 + * <p>This method is equivalent to {@link #removeFirst() removeFirst}.
31.668 + *
31.669 + * @return the head of the queue represented by this deque
31.670 + * @throws NoSuchElementException if this deque is empty
31.671 + */
31.672 + public E remove() {
31.673 + return removeFirst();
31.674 + }
31.675 +
31.676 + public E poll() {
31.677 + return pollFirst();
31.678 + }
31.679 +
31.680 + public E take() throws InterruptedException {
31.681 + return takeFirst();
31.682 + }
31.683 +
31.684 + public E poll(long timeout, TimeUnit unit) throws InterruptedException {
31.685 + return pollFirst(timeout, unit);
31.686 + }
31.687 +
31.688 + /**
31.689 + * Retrieves, but does not remove, the head of the queue represented by
31.690 + * this deque. This method differs from {@link #peek peek} only in that
31.691 + * it throws an exception if this deque is empty.
31.692 + *
31.693 + * <p>This method is equivalent to {@link #getFirst() getFirst}.
31.694 + *
31.695 + * @return the head of the queue represented by this deque
31.696 + * @throws NoSuchElementException if this deque is empty
31.697 + */
31.698 + public E element() {
31.699 + return getFirst();
31.700 + }
31.701 +
31.702 + public E peek() {
31.703 + return peekFirst();
31.704 + }
31.705 +
31.706 + /**
31.707 + * Returns the number of additional elements that this deque can ideally
31.708 + * (in the absence of memory or resource constraints) accept without
31.709 + * blocking. This is always equal to the initial capacity of this deque
31.710 + * less the current {@code size} of this deque.
31.711 + *
31.712 + * <p>Note that you <em>cannot</em> always tell if an attempt to insert
31.713 + * an element will succeed by inspecting {@code remainingCapacity}
31.714 + * because it may be the case that another thread is about to
31.715 + * insert or remove an element.
31.716 + */
31.717 + public int remainingCapacity() {
31.718 + final ReentrantLock lock = this.lock;
31.719 + lock.lock();
31.720 + try {
31.721 + return capacity - count;
31.722 + } finally {
31.723 + lock.unlock();
31.724 + }
31.725 + }
31.726 +
31.727 + /**
31.728 + * @throws UnsupportedOperationException {@inheritDoc}
31.729 + * @throws ClassCastException {@inheritDoc}
31.730 + * @throws NullPointerException {@inheritDoc}
31.731 + * @throws IllegalArgumentException {@inheritDoc}
31.732 + */
31.733 + public int drainTo(Collection<? super E> c) {
31.734 + return drainTo(c, Integer.MAX_VALUE);
31.735 + }
31.736 +
31.737 + /**
31.738 + * @throws UnsupportedOperationException {@inheritDoc}
31.739 + * @throws ClassCastException {@inheritDoc}
31.740 + * @throws NullPointerException {@inheritDoc}
31.741 + * @throws IllegalArgumentException {@inheritDoc}
31.742 + */
31.743 + public int drainTo(Collection<? super E> c, int maxElements) {
31.744 + if (c == null)
31.745 + throw new NullPointerException();
31.746 + if (c == this)
31.747 + throw new IllegalArgumentException();
31.748 + final ReentrantLock lock = this.lock;
31.749 + lock.lock();
31.750 + try {
31.751 + int n = Math.min(maxElements, count);
31.752 + for (int i = 0; i < n; i++) {
31.753 + c.add(first.item); // In this order, in case add() throws.
31.754 + unlinkFirst();
31.755 + }
31.756 + return n;
31.757 + } finally {
31.758 + lock.unlock();
31.759 + }
31.760 + }
31.761 +
31.762 + // Stack methods
31.763 +
31.764 + /**
31.765 + * @throws IllegalStateException {@inheritDoc}
31.766 + * @throws NullPointerException {@inheritDoc}
31.767 + */
31.768 + public void push(E e) {
31.769 + addFirst(e);
31.770 + }
31.771 +
31.772 + /**
31.773 + * @throws NoSuchElementException {@inheritDoc}
31.774 + */
31.775 + public E pop() {
31.776 + return removeFirst();
31.777 + }
31.778 +
31.779 + // Collection methods
31.780 +
31.781 + /**
31.782 + * Removes the first occurrence of the specified element from this deque.
31.783 + * If the deque does not contain the element, it is unchanged.
31.784 + * More formally, removes the first element {@code e} such that
31.785 + * {@code o.equals(e)} (if such an element exists).
31.786 + * Returns {@code true} if this deque contained the specified element
31.787 + * (or equivalently, if this deque changed as a result of the call).
31.788 + *
31.789 + * <p>This method is equivalent to
31.790 + * {@link #removeFirstOccurrence(Object) removeFirstOccurrence}.
31.791 + *
31.792 + * @param o element to be removed from this deque, if present
31.793 + * @return {@code true} if this deque changed as a result of the call
31.794 + */
31.795 + public boolean remove(Object o) {
31.796 + return removeFirstOccurrence(o);
31.797 + }
31.798 +
31.799 + /**
31.800 + * Returns the number of elements in this deque.
31.801 + *
31.802 + * @return the number of elements in this deque
31.803 + */
31.804 + public int size() {
31.805 + final ReentrantLock lock = this.lock;
31.806 + lock.lock();
31.807 + try {
31.808 + return count;
31.809 + } finally {
31.810 + lock.unlock();
31.811 + }
31.812 + }
31.813 +
31.814 + /**
31.815 + * Returns {@code true} if this deque contains the specified element.
31.816 + * More formally, returns {@code true} if and only if this deque contains
31.817 + * at least one element {@code e} such that {@code o.equals(e)}.
31.818 + *
31.819 + * @param o object to be checked for containment in this deque
31.820 + * @return {@code true} if this deque contains the specified element
31.821 + */
31.822 + public boolean contains(Object o) {
31.823 + if (o == null) return false;
31.824 + final ReentrantLock lock = this.lock;
31.825 + lock.lock();
31.826 + try {
31.827 + for (Node<E> p = first; p != null; p = p.next)
31.828 + if (o.equals(p.item))
31.829 + return true;
31.830 + return false;
31.831 + } finally {
31.832 + lock.unlock();
31.833 + }
31.834 + }
31.835 +
31.836 + /*
31.837 + * TODO: Add support for more efficient bulk operations.
31.838 + *
31.839 + * We don't want to acquire the lock for every iteration, but we
31.840 + * also want other threads a chance to interact with the
31.841 + * collection, especially when count is close to capacity.
31.842 + */
31.843 +
31.844 +// /**
31.845 +// * Adds all of the elements in the specified collection to this
31.846 +// * queue. Attempts to addAll of a queue to itself result in
31.847 +// * {@code IllegalArgumentException}. Further, the behavior of
31.848 +// * this operation is undefined if the specified collection is
31.849 +// * modified while the operation is in progress.
31.850 +// *
31.851 +// * @param c collection containing elements to be added to this queue
31.852 +// * @return {@code true} if this queue changed as a result of the call
31.853 +// * @throws ClassCastException {@inheritDoc}
31.854 +// * @throws NullPointerException {@inheritDoc}
31.855 +// * @throws IllegalArgumentException {@inheritDoc}
31.856 +// * @throws IllegalStateException {@inheritDoc}
31.857 +// * @see #add(Object)
31.858 +// */
31.859 +// public boolean addAll(Collection<? extends E> c) {
31.860 +// if (c == null)
31.861 +// throw new NullPointerException();
31.862 +// if (c == this)
31.863 +// throw new IllegalArgumentException();
31.864 +// final ReentrantLock lock = this.lock;
31.865 +// lock.lock();
31.866 +// try {
31.867 +// boolean modified = false;
31.868 +// for (E e : c)
31.869 +// if (linkLast(e))
31.870 +// modified = true;
31.871 +// return modified;
31.872 +// } finally {
31.873 +// lock.unlock();
31.874 +// }
31.875 +// }
31.876 +
31.877 + /**
31.878 + * Returns an array containing all of the elements in this deque, in
31.879 + * proper sequence (from first to last element).
31.880 + *
31.881 + * <p>The returned array will be "safe" in that no references to it are
31.882 + * maintained by this deque. (In other words, this method must allocate
31.883 + * a new array). The caller is thus free to modify the returned array.
31.884 + *
31.885 + * <p>This method acts as bridge between array-based and collection-based
31.886 + * APIs.
31.887 + *
31.888 + * @return an array containing all of the elements in this deque
31.889 + */
31.890 + @SuppressWarnings("unchecked")
31.891 + public Object[] toArray() {
31.892 + final ReentrantLock lock = this.lock;
31.893 + lock.lock();
31.894 + try {
31.895 + Object[] a = new Object[count];
31.896 + int k = 0;
31.897 + for (Node<E> p = first; p != null; p = p.next)
31.898 + a[k++] = p.item;
31.899 + return a;
31.900 + } finally {
31.901 + lock.unlock();
31.902 + }
31.903 + }
31.904 +
31.905 + /**
31.906 + * Returns an array containing all of the elements in this deque, in
31.907 + * proper sequence; the runtime type of the returned array is that of
31.908 + * the specified array. If the deque fits in the specified array, it
31.909 + * is returned therein. Otherwise, a new array is allocated with the
31.910 + * runtime type of the specified array and the size of this deque.
31.911 + *
31.912 + * <p>If this deque fits in the specified array with room to spare
31.913 + * (i.e., the array has more elements than this deque), the element in
31.914 + * the array immediately following the end of the deque is set to
31.915 + * {@code null}.
31.916 + *
31.917 + * <p>Like the {@link #toArray()} method, this method acts as bridge between
31.918 + * array-based and collection-based APIs. Further, this method allows
31.919 + * precise control over the runtime type of the output array, and may,
31.920 + * under certain circumstances, be used to save allocation costs.
31.921 + *
31.922 + * <p>Suppose {@code x} is a deque known to contain only strings.
31.923 + * The following code can be used to dump the deque into a newly
31.924 + * allocated array of {@code String}:
31.925 + *
31.926 + * <pre>
31.927 + * String[] y = x.toArray(new String[0]);</pre>
31.928 + *
31.929 + * Note that {@code toArray(new Object[0])} is identical in function to
31.930 + * {@code toArray()}.
31.931 + *
31.932 + * @param a the array into which the elements of the deque are to
31.933 + * be stored, if it is big enough; otherwise, a new array of the
31.934 + * same runtime type is allocated for this purpose
31.935 + * @return an array containing all of the elements in this deque
31.936 + * @throws ArrayStoreException if the runtime type of the specified array
31.937 + * is not a supertype of the runtime type of every element in
31.938 + * this deque
31.939 + * @throws NullPointerException if the specified array is null
31.940 + */
31.941 + @SuppressWarnings("unchecked")
31.942 + public <T> T[] toArray(T[] a) {
31.943 + final ReentrantLock lock = this.lock;
31.944 + lock.lock();
31.945 + try {
31.946 + if (a.length < count)
31.947 + a = (T[])java.lang.reflect.Array.newInstance
31.948 + (a.getClass().getComponentType(), count);
31.949 +
31.950 + int k = 0;
31.951 + for (Node<E> p = first; p != null; p = p.next)
31.952 + a[k++] = (T)p.item;
31.953 + if (a.length > k)
31.954 + a[k] = null;
31.955 + return a;
31.956 + } finally {
31.957 + lock.unlock();
31.958 + }
31.959 + }
31.960 +
31.961 + public String toString() {
31.962 + final ReentrantLock lock = this.lock;
31.963 + lock.lock();
31.964 + try {
31.965 + Node<E> p = first;
31.966 + if (p == null)
31.967 + return "[]";
31.968 +
31.969 + StringBuilder sb = new StringBuilder();
31.970 + sb.append('[');
31.971 + for (;;) {
31.972 + E e = p.item;
31.973 + sb.append(e == this ? "(this Collection)" : e);
31.974 + p = p.next;
31.975 + if (p == null)
31.976 + return sb.append(']').toString();
31.977 + sb.append(',').append(' ');
31.978 + }
31.979 + } finally {
31.980 + lock.unlock();
31.981 + }
31.982 + }
31.983 +
31.984 + /**
31.985 + * Atomically removes all of the elements from this deque.
31.986 + * The deque will be empty after this call returns.
31.987 + */
31.988 + public void clear() {
31.989 + final ReentrantLock lock = this.lock;
31.990 + lock.lock();
31.991 + try {
31.992 + for (Node<E> f = first; f != null; ) {
31.993 + f.item = null;
31.994 + Node<E> n = f.next;
31.995 + f.prev = null;
31.996 + f.next = null;
31.997 + f = n;
31.998 + }
31.999 + first = last = null;
31.1000 + count = 0;
31.1001 + notFull.signalAll();
31.1002 + } finally {
31.1003 + lock.unlock();
31.1004 + }
31.1005 + }
31.1006 +
31.1007 + /**
31.1008 + * Returns an iterator over the elements in this deque in proper sequence.
31.1009 + * The elements will be returned in order from first (head) to last (tail).
31.1010 + *
31.1011 + * <p>The returned iterator is a "weakly consistent" iterator that
31.1012 + * will never throw {@link java.util.ConcurrentModificationException
31.1013 + * ConcurrentModificationException}, and guarantees to traverse
31.1014 + * elements as they existed upon construction of the iterator, and
31.1015 + * may (but is not guaranteed to) reflect any modifications
31.1016 + * subsequent to construction.
31.1017 + *
31.1018 + * @return an iterator over the elements in this deque in proper sequence
31.1019 + */
31.1020 + public Iterator<E> iterator() {
31.1021 + return new Itr();
31.1022 + }
31.1023 +
31.1024 + /**
31.1025 + * Returns an iterator over the elements in this deque in reverse
31.1026 + * sequential order. The elements will be returned in order from
31.1027 + * last (tail) to first (head).
31.1028 + *
31.1029 + * <p>The returned iterator is a "weakly consistent" iterator that
31.1030 + * will never throw {@link java.util.ConcurrentModificationException
31.1031 + * ConcurrentModificationException}, and guarantees to traverse
31.1032 + * elements as they existed upon construction of the iterator, and
31.1033 + * may (but is not guaranteed to) reflect any modifications
31.1034 + * subsequent to construction.
31.1035 + *
31.1036 + * @return an iterator over the elements in this deque in reverse order
31.1037 + */
31.1038 + public Iterator<E> descendingIterator() {
31.1039 + return new DescendingItr();
31.1040 + }
31.1041 +
31.1042 + /**
31.1043 + * Base class for Iterators for LinkedBlockingDeque
31.1044 + */
31.1045 + private abstract class AbstractItr implements Iterator<E> {
31.1046 + /**
31.1047 + * The next node to return in next()
31.1048 + */
31.1049 + Node<E> next;
31.1050 +
31.1051 + /**
31.1052 + * nextItem holds on to item fields because once we claim that
31.1053 + * an element exists in hasNext(), we must return item read
31.1054 + * under lock (in advance()) even if it was in the process of
31.1055 + * being removed when hasNext() was called.
31.1056 + */
31.1057 + E nextItem;
31.1058 +
31.1059 + /**
31.1060 + * Node returned by most recent call to next. Needed by remove.
31.1061 + * Reset to null if this element is deleted by a call to remove.
31.1062 + */
31.1063 + private Node<E> lastRet;
31.1064 +
31.1065 + abstract Node<E> firstNode();
31.1066 + abstract Node<E> nextNode(Node<E> n);
31.1067 +
31.1068 + AbstractItr() {
31.1069 + // set to initial position
31.1070 + final ReentrantLock lock = LinkedBlockingDeque.this.lock;
31.1071 + lock.lock();
31.1072 + try {
31.1073 + next = firstNode();
31.1074 + nextItem = (next == null) ? null : next.item;
31.1075 + } finally {
31.1076 + lock.unlock();
31.1077 + }
31.1078 + }
31.1079 +
31.1080 + /**
31.1081 + * Returns the successor node of the given non-null, but
31.1082 + * possibly previously deleted, node.
31.1083 + */
31.1084 + private Node<E> succ(Node<E> n) {
31.1085 + // Chains of deleted nodes ending in null or self-links
31.1086 + // are possible if multiple interior nodes are removed.
31.1087 + for (;;) {
31.1088 + Node<E> s = nextNode(n);
31.1089 + if (s == null)
31.1090 + return null;
31.1091 + else if (s.item != null)
31.1092 + return s;
31.1093 + else if (s == n)
31.1094 + return firstNode();
31.1095 + else
31.1096 + n = s;
31.1097 + }
31.1098 + }
31.1099 +
31.1100 + /**
31.1101 + * Advances next.
31.1102 + */
31.1103 + void advance() {
31.1104 + final ReentrantLock lock = LinkedBlockingDeque.this.lock;
31.1105 + lock.lock();
31.1106 + try {
31.1107 + // assert next != null;
31.1108 + next = succ(next);
31.1109 + nextItem = (next == null) ? null : next.item;
31.1110 + } finally {
31.1111 + lock.unlock();
31.1112 + }
31.1113 + }
31.1114 +
31.1115 + public boolean hasNext() {
31.1116 + return next != null;
31.1117 + }
31.1118 +
31.1119 + public E next() {
31.1120 + if (next == null)
31.1121 + throw new NoSuchElementException();
31.1122 + lastRet = next;
31.1123 + E x = nextItem;
31.1124 + advance();
31.1125 + return x;
31.1126 + }
31.1127 +
31.1128 + public void remove() {
31.1129 + Node<E> n = lastRet;
31.1130 + if (n == null)
31.1131 + throw new IllegalStateException();
31.1132 + lastRet = null;
31.1133 + final ReentrantLock lock = LinkedBlockingDeque.this.lock;
31.1134 + lock.lock();
31.1135 + try {
31.1136 + if (n.item != null)
31.1137 + unlink(n);
31.1138 + } finally {
31.1139 + lock.unlock();
31.1140 + }
31.1141 + }
31.1142 + }
31.1143 +
31.1144 + /** Forward iterator */
31.1145 + private class Itr extends AbstractItr {
31.1146 + Node<E> firstNode() { return first; }
31.1147 + Node<E> nextNode(Node<E> n) { return n.next; }
31.1148 + }
31.1149 +
31.1150 + /** Descending iterator */
31.1151 + private class DescendingItr extends AbstractItr {
31.1152 + Node<E> firstNode() { return last; }
31.1153 + Node<E> nextNode(Node<E> n) { return n.prev; }
31.1154 + }
31.1155 +
31.1156 + /**
31.1157 + * Save the state of this deque to a stream (that is, serialize it).
31.1158 + *
31.1159 + * @serialData The capacity (int), followed by elements (each an
31.1160 + * {@code Object}) in the proper order, followed by a null
31.1161 + * @param s the stream
31.1162 + */
31.1163 + private void writeObject(java.io.ObjectOutputStream s)
31.1164 + throws java.io.IOException {
31.1165 + final ReentrantLock lock = this.lock;
31.1166 + lock.lock();
31.1167 + try {
31.1168 + // Write out capacity and any hidden stuff
31.1169 + s.defaultWriteObject();
31.1170 + // Write out all elements in the proper order.
31.1171 + for (Node<E> p = first; p != null; p = p.next)
31.1172 + s.writeObject(p.item);
31.1173 + // Use trailing null as sentinel
31.1174 + s.writeObject(null);
31.1175 + } finally {
31.1176 + lock.unlock();
31.1177 + }
31.1178 + }
31.1179 +
31.1180 + /**
31.1181 + * Reconstitute this deque from a stream (that is,
31.1182 + * deserialize it).
31.1183 + * @param s the stream
31.1184 + */
31.1185 + private void readObject(java.io.ObjectInputStream s)
31.1186 + throws java.io.IOException, ClassNotFoundException {
31.1187 + s.defaultReadObject();
31.1188 + count = 0;
31.1189 + first = null;
31.1190 + last = null;
31.1191 + // Read in all elements and place in queue
31.1192 + for (;;) {
31.1193 + @SuppressWarnings("unchecked")
31.1194 + E item = (E)s.readObject();
31.1195 + if (item == null)
31.1196 + break;
31.1197 + add(item);
31.1198 + }
31.1199 + }
31.1200 +
31.1201 +}
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
32.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/LinkedBlockingQueue.java Sat Mar 19 10:46:31 2016 +0100
32.3 @@ -0,0 +1,910 @@
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.atomic.AtomicInteger;
32.42 +import java.util.concurrent.locks.Condition;
32.43 +import java.util.concurrent.locks.ReentrantLock;
32.44 +import java.util.AbstractQueue;
32.45 +import java.util.Collection;
32.46 +import java.util.Iterator;
32.47 +import java.util.NoSuchElementException;
32.48 +
32.49 +/**
32.50 + * An optionally-bounded {@linkplain BlockingQueue blocking queue} based on
32.51 + * linked nodes.
32.52 + * This queue orders elements FIFO (first-in-first-out).
32.53 + * The <em>head</em> of the queue is that element that has been on the
32.54 + * queue the longest time.
32.55 + * The <em>tail</em> of the queue is that element that has been on the
32.56 + * queue the shortest time. New elements
32.57 + * are inserted at the tail of the queue, and the queue retrieval
32.58 + * operations obtain elements at the head of the queue.
32.59 + * Linked queues typically have higher throughput than array-based queues but
32.60 + * less predictable performance in most concurrent applications.
32.61 + *
32.62 + * <p> The optional capacity bound constructor argument serves as a
32.63 + * way to prevent excessive queue expansion. The capacity, if unspecified,
32.64 + * is equal to {@link Integer#MAX_VALUE}. Linked nodes are
32.65 + * dynamically created upon each insertion unless this would bring the
32.66 + * queue above capacity.
32.67 + *
32.68 + * <p>This class and its iterator implement all of the
32.69 + * <em>optional</em> methods of the {@link Collection} and {@link
32.70 + * Iterator} interfaces.
32.71 + *
32.72 + * <p>This class is a member of the
32.73 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
32.74 + * Java Collections Framework</a>.
32.75 + *
32.76 + * @since 1.5
32.77 + * @author Doug Lea
32.78 + * @param <E> the type of elements held in this collection
32.79 + *
32.80 + */
32.81 +public class LinkedBlockingQueue<E> extends AbstractQueue<E>
32.82 + implements BlockingQueue<E>, java.io.Serializable {
32.83 + private static final long serialVersionUID = -6903933977591709194L;
32.84 +
32.85 + /*
32.86 + * A variant of the "two lock queue" algorithm. The putLock gates
32.87 + * entry to put (and offer), and has an associated condition for
32.88 + * waiting puts. Similarly for the takeLock. The "count" field
32.89 + * that they both rely on is maintained as an atomic to avoid
32.90 + * needing to get both locks in most cases. Also, to minimize need
32.91 + * for puts to get takeLock and vice-versa, cascading notifies are
32.92 + * used. When a put notices that it has enabled at least one take,
32.93 + * it signals taker. That taker in turn signals others if more
32.94 + * items have been entered since the signal. And symmetrically for
32.95 + * takes signalling puts. Operations such as remove(Object) and
32.96 + * iterators acquire both locks.
32.97 + *
32.98 + * Visibility between writers and readers is provided as follows:
32.99 + *
32.100 + * Whenever an element is enqueued, the putLock is acquired and
32.101 + * count updated. A subsequent reader guarantees visibility to the
32.102 + * enqueued Node by either acquiring the putLock (via fullyLock)
32.103 + * or by acquiring the takeLock, and then reading n = count.get();
32.104 + * this gives visibility to the first n items.
32.105 + *
32.106 + * To implement weakly consistent iterators, it appears we need to
32.107 + * keep all Nodes GC-reachable from a predecessor dequeued Node.
32.108 + * That would cause two problems:
32.109 + * - allow a rogue Iterator to cause unbounded memory retention
32.110 + * - cause cross-generational linking of old Nodes to new Nodes if
32.111 + * a Node was tenured while live, which generational GCs have a
32.112 + * hard time dealing with, causing repeated major collections.
32.113 + * However, only non-deleted Nodes need to be reachable from
32.114 + * dequeued Nodes, and reachability does not necessarily have to
32.115 + * be of the kind understood by the GC. We use the trick of
32.116 + * linking a Node that has just been dequeued to itself. Such a
32.117 + * self-link implicitly means to advance to head.next.
32.118 + */
32.119 +
32.120 + /**
32.121 + * Linked list node class
32.122 + */
32.123 + static class Node<E> {
32.124 + E item;
32.125 +
32.126 + /**
32.127 + * One of:
32.128 + * - the real successor Node
32.129 + * - this Node, meaning the successor is head.next
32.130 + * - null, meaning there is no successor (this is the last node)
32.131 + */
32.132 + Node<E> next;
32.133 +
32.134 + Node(E x) { item = x; }
32.135 + }
32.136 +
32.137 + /** The capacity bound, or Integer.MAX_VALUE if none */
32.138 + private final int capacity;
32.139 +
32.140 + /** Current number of elements */
32.141 + private final AtomicInteger count = new AtomicInteger(0);
32.142 +
32.143 + /**
32.144 + * Head of linked list.
32.145 + * Invariant: head.item == null
32.146 + */
32.147 + private transient Node<E> head;
32.148 +
32.149 + /**
32.150 + * Tail of linked list.
32.151 + * Invariant: last.next == null
32.152 + */
32.153 + private transient Node<E> last;
32.154 +
32.155 + /** Lock held by take, poll, etc */
32.156 + private final ReentrantLock takeLock = new ReentrantLock();
32.157 +
32.158 + /** Wait queue for waiting takes */
32.159 + private final Condition notEmpty = takeLock.newCondition();
32.160 +
32.161 + /** Lock held by put, offer, etc */
32.162 + private final ReentrantLock putLock = new ReentrantLock();
32.163 +
32.164 + /** Wait queue for waiting puts */
32.165 + private final Condition notFull = putLock.newCondition();
32.166 +
32.167 + /**
32.168 + * Signals a waiting take. Called only from put/offer (which do not
32.169 + * otherwise ordinarily lock takeLock.)
32.170 + */
32.171 + private void signalNotEmpty() {
32.172 + final ReentrantLock takeLock = this.takeLock;
32.173 + takeLock.lock();
32.174 + try {
32.175 + notEmpty.signal();
32.176 + } finally {
32.177 + takeLock.unlock();
32.178 + }
32.179 + }
32.180 +
32.181 + /**
32.182 + * Signals a waiting put. Called only from take/poll.
32.183 + */
32.184 + private void signalNotFull() {
32.185 + final ReentrantLock putLock = this.putLock;
32.186 + putLock.lock();
32.187 + try {
32.188 + notFull.signal();
32.189 + } finally {
32.190 + putLock.unlock();
32.191 + }
32.192 + }
32.193 +
32.194 + /**
32.195 + * Links node at end of queue.
32.196 + *
32.197 + * @param node the node
32.198 + */
32.199 + private void enqueue(Node<E> node) {
32.200 + // assert putLock.isHeldByCurrentThread();
32.201 + // assert last.next == null;
32.202 + last = last.next = node;
32.203 + }
32.204 +
32.205 + /**
32.206 + * Removes a node from head of queue.
32.207 + *
32.208 + * @return the node
32.209 + */
32.210 + private E dequeue() {
32.211 + // assert takeLock.isHeldByCurrentThread();
32.212 + // assert head.item == null;
32.213 + Node<E> h = head;
32.214 + Node<E> first = h.next;
32.215 + h.next = h; // help GC
32.216 + head = first;
32.217 + E x = first.item;
32.218 + first.item = null;
32.219 + return x;
32.220 + }
32.221 +
32.222 + /**
32.223 + * Lock to prevent both puts and takes.
32.224 + */
32.225 + void fullyLock() {
32.226 + putLock.lock();
32.227 + takeLock.lock();
32.228 + }
32.229 +
32.230 + /**
32.231 + * Unlock to allow both puts and takes.
32.232 + */
32.233 + void fullyUnlock() {
32.234 + takeLock.unlock();
32.235 + putLock.unlock();
32.236 + }
32.237 +
32.238 +// /**
32.239 +// * Tells whether both locks are held by current thread.
32.240 +// */
32.241 +// boolean isFullyLocked() {
32.242 +// return (putLock.isHeldByCurrentThread() &&
32.243 +// takeLock.isHeldByCurrentThread());
32.244 +// }
32.245 +
32.246 + /**
32.247 + * Creates a {@code LinkedBlockingQueue} with a capacity of
32.248 + * {@link Integer#MAX_VALUE}.
32.249 + */
32.250 + public LinkedBlockingQueue() {
32.251 + this(Integer.MAX_VALUE);
32.252 + }
32.253 +
32.254 + /**
32.255 + * Creates a {@code LinkedBlockingQueue} with the given (fixed) capacity.
32.256 + *
32.257 + * @param capacity the capacity of this queue
32.258 + * @throws IllegalArgumentException if {@code capacity} is not greater
32.259 + * than zero
32.260 + */
32.261 + public LinkedBlockingQueue(int capacity) {
32.262 + if (capacity <= 0) throw new IllegalArgumentException();
32.263 + this.capacity = capacity;
32.264 + last = head = new Node<E>(null);
32.265 + }
32.266 +
32.267 + /**
32.268 + * Creates a {@code LinkedBlockingQueue} with a capacity of
32.269 + * {@link Integer#MAX_VALUE}, initially containing the elements of the
32.270 + * given collection,
32.271 + * added in traversal order of the collection's iterator.
32.272 + *
32.273 + * @param c the collection of elements to initially contain
32.274 + * @throws NullPointerException if the specified collection or any
32.275 + * of its elements are null
32.276 + */
32.277 + public LinkedBlockingQueue(Collection<? extends E> c) {
32.278 + this(Integer.MAX_VALUE);
32.279 + final ReentrantLock putLock = this.putLock;
32.280 + putLock.lock(); // Never contended, but necessary for visibility
32.281 + try {
32.282 + int n = 0;
32.283 + for (E e : c) {
32.284 + if (e == null)
32.285 + throw new NullPointerException();
32.286 + if (n == capacity)
32.287 + throw new IllegalStateException("Queue full");
32.288 + enqueue(new Node<E>(e));
32.289 + ++n;
32.290 + }
32.291 + count.set(n);
32.292 + } finally {
32.293 + putLock.unlock();
32.294 + }
32.295 + }
32.296 +
32.297 +
32.298 + // this doc comment is overridden to remove the reference to collections
32.299 + // greater in size than Integer.MAX_VALUE
32.300 + /**
32.301 + * Returns the number of elements in this queue.
32.302 + *
32.303 + * @return the number of elements in this queue
32.304 + */
32.305 + public int size() {
32.306 + return count.get();
32.307 + }
32.308 +
32.309 + // this doc comment is a modified copy of the inherited doc comment,
32.310 + // without the reference to unlimited queues.
32.311 + /**
32.312 + * Returns the number of additional elements that this queue can ideally
32.313 + * (in the absence of memory or resource constraints) accept without
32.314 + * blocking. This is always equal to the initial capacity of this queue
32.315 + * less the current {@code size} of this queue.
32.316 + *
32.317 + * <p>Note that you <em>cannot</em> always tell if an attempt to insert
32.318 + * an element will succeed by inspecting {@code remainingCapacity}
32.319 + * because it may be the case that another thread is about to
32.320 + * insert or remove an element.
32.321 + */
32.322 + public int remainingCapacity() {
32.323 + return capacity - count.get();
32.324 + }
32.325 +
32.326 + /**
32.327 + * Inserts the specified element at the tail of this queue, waiting if
32.328 + * necessary for space to become available.
32.329 + *
32.330 + * @throws InterruptedException {@inheritDoc}
32.331 + * @throws NullPointerException {@inheritDoc}
32.332 + */
32.333 + public void put(E e) throws InterruptedException {
32.334 + if (e == null) throw new NullPointerException();
32.335 + // Note: convention in all put/take/etc is to preset local var
32.336 + // holding count negative to indicate failure unless set.
32.337 + int c = -1;
32.338 + Node<E> node = new Node(e);
32.339 + final ReentrantLock putLock = this.putLock;
32.340 + final AtomicInteger count = this.count;
32.341 + putLock.lockInterruptibly();
32.342 + try {
32.343 + /*
32.344 + * Note that count is used in wait guard even though it is
32.345 + * not protected by lock. This works because count can
32.346 + * only decrease at this point (all other puts are shut
32.347 + * out by lock), and we (or some other waiting put) are
32.348 + * signalled if it ever changes from capacity. Similarly
32.349 + * for all other uses of count in other wait guards.
32.350 + */
32.351 + while (count.get() == capacity) {
32.352 + notFull.await();
32.353 + }
32.354 + enqueue(node);
32.355 + c = count.getAndIncrement();
32.356 + if (c + 1 < capacity)
32.357 + notFull.signal();
32.358 + } finally {
32.359 + putLock.unlock();
32.360 + }
32.361 + if (c == 0)
32.362 + signalNotEmpty();
32.363 + }
32.364 +
32.365 + /**
32.366 + * Inserts the specified element at the tail of this queue, waiting if
32.367 + * necessary up to the specified wait time for space to become available.
32.368 + *
32.369 + * @return {@code true} if successful, or {@code false} if
32.370 + * the specified waiting time elapses before space is available.
32.371 + * @throws InterruptedException {@inheritDoc}
32.372 + * @throws NullPointerException {@inheritDoc}
32.373 + */
32.374 + public boolean offer(E e, long timeout, TimeUnit unit)
32.375 + throws InterruptedException {
32.376 +
32.377 + if (e == null) throw new NullPointerException();
32.378 + long nanos = unit.toNanos(timeout);
32.379 + int c = -1;
32.380 + final ReentrantLock putLock = this.putLock;
32.381 + final AtomicInteger count = this.count;
32.382 + putLock.lockInterruptibly();
32.383 + try {
32.384 + while (count.get() == capacity) {
32.385 + if (nanos <= 0)
32.386 + return false;
32.387 + nanos = notFull.awaitNanos(nanos);
32.388 + }
32.389 + enqueue(new Node<E>(e));
32.390 + c = count.getAndIncrement();
32.391 + if (c + 1 < capacity)
32.392 + notFull.signal();
32.393 + } finally {
32.394 + putLock.unlock();
32.395 + }
32.396 + if (c == 0)
32.397 + signalNotEmpty();
32.398 + return true;
32.399 + }
32.400 +
32.401 + /**
32.402 + * Inserts the specified element at the tail of this queue if it is
32.403 + * possible to do so immediately without exceeding the queue's capacity,
32.404 + * returning {@code true} upon success and {@code false} if this queue
32.405 + * is full.
32.406 + * When using a capacity-restricted queue, this method is generally
32.407 + * preferable to method {@link BlockingQueue#add add}, which can fail to
32.408 + * insert an element only by throwing an exception.
32.409 + *
32.410 + * @throws NullPointerException if the specified element is null
32.411 + */
32.412 + public boolean offer(E e) {
32.413 + if (e == null) throw new NullPointerException();
32.414 + final AtomicInteger count = this.count;
32.415 + if (count.get() == capacity)
32.416 + return false;
32.417 + int c = -1;
32.418 + Node<E> node = new Node(e);
32.419 + final ReentrantLock putLock = this.putLock;
32.420 + putLock.lock();
32.421 + try {
32.422 + if (count.get() < capacity) {
32.423 + enqueue(node);
32.424 + c = count.getAndIncrement();
32.425 + if (c + 1 < capacity)
32.426 + notFull.signal();
32.427 + }
32.428 + } finally {
32.429 + putLock.unlock();
32.430 + }
32.431 + if (c == 0)
32.432 + signalNotEmpty();
32.433 + return c >= 0;
32.434 + }
32.435 +
32.436 +
32.437 + public E take() throws InterruptedException {
32.438 + E x;
32.439 + int c = -1;
32.440 + final AtomicInteger count = this.count;
32.441 + final ReentrantLock takeLock = this.takeLock;
32.442 + takeLock.lockInterruptibly();
32.443 + try {
32.444 + while (count.get() == 0) {
32.445 + notEmpty.await();
32.446 + }
32.447 + x = dequeue();
32.448 + c = count.getAndDecrement();
32.449 + if (c > 1)
32.450 + notEmpty.signal();
32.451 + } finally {
32.452 + takeLock.unlock();
32.453 + }
32.454 + if (c == capacity)
32.455 + signalNotFull();
32.456 + return x;
32.457 + }
32.458 +
32.459 + public E poll(long timeout, TimeUnit unit) throws InterruptedException {
32.460 + E x = null;
32.461 + int c = -1;
32.462 + long nanos = unit.toNanos(timeout);
32.463 + final AtomicInteger count = this.count;
32.464 + final ReentrantLock takeLock = this.takeLock;
32.465 + takeLock.lockInterruptibly();
32.466 + try {
32.467 + while (count.get() == 0) {
32.468 + if (nanos <= 0)
32.469 + return null;
32.470 + nanos = notEmpty.awaitNanos(nanos);
32.471 + }
32.472 + x = dequeue();
32.473 + c = count.getAndDecrement();
32.474 + if (c > 1)
32.475 + notEmpty.signal();
32.476 + } finally {
32.477 + takeLock.unlock();
32.478 + }
32.479 + if (c == capacity)
32.480 + signalNotFull();
32.481 + return x;
32.482 + }
32.483 +
32.484 + public E poll() {
32.485 + final AtomicInteger count = this.count;
32.486 + if (count.get() == 0)
32.487 + return null;
32.488 + E x = null;
32.489 + int c = -1;
32.490 + final ReentrantLock takeLock = this.takeLock;
32.491 + takeLock.lock();
32.492 + try {
32.493 + if (count.get() > 0) {
32.494 + x = dequeue();
32.495 + c = count.getAndDecrement();
32.496 + if (c > 1)
32.497 + notEmpty.signal();
32.498 + }
32.499 + } finally {
32.500 + takeLock.unlock();
32.501 + }
32.502 + if (c == capacity)
32.503 + signalNotFull();
32.504 + return x;
32.505 + }
32.506 +
32.507 + public E peek() {
32.508 + if (count.get() == 0)
32.509 + return null;
32.510 + final ReentrantLock takeLock = this.takeLock;
32.511 + takeLock.lock();
32.512 + try {
32.513 + Node<E> first = head.next;
32.514 + if (first == null)
32.515 + return null;
32.516 + else
32.517 + return first.item;
32.518 + } finally {
32.519 + takeLock.unlock();
32.520 + }
32.521 + }
32.522 +
32.523 + /**
32.524 + * Unlinks interior Node p with predecessor trail.
32.525 + */
32.526 + void unlink(Node<E> p, Node<E> trail) {
32.527 + // assert isFullyLocked();
32.528 + // p.next is not changed, to allow iterators that are
32.529 + // traversing p to maintain their weak-consistency guarantee.
32.530 + p.item = null;
32.531 + trail.next = p.next;
32.532 + if (last == p)
32.533 + last = trail;
32.534 + if (count.getAndDecrement() == capacity)
32.535 + notFull.signal();
32.536 + }
32.537 +
32.538 + /**
32.539 + * Removes a single instance of the specified element from this queue,
32.540 + * if it is present. More formally, removes an element {@code e} such
32.541 + * that {@code o.equals(e)}, if this queue contains one or more such
32.542 + * elements.
32.543 + * Returns {@code true} if this queue contained the specified element
32.544 + * (or equivalently, if this queue changed as a result of the call).
32.545 + *
32.546 + * @param o element to be removed from this queue, if present
32.547 + * @return {@code true} if this queue changed as a result of the call
32.548 + */
32.549 + public boolean remove(Object o) {
32.550 + if (o == null) return false;
32.551 + fullyLock();
32.552 + try {
32.553 + for (Node<E> trail = head, p = trail.next;
32.554 + p != null;
32.555 + trail = p, p = p.next) {
32.556 + if (o.equals(p.item)) {
32.557 + unlink(p, trail);
32.558 + return true;
32.559 + }
32.560 + }
32.561 + return false;
32.562 + } finally {
32.563 + fullyUnlock();
32.564 + }
32.565 + }
32.566 +
32.567 + /**
32.568 + * Returns {@code true} if this queue contains the specified element.
32.569 + * More formally, returns {@code true} if and only if this queue contains
32.570 + * at least one element {@code e} such that {@code o.equals(e)}.
32.571 + *
32.572 + * @param o object to be checked for containment in this queue
32.573 + * @return {@code true} if this queue contains the specified element
32.574 + */
32.575 + public boolean contains(Object o) {
32.576 + if (o == null) return false;
32.577 + fullyLock();
32.578 + try {
32.579 + for (Node<E> p = head.next; p != null; p = p.next)
32.580 + if (o.equals(p.item))
32.581 + return true;
32.582 + return false;
32.583 + } finally {
32.584 + fullyUnlock();
32.585 + }
32.586 + }
32.587 +
32.588 + /**
32.589 + * Returns an array containing all of the elements in this queue, in
32.590 + * proper sequence.
32.591 + *
32.592 + * <p>The returned array will be "safe" in that no references to it are
32.593 + * maintained by this queue. (In other words, this method must allocate
32.594 + * a new array). The caller is thus free to modify the returned array.
32.595 + *
32.596 + * <p>This method acts as bridge between array-based and collection-based
32.597 + * APIs.
32.598 + *
32.599 + * @return an array containing all of the elements in this queue
32.600 + */
32.601 + public Object[] toArray() {
32.602 + fullyLock();
32.603 + try {
32.604 + int size = count.get();
32.605 + Object[] a = new Object[size];
32.606 + int k = 0;
32.607 + for (Node<E> p = head.next; p != null; p = p.next)
32.608 + a[k++] = p.item;
32.609 + return a;
32.610 + } finally {
32.611 + fullyUnlock();
32.612 + }
32.613 + }
32.614 +
32.615 + /**
32.616 + * Returns an array containing all of the elements in this queue, in
32.617 + * proper sequence; the runtime type of the returned array is that of
32.618 + * the specified array. If the queue fits in the specified array, it
32.619 + * is returned therein. Otherwise, a new array is allocated with the
32.620 + * runtime type of the specified array and the size of this queue.
32.621 + *
32.622 + * <p>If this queue fits in the specified array with room to spare
32.623 + * (i.e., the array has more elements than this queue), the element in
32.624 + * the array immediately following the end of the queue is set to
32.625 + * {@code null}.
32.626 + *
32.627 + * <p>Like the {@link #toArray()} method, this method acts as bridge between
32.628 + * array-based and collection-based APIs. Further, this method allows
32.629 + * precise control over the runtime type of the output array, and may,
32.630 + * under certain circumstances, be used to save allocation costs.
32.631 + *
32.632 + * <p>Suppose {@code x} is a queue known to contain only strings.
32.633 + * The following code can be used to dump the queue into a newly
32.634 + * allocated array of {@code String}:
32.635 + *
32.636 + * <pre>
32.637 + * String[] y = x.toArray(new String[0]);</pre>
32.638 + *
32.639 + * Note that {@code toArray(new Object[0])} is identical in function to
32.640 + * {@code toArray()}.
32.641 + *
32.642 + * @param a the array into which the elements of the queue are to
32.643 + * be stored, if it is big enough; otherwise, a new array of the
32.644 + * same runtime type is allocated for this purpose
32.645 + * @return an array containing all of the elements in this queue
32.646 + * @throws ArrayStoreException if the runtime type of the specified array
32.647 + * is not a supertype of the runtime type of every element in
32.648 + * this queue
32.649 + * @throws NullPointerException if the specified array is null
32.650 + */
32.651 + @SuppressWarnings("unchecked")
32.652 + public <T> T[] toArray(T[] a) {
32.653 + fullyLock();
32.654 + try {
32.655 + int size = count.get();
32.656 + if (a.length < size)
32.657 + a = (T[])java.lang.reflect.Array.newInstance
32.658 + (a.getClass().getComponentType(), size);
32.659 +
32.660 + int k = 0;
32.661 + for (Node<E> p = head.next; p != null; p = p.next)
32.662 + a[k++] = (T)p.item;
32.663 + if (a.length > k)
32.664 + a[k] = null;
32.665 + return a;
32.666 + } finally {
32.667 + fullyUnlock();
32.668 + }
32.669 + }
32.670 +
32.671 + public String toString() {
32.672 + fullyLock();
32.673 + try {
32.674 + Node<E> p = head.next;
32.675 + if (p == null)
32.676 + return "[]";
32.677 +
32.678 + StringBuilder sb = new StringBuilder();
32.679 + sb.append('[');
32.680 + for (;;) {
32.681 + E e = p.item;
32.682 + sb.append(e == this ? "(this Collection)" : e);
32.683 + p = p.next;
32.684 + if (p == null)
32.685 + return sb.append(']').toString();
32.686 + sb.append(',').append(' ');
32.687 + }
32.688 + } finally {
32.689 + fullyUnlock();
32.690 + }
32.691 + }
32.692 +
32.693 + /**
32.694 + * Atomically removes all of the elements from this queue.
32.695 + * The queue will be empty after this call returns.
32.696 + */
32.697 + public void clear() {
32.698 + fullyLock();
32.699 + try {
32.700 + for (Node<E> p, h = head; (p = h.next) != null; h = p) {
32.701 + h.next = h;
32.702 + p.item = null;
32.703 + }
32.704 + head = last;
32.705 + // assert head.item == null && head.next == null;
32.706 + if (count.getAndSet(0) == capacity)
32.707 + notFull.signal();
32.708 + } finally {
32.709 + fullyUnlock();
32.710 + }
32.711 + }
32.712 +
32.713 + /**
32.714 + * @throws UnsupportedOperationException {@inheritDoc}
32.715 + * @throws ClassCastException {@inheritDoc}
32.716 + * @throws NullPointerException {@inheritDoc}
32.717 + * @throws IllegalArgumentException {@inheritDoc}
32.718 + */
32.719 + public int drainTo(Collection<? super E> c) {
32.720 + return drainTo(c, Integer.MAX_VALUE);
32.721 + }
32.722 +
32.723 + /**
32.724 + * @throws UnsupportedOperationException {@inheritDoc}
32.725 + * @throws ClassCastException {@inheritDoc}
32.726 + * @throws NullPointerException {@inheritDoc}
32.727 + * @throws IllegalArgumentException {@inheritDoc}
32.728 + */
32.729 + public int drainTo(Collection<? super E> c, int maxElements) {
32.730 + if (c == null)
32.731 + throw new NullPointerException();
32.732 + if (c == this)
32.733 + throw new IllegalArgumentException();
32.734 + boolean signalNotFull = false;
32.735 + final ReentrantLock takeLock = this.takeLock;
32.736 + takeLock.lock();
32.737 + try {
32.738 + int n = Math.min(maxElements, count.get());
32.739 + // count.get provides visibility to first n Nodes
32.740 + Node<E> h = head;
32.741 + int i = 0;
32.742 + try {
32.743 + while (i < n) {
32.744 + Node<E> p = h.next;
32.745 + c.add(p.item);
32.746 + p.item = null;
32.747 + h.next = h;
32.748 + h = p;
32.749 + ++i;
32.750 + }
32.751 + return n;
32.752 + } finally {
32.753 + // Restore invariants even if c.add() threw
32.754 + if (i > 0) {
32.755 + // assert h.item == null;
32.756 + head = h;
32.757 + signalNotFull = (count.getAndAdd(-i) == capacity);
32.758 + }
32.759 + }
32.760 + } finally {
32.761 + takeLock.unlock();
32.762 + if (signalNotFull)
32.763 + signalNotFull();
32.764 + }
32.765 + }
32.766 +
32.767 + /**
32.768 + * Returns an iterator over the elements in this queue in proper sequence.
32.769 + * The elements will be returned in order from first (head) to last (tail).
32.770 + *
32.771 + * <p>The returned iterator is a "weakly consistent" iterator that
32.772 + * will never throw {@link java.util.ConcurrentModificationException
32.773 + * ConcurrentModificationException}, and guarantees to traverse
32.774 + * elements as they existed upon construction of the iterator, and
32.775 + * may (but is not guaranteed to) reflect any modifications
32.776 + * subsequent to construction.
32.777 + *
32.778 + * @return an iterator over the elements in this queue in proper sequence
32.779 + */
32.780 + public Iterator<E> iterator() {
32.781 + return new Itr();
32.782 + }
32.783 +
32.784 + private class Itr implements Iterator<E> {
32.785 + /*
32.786 + * Basic weakly-consistent iterator. At all times hold the next
32.787 + * item to hand out so that if hasNext() reports true, we will
32.788 + * still have it to return even if lost race with a take etc.
32.789 + */
32.790 + private Node<E> current;
32.791 + private Node<E> lastRet;
32.792 + private E currentElement;
32.793 +
32.794 + Itr() {
32.795 + fullyLock();
32.796 + try {
32.797 + current = head.next;
32.798 + if (current != null)
32.799 + currentElement = current.item;
32.800 + } finally {
32.801 + fullyUnlock();
32.802 + }
32.803 + }
32.804 +
32.805 + public boolean hasNext() {
32.806 + return current != null;
32.807 + }
32.808 +
32.809 + /**
32.810 + * Returns the next live successor of p, or null if no such.
32.811 + *
32.812 + * Unlike other traversal methods, iterators need to handle both:
32.813 + * - dequeued nodes (p.next == p)
32.814 + * - (possibly multiple) interior removed nodes (p.item == null)
32.815 + */
32.816 + private Node<E> nextNode(Node<E> p) {
32.817 + for (;;) {
32.818 + Node<E> s = p.next;
32.819 + if (s == p)
32.820 + return head.next;
32.821 + if (s == null || s.item != null)
32.822 + return s;
32.823 + p = s;
32.824 + }
32.825 + }
32.826 +
32.827 + public E next() {
32.828 + fullyLock();
32.829 + try {
32.830 + if (current == null)
32.831 + throw new NoSuchElementException();
32.832 + E x = currentElement;
32.833 + lastRet = current;
32.834 + current = nextNode(current);
32.835 + currentElement = (current == null) ? null : current.item;
32.836 + return x;
32.837 + } finally {
32.838 + fullyUnlock();
32.839 + }
32.840 + }
32.841 +
32.842 + public void remove() {
32.843 + if (lastRet == null)
32.844 + throw new IllegalStateException();
32.845 + fullyLock();
32.846 + try {
32.847 + Node<E> node = lastRet;
32.848 + lastRet = null;
32.849 + for (Node<E> trail = head, p = trail.next;
32.850 + p != null;
32.851 + trail = p, p = p.next) {
32.852 + if (p == node) {
32.853 + unlink(p, trail);
32.854 + break;
32.855 + }
32.856 + }
32.857 + } finally {
32.858 + fullyUnlock();
32.859 + }
32.860 + }
32.861 + }
32.862 +
32.863 + /**
32.864 + * Save the state to a stream (that is, serialize it).
32.865 + *
32.866 + * @serialData The capacity is emitted (int), followed by all of
32.867 + * its elements (each an {@code Object}) in the proper order,
32.868 + * followed by a null
32.869 + * @param s the stream
32.870 + */
32.871 + private void writeObject(java.io.ObjectOutputStream s)
32.872 + throws java.io.IOException {
32.873 +
32.874 + fullyLock();
32.875 + try {
32.876 + // Write out any hidden stuff, plus capacity
32.877 + s.defaultWriteObject();
32.878 +
32.879 + // Write out all elements in the proper order.
32.880 + for (Node<E> p = head.next; p != null; p = p.next)
32.881 + s.writeObject(p.item);
32.882 +
32.883 + // Use trailing null as sentinel
32.884 + s.writeObject(null);
32.885 + } finally {
32.886 + fullyUnlock();
32.887 + }
32.888 + }
32.889 +
32.890 + /**
32.891 + * Reconstitute this queue instance from a stream (that is,
32.892 + * deserialize it).
32.893 + *
32.894 + * @param s the stream
32.895 + */
32.896 + private void readObject(java.io.ObjectInputStream s)
32.897 + throws java.io.IOException, ClassNotFoundException {
32.898 + // Read in capacity, and any hidden stuff
32.899 + s.defaultReadObject();
32.900 +
32.901 + count.set(0);
32.902 + last = head = new Node<E>(null);
32.903 +
32.904 + // Read in all elements and place in queue
32.905 + for (;;) {
32.906 + @SuppressWarnings("unchecked")
32.907 + E item = (E)s.readObject();
32.908 + if (item == null)
32.909 + break;
32.910 + add(item);
32.911 + }
32.912 + }
32.913 +}
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
33.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/LinkedTransferQueue.java Sat Mar 19 10:46:31 2016 +0100
33.3 @@ -0,0 +1,1351 @@
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.AbstractQueue;
33.42 +import java.util.Collection;
33.43 +import java.util.Iterator;
33.44 +import java.util.NoSuchElementException;
33.45 +import java.util.Queue;
33.46 +import java.util.concurrent.TimeUnit;
33.47 +import java.util.concurrent.locks.LockSupport;
33.48 +
33.49 +/**
33.50 + * An unbounded {@link TransferQueue} based on linked nodes.
33.51 + * This queue orders elements FIFO (first-in-first-out) with respect
33.52 + * to any given producer. The <em>head</em> of the queue is that
33.53 + * element that has been on the queue the longest time for some
33.54 + * producer. The <em>tail</em> of the queue is that element that has
33.55 + * been on the queue the shortest time for some producer.
33.56 + *
33.57 + * <p>Beware that, unlike in most collections, the {@code size} method
33.58 + * is <em>NOT</em> a constant-time operation. Because of the
33.59 + * asynchronous nature of these queues, determining the current number
33.60 + * of elements requires a traversal of the elements, and so may report
33.61 + * inaccurate results if this collection is modified during traversal.
33.62 + * Additionally, the bulk operations {@code addAll},
33.63 + * {@code removeAll}, {@code retainAll}, {@code containsAll},
33.64 + * {@code equals}, and {@code toArray} are <em>not</em> guaranteed
33.65 + * to be performed atomically. For example, an iterator operating
33.66 + * concurrently with an {@code addAll} operation might view only some
33.67 + * of the added elements.
33.68 + *
33.69 + * <p>This class and its iterator implement all of the
33.70 + * <em>optional</em> methods of the {@link Collection} and {@link
33.71 + * Iterator} interfaces.
33.72 + *
33.73 + * <p>Memory consistency effects: As with other concurrent
33.74 + * collections, actions in a thread prior to placing an object into a
33.75 + * {@code LinkedTransferQueue}
33.76 + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
33.77 + * actions subsequent to the access or removal of that element from
33.78 + * the {@code LinkedTransferQueue} in another thread.
33.79 + *
33.80 + * <p>This class is a member of the
33.81 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
33.82 + * Java Collections Framework</a>.
33.83 + *
33.84 + * @since 1.7
33.85 + * @author Doug Lea
33.86 + * @param <E> the type of elements held in this collection
33.87 + */
33.88 +public class LinkedTransferQueue<E> extends AbstractQueue<E>
33.89 + implements TransferQueue<E>, java.io.Serializable {
33.90 + private static final long serialVersionUID = -3223113410248163686L;
33.91 +
33.92 + /*
33.93 + * *** Overview of Dual Queues with Slack ***
33.94 + *
33.95 + * Dual Queues, introduced by Scherer and Scott
33.96 + * (http://www.cs.rice.edu/~wns1/papers/2004-DISC-DDS.pdf) are
33.97 + * (linked) queues in which nodes may represent either data or
33.98 + * requests. When a thread tries to enqueue a data node, but
33.99 + * encounters a request node, it instead "matches" and removes it;
33.100 + * and vice versa for enqueuing requests. Blocking Dual Queues
33.101 + * arrange that threads enqueuing unmatched requests block until
33.102 + * other threads provide the match. Dual Synchronous Queues (see
33.103 + * Scherer, Lea, & Scott
33.104 + * http://www.cs.rochester.edu/u/scott/papers/2009_Scherer_CACM_SSQ.pdf)
33.105 + * additionally arrange that threads enqueuing unmatched data also
33.106 + * block. Dual Transfer Queues support all of these modes, as
33.107 + * dictated by callers.
33.108 + *
33.109 + * A FIFO dual queue may be implemented using a variation of the
33.110 + * Michael & Scott (M&S) lock-free queue algorithm
33.111 + * (http://www.cs.rochester.edu/u/scott/papers/1996_PODC_queues.pdf).
33.112 + * It maintains two pointer fields, "head", pointing to a
33.113 + * (matched) node that in turn points to the first actual
33.114 + * (unmatched) queue node (or null if empty); and "tail" that
33.115 + * points to the last node on the queue (or again null if
33.116 + * empty). For example, here is a possible queue with four data
33.117 + * elements:
33.118 + *
33.119 + * head tail
33.120 + * | |
33.121 + * v v
33.122 + * M -> U -> U -> U -> U
33.123 + *
33.124 + * The M&S queue algorithm is known to be prone to scalability and
33.125 + * overhead limitations when maintaining (via CAS) these head and
33.126 + * tail pointers. This has led to the development of
33.127 + * contention-reducing variants such as elimination arrays (see
33.128 + * Moir et al http://portal.acm.org/citation.cfm?id=1074013) and
33.129 + * optimistic back pointers (see Ladan-Mozes & Shavit
33.130 + * http://people.csail.mit.edu/edya/publications/OptimisticFIFOQueue-journal.pdf).
33.131 + * However, the nature of dual queues enables a simpler tactic for
33.132 + * improving M&S-style implementations when dual-ness is needed.
33.133 + *
33.134 + * In a dual queue, each node must atomically maintain its match
33.135 + * status. While there are other possible variants, we implement
33.136 + * this here as: for a data-mode node, matching entails CASing an
33.137 + * "item" field from a non-null data value to null upon match, and
33.138 + * vice-versa for request nodes, CASing from null to a data
33.139 + * value. (Note that the linearization properties of this style of
33.140 + * queue are easy to verify -- elements are made available by
33.141 + * linking, and unavailable by matching.) Compared to plain M&S
33.142 + * queues, this property of dual queues requires one additional
33.143 + * successful atomic operation per enq/deq pair. But it also
33.144 + * enables lower cost variants of queue maintenance mechanics. (A
33.145 + * variation of this idea applies even for non-dual queues that
33.146 + * support deletion of interior elements, such as
33.147 + * j.u.c.ConcurrentLinkedQueue.)
33.148 + *
33.149 + * Once a node is matched, its match status can never again
33.150 + * change. We may thus arrange that the linked list of them
33.151 + * contain a prefix of zero or more matched nodes, followed by a
33.152 + * suffix of zero or more unmatched nodes. (Note that we allow
33.153 + * both the prefix and suffix to be zero length, which in turn
33.154 + * means that we do not use a dummy header.) If we were not
33.155 + * concerned with either time or space efficiency, we could
33.156 + * correctly perform enqueue and dequeue operations by traversing
33.157 + * from a pointer to the initial node; CASing the item of the
33.158 + * first unmatched node on match and CASing the next field of the
33.159 + * trailing node on appends. (Plus some special-casing when
33.160 + * initially empty). While this would be a terrible idea in
33.161 + * itself, it does have the benefit of not requiring ANY atomic
33.162 + * updates on head/tail fields.
33.163 + *
33.164 + * We introduce here an approach that lies between the extremes of
33.165 + * never versus always updating queue (head and tail) pointers.
33.166 + * This offers a tradeoff between sometimes requiring extra
33.167 + * traversal steps to locate the first and/or last unmatched
33.168 + * nodes, versus the reduced overhead and contention of fewer
33.169 + * updates to queue pointers. For example, a possible snapshot of
33.170 + * a queue is:
33.171 + *
33.172 + * head tail
33.173 + * | |
33.174 + * v v
33.175 + * M -> M -> U -> U -> U -> U
33.176 + *
33.177 + * The best value for this "slack" (the targeted maximum distance
33.178 + * between the value of "head" and the first unmatched node, and
33.179 + * similarly for "tail") is an empirical matter. We have found
33.180 + * that using very small constants in the range of 1-3 work best
33.181 + * over a range of platforms. Larger values introduce increasing
33.182 + * costs of cache misses and risks of long traversal chains, while
33.183 + * smaller values increase CAS contention and overhead.
33.184 + *
33.185 + * Dual queues with slack differ from plain M&S dual queues by
33.186 + * virtue of only sometimes updating head or tail pointers when
33.187 + * matching, appending, or even traversing nodes; in order to
33.188 + * maintain a targeted slack. The idea of "sometimes" may be
33.189 + * operationalized in several ways. The simplest is to use a
33.190 + * per-operation counter incremented on each traversal step, and
33.191 + * to try (via CAS) to update the associated queue pointer
33.192 + * whenever the count exceeds a threshold. Another, that requires
33.193 + * more overhead, is to use random number generators to update
33.194 + * with a given probability per traversal step.
33.195 + *
33.196 + * In any strategy along these lines, because CASes updating
33.197 + * fields may fail, the actual slack may exceed targeted
33.198 + * slack. However, they may be retried at any time to maintain
33.199 + * targets. Even when using very small slack values, this
33.200 + * approach works well for dual queues because it allows all
33.201 + * operations up to the point of matching or appending an item
33.202 + * (hence potentially allowing progress by another thread) to be
33.203 + * read-only, thus not introducing any further contention. As
33.204 + * described below, we implement this by performing slack
33.205 + * maintenance retries only after these points.
33.206 + *
33.207 + * As an accompaniment to such techniques, traversal overhead can
33.208 + * be further reduced without increasing contention of head
33.209 + * pointer updates: Threads may sometimes shortcut the "next" link
33.210 + * path from the current "head" node to be closer to the currently
33.211 + * known first unmatched node, and similarly for tail. Again, this
33.212 + * may be triggered with using thresholds or randomization.
33.213 + *
33.214 + * These ideas must be further extended to avoid unbounded amounts
33.215 + * of costly-to-reclaim garbage caused by the sequential "next"
33.216 + * links of nodes starting at old forgotten head nodes: As first
33.217 + * described in detail by Boehm
33.218 + * (http://portal.acm.org/citation.cfm?doid=503272.503282) if a GC
33.219 + * delays noticing that any arbitrarily old node has become
33.220 + * garbage, all newer dead nodes will also be unreclaimed.
33.221 + * (Similar issues arise in non-GC environments.) To cope with
33.222 + * this in our implementation, upon CASing to advance the head
33.223 + * pointer, we set the "next" link of the previous head to point
33.224 + * only to itself; thus limiting the length of connected dead lists.
33.225 + * (We also take similar care to wipe out possibly garbage
33.226 + * retaining values held in other Node fields.) However, doing so
33.227 + * adds some further complexity to traversal: If any "next"
33.228 + * pointer links to itself, it indicates that the current thread
33.229 + * has lagged behind a head-update, and so the traversal must
33.230 + * continue from the "head". Traversals trying to find the
33.231 + * current tail starting from "tail" may also encounter
33.232 + * self-links, in which case they also continue at "head".
33.233 + *
33.234 + * It is tempting in slack-based scheme to not even use CAS for
33.235 + * updates (similarly to Ladan-Mozes & Shavit). However, this
33.236 + * cannot be done for head updates under the above link-forgetting
33.237 + * mechanics because an update may leave head at a detached node.
33.238 + * And while direct writes are possible for tail updates, they
33.239 + * increase the risk of long retraversals, and hence long garbage
33.240 + * chains, which can be much more costly than is worthwhile
33.241 + * considering that the cost difference of performing a CAS vs
33.242 + * write is smaller when they are not triggered on each operation
33.243 + * (especially considering that writes and CASes equally require
33.244 + * additional GC bookkeeping ("write barriers") that are sometimes
33.245 + * more costly than the writes themselves because of contention).
33.246 + *
33.247 + * *** Overview of implementation ***
33.248 + *
33.249 + * We use a threshold-based approach to updates, with a slack
33.250 + * threshold of two -- that is, we update head/tail when the
33.251 + * current pointer appears to be two or more steps away from the
33.252 + * first/last node. The slack value is hard-wired: a path greater
33.253 + * than one is naturally implemented by checking equality of
33.254 + * traversal pointers except when the list has only one element,
33.255 + * in which case we keep slack threshold at one. Avoiding tracking
33.256 + * explicit counts across method calls slightly simplifies an
33.257 + * already-messy implementation. Using randomization would
33.258 + * probably work better if there were a low-quality dirt-cheap
33.259 + * per-thread one available, but even ThreadLocalRandom is too
33.260 + * heavy for these purposes.
33.261 + *
33.262 + * With such a small slack threshold value, it is not worthwhile
33.263 + * to augment this with path short-circuiting (i.e., unsplicing
33.264 + * interior nodes) except in the case of cancellation/removal (see
33.265 + * below).
33.266 + *
33.267 + * We allow both the head and tail fields to be null before any
33.268 + * nodes are enqueued; initializing upon first append. This
33.269 + * simplifies some other logic, as well as providing more
33.270 + * efficient explicit control paths instead of letting JVMs insert
33.271 + * implicit NullPointerExceptions when they are null. While not
33.272 + * currently fully implemented, we also leave open the possibility
33.273 + * of re-nulling these fields when empty (which is complicated to
33.274 + * arrange, for little benefit.)
33.275 + *
33.276 + * All enqueue/dequeue operations are handled by the single method
33.277 + * "xfer" with parameters indicating whether to act as some form
33.278 + * of offer, put, poll, take, or transfer (each possibly with
33.279 + * timeout). The relative complexity of using one monolithic
33.280 + * method outweighs the code bulk and maintenance problems of
33.281 + * using separate methods for each case.
33.282 + *
33.283 + * Operation consists of up to three phases. The first is
33.284 + * implemented within method xfer, the second in tryAppend, and
33.285 + * the third in method awaitMatch.
33.286 + *
33.287 + * 1. Try to match an existing node
33.288 + *
33.289 + * Starting at head, skip already-matched nodes until finding
33.290 + * an unmatched node of opposite mode, if one exists, in which
33.291 + * case matching it and returning, also if necessary updating
33.292 + * head to one past the matched node (or the node itself if the
33.293 + * list has no other unmatched nodes). If the CAS misses, then
33.294 + * a loop retries advancing head by two steps until either
33.295 + * success or the slack is at most two. By requiring that each
33.296 + * attempt advances head by two (if applicable), we ensure that
33.297 + * the slack does not grow without bound. Traversals also check
33.298 + * if the initial head is now off-list, in which case they
33.299 + * start at the new head.
33.300 + *
33.301 + * If no candidates are found and the call was untimed
33.302 + * poll/offer, (argument "how" is NOW) return.
33.303 + *
33.304 + * 2. Try to append a new node (method tryAppend)
33.305 + *
33.306 + * Starting at current tail pointer, find the actual last node
33.307 + * and try to append a new node (or if head was null, establish
33.308 + * the first node). Nodes can be appended only if their
33.309 + * predecessors are either already matched or are of the same
33.310 + * mode. If we detect otherwise, then a new node with opposite
33.311 + * mode must have been appended during traversal, so we must
33.312 + * restart at phase 1. The traversal and update steps are
33.313 + * otherwise similar to phase 1: Retrying upon CAS misses and
33.314 + * checking for staleness. In particular, if a self-link is
33.315 + * encountered, then we can safely jump to a node on the list
33.316 + * by continuing the traversal at current head.
33.317 + *
33.318 + * On successful append, if the call was ASYNC, return.
33.319 + *
33.320 + * 3. Await match or cancellation (method awaitMatch)
33.321 + *
33.322 + * Wait for another thread to match node; instead cancelling if
33.323 + * the current thread was interrupted or the wait timed out. On
33.324 + * multiprocessors, we use front-of-queue spinning: If a node
33.325 + * appears to be the first unmatched node in the queue, it
33.326 + * spins a bit before blocking. In either case, before blocking
33.327 + * it tries to unsplice any nodes between the current "head"
33.328 + * and the first unmatched node.
33.329 + *
33.330 + * Front-of-queue spinning vastly improves performance of
33.331 + * heavily contended queues. And so long as it is relatively
33.332 + * brief and "quiet", spinning does not much impact performance
33.333 + * of less-contended queues. During spins threads check their
33.334 + * interrupt status and generate a thread-local random number
33.335 + * to decide to occasionally perform a Thread.yield. While
33.336 + * yield has underdefined specs, we assume that might it help,
33.337 + * and will not hurt in limiting impact of spinning on busy
33.338 + * systems. We also use smaller (1/2) spins for nodes that are
33.339 + * not known to be front but whose predecessors have not
33.340 + * blocked -- these "chained" spins avoid artifacts of
33.341 + * front-of-queue rules which otherwise lead to alternating
33.342 + * nodes spinning vs blocking. Further, front threads that
33.343 + * represent phase changes (from data to request node or vice
33.344 + * versa) compared to their predecessors receive additional
33.345 + * chained spins, reflecting longer paths typically required to
33.346 + * unblock threads during phase changes.
33.347 + *
33.348 + *
33.349 + * ** Unlinking removed interior nodes **
33.350 + *
33.351 + * In addition to minimizing garbage retention via self-linking
33.352 + * described above, we also unlink removed interior nodes. These
33.353 + * may arise due to timed out or interrupted waits, or calls to
33.354 + * remove(x) or Iterator.remove. Normally, given a node that was
33.355 + * at one time known to be the predecessor of some node s that is
33.356 + * to be removed, we can unsplice s by CASing the next field of
33.357 + * its predecessor if it still points to s (otherwise s must
33.358 + * already have been removed or is now offlist). But there are two
33.359 + * situations in which we cannot guarantee to make node s
33.360 + * unreachable in this way: (1) If s is the trailing node of list
33.361 + * (i.e., with null next), then it is pinned as the target node
33.362 + * for appends, so can only be removed later after other nodes are
33.363 + * appended. (2) We cannot necessarily unlink s given a
33.364 + * predecessor node that is matched (including the case of being
33.365 + * cancelled): the predecessor may already be unspliced, in which
33.366 + * case some previous reachable node may still point to s.
33.367 + * (For further explanation see Herlihy & Shavit "The Art of
33.368 + * Multiprocessor Programming" chapter 9). Although, in both
33.369 + * cases, we can rule out the need for further action if either s
33.370 + * or its predecessor are (or can be made to be) at, or fall off
33.371 + * from, the head of list.
33.372 + *
33.373 + * Without taking these into account, it would be possible for an
33.374 + * unbounded number of supposedly removed nodes to remain
33.375 + * reachable. Situations leading to such buildup are uncommon but
33.376 + * can occur in practice; for example when a series of short timed
33.377 + * calls to poll repeatedly time out but never otherwise fall off
33.378 + * the list because of an untimed call to take at the front of the
33.379 + * queue.
33.380 + *
33.381 + * When these cases arise, rather than always retraversing the
33.382 + * entire list to find an actual predecessor to unlink (which
33.383 + * won't help for case (1) anyway), we record a conservative
33.384 + * estimate of possible unsplice failures (in "sweepVotes").
33.385 + * We trigger a full sweep when the estimate exceeds a threshold
33.386 + * ("SWEEP_THRESHOLD") indicating the maximum number of estimated
33.387 + * removal failures to tolerate before sweeping through, unlinking
33.388 + * cancelled nodes that were not unlinked upon initial removal.
33.389 + * We perform sweeps by the thread hitting threshold (rather than
33.390 + * background threads or by spreading work to other threads)
33.391 + * because in the main contexts in which removal occurs, the
33.392 + * caller is already timed-out, cancelled, or performing a
33.393 + * potentially O(n) operation (e.g. remove(x)), none of which are
33.394 + * time-critical enough to warrant the overhead that alternatives
33.395 + * would impose on other threads.
33.396 + *
33.397 + * Because the sweepVotes estimate is conservative, and because
33.398 + * nodes become unlinked "naturally" as they fall off the head of
33.399 + * the queue, and because we allow votes to accumulate even while
33.400 + * sweeps are in progress, there are typically significantly fewer
33.401 + * such nodes than estimated. Choice of a threshold value
33.402 + * balances the likelihood of wasted effort and contention, versus
33.403 + * providing a worst-case bound on retention of interior nodes in
33.404 + * quiescent queues. The value defined below was chosen
33.405 + * empirically to balance these under various timeout scenarios.
33.406 + *
33.407 + * Note that we cannot self-link unlinked interior nodes during
33.408 + * sweeps. However, the associated garbage chains terminate when
33.409 + * some successor ultimately falls off the head of the list and is
33.410 + * self-linked.
33.411 + */
33.412 +
33.413 + /** True if on multiprocessor */
33.414 + private static final boolean MP =
33.415 + Runtime.getRuntime().availableProcessors() > 1;
33.416 +
33.417 + /**
33.418 + * The number of times to spin (with randomly interspersed calls
33.419 + * to Thread.yield) on multiprocessor before blocking when a node
33.420 + * is apparently the first waiter in the queue. See above for
33.421 + * explanation. Must be a power of two. The value is empirically
33.422 + * derived -- it works pretty well across a variety of processors,
33.423 + * numbers of CPUs, and OSes.
33.424 + */
33.425 + private static final int FRONT_SPINS = 1 << 7;
33.426 +
33.427 + /**
33.428 + * The number of times to spin before blocking when a node is
33.429 + * preceded by another node that is apparently spinning. Also
33.430 + * serves as an increment to FRONT_SPINS on phase changes, and as
33.431 + * base average frequency for yielding during spins. Must be a
33.432 + * power of two.
33.433 + */
33.434 + private static final int CHAINED_SPINS = FRONT_SPINS >>> 1;
33.435 +
33.436 + /**
33.437 + * The maximum number of estimated removal failures (sweepVotes)
33.438 + * to tolerate before sweeping through the queue unlinking
33.439 + * cancelled nodes that were not unlinked upon initial
33.440 + * removal. See above for explanation. The value must be at least
33.441 + * two to avoid useless sweeps when removing trailing nodes.
33.442 + */
33.443 + static final int SWEEP_THRESHOLD = 32;
33.444 +
33.445 + /**
33.446 + * Queue nodes. Uses Object, not E, for items to allow forgetting
33.447 + * them after use. Relies heavily on Unsafe mechanics to minimize
33.448 + * unnecessary ordering constraints: Writes that are intrinsically
33.449 + * ordered wrt other accesses or CASes use simple relaxed forms.
33.450 + */
33.451 + static final class Node {
33.452 + final boolean isData; // false if this is a request node
33.453 + volatile Object item; // initially non-null if isData; CASed to match
33.454 + volatile Node next;
33.455 + volatile Thread waiter; // null until waiting
33.456 +
33.457 + // CAS methods for fields
33.458 + final boolean casNext(Node cmp, Node val) {
33.459 + return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
33.460 + }
33.461 +
33.462 + final boolean casItem(Object cmp, Object val) {
33.463 + // assert cmp == null || cmp.getClass() != Node.class;
33.464 + return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);
33.465 + }
33.466 +
33.467 + /**
33.468 + * Constructs a new node. Uses relaxed write because item can
33.469 + * only be seen after publication via casNext.
33.470 + */
33.471 + Node(Object item, boolean isData) {
33.472 + UNSAFE.putObject(this, itemOffset, item); // relaxed write
33.473 + this.isData = isData;
33.474 + }
33.475 +
33.476 + /**
33.477 + * Links node to itself to avoid garbage retention. Called
33.478 + * only after CASing head field, so uses relaxed write.
33.479 + */
33.480 + final void forgetNext() {
33.481 + UNSAFE.putObject(this, nextOffset, this);
33.482 + }
33.483 +
33.484 + /**
33.485 + * Sets item to self and waiter to null, to avoid garbage
33.486 + * retention after matching or cancelling. Uses relaxed writes
33.487 + * because order is already constrained in the only calling
33.488 + * contexts: item is forgotten only after volatile/atomic
33.489 + * mechanics that extract items. Similarly, clearing waiter
33.490 + * follows either CAS or return from park (if ever parked;
33.491 + * else we don't care).
33.492 + */
33.493 + final void forgetContents() {
33.494 + UNSAFE.putObject(this, itemOffset, this);
33.495 + UNSAFE.putObject(this, waiterOffset, null);
33.496 + }
33.497 +
33.498 + /**
33.499 + * Returns true if this node has been matched, including the
33.500 + * case of artificial matches due to cancellation.
33.501 + */
33.502 + final boolean isMatched() {
33.503 + Object x = item;
33.504 + return (x == this) || ((x == null) == isData);
33.505 + }
33.506 +
33.507 + /**
33.508 + * Returns true if this is an unmatched request node.
33.509 + */
33.510 + final boolean isUnmatchedRequest() {
33.511 + return !isData && item == null;
33.512 + }
33.513 +
33.514 + /**
33.515 + * Returns true if a node with the given mode cannot be
33.516 + * appended to this node because this node is unmatched and
33.517 + * has opposite data mode.
33.518 + */
33.519 + final boolean cannotPrecede(boolean haveData) {
33.520 + boolean d = isData;
33.521 + Object x;
33.522 + return d != haveData && (x = item) != this && (x != null) == d;
33.523 + }
33.524 +
33.525 + /**
33.526 + * Tries to artificially match a data node -- used by remove.
33.527 + */
33.528 + final boolean tryMatchData() {
33.529 + // assert isData;
33.530 + Object x = item;
33.531 + if (x != null && x != this && casItem(x, null)) {
33.532 + LockSupport.unpark(waiter);
33.533 + return true;
33.534 + }
33.535 + return false;
33.536 + }
33.537 +
33.538 + private static final long serialVersionUID = -3375979862319811754L;
33.539 +
33.540 + // Unsafe mechanics
33.541 + private static final sun.misc.Unsafe UNSAFE;
33.542 + private static final long itemOffset;
33.543 + private static final long nextOffset;
33.544 + private static final long waiterOffset;
33.545 + static {
33.546 + try {
33.547 + UNSAFE = sun.misc.Unsafe.getUnsafe();
33.548 + Class k = Node.class;
33.549 + itemOffset = UNSAFE.objectFieldOffset
33.550 + (k.getDeclaredField("item"));
33.551 + nextOffset = UNSAFE.objectFieldOffset
33.552 + (k.getDeclaredField("next"));
33.553 + waiterOffset = UNSAFE.objectFieldOffset
33.554 + (k.getDeclaredField("waiter"));
33.555 + } catch (Exception e) {
33.556 + throw new Error(e);
33.557 + }
33.558 + }
33.559 + }
33.560 +
33.561 + /** head of the queue; null until first enqueue */
33.562 + transient volatile Node head;
33.563 +
33.564 + /** tail of the queue; null until first append */
33.565 + private transient volatile Node tail;
33.566 +
33.567 + /** The number of apparent failures to unsplice removed nodes */
33.568 + private transient volatile int sweepVotes;
33.569 +
33.570 + // CAS methods for fields
33.571 + private boolean casTail(Node cmp, Node val) {
33.572 + return UNSAFE.compareAndSwapObject(this, tailOffset, cmp, val);
33.573 + }
33.574 +
33.575 + private boolean casHead(Node cmp, Node val) {
33.576 + return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
33.577 + }
33.578 +
33.579 + private boolean casSweepVotes(int cmp, int val) {
33.580 + return UNSAFE.compareAndSwapInt(this, sweepVotesOffset, cmp, val);
33.581 + }
33.582 +
33.583 + /*
33.584 + * Possible values for "how" argument in xfer method.
33.585 + */
33.586 + private static final int NOW = 0; // for untimed poll, tryTransfer
33.587 + private static final int ASYNC = 1; // for offer, put, add
33.588 + private static final int SYNC = 2; // for transfer, take
33.589 + private static final int TIMED = 3; // for timed poll, tryTransfer
33.590 +
33.591 + @SuppressWarnings("unchecked")
33.592 + static <E> E cast(Object item) {
33.593 + // assert item == null || item.getClass() != Node.class;
33.594 + return (E) item;
33.595 + }
33.596 +
33.597 + /**
33.598 + * Implements all queuing methods. See above for explanation.
33.599 + *
33.600 + * @param e the item or null for take
33.601 + * @param haveData true if this is a put, else a take
33.602 + * @param how NOW, ASYNC, SYNC, or TIMED
33.603 + * @param nanos timeout in nanosecs, used only if mode is TIMED
33.604 + * @return an item if matched, else e
33.605 + * @throws NullPointerException if haveData mode but e is null
33.606 + */
33.607 + private E xfer(E e, boolean haveData, int how, long nanos) {
33.608 + if (haveData && (e == null))
33.609 + throw new NullPointerException();
33.610 + Node s = null; // the node to append, if needed
33.611 +
33.612 + retry:
33.613 + for (;;) { // restart on append race
33.614 +
33.615 + for (Node h = head, p = h; p != null;) { // find & match first node
33.616 + boolean isData = p.isData;
33.617 + Object item = p.item;
33.618 + if (item != p && (item != null) == isData) { // unmatched
33.619 + if (isData == haveData) // can't match
33.620 + break;
33.621 + if (p.casItem(item, e)) { // match
33.622 + for (Node q = p; q != h;) {
33.623 + Node n = q.next; // update by 2 unless singleton
33.624 + if (head == h && casHead(h, n == null ? q : n)) {
33.625 + h.forgetNext();
33.626 + break;
33.627 + } // advance and retry
33.628 + if ((h = head) == null ||
33.629 + (q = h.next) == null || !q.isMatched())
33.630 + break; // unless slack < 2
33.631 + }
33.632 + LockSupport.unpark(p.waiter);
33.633 + return this.<E>cast(item);
33.634 + }
33.635 + }
33.636 + Node n = p.next;
33.637 + p = (p != n) ? n : (h = head); // Use head if p offlist
33.638 + }
33.639 +
33.640 + if (how != NOW) { // No matches available
33.641 + if (s == null)
33.642 + s = new Node(e, haveData);
33.643 + Node pred = tryAppend(s, haveData);
33.644 + if (pred == null)
33.645 + continue retry; // lost race vs opposite mode
33.646 + if (how != ASYNC)
33.647 + return awaitMatch(s, pred, e, (how == TIMED), nanos);
33.648 + }
33.649 + return e; // not waiting
33.650 + }
33.651 + }
33.652 +
33.653 + /**
33.654 + * Tries to append node s as tail.
33.655 + *
33.656 + * @param s the node to append
33.657 + * @param haveData true if appending in data mode
33.658 + * @return null on failure due to losing race with append in
33.659 + * different mode, else s's predecessor, or s itself if no
33.660 + * predecessor
33.661 + */
33.662 + private Node tryAppend(Node s, boolean haveData) {
33.663 + for (Node t = tail, p = t;;) { // move p to last node and append
33.664 + Node n, u; // temps for reads of next & tail
33.665 + if (p == null && (p = head) == null) {
33.666 + if (casHead(null, s))
33.667 + return s; // initialize
33.668 + }
33.669 + else if (p.cannotPrecede(haveData))
33.670 + return null; // lost race vs opposite mode
33.671 + else if ((n = p.next) != null) // not last; keep traversing
33.672 + p = p != t && t != (u = tail) ? (t = u) : // stale tail
33.673 + (p != n) ? n : null; // restart if off list
33.674 + else if (!p.casNext(null, s))
33.675 + p = p.next; // re-read on CAS failure
33.676 + else {
33.677 + if (p != t) { // update if slack now >= 2
33.678 + while ((tail != t || !casTail(t, s)) &&
33.679 + (t = tail) != null &&
33.680 + (s = t.next) != null && // advance and retry
33.681 + (s = s.next) != null && s != t);
33.682 + }
33.683 + return p;
33.684 + }
33.685 + }
33.686 + }
33.687 +
33.688 + /**
33.689 + * Spins/yields/blocks until node s is matched or caller gives up.
33.690 + *
33.691 + * @param s the waiting node
33.692 + * @param pred the predecessor of s, or s itself if it has no
33.693 + * predecessor, or null if unknown (the null case does not occur
33.694 + * in any current calls but may in possible future extensions)
33.695 + * @param e the comparison value for checking match
33.696 + * @param timed if true, wait only until timeout elapses
33.697 + * @param nanos timeout in nanosecs, used only if timed is true
33.698 + * @return matched item, or e if unmatched on interrupt or timeout
33.699 + */
33.700 + private E awaitMatch(Node s, Node pred, E e, boolean timed, long nanos) {
33.701 + long lastTime = timed ? System.nanoTime() : 0L;
33.702 + Thread w = Thread.currentThread();
33.703 + int spins = -1; // initialized after first item and cancel checks
33.704 + ThreadLocalRandom randomYields = null; // bound if needed
33.705 +
33.706 + for (;;) {
33.707 + Object item = s.item;
33.708 + if (item != e) { // matched
33.709 + // assert item != s;
33.710 + s.forgetContents(); // avoid garbage
33.711 + return this.<E>cast(item);
33.712 + }
33.713 + if ((w.isInterrupted() || (timed && nanos <= 0)) &&
33.714 + s.casItem(e, s)) { // cancel
33.715 + unsplice(pred, s);
33.716 + return e;
33.717 + }
33.718 +
33.719 + if (spins < 0) { // establish spins at/near front
33.720 + if ((spins = spinsFor(pred, s.isData)) > 0)
33.721 + randomYields = ThreadLocalRandom.current();
33.722 + }
33.723 + else if (spins > 0) { // spin
33.724 + --spins;
33.725 + if (randomYields.nextInt(CHAINED_SPINS) == 0)
33.726 + Thread.yield(); // occasionally yield
33.727 + }
33.728 + else if (s.waiter == null) {
33.729 + s.waiter = w; // request unpark then recheck
33.730 + }
33.731 + else if (timed) {
33.732 + long now = System.nanoTime();
33.733 + if ((nanos -= now - lastTime) > 0)
33.734 + LockSupport.parkNanos(this, nanos);
33.735 + lastTime = now;
33.736 + }
33.737 + else {
33.738 + LockSupport.park(this);
33.739 + }
33.740 + }
33.741 + }
33.742 +
33.743 + /**
33.744 + * Returns spin/yield value for a node with given predecessor and
33.745 + * data mode. See above for explanation.
33.746 + */
33.747 + private static int spinsFor(Node pred, boolean haveData) {
33.748 + if (MP && pred != null) {
33.749 + if (pred.isData != haveData) // phase change
33.750 + return FRONT_SPINS + CHAINED_SPINS;
33.751 + if (pred.isMatched()) // probably at front
33.752 + return FRONT_SPINS;
33.753 + if (pred.waiter == null) // pred apparently spinning
33.754 + return CHAINED_SPINS;
33.755 + }
33.756 + return 0;
33.757 + }
33.758 +
33.759 + /* -------------- Traversal methods -------------- */
33.760 +
33.761 + /**
33.762 + * Returns the successor of p, or the head node if p.next has been
33.763 + * linked to self, which will only be true if traversing with a
33.764 + * stale pointer that is now off the list.
33.765 + */
33.766 + final Node succ(Node p) {
33.767 + Node next = p.next;
33.768 + return (p == next) ? head : next;
33.769 + }
33.770 +
33.771 + /**
33.772 + * Returns the first unmatched node of the given mode, or null if
33.773 + * none. Used by methods isEmpty, hasWaitingConsumer.
33.774 + */
33.775 + private Node firstOfMode(boolean isData) {
33.776 + for (Node p = head; p != null; p = succ(p)) {
33.777 + if (!p.isMatched())
33.778 + return (p.isData == isData) ? p : null;
33.779 + }
33.780 + return null;
33.781 + }
33.782 +
33.783 + /**
33.784 + * Returns the item in the first unmatched node with isData; or
33.785 + * null if none. Used by peek.
33.786 + */
33.787 + private E firstDataItem() {
33.788 + for (Node p = head; p != null; p = succ(p)) {
33.789 + Object item = p.item;
33.790 + if (p.isData) {
33.791 + if (item != null && item != p)
33.792 + return this.<E>cast(item);
33.793 + }
33.794 + else if (item == null)
33.795 + return null;
33.796 + }
33.797 + return null;
33.798 + }
33.799 +
33.800 + /**
33.801 + * Traverses and counts unmatched nodes of the given mode.
33.802 + * Used by methods size and getWaitingConsumerCount.
33.803 + */
33.804 + private int countOfMode(boolean data) {
33.805 + int count = 0;
33.806 + for (Node p = head; p != null; ) {
33.807 + if (!p.isMatched()) {
33.808 + if (p.isData != data)
33.809 + return 0;
33.810 + if (++count == Integer.MAX_VALUE) // saturated
33.811 + break;
33.812 + }
33.813 + Node n = p.next;
33.814 + if (n != p)
33.815 + p = n;
33.816 + else {
33.817 + count = 0;
33.818 + p = head;
33.819 + }
33.820 + }
33.821 + return count;
33.822 + }
33.823 +
33.824 + final class Itr implements Iterator<E> {
33.825 + private Node nextNode; // next node to return item for
33.826 + private E nextItem; // the corresponding item
33.827 + private Node lastRet; // last returned node, to support remove
33.828 + private Node lastPred; // predecessor to unlink lastRet
33.829 +
33.830 + /**
33.831 + * Moves to next node after prev, or first node if prev null.
33.832 + */
33.833 + private void advance(Node prev) {
33.834 + /*
33.835 + * To track and avoid buildup of deleted nodes in the face
33.836 + * of calls to both Queue.remove and Itr.remove, we must
33.837 + * include variants of unsplice and sweep upon each
33.838 + * advance: Upon Itr.remove, we may need to catch up links
33.839 + * from lastPred, and upon other removes, we might need to
33.840 + * skip ahead from stale nodes and unsplice deleted ones
33.841 + * found while advancing.
33.842 + */
33.843 +
33.844 + Node r, b; // reset lastPred upon possible deletion of lastRet
33.845 + if ((r = lastRet) != null && !r.isMatched())
33.846 + lastPred = r; // next lastPred is old lastRet
33.847 + else if ((b = lastPred) == null || b.isMatched())
33.848 + lastPred = null; // at start of list
33.849 + else {
33.850 + Node s, n; // help with removal of lastPred.next
33.851 + while ((s = b.next) != null &&
33.852 + s != b && s.isMatched() &&
33.853 + (n = s.next) != null && n != s)
33.854 + b.casNext(s, n);
33.855 + }
33.856 +
33.857 + this.lastRet = prev;
33.858 +
33.859 + for (Node p = prev, s, n;;) {
33.860 + s = (p == null) ? head : p.next;
33.861 + if (s == null)
33.862 + break;
33.863 + else if (s == p) {
33.864 + p = null;
33.865 + continue;
33.866 + }
33.867 + Object item = s.item;
33.868 + if (s.isData) {
33.869 + if (item != null && item != s) {
33.870 + nextItem = LinkedTransferQueue.<E>cast(item);
33.871 + nextNode = s;
33.872 + return;
33.873 + }
33.874 + }
33.875 + else if (item == null)
33.876 + break;
33.877 + // assert s.isMatched();
33.878 + if (p == null)
33.879 + p = s;
33.880 + else if ((n = s.next) == null)
33.881 + break;
33.882 + else if (s == n)
33.883 + p = null;
33.884 + else
33.885 + p.casNext(s, n);
33.886 + }
33.887 + nextNode = null;
33.888 + nextItem = null;
33.889 + }
33.890 +
33.891 + Itr() {
33.892 + advance(null);
33.893 + }
33.894 +
33.895 + public final boolean hasNext() {
33.896 + return nextNode != null;
33.897 + }
33.898 +
33.899 + public final E next() {
33.900 + Node p = nextNode;
33.901 + if (p == null) throw new NoSuchElementException();
33.902 + E e = nextItem;
33.903 + advance(p);
33.904 + return e;
33.905 + }
33.906 +
33.907 + public final void remove() {
33.908 + final Node lastRet = this.lastRet;
33.909 + if (lastRet == null)
33.910 + throw new IllegalStateException();
33.911 + this.lastRet = null;
33.912 + if (lastRet.tryMatchData())
33.913 + unsplice(lastPred, lastRet);
33.914 + }
33.915 + }
33.916 +
33.917 + /* -------------- Removal methods -------------- */
33.918 +
33.919 + /**
33.920 + * Unsplices (now or later) the given deleted/cancelled node with
33.921 + * the given predecessor.
33.922 + *
33.923 + * @param pred a node that was at one time known to be the
33.924 + * predecessor of s, or null or s itself if s is/was at head
33.925 + * @param s the node to be unspliced
33.926 + */
33.927 + final void unsplice(Node pred, Node s) {
33.928 + s.forgetContents(); // forget unneeded fields
33.929 + /*
33.930 + * See above for rationale. Briefly: if pred still points to
33.931 + * s, try to unlink s. If s cannot be unlinked, because it is
33.932 + * trailing node or pred might be unlinked, and neither pred
33.933 + * nor s are head or offlist, add to sweepVotes, and if enough
33.934 + * votes have accumulated, sweep.
33.935 + */
33.936 + if (pred != null && pred != s && pred.next == s) {
33.937 + Node n = s.next;
33.938 + if (n == null ||
33.939 + (n != s && pred.casNext(s, n) && pred.isMatched())) {
33.940 + for (;;) { // check if at, or could be, head
33.941 + Node h = head;
33.942 + if (h == pred || h == s || h == null)
33.943 + return; // at head or list empty
33.944 + if (!h.isMatched())
33.945 + break;
33.946 + Node hn = h.next;
33.947 + if (hn == null)
33.948 + return; // now empty
33.949 + if (hn != h && casHead(h, hn))
33.950 + h.forgetNext(); // advance head
33.951 + }
33.952 + if (pred.next != pred && s.next != s) { // recheck if offlist
33.953 + for (;;) { // sweep now if enough votes
33.954 + int v = sweepVotes;
33.955 + if (v < SWEEP_THRESHOLD) {
33.956 + if (casSweepVotes(v, v + 1))
33.957 + break;
33.958 + }
33.959 + else if (casSweepVotes(v, 0)) {
33.960 + sweep();
33.961 + break;
33.962 + }
33.963 + }
33.964 + }
33.965 + }
33.966 + }
33.967 + }
33.968 +
33.969 + /**
33.970 + * Unlinks matched (typically cancelled) nodes encountered in a
33.971 + * traversal from head.
33.972 + */
33.973 + private void sweep() {
33.974 + for (Node p = head, s, n; p != null && (s = p.next) != null; ) {
33.975 + if (!s.isMatched())
33.976 + // Unmatched nodes are never self-linked
33.977 + p = s;
33.978 + else if ((n = s.next) == null) // trailing node is pinned
33.979 + break;
33.980 + else if (s == n) // stale
33.981 + // No need to also check for p == s, since that implies s == n
33.982 + p = head;
33.983 + else
33.984 + p.casNext(s, n);
33.985 + }
33.986 + }
33.987 +
33.988 + /**
33.989 + * Main implementation of remove(Object)
33.990 + */
33.991 + private boolean findAndRemove(Object e) {
33.992 + if (e != null) {
33.993 + for (Node pred = null, p = head; p != null; ) {
33.994 + Object item = p.item;
33.995 + if (p.isData) {
33.996 + if (item != null && item != p && e.equals(item) &&
33.997 + p.tryMatchData()) {
33.998 + unsplice(pred, p);
33.999 + return true;
33.1000 + }
33.1001 + }
33.1002 + else if (item == null)
33.1003 + break;
33.1004 + pred = p;
33.1005 + if ((p = p.next) == pred) { // stale
33.1006 + pred = null;
33.1007 + p = head;
33.1008 + }
33.1009 + }
33.1010 + }
33.1011 + return false;
33.1012 + }
33.1013 +
33.1014 +
33.1015 + /**
33.1016 + * Creates an initially empty {@code LinkedTransferQueue}.
33.1017 + */
33.1018 + public LinkedTransferQueue() {
33.1019 + }
33.1020 +
33.1021 + /**
33.1022 + * Creates a {@code LinkedTransferQueue}
33.1023 + * initially containing the elements of the given collection,
33.1024 + * added in traversal order of the collection's iterator.
33.1025 + *
33.1026 + * @param c the collection of elements to initially contain
33.1027 + * @throws NullPointerException if the specified collection or any
33.1028 + * of its elements are null
33.1029 + */
33.1030 + public LinkedTransferQueue(Collection<? extends E> c) {
33.1031 + this();
33.1032 + addAll(c);
33.1033 + }
33.1034 +
33.1035 + /**
33.1036 + * Inserts the specified element at the tail of this queue.
33.1037 + * As the queue is unbounded, this method will never block.
33.1038 + *
33.1039 + * @throws NullPointerException if the specified element is null
33.1040 + */
33.1041 + public void put(E e) {
33.1042 + xfer(e, true, ASYNC, 0);
33.1043 + }
33.1044 +
33.1045 + /**
33.1046 + * Inserts the specified element at the tail of this queue.
33.1047 + * As the queue is unbounded, this method will never block or
33.1048 + * return {@code false}.
33.1049 + *
33.1050 + * @return {@code true} (as specified by
33.1051 + * {@link BlockingQueue#offer(Object,long,TimeUnit) BlockingQueue.offer})
33.1052 + * @throws NullPointerException if the specified element is null
33.1053 + */
33.1054 + public boolean offer(E e, long timeout, TimeUnit unit) {
33.1055 + xfer(e, true, ASYNC, 0);
33.1056 + return true;
33.1057 + }
33.1058 +
33.1059 + /**
33.1060 + * Inserts the specified element at the tail of this queue.
33.1061 + * As the queue is unbounded, this method will never return {@code false}.
33.1062 + *
33.1063 + * @return {@code true} (as specified by {@link Queue#offer})
33.1064 + * @throws NullPointerException if the specified element is null
33.1065 + */
33.1066 + public boolean offer(E e) {
33.1067 + xfer(e, true, ASYNC, 0);
33.1068 + return true;
33.1069 + }
33.1070 +
33.1071 + /**
33.1072 + * Inserts the specified element at the tail of this queue.
33.1073 + * As the queue is unbounded, this method will never throw
33.1074 + * {@link IllegalStateException} or return {@code false}.
33.1075 + *
33.1076 + * @return {@code true} (as specified by {@link Collection#add})
33.1077 + * @throws NullPointerException if the specified element is null
33.1078 + */
33.1079 + public boolean add(E e) {
33.1080 + xfer(e, true, ASYNC, 0);
33.1081 + return true;
33.1082 + }
33.1083 +
33.1084 + /**
33.1085 + * Transfers the element to a waiting consumer immediately, if possible.
33.1086 + *
33.1087 + * <p>More precisely, transfers the specified element immediately
33.1088 + * if there exists a consumer already waiting to receive it (in
33.1089 + * {@link #take} or timed {@link #poll(long,TimeUnit) poll}),
33.1090 + * otherwise returning {@code false} without enqueuing the element.
33.1091 + *
33.1092 + * @throws NullPointerException if the specified element is null
33.1093 + */
33.1094 + public boolean tryTransfer(E e) {
33.1095 + return xfer(e, true, NOW, 0) == null;
33.1096 + }
33.1097 +
33.1098 + /**
33.1099 + * Transfers the element to a consumer, waiting if necessary to do so.
33.1100 + *
33.1101 + * <p>More precisely, transfers the specified element immediately
33.1102 + * if there exists a consumer already waiting to receive it (in
33.1103 + * {@link #take} or timed {@link #poll(long,TimeUnit) poll}),
33.1104 + * else inserts the specified element at the tail of this queue
33.1105 + * and waits until the element is received by a consumer.
33.1106 + *
33.1107 + * @throws NullPointerException if the specified element is null
33.1108 + */
33.1109 + public void transfer(E e) throws InterruptedException {
33.1110 + if (xfer(e, true, SYNC, 0) != null) {
33.1111 + Thread.interrupted(); // failure possible only due to interrupt
33.1112 + throw new InterruptedException();
33.1113 + }
33.1114 + }
33.1115 +
33.1116 + /**
33.1117 + * Transfers the element to a consumer if it is possible to do so
33.1118 + * before the timeout elapses.
33.1119 + *
33.1120 + * <p>More precisely, transfers the specified element immediately
33.1121 + * if there exists a consumer already waiting to receive it (in
33.1122 + * {@link #take} or timed {@link #poll(long,TimeUnit) poll}),
33.1123 + * else inserts the specified element at the tail of this queue
33.1124 + * and waits until the element is received by a consumer,
33.1125 + * returning {@code false} if the specified wait time elapses
33.1126 + * before the element can be transferred.
33.1127 + *
33.1128 + * @throws NullPointerException if the specified element is null
33.1129 + */
33.1130 + public boolean tryTransfer(E e, long timeout, TimeUnit unit)
33.1131 + throws InterruptedException {
33.1132 + if (xfer(e, true, TIMED, unit.toNanos(timeout)) == null)
33.1133 + return true;
33.1134 + if (!Thread.interrupted())
33.1135 + return false;
33.1136 + throw new InterruptedException();
33.1137 + }
33.1138 +
33.1139 + public E take() throws InterruptedException {
33.1140 + E e = xfer(null, false, SYNC, 0);
33.1141 + if (e != null)
33.1142 + return e;
33.1143 + Thread.interrupted();
33.1144 + throw new InterruptedException();
33.1145 + }
33.1146 +
33.1147 + public E poll(long timeout, TimeUnit unit) throws InterruptedException {
33.1148 + E e = xfer(null, false, TIMED, unit.toNanos(timeout));
33.1149 + if (e != null || !Thread.interrupted())
33.1150 + return e;
33.1151 + throw new InterruptedException();
33.1152 + }
33.1153 +
33.1154 + public E poll() {
33.1155 + return xfer(null, false, NOW, 0);
33.1156 + }
33.1157 +
33.1158 + /**
33.1159 + * @throws NullPointerException {@inheritDoc}
33.1160 + * @throws IllegalArgumentException {@inheritDoc}
33.1161 + */
33.1162 + public int drainTo(Collection<? super E> c) {
33.1163 + if (c == null)
33.1164 + throw new NullPointerException();
33.1165 + if (c == this)
33.1166 + throw new IllegalArgumentException();
33.1167 + int n = 0;
33.1168 + E e;
33.1169 + while ( (e = poll()) != null) {
33.1170 + c.add(e);
33.1171 + ++n;
33.1172 + }
33.1173 + return n;
33.1174 + }
33.1175 +
33.1176 + /**
33.1177 + * @throws NullPointerException {@inheritDoc}
33.1178 + * @throws IllegalArgumentException {@inheritDoc}
33.1179 + */
33.1180 + public int drainTo(Collection<? super E> c, int maxElements) {
33.1181 + if (c == null)
33.1182 + throw new NullPointerException();
33.1183 + if (c == this)
33.1184 + throw new IllegalArgumentException();
33.1185 + int n = 0;
33.1186 + E e;
33.1187 + while (n < maxElements && (e = poll()) != null) {
33.1188 + c.add(e);
33.1189 + ++n;
33.1190 + }
33.1191 + return n;
33.1192 + }
33.1193 +
33.1194 + /**
33.1195 + * Returns an iterator over the elements in this queue in proper sequence.
33.1196 + * The elements will be returned in order from first (head) to last (tail).
33.1197 + *
33.1198 + * <p>The returned iterator is a "weakly consistent" iterator that
33.1199 + * will never throw {@link java.util.ConcurrentModificationException
33.1200 + * ConcurrentModificationException}, and guarantees to traverse
33.1201 + * elements as they existed upon construction of the iterator, and
33.1202 + * may (but is not guaranteed to) reflect any modifications
33.1203 + * subsequent to construction.
33.1204 + *
33.1205 + * @return an iterator over the elements in this queue in proper sequence
33.1206 + */
33.1207 + public Iterator<E> iterator() {
33.1208 + return new Itr();
33.1209 + }
33.1210 +
33.1211 + public E peek() {
33.1212 + return firstDataItem();
33.1213 + }
33.1214 +
33.1215 + /**
33.1216 + * Returns {@code true} if this queue contains no elements.
33.1217 + *
33.1218 + * @return {@code true} if this queue contains no elements
33.1219 + */
33.1220 + public boolean isEmpty() {
33.1221 + for (Node p = head; p != null; p = succ(p)) {
33.1222 + if (!p.isMatched())
33.1223 + return !p.isData;
33.1224 + }
33.1225 + return true;
33.1226 + }
33.1227 +
33.1228 + public boolean hasWaitingConsumer() {
33.1229 + return firstOfMode(false) != null;
33.1230 + }
33.1231 +
33.1232 + /**
33.1233 + * Returns the number of elements in this queue. If this queue
33.1234 + * contains more than {@code Integer.MAX_VALUE} elements, returns
33.1235 + * {@code Integer.MAX_VALUE}.
33.1236 + *
33.1237 + * <p>Beware that, unlike in most collections, this method is
33.1238 + * <em>NOT</em> a constant-time operation. Because of the
33.1239 + * asynchronous nature of these queues, determining the current
33.1240 + * number of elements requires an O(n) traversal.
33.1241 + *
33.1242 + * @return the number of elements in this queue
33.1243 + */
33.1244 + public int size() {
33.1245 + return countOfMode(true);
33.1246 + }
33.1247 +
33.1248 + public int getWaitingConsumerCount() {
33.1249 + return countOfMode(false);
33.1250 + }
33.1251 +
33.1252 + /**
33.1253 + * Removes a single instance of the specified element from this queue,
33.1254 + * if it is present. More formally, removes an element {@code e} such
33.1255 + * that {@code o.equals(e)}, if this queue contains one or more such
33.1256 + * elements.
33.1257 + * Returns {@code true} if this queue contained the specified element
33.1258 + * (or equivalently, if this queue changed as a result of the call).
33.1259 + *
33.1260 + * @param o element to be removed from this queue, if present
33.1261 + * @return {@code true} if this queue changed as a result of the call
33.1262 + */
33.1263 + public boolean remove(Object o) {
33.1264 + return findAndRemove(o);
33.1265 + }
33.1266 +
33.1267 + /**
33.1268 + * Returns {@code true} if this queue contains the specified element.
33.1269 + * More formally, returns {@code true} if and only if this queue contains
33.1270 + * at least one element {@code e} such that {@code o.equals(e)}.
33.1271 + *
33.1272 + * @param o object to be checked for containment in this queue
33.1273 + * @return {@code true} if this queue contains the specified element
33.1274 + */
33.1275 + public boolean contains(Object o) {
33.1276 + if (o == null) return false;
33.1277 + for (Node p = head; p != null; p = succ(p)) {
33.1278 + Object item = p.item;
33.1279 + if (p.isData) {
33.1280 + if (item != null && item != p && o.equals(item))
33.1281 + return true;
33.1282 + }
33.1283 + else if (item == null)
33.1284 + break;
33.1285 + }
33.1286 + return false;
33.1287 + }
33.1288 +
33.1289 + /**
33.1290 + * Always returns {@code Integer.MAX_VALUE} because a
33.1291 + * {@code LinkedTransferQueue} is not capacity constrained.
33.1292 + *
33.1293 + * @return {@code Integer.MAX_VALUE} (as specified by
33.1294 + * {@link BlockingQueue#remainingCapacity()})
33.1295 + */
33.1296 + public int remainingCapacity() {
33.1297 + return Integer.MAX_VALUE;
33.1298 + }
33.1299 +
33.1300 + /**
33.1301 + * Saves the state to a stream (that is, serializes it).
33.1302 + *
33.1303 + * @serialData All of the elements (each an {@code E}) in
33.1304 + * the proper order, followed by a null
33.1305 + * @param s the stream
33.1306 + */
33.1307 + private void writeObject(java.io.ObjectOutputStream s)
33.1308 + throws java.io.IOException {
33.1309 + s.defaultWriteObject();
33.1310 + for (E e : this)
33.1311 + s.writeObject(e);
33.1312 + // Use trailing null as sentinel
33.1313 + s.writeObject(null);
33.1314 + }
33.1315 +
33.1316 + /**
33.1317 + * Reconstitutes the Queue instance from a stream (that is,
33.1318 + * deserializes it).
33.1319 + *
33.1320 + * @param s the stream
33.1321 + */
33.1322 + private void readObject(java.io.ObjectInputStream s)
33.1323 + throws java.io.IOException, ClassNotFoundException {
33.1324 + s.defaultReadObject();
33.1325 + for (;;) {
33.1326 + @SuppressWarnings("unchecked") E item = (E) s.readObject();
33.1327 + if (item == null)
33.1328 + break;
33.1329 + else
33.1330 + offer(item);
33.1331 + }
33.1332 + }
33.1333 +
33.1334 + // Unsafe mechanics
33.1335 +
33.1336 + private static final sun.misc.Unsafe UNSAFE;
33.1337 + private static final long headOffset;
33.1338 + private static final long tailOffset;
33.1339 + private static final long sweepVotesOffset;
33.1340 + static {
33.1341 + try {
33.1342 + UNSAFE = sun.misc.Unsafe.getUnsafe();
33.1343 + Class k = LinkedTransferQueue.class;
33.1344 + headOffset = UNSAFE.objectFieldOffset
33.1345 + (k.getDeclaredField("head"));
33.1346 + tailOffset = UNSAFE.objectFieldOffset
33.1347 + (k.getDeclaredField("tail"));
33.1348 + sweepVotesOffset = UNSAFE.objectFieldOffset
33.1349 + (k.getDeclaredField("sweepVotes"));
33.1350 + } catch (Exception e) {
33.1351 + throw new Error(e);
33.1352 + }
33.1353 + }
33.1354 +}
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
34.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/Phaser.java Sat Mar 19 10:46:31 2016 +0100
34.3 @@ -0,0 +1,1152 @@
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 +import java.util.concurrent.TimeUnit;
34.42 +import java.util.concurrent.TimeoutException;
34.43 +import java.util.concurrent.atomic.AtomicReference;
34.44 +import java.util.concurrent.locks.LockSupport;
34.45 +
34.46 +/**
34.47 + * A reusable synchronization barrier, similar in functionality to
34.48 + * {@link java.util.concurrent.CyclicBarrier CyclicBarrier} and
34.49 + * {@link java.util.concurrent.CountDownLatch CountDownLatch}
34.50 + * but supporting more flexible usage.
34.51 + *
34.52 + * <p> <b>Registration.</b> Unlike the case for other barriers, the
34.53 + * number of parties <em>registered</em> to synchronize on a phaser
34.54 + * may vary over time. Tasks may be registered at any time (using
34.55 + * methods {@link #register}, {@link #bulkRegister}, or forms of
34.56 + * constructors establishing initial numbers of parties), and
34.57 + * optionally deregistered upon any arrival (using {@link
34.58 + * #arriveAndDeregister}). As is the case with most basic
34.59 + * synchronization constructs, registration and deregistration affect
34.60 + * only internal counts; they do not establish any further internal
34.61 + * bookkeeping, so tasks cannot query whether they are registered.
34.62 + * (However, you can introduce such bookkeeping by subclassing this
34.63 + * class.)
34.64 + *
34.65 + * <p> <b>Synchronization.</b> Like a {@code CyclicBarrier}, a {@code
34.66 + * Phaser} may be repeatedly awaited. Method {@link
34.67 + * #arriveAndAwaitAdvance} has effect analogous to {@link
34.68 + * java.util.concurrent.CyclicBarrier#await CyclicBarrier.await}. Each
34.69 + * generation of a phaser has an associated phase number. The phase
34.70 + * number starts at zero, and advances when all parties arrive at the
34.71 + * phaser, wrapping around to zero after reaching {@code
34.72 + * Integer.MAX_VALUE}. The use of phase numbers enables independent
34.73 + * control of actions upon arrival at a phaser and upon awaiting
34.74 + * others, via two kinds of methods that may be invoked by any
34.75 + * registered party:
34.76 + *
34.77 + * <ul>
34.78 + *
34.79 + * <li> <b>Arrival.</b> Methods {@link #arrive} and
34.80 + * {@link #arriveAndDeregister} record arrival. These methods
34.81 + * do not block, but return an associated <em>arrival phase
34.82 + * number</em>; that is, the phase number of the phaser to which
34.83 + * the arrival applied. When the final party for a given phase
34.84 + * arrives, an optional action is performed and the phase
34.85 + * advances. These actions are performed by the party
34.86 + * triggering a phase advance, and are arranged by overriding
34.87 + * method {@link #onAdvance(int, int)}, which also controls
34.88 + * termination. Overriding this method is similar to, but more
34.89 + * flexible than, providing a barrier action to a {@code
34.90 + * CyclicBarrier}.
34.91 + *
34.92 + * <li> <b>Waiting.</b> Method {@link #awaitAdvance} requires an
34.93 + * argument indicating an arrival phase number, and returns when
34.94 + * the phaser advances to (or is already at) a different phase.
34.95 + * Unlike similar constructions using {@code CyclicBarrier},
34.96 + * method {@code awaitAdvance} continues to wait even if the
34.97 + * waiting thread is interrupted. Interruptible and timeout
34.98 + * versions are also available, but exceptions encountered while
34.99 + * tasks wait interruptibly or with timeout do not change the
34.100 + * state of the phaser. If necessary, you can perform any
34.101 + * associated recovery within handlers of those exceptions,
34.102 + * often after invoking {@code forceTermination}. Phasers may
34.103 + * also be used by tasks executing in a {@link ForkJoinPool},
34.104 + * which will ensure sufficient parallelism to execute tasks
34.105 + * when others are blocked waiting for a phase to advance.
34.106 + *
34.107 + * </ul>
34.108 + *
34.109 + * <p> <b>Termination.</b> A phaser may enter a <em>termination</em>
34.110 + * state, that may be checked using method {@link #isTerminated}. Upon
34.111 + * termination, all synchronization methods immediately return without
34.112 + * waiting for advance, as indicated by a negative return value.
34.113 + * Similarly, attempts to register upon termination have no effect.
34.114 + * Termination is triggered when an invocation of {@code onAdvance}
34.115 + * returns {@code true}. The default implementation returns {@code
34.116 + * true} if a deregistration has caused the number of registered
34.117 + * parties to become zero. As illustrated below, when phasers control
34.118 + * actions with a fixed number of iterations, it is often convenient
34.119 + * to override this method to cause termination when the current phase
34.120 + * number reaches a threshold. Method {@link #forceTermination} is
34.121 + * also available to abruptly release waiting threads and allow them
34.122 + * to terminate.
34.123 + *
34.124 + * <p> <b>Tiering.</b> Phasers may be <em>tiered</em> (i.e.,
34.125 + * constructed in tree structures) to reduce contention. Phasers with
34.126 + * large numbers of parties that would otherwise experience heavy
34.127 + * synchronization contention costs may instead be set up so that
34.128 + * groups of sub-phasers share a common parent. This may greatly
34.129 + * increase throughput even though it incurs greater per-operation
34.130 + * overhead.
34.131 + *
34.132 + * <p>In a tree of tiered phasers, registration and deregistration of
34.133 + * child phasers with their parent are managed automatically.
34.134 + * Whenever the number of registered parties of a child phaser becomes
34.135 + * non-zero (as established in the {@link #Phaser(Phaser,int)}
34.136 + * constructor, {@link #register}, or {@link #bulkRegister}), the
34.137 + * child phaser is registered with its parent. Whenever the number of
34.138 + * registered parties becomes zero as the result of an invocation of
34.139 + * {@link #arriveAndDeregister}, the child phaser is deregistered
34.140 + * from its parent.
34.141 + *
34.142 + * <p><b>Monitoring.</b> While synchronization methods may be invoked
34.143 + * only by registered parties, the current state of a phaser may be
34.144 + * monitored by any caller. At any given moment there are {@link
34.145 + * #getRegisteredParties} parties in total, of which {@link
34.146 + * #getArrivedParties} have arrived at the current phase ({@link
34.147 + * #getPhase}). When the remaining ({@link #getUnarrivedParties})
34.148 + * parties arrive, the phase advances. The values returned by these
34.149 + * methods may reflect transient states and so are not in general
34.150 + * useful for synchronization control. Method {@link #toString}
34.151 + * returns snapshots of these state queries in a form convenient for
34.152 + * informal monitoring.
34.153 + *
34.154 + * <p><b>Sample usages:</b>
34.155 + *
34.156 + * <p>A {@code Phaser} may be used instead of a {@code CountDownLatch}
34.157 + * to control a one-shot action serving a variable number of parties.
34.158 + * The typical idiom is for the method setting this up to first
34.159 + * register, then start the actions, then deregister, as in:
34.160 + *
34.161 + * <pre> {@code
34.162 + * void runTasks(List<Runnable> tasks) {
34.163 + * final Phaser phaser = new Phaser(1); // "1" to register self
34.164 + * // create and start threads
34.165 + * for (final Runnable task : tasks) {
34.166 + * phaser.register();
34.167 + * new Thread() {
34.168 + * public void run() {
34.169 + * phaser.arriveAndAwaitAdvance(); // await all creation
34.170 + * task.run();
34.171 + * }
34.172 + * }.start();
34.173 + * }
34.174 + *
34.175 + * // allow threads to start and deregister self
34.176 + * phaser.arriveAndDeregister();
34.177 + * }}</pre>
34.178 + *
34.179 + * <p>One way to cause a set of threads to repeatedly perform actions
34.180 + * for a given number of iterations is to override {@code onAdvance}:
34.181 + *
34.182 + * <pre> {@code
34.183 + * void startTasks(List<Runnable> tasks, final int iterations) {
34.184 + * final Phaser phaser = new Phaser() {
34.185 + * protected boolean onAdvance(int phase, int registeredParties) {
34.186 + * return phase >= iterations || registeredParties == 0;
34.187 + * }
34.188 + * };
34.189 + * phaser.register();
34.190 + * for (final Runnable task : tasks) {
34.191 + * phaser.register();
34.192 + * new Thread() {
34.193 + * public void run() {
34.194 + * do {
34.195 + * task.run();
34.196 + * phaser.arriveAndAwaitAdvance();
34.197 + * } while (!phaser.isTerminated());
34.198 + * }
34.199 + * }.start();
34.200 + * }
34.201 + * phaser.arriveAndDeregister(); // deregister self, don't wait
34.202 + * }}</pre>
34.203 + *
34.204 + * If the main task must later await termination, it
34.205 + * may re-register and then execute a similar loop:
34.206 + * <pre> {@code
34.207 + * // ...
34.208 + * phaser.register();
34.209 + * while (!phaser.isTerminated())
34.210 + * phaser.arriveAndAwaitAdvance();}</pre>
34.211 + *
34.212 + * <p>Related constructions may be used to await particular phase numbers
34.213 + * in contexts where you are sure that the phase will never wrap around
34.214 + * {@code Integer.MAX_VALUE}. For example:
34.215 + *
34.216 + * <pre> {@code
34.217 + * void awaitPhase(Phaser phaser, int phase) {
34.218 + * int p = phaser.register(); // assumes caller not already registered
34.219 + * while (p < phase) {
34.220 + * if (phaser.isTerminated())
34.221 + * // ... deal with unexpected termination
34.222 + * else
34.223 + * p = phaser.arriveAndAwaitAdvance();
34.224 + * }
34.225 + * phaser.arriveAndDeregister();
34.226 + * }}</pre>
34.227 + *
34.228 + *
34.229 + * <p>To create a set of {@code n} tasks using a tree of phasers, you
34.230 + * could use code of the following form, assuming a Task class with a
34.231 + * constructor accepting a {@code Phaser} that it registers with upon
34.232 + * construction. After invocation of {@code build(new Task[n], 0, n,
34.233 + * new Phaser())}, these tasks could then be started, for example by
34.234 + * submitting to a pool:
34.235 + *
34.236 + * <pre> {@code
34.237 + * void build(Task[] tasks, int lo, int hi, Phaser ph) {
34.238 + * if (hi - lo > TASKS_PER_PHASER) {
34.239 + * for (int i = lo; i < hi; i += TASKS_PER_PHASER) {
34.240 + * int j = Math.min(i + TASKS_PER_PHASER, hi);
34.241 + * build(tasks, i, j, new Phaser(ph));
34.242 + * }
34.243 + * } else {
34.244 + * for (int i = lo; i < hi; ++i)
34.245 + * tasks[i] = new Task(ph);
34.246 + * // assumes new Task(ph) performs ph.register()
34.247 + * }
34.248 + * }}</pre>
34.249 + *
34.250 + * The best value of {@code TASKS_PER_PHASER} depends mainly on
34.251 + * expected synchronization rates. A value as low as four may
34.252 + * be appropriate for extremely small per-phase task bodies (thus
34.253 + * high rates), or up to hundreds for extremely large ones.
34.254 + *
34.255 + * <p><b>Implementation notes</b>: This implementation restricts the
34.256 + * maximum number of parties to 65535. Attempts to register additional
34.257 + * parties result in {@code IllegalStateException}. However, you can and
34.258 + * should create tiered phasers to accommodate arbitrarily large sets
34.259 + * of participants.
34.260 + *
34.261 + * @since 1.7
34.262 + * @author Doug Lea
34.263 + */
34.264 +public class Phaser {
34.265 + /*
34.266 + * This class implements an extension of X10 "clocks". Thanks to
34.267 + * Vijay Saraswat for the idea, and to Vivek Sarkar for
34.268 + * enhancements to extend functionality.
34.269 + */
34.270 +
34.271 + /**
34.272 + * Primary state representation, holding four bit-fields:
34.273 + *
34.274 + * unarrived -- the number of parties yet to hit barrier (bits 0-15)
34.275 + * parties -- the number of parties to wait (bits 16-31)
34.276 + * phase -- the generation of the barrier (bits 32-62)
34.277 + * terminated -- set if barrier is terminated (bit 63 / sign)
34.278 + *
34.279 + * Except that a phaser with no registered parties is
34.280 + * distinguished by the otherwise illegal state of having zero
34.281 + * parties and one unarrived parties (encoded as EMPTY below).
34.282 + *
34.283 + * To efficiently maintain atomicity, these values are packed into
34.284 + * a single (atomic) long. Good performance relies on keeping
34.285 + * state decoding and encoding simple, and keeping race windows
34.286 + * short.
34.287 + *
34.288 + * All state updates are performed via CAS except initial
34.289 + * registration of a sub-phaser (i.e., one with a non-null
34.290 + * parent). In this (relatively rare) case, we use built-in
34.291 + * synchronization to lock while first registering with its
34.292 + * parent.
34.293 + *
34.294 + * The phase of a subphaser is allowed to lag that of its
34.295 + * ancestors until it is actually accessed -- see method
34.296 + * reconcileState.
34.297 + */
34.298 + private volatile long state;
34.299 +
34.300 + private static final int MAX_PARTIES = 0xffff;
34.301 + private static final int MAX_PHASE = Integer.MAX_VALUE;
34.302 + private static final int PARTIES_SHIFT = 16;
34.303 + private static final int PHASE_SHIFT = 32;
34.304 + private static final int UNARRIVED_MASK = 0xffff; // to mask ints
34.305 + private static final long PARTIES_MASK = 0xffff0000L; // to mask longs
34.306 + private static final long TERMINATION_BIT = 1L << 63;
34.307 +
34.308 + // some special values
34.309 + private static final int ONE_ARRIVAL = 1;
34.310 + private static final int ONE_PARTY = 1 << PARTIES_SHIFT;
34.311 + private static final int EMPTY = 1;
34.312 +
34.313 + // The following unpacking methods are usually manually inlined
34.314 +
34.315 + private static int unarrivedOf(long s) {
34.316 + int counts = (int)s;
34.317 + return (counts == EMPTY) ? 0 : counts & UNARRIVED_MASK;
34.318 + }
34.319 +
34.320 + private static int partiesOf(long s) {
34.321 + return (int)s >>> PARTIES_SHIFT;
34.322 + }
34.323 +
34.324 + private static int phaseOf(long s) {
34.325 + return (int)(s >>> PHASE_SHIFT);
34.326 + }
34.327 +
34.328 + private static int arrivedOf(long s) {
34.329 + int counts = (int)s;
34.330 + return (counts == EMPTY) ? 0 :
34.331 + (counts >>> PARTIES_SHIFT) - (counts & UNARRIVED_MASK);
34.332 + }
34.333 +
34.334 + /**
34.335 + * The parent of this phaser, or null if none
34.336 + */
34.337 + private final Phaser parent;
34.338 +
34.339 + /**
34.340 + * The root of phaser tree. Equals this if not in a tree.
34.341 + */
34.342 + private final Phaser root;
34.343 +
34.344 + /**
34.345 + * Heads of Treiber stacks for waiting threads. To eliminate
34.346 + * contention when releasing some threads while adding others, we
34.347 + * use two of them, alternating across even and odd phases.
34.348 + * Subphasers share queues with root to speed up releases.
34.349 + */
34.350 + private final AtomicReference<QNode> evenQ;
34.351 + private final AtomicReference<QNode> oddQ;
34.352 +
34.353 + private AtomicReference<QNode> queueFor(int phase) {
34.354 + return ((phase & 1) == 0) ? evenQ : oddQ;
34.355 + }
34.356 +
34.357 + /**
34.358 + * Returns message string for bounds exceptions on arrival.
34.359 + */
34.360 + private String badArrive(long s) {
34.361 + return "Attempted arrival of unregistered party for " +
34.362 + stateToString(s);
34.363 + }
34.364 +
34.365 + /**
34.366 + * Returns message string for bounds exceptions on registration.
34.367 + */
34.368 + private String badRegister(long s) {
34.369 + return "Attempt to register more than " +
34.370 + MAX_PARTIES + " parties for " + stateToString(s);
34.371 + }
34.372 +
34.373 + /**
34.374 + * Main implementation for methods arrive and arriveAndDeregister.
34.375 + * Manually tuned to speed up and minimize race windows for the
34.376 + * common case of just decrementing unarrived field.
34.377 + *
34.378 + * @param deregister false for arrive, true for arriveAndDeregister
34.379 + */
34.380 + private int doArrive(boolean deregister) {
34.381 + int adj = deregister ? ONE_ARRIVAL|ONE_PARTY : ONE_ARRIVAL;
34.382 + final Phaser root = this.root;
34.383 + for (;;) {
34.384 + long s = (root == this) ? state : reconcileState();
34.385 + int phase = (int)(s >>> PHASE_SHIFT);
34.386 + int counts = (int)s;
34.387 + int unarrived = (counts & UNARRIVED_MASK) - 1;
34.388 + if (phase < 0)
34.389 + return phase;
34.390 + else if (counts == EMPTY || unarrived < 0) {
34.391 + if (root == this || reconcileState() == s)
34.392 + throw new IllegalStateException(badArrive(s));
34.393 + }
34.394 + else if (UNSAFE.compareAndSwapLong(this, stateOffset, s, s-=adj)) {
34.395 + if (unarrived == 0) {
34.396 + long n = s & PARTIES_MASK; // base of next state
34.397 + int nextUnarrived = (int)n >>> PARTIES_SHIFT;
34.398 + if (root != this)
34.399 + return parent.doArrive(nextUnarrived == 0);
34.400 + if (onAdvance(phase, nextUnarrived))
34.401 + n |= TERMINATION_BIT;
34.402 + else if (nextUnarrived == 0)
34.403 + n |= EMPTY;
34.404 + else
34.405 + n |= nextUnarrived;
34.406 + n |= (long)((phase + 1) & MAX_PHASE) << PHASE_SHIFT;
34.407 + UNSAFE.compareAndSwapLong(this, stateOffset, s, n);
34.408 + releaseWaiters(phase);
34.409 + }
34.410 + return phase;
34.411 + }
34.412 + }
34.413 + }
34.414 +
34.415 + /**
34.416 + * Implementation of register, bulkRegister
34.417 + *
34.418 + * @param registrations number to add to both parties and
34.419 + * unarrived fields. Must be greater than zero.
34.420 + */
34.421 + private int doRegister(int registrations) {
34.422 + // adjustment to state
34.423 + long adj = ((long)registrations << PARTIES_SHIFT) | registrations;
34.424 + final Phaser parent = this.parent;
34.425 + int phase;
34.426 + for (;;) {
34.427 + long s = state;
34.428 + int counts = (int)s;
34.429 + int parties = counts >>> PARTIES_SHIFT;
34.430 + int unarrived = counts & UNARRIVED_MASK;
34.431 + if (registrations > MAX_PARTIES - parties)
34.432 + throw new IllegalStateException(badRegister(s));
34.433 + else if ((phase = (int)(s >>> PHASE_SHIFT)) < 0)
34.434 + break;
34.435 + else if (counts != EMPTY) { // not 1st registration
34.436 + if (parent == null || reconcileState() == s) {
34.437 + if (unarrived == 0) // wait out advance
34.438 + root.internalAwaitAdvance(phase, null);
34.439 + else if (UNSAFE.compareAndSwapLong(this, stateOffset,
34.440 + s, s + adj))
34.441 + break;
34.442 + }
34.443 + }
34.444 + else if (parent == null) { // 1st root registration
34.445 + long next = ((long)phase << PHASE_SHIFT) | adj;
34.446 + if (UNSAFE.compareAndSwapLong(this, stateOffset, s, next))
34.447 + break;
34.448 + }
34.449 + else {
34.450 + synchronized (this) { // 1st sub registration
34.451 + if (state == s) { // recheck under lock
34.452 + parent.doRegister(1);
34.453 + do { // force current phase
34.454 + phase = (int)(root.state >>> PHASE_SHIFT);
34.455 + // assert phase < 0 || (int)state == EMPTY;
34.456 + } while (!UNSAFE.compareAndSwapLong
34.457 + (this, stateOffset, state,
34.458 + ((long)phase << PHASE_SHIFT) | adj));
34.459 + break;
34.460 + }
34.461 + }
34.462 + }
34.463 + }
34.464 + return phase;
34.465 + }
34.466 +
34.467 + /**
34.468 + * Resolves lagged phase propagation from root if necessary.
34.469 + * Reconciliation normally occurs when root has advanced but
34.470 + * subphasers have not yet done so, in which case they must finish
34.471 + * their own advance by setting unarrived to parties (or if
34.472 + * parties is zero, resetting to unregistered EMPTY state).
34.473 + * However, this method may also be called when "floating"
34.474 + * subphasers with possibly some unarrived parties are merely
34.475 + * catching up to current phase, in which case counts are
34.476 + * unaffected.
34.477 + *
34.478 + * @return reconciled state
34.479 + */
34.480 + private long reconcileState() {
34.481 + final Phaser root = this.root;
34.482 + long s = state;
34.483 + if (root != this) {
34.484 + int phase, u, p;
34.485 + // CAS root phase with current parties; possibly trip unarrived
34.486 + while ((phase = (int)(root.state >>> PHASE_SHIFT)) !=
34.487 + (int)(s >>> PHASE_SHIFT) &&
34.488 + !UNSAFE.compareAndSwapLong
34.489 + (this, stateOffset, s,
34.490 + s = (((long)phase << PHASE_SHIFT) |
34.491 + (s & PARTIES_MASK) |
34.492 + ((p = (int)s >>> PARTIES_SHIFT) == 0 ? EMPTY :
34.493 + (u = (int)s & UNARRIVED_MASK) == 0 ? p : u))))
34.494 + s = state;
34.495 + }
34.496 + return s;
34.497 + }
34.498 +
34.499 + /**
34.500 + * Creates a new phaser with no initially registered parties, no
34.501 + * parent, and initial phase number 0. Any thread using this
34.502 + * phaser will need to first register for it.
34.503 + */
34.504 + public Phaser() {
34.505 + this(null, 0);
34.506 + }
34.507 +
34.508 + /**
34.509 + * Creates a new phaser with the given number of registered
34.510 + * unarrived parties, no parent, and initial phase number 0.
34.511 + *
34.512 + * @param parties the number of parties required to advance to the
34.513 + * next phase
34.514 + * @throws IllegalArgumentException if parties less than zero
34.515 + * or greater than the maximum number of parties supported
34.516 + */
34.517 + public Phaser(int parties) {
34.518 + this(null, parties);
34.519 + }
34.520 +
34.521 + /**
34.522 + * Equivalent to {@link #Phaser(Phaser, int) Phaser(parent, 0)}.
34.523 + *
34.524 + * @param parent the parent phaser
34.525 + */
34.526 + public Phaser(Phaser parent) {
34.527 + this(parent, 0);
34.528 + }
34.529 +
34.530 + /**
34.531 + * Creates a new phaser with the given parent and number of
34.532 + * registered unarrived parties. When the given parent is non-null
34.533 + * and the given number of parties is greater than zero, this
34.534 + * child phaser is registered with its parent.
34.535 + *
34.536 + * @param parent the parent phaser
34.537 + * @param parties the number of parties required to advance to the
34.538 + * next phase
34.539 + * @throws IllegalArgumentException if parties less than zero
34.540 + * or greater than the maximum number of parties supported
34.541 + */
34.542 + public Phaser(Phaser parent, int parties) {
34.543 + if (parties >>> PARTIES_SHIFT != 0)
34.544 + throw new IllegalArgumentException("Illegal number of parties");
34.545 + int phase = 0;
34.546 + this.parent = parent;
34.547 + if (parent != null) {
34.548 + final Phaser root = parent.root;
34.549 + this.root = root;
34.550 + this.evenQ = root.evenQ;
34.551 + this.oddQ = root.oddQ;
34.552 + if (parties != 0)
34.553 + phase = parent.doRegister(1);
34.554 + }
34.555 + else {
34.556 + this.root = this;
34.557 + this.evenQ = new AtomicReference<QNode>();
34.558 + this.oddQ = new AtomicReference<QNode>();
34.559 + }
34.560 + this.state = (parties == 0) ? (long)EMPTY :
34.561 + ((long)phase << PHASE_SHIFT) |
34.562 + ((long)parties << PARTIES_SHIFT) |
34.563 + ((long)parties);
34.564 + }
34.565 +
34.566 + /**
34.567 + * Adds a new unarrived party to this phaser. If an ongoing
34.568 + * invocation of {@link #onAdvance} is in progress, this method
34.569 + * may await its completion before returning. If this phaser has
34.570 + * a parent, and this phaser previously had no registered parties,
34.571 + * this child phaser is also registered with its parent. If
34.572 + * this phaser is terminated, the attempt to register has
34.573 + * no effect, and a negative value is returned.
34.574 + *
34.575 + * @return the arrival phase number to which this registration
34.576 + * applied. If this value is negative, then this phaser has
34.577 + * terminated, in which case registration has no effect.
34.578 + * @throws IllegalStateException if attempting to register more
34.579 + * than the maximum supported number of parties
34.580 + */
34.581 + public int register() {
34.582 + return doRegister(1);
34.583 + }
34.584 +
34.585 + /**
34.586 + * Adds the given number of new unarrived parties to this phaser.
34.587 + * If an ongoing invocation of {@link #onAdvance} is in progress,
34.588 + * this method may await its completion before returning. If this
34.589 + * phaser has a parent, and the given number of parties is greater
34.590 + * than zero, and this phaser previously had no registered
34.591 + * parties, this child phaser is also registered with its parent.
34.592 + * If this phaser is terminated, the attempt to register has no
34.593 + * effect, and a negative value is returned.
34.594 + *
34.595 + * @param parties the number of additional parties required to
34.596 + * advance to the next phase
34.597 + * @return the arrival phase number to which this registration
34.598 + * applied. If this value is negative, then this phaser has
34.599 + * terminated, in which case registration has no effect.
34.600 + * @throws IllegalStateException if attempting to register more
34.601 + * than the maximum supported number of parties
34.602 + * @throws IllegalArgumentException if {@code parties < 0}
34.603 + */
34.604 + public int bulkRegister(int parties) {
34.605 + if (parties < 0)
34.606 + throw new IllegalArgumentException();
34.607 + if (parties == 0)
34.608 + return getPhase();
34.609 + return doRegister(parties);
34.610 + }
34.611 +
34.612 + /**
34.613 + * Arrives at this phaser, without waiting for others to arrive.
34.614 + *
34.615 + * <p>It is a usage error for an unregistered party to invoke this
34.616 + * method. However, this error may result in an {@code
34.617 + * IllegalStateException} only upon some subsequent operation on
34.618 + * this phaser, if ever.
34.619 + *
34.620 + * @return the arrival phase number, or a negative value if terminated
34.621 + * @throws IllegalStateException if not terminated and the number
34.622 + * of unarrived parties would become negative
34.623 + */
34.624 + public int arrive() {
34.625 + return doArrive(false);
34.626 + }
34.627 +
34.628 + /**
34.629 + * Arrives at this phaser and deregisters from it without waiting
34.630 + * for others to arrive. Deregistration reduces the number of
34.631 + * parties required to advance in future phases. If this phaser
34.632 + * has a parent, and deregistration causes this phaser to have
34.633 + * zero parties, this phaser is also deregistered from its parent.
34.634 + *
34.635 + * <p>It is a usage error for an unregistered party to invoke this
34.636 + * method. However, this error may result in an {@code
34.637 + * IllegalStateException} only upon some subsequent operation on
34.638 + * this phaser, if ever.
34.639 + *
34.640 + * @return the arrival phase number, or a negative value if terminated
34.641 + * @throws IllegalStateException if not terminated and the number
34.642 + * of registered or unarrived parties would become negative
34.643 + */
34.644 + public int arriveAndDeregister() {
34.645 + return doArrive(true);
34.646 + }
34.647 +
34.648 + /**
34.649 + * Arrives at this phaser and awaits others. Equivalent in effect
34.650 + * to {@code awaitAdvance(arrive())}. If you need to await with
34.651 + * interruption or timeout, you can arrange this with an analogous
34.652 + * construction using one of the other forms of the {@code
34.653 + * awaitAdvance} method. If instead you need to deregister upon
34.654 + * arrival, use {@code awaitAdvance(arriveAndDeregister())}.
34.655 + *
34.656 + * <p>It is a usage error for an unregistered party to invoke this
34.657 + * method. However, this error may result in an {@code
34.658 + * IllegalStateException} only upon some subsequent operation on
34.659 + * this phaser, if ever.
34.660 + *
34.661 + * @return the arrival phase number, or the (negative)
34.662 + * {@linkplain #getPhase() current phase} if terminated
34.663 + * @throws IllegalStateException if not terminated and the number
34.664 + * of unarrived parties would become negative
34.665 + */
34.666 + public int arriveAndAwaitAdvance() {
34.667 + // Specialization of doArrive+awaitAdvance eliminating some reads/paths
34.668 + final Phaser root = this.root;
34.669 + for (;;) {
34.670 + long s = (root == this) ? state : reconcileState();
34.671 + int phase = (int)(s >>> PHASE_SHIFT);
34.672 + int counts = (int)s;
34.673 + int unarrived = (counts & UNARRIVED_MASK) - 1;
34.674 + if (phase < 0)
34.675 + return phase;
34.676 + else if (counts == EMPTY || unarrived < 0) {
34.677 + if (reconcileState() == s)
34.678 + throw new IllegalStateException(badArrive(s));
34.679 + }
34.680 + else if (UNSAFE.compareAndSwapLong(this, stateOffset, s,
34.681 + s -= ONE_ARRIVAL)) {
34.682 + if (unarrived != 0)
34.683 + return root.internalAwaitAdvance(phase, null);
34.684 + if (root != this)
34.685 + return parent.arriveAndAwaitAdvance();
34.686 + long n = s & PARTIES_MASK; // base of next state
34.687 + int nextUnarrived = (int)n >>> PARTIES_SHIFT;
34.688 + if (onAdvance(phase, nextUnarrived))
34.689 + n |= TERMINATION_BIT;
34.690 + else if (nextUnarrived == 0)
34.691 + n |= EMPTY;
34.692 + else
34.693 + n |= nextUnarrived;
34.694 + int nextPhase = (phase + 1) & MAX_PHASE;
34.695 + n |= (long)nextPhase << PHASE_SHIFT;
34.696 + if (!UNSAFE.compareAndSwapLong(this, stateOffset, s, n))
34.697 + return (int)(state >>> PHASE_SHIFT); // terminated
34.698 + releaseWaiters(phase);
34.699 + return nextPhase;
34.700 + }
34.701 + }
34.702 + }
34.703 +
34.704 + /**
34.705 + * Awaits the phase of this phaser to advance from the given phase
34.706 + * value, returning immediately if the current phase is not equal
34.707 + * to the given phase value or this phaser is terminated.
34.708 + *
34.709 + * @param phase an arrival phase number, or negative value if
34.710 + * terminated; this argument is normally the value returned by a
34.711 + * previous call to {@code arrive} or {@code arriveAndDeregister}.
34.712 + * @return the next arrival phase number, or the argument if it is
34.713 + * negative, or the (negative) {@linkplain #getPhase() current phase}
34.714 + * if terminated
34.715 + */
34.716 + public int awaitAdvance(int phase) {
34.717 + final Phaser root = this.root;
34.718 + long s = (root == this) ? state : reconcileState();
34.719 + int p = (int)(s >>> PHASE_SHIFT);
34.720 + if (phase < 0)
34.721 + return phase;
34.722 + if (p == phase)
34.723 + return root.internalAwaitAdvance(phase, null);
34.724 + return p;
34.725 + }
34.726 +
34.727 + /**
34.728 + * Awaits the phase of this phaser to advance from the given phase
34.729 + * value, throwing {@code InterruptedException} if interrupted
34.730 + * while waiting, or returning immediately if the current phase is
34.731 + * not equal to the given phase value or this phaser is
34.732 + * terminated.
34.733 + *
34.734 + * @param phase an arrival phase number, or negative value if
34.735 + * terminated; this argument is normally the value returned by a
34.736 + * previous call to {@code arrive} or {@code arriveAndDeregister}.
34.737 + * @return the next arrival phase number, or the argument if it is
34.738 + * negative, or the (negative) {@linkplain #getPhase() current phase}
34.739 + * if terminated
34.740 + * @throws InterruptedException if thread interrupted while waiting
34.741 + */
34.742 + public int awaitAdvanceInterruptibly(int phase)
34.743 + throws InterruptedException {
34.744 + final Phaser root = this.root;
34.745 + long s = (root == this) ? state : reconcileState();
34.746 + int p = (int)(s >>> PHASE_SHIFT);
34.747 + if (phase < 0)
34.748 + return phase;
34.749 + if (p == phase) {
34.750 + QNode node = new QNode(this, phase, true, false, 0L);
34.751 + p = root.internalAwaitAdvance(phase, node);
34.752 + if (node.wasInterrupted)
34.753 + throw new InterruptedException();
34.754 + }
34.755 + return p;
34.756 + }
34.757 +
34.758 + /**
34.759 + * Awaits the phase of this phaser to advance from the given phase
34.760 + * value or the given timeout to elapse, throwing {@code
34.761 + * InterruptedException} if interrupted while waiting, or
34.762 + * returning immediately if the current phase is not equal to the
34.763 + * given phase value or this phaser is terminated.
34.764 + *
34.765 + * @param phase an arrival phase number, or negative value if
34.766 + * terminated; this argument is normally the value returned by a
34.767 + * previous call to {@code arrive} or {@code arriveAndDeregister}.
34.768 + * @param timeout how long to wait before giving up, in units of
34.769 + * {@code unit}
34.770 + * @param unit a {@code TimeUnit} determining how to interpret the
34.771 + * {@code timeout} parameter
34.772 + * @return the next arrival phase number, or the argument if it is
34.773 + * negative, or the (negative) {@linkplain #getPhase() current phase}
34.774 + * if terminated
34.775 + * @throws InterruptedException if thread interrupted while waiting
34.776 + * @throws TimeoutException if timed out while waiting
34.777 + */
34.778 + public int awaitAdvanceInterruptibly(int phase,
34.779 + long timeout, TimeUnit unit)
34.780 + throws InterruptedException, TimeoutException {
34.781 + long nanos = unit.toNanos(timeout);
34.782 + final Phaser root = this.root;
34.783 + long s = (root == this) ? state : reconcileState();
34.784 + int p = (int)(s >>> PHASE_SHIFT);
34.785 + if (phase < 0)
34.786 + return phase;
34.787 + if (p == phase) {
34.788 + QNode node = new QNode(this, phase, true, true, nanos);
34.789 + p = root.internalAwaitAdvance(phase, node);
34.790 + if (node.wasInterrupted)
34.791 + throw new InterruptedException();
34.792 + else if (p == phase)
34.793 + throw new TimeoutException();
34.794 + }
34.795 + return p;
34.796 + }
34.797 +
34.798 + /**
34.799 + * Forces this phaser to enter termination state. Counts of
34.800 + * registered parties are unaffected. If this phaser is a member
34.801 + * of a tiered set of phasers, then all of the phasers in the set
34.802 + * are terminated. If this phaser is already terminated, this
34.803 + * method has no effect. This method may be useful for
34.804 + * coordinating recovery after one or more tasks encounter
34.805 + * unexpected exceptions.
34.806 + */
34.807 + public void forceTermination() {
34.808 + // Only need to change root state
34.809 + final Phaser root = this.root;
34.810 + long s;
34.811 + while ((s = root.state) >= 0) {
34.812 + if (UNSAFE.compareAndSwapLong(root, stateOffset,
34.813 + s, s | TERMINATION_BIT)) {
34.814 + // signal all threads
34.815 + releaseWaiters(0);
34.816 + releaseWaiters(1);
34.817 + return;
34.818 + }
34.819 + }
34.820 + }
34.821 +
34.822 + /**
34.823 + * Returns the current phase number. The maximum phase number is
34.824 + * {@code Integer.MAX_VALUE}, after which it restarts at
34.825 + * zero. Upon termination, the phase number is negative,
34.826 + * in which case the prevailing phase prior to termination
34.827 + * may be obtained via {@code getPhase() + Integer.MIN_VALUE}.
34.828 + *
34.829 + * @return the phase number, or a negative value if terminated
34.830 + */
34.831 + public final int getPhase() {
34.832 + return (int)(root.state >>> PHASE_SHIFT);
34.833 + }
34.834 +
34.835 + /**
34.836 + * Returns the number of parties registered at this phaser.
34.837 + *
34.838 + * @return the number of parties
34.839 + */
34.840 + public int getRegisteredParties() {
34.841 + return partiesOf(state);
34.842 + }
34.843 +
34.844 + /**
34.845 + * Returns the number of registered parties that have arrived at
34.846 + * the current phase of this phaser. If this phaser has terminated,
34.847 + * the returned value is meaningless and arbitrary.
34.848 + *
34.849 + * @return the number of arrived parties
34.850 + */
34.851 + public int getArrivedParties() {
34.852 + return arrivedOf(reconcileState());
34.853 + }
34.854 +
34.855 + /**
34.856 + * Returns the number of registered parties that have not yet
34.857 + * arrived at the current phase of this phaser. If this phaser has
34.858 + * terminated, the returned value is meaningless and arbitrary.
34.859 + *
34.860 + * @return the number of unarrived parties
34.861 + */
34.862 + public int getUnarrivedParties() {
34.863 + return unarrivedOf(reconcileState());
34.864 + }
34.865 +
34.866 + /**
34.867 + * Returns the parent of this phaser, or {@code null} if none.
34.868 + *
34.869 + * @return the parent of this phaser, or {@code null} if none
34.870 + */
34.871 + public Phaser getParent() {
34.872 + return parent;
34.873 + }
34.874 +
34.875 + /**
34.876 + * Returns the root ancestor of this phaser, which is the same as
34.877 + * this phaser if it has no parent.
34.878 + *
34.879 + * @return the root ancestor of this phaser
34.880 + */
34.881 + public Phaser getRoot() {
34.882 + return root;
34.883 + }
34.884 +
34.885 + /**
34.886 + * Returns {@code true} if this phaser has been terminated.
34.887 + *
34.888 + * @return {@code true} if this phaser has been terminated
34.889 + */
34.890 + public boolean isTerminated() {
34.891 + return root.state < 0L;
34.892 + }
34.893 +
34.894 + /**
34.895 + * Overridable method to perform an action upon impending phase
34.896 + * advance, and to control termination. This method is invoked
34.897 + * upon arrival of the party advancing this phaser (when all other
34.898 + * waiting parties are dormant). If this method returns {@code
34.899 + * true}, this phaser will be set to a final termination state
34.900 + * upon advance, and subsequent calls to {@link #isTerminated}
34.901 + * will return true. Any (unchecked) Exception or Error thrown by
34.902 + * an invocation of this method is propagated to the party
34.903 + * attempting to advance this phaser, in which case no advance
34.904 + * occurs.
34.905 + *
34.906 + * <p>The arguments to this method provide the state of the phaser
34.907 + * prevailing for the current transition. The effects of invoking
34.908 + * arrival, registration, and waiting methods on this phaser from
34.909 + * within {@code onAdvance} are unspecified and should not be
34.910 + * relied on.
34.911 + *
34.912 + * <p>If this phaser is a member of a tiered set of phasers, then
34.913 + * {@code onAdvance} is invoked only for its root phaser on each
34.914 + * advance.
34.915 + *
34.916 + * <p>To support the most common use cases, the default
34.917 + * implementation of this method returns {@code true} when the
34.918 + * number of registered parties has become zero as the result of a
34.919 + * party invoking {@code arriveAndDeregister}. You can disable
34.920 + * this behavior, thus enabling continuation upon future
34.921 + * registrations, by overriding this method to always return
34.922 + * {@code false}:
34.923 + *
34.924 + * <pre> {@code
34.925 + * Phaser phaser = new Phaser() {
34.926 + * protected boolean onAdvance(int phase, int parties) { return false; }
34.927 + * }}</pre>
34.928 + *
34.929 + * @param phase the current phase number on entry to this method,
34.930 + * before this phaser is advanced
34.931 + * @param registeredParties the current number of registered parties
34.932 + * @return {@code true} if this phaser should terminate
34.933 + */
34.934 + protected boolean onAdvance(int phase, int registeredParties) {
34.935 + return registeredParties == 0;
34.936 + }
34.937 +
34.938 + /**
34.939 + * Returns a string identifying this phaser, as well as its
34.940 + * state. The state, in brackets, includes the String {@code
34.941 + * "phase = "} followed by the phase number, {@code "parties = "}
34.942 + * followed by the number of registered parties, and {@code
34.943 + * "arrived = "} followed by the number of arrived parties.
34.944 + *
34.945 + * @return a string identifying this phaser, as well as its state
34.946 + */
34.947 + public String toString() {
34.948 + return stateToString(reconcileState());
34.949 + }
34.950 +
34.951 + /**
34.952 + * Implementation of toString and string-based error messages
34.953 + */
34.954 + private String stateToString(long s) {
34.955 + return super.toString() +
34.956 + "[phase = " + phaseOf(s) +
34.957 + " parties = " + partiesOf(s) +
34.958 + " arrived = " + arrivedOf(s) + "]";
34.959 + }
34.960 +
34.961 + // Waiting mechanics
34.962 +
34.963 + /**
34.964 + * Removes and signals threads from queue for phase.
34.965 + */
34.966 + private void releaseWaiters(int phase) {
34.967 + QNode q; // first element of queue
34.968 + Thread t; // its thread
34.969 + AtomicReference<QNode> head = (phase & 1) == 0 ? evenQ : oddQ;
34.970 + while ((q = head.get()) != null &&
34.971 + q.phase != (int)(root.state >>> PHASE_SHIFT)) {
34.972 + if (head.compareAndSet(q, q.next) &&
34.973 + (t = q.thread) != null) {
34.974 + q.thread = null;
34.975 + LockSupport.unpark(t);
34.976 + }
34.977 + }
34.978 + }
34.979 +
34.980 + /**
34.981 + * Variant of releaseWaiters that additionally tries to remove any
34.982 + * nodes no longer waiting for advance due to timeout or
34.983 + * interrupt. Currently, nodes are removed only if they are at
34.984 + * head of queue, which suffices to reduce memory footprint in
34.985 + * most usages.
34.986 + *
34.987 + * @return current phase on exit
34.988 + */
34.989 + private int abortWait(int phase) {
34.990 + AtomicReference<QNode> head = (phase & 1) == 0 ? evenQ : oddQ;
34.991 + for (;;) {
34.992 + Thread t;
34.993 + QNode q = head.get();
34.994 + int p = (int)(root.state >>> PHASE_SHIFT);
34.995 + if (q == null || ((t = q.thread) != null && q.phase == p))
34.996 + return p;
34.997 + if (head.compareAndSet(q, q.next) && t != null) {
34.998 + q.thread = null;
34.999 + LockSupport.unpark(t);
34.1000 + }
34.1001 + }
34.1002 + }
34.1003 +
34.1004 + /** The number of CPUs, for spin control */
34.1005 + private static final int NCPU = Runtime.getRuntime().availableProcessors();
34.1006 +
34.1007 + /**
34.1008 + * The number of times to spin before blocking while waiting for
34.1009 + * advance, per arrival while waiting. On multiprocessors, fully
34.1010 + * blocking and waking up a large number of threads all at once is
34.1011 + * usually a very slow process, so we use rechargeable spins to
34.1012 + * avoid it when threads regularly arrive: When a thread in
34.1013 + * internalAwaitAdvance notices another arrival before blocking,
34.1014 + * and there appear to be enough CPUs available, it spins
34.1015 + * SPINS_PER_ARRIVAL more times before blocking. The value trades
34.1016 + * off good-citizenship vs big unnecessary slowdowns.
34.1017 + */
34.1018 + static final int SPINS_PER_ARRIVAL = (NCPU < 2) ? 1 : 1 << 8;
34.1019 +
34.1020 + /**
34.1021 + * Possibly blocks and waits for phase to advance unless aborted.
34.1022 + * Call only from root node.
34.1023 + *
34.1024 + * @param phase current phase
34.1025 + * @param node if non-null, the wait node to track interrupt and timeout;
34.1026 + * if null, denotes noninterruptible wait
34.1027 + * @return current phase
34.1028 + */
34.1029 + private int internalAwaitAdvance(int phase, QNode node) {
34.1030 + releaseWaiters(phase-1); // ensure old queue clean
34.1031 + boolean queued = false; // true when node is enqueued
34.1032 + int lastUnarrived = 0; // to increase spins upon change
34.1033 + int spins = SPINS_PER_ARRIVAL;
34.1034 + long s;
34.1035 + int p;
34.1036 + while ((p = (int)((s = state) >>> PHASE_SHIFT)) == phase) {
34.1037 + if (node == null) { // spinning in noninterruptible mode
34.1038 + int unarrived = (int)s & UNARRIVED_MASK;
34.1039 + if (unarrived != lastUnarrived &&
34.1040 + (lastUnarrived = unarrived) < NCPU)
34.1041 + spins += SPINS_PER_ARRIVAL;
34.1042 + boolean interrupted = Thread.interrupted();
34.1043 + if (interrupted || --spins < 0) { // need node to record intr
34.1044 + node = new QNode(this, phase, false, false, 0L);
34.1045 + node.wasInterrupted = interrupted;
34.1046 + }
34.1047 + }
34.1048 + else if (node.isReleasable()) // done or aborted
34.1049 + break;
34.1050 + else if (!queued) { // push onto queue
34.1051 + AtomicReference<QNode> head = (phase & 1) == 0 ? evenQ : oddQ;
34.1052 + QNode q = node.next = head.get();
34.1053 + if ((q == null || q.phase == phase) &&
34.1054 + (int)(state >>> PHASE_SHIFT) == phase) // avoid stale enq
34.1055 + queued = head.compareAndSet(q, node);
34.1056 + }
34.1057 + else {
34.1058 + try {
34.1059 + ForkJoinPool.managedBlock(node);
34.1060 + } catch (InterruptedException ie) {
34.1061 + node.wasInterrupted = true;
34.1062 + }
34.1063 + }
34.1064 + }
34.1065 +
34.1066 + if (node != null) {
34.1067 + if (node.thread != null)
34.1068 + node.thread = null; // avoid need for unpark()
34.1069 + if (node.wasInterrupted && !node.interruptible)
34.1070 + Thread.currentThread().interrupt();
34.1071 + if (p == phase && (p = (int)(state >>> PHASE_SHIFT)) == phase)
34.1072 + return abortWait(phase); // possibly clean up on abort
34.1073 + }
34.1074 + releaseWaiters(phase);
34.1075 + return p;
34.1076 + }
34.1077 +
34.1078 + /**
34.1079 + * Wait nodes for Treiber stack representing wait queue
34.1080 + */
34.1081 + static final class QNode implements ForkJoinPool.ManagedBlocker {
34.1082 + final Phaser phaser;
34.1083 + final int phase;
34.1084 + final boolean interruptible;
34.1085 + final boolean timed;
34.1086 + boolean wasInterrupted;
34.1087 + long nanos;
34.1088 + long lastTime;
34.1089 + volatile Thread thread; // nulled to cancel wait
34.1090 + QNode next;
34.1091 +
34.1092 + QNode(Phaser phaser, int phase, boolean interruptible,
34.1093 + boolean timed, long nanos) {
34.1094 + this.phaser = phaser;
34.1095 + this.phase = phase;
34.1096 + this.interruptible = interruptible;
34.1097 + this.nanos = nanos;
34.1098 + this.timed = timed;
34.1099 + this.lastTime = timed ? System.nanoTime() : 0L;
34.1100 + thread = Thread.currentThread();
34.1101 + }
34.1102 +
34.1103 + public boolean isReleasable() {
34.1104 + if (thread == null)
34.1105 + return true;
34.1106 + if (phaser.getPhase() != phase) {
34.1107 + thread = null;
34.1108 + return true;
34.1109 + }
34.1110 + if (Thread.interrupted())
34.1111 + wasInterrupted = true;
34.1112 + if (wasInterrupted && interruptible) {
34.1113 + thread = null;
34.1114 + return true;
34.1115 + }
34.1116 + if (timed) {
34.1117 + if (nanos > 0L) {
34.1118 + long now = System.nanoTime();
34.1119 + nanos -= now - lastTime;
34.1120 + lastTime = now;
34.1121 + }
34.1122 + if (nanos <= 0L) {
34.1123 + thread = null;
34.1124 + return true;
34.1125 + }
34.1126 + }
34.1127 + return false;
34.1128 + }
34.1129 +
34.1130 + public boolean block() {
34.1131 + if (isReleasable())
34.1132 + return true;
34.1133 + else if (!timed)
34.1134 + LockSupport.park(this);
34.1135 + else if (nanos > 0)
34.1136 + LockSupport.parkNanos(this, nanos);
34.1137 + return isReleasable();
34.1138 + }
34.1139 + }
34.1140 +
34.1141 + // Unsafe mechanics
34.1142 +
34.1143 + private static final sun.misc.Unsafe UNSAFE;
34.1144 + private static final long stateOffset;
34.1145 + static {
34.1146 + try {
34.1147 + UNSAFE = sun.misc.Unsafe.getUnsafe();
34.1148 + Class k = Phaser.class;
34.1149 + stateOffset = UNSAFE.objectFieldOffset
34.1150 + (k.getDeclaredField("state"));
34.1151 + } catch (Exception e) {
34.1152 + throw new Error(e);
34.1153 + }
34.1154 + }
34.1155 +}
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
35.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/PriorityBlockingQueue.java Sat Mar 19 10:46:31 2016 +0100
35.3 @@ -0,0 +1,978 @@
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 +import java.util.concurrent.locks.*;
35.42 +import java.util.*;
35.43 +
35.44 +/**
35.45 + * An unbounded {@linkplain BlockingQueue blocking queue} that uses
35.46 + * the same ordering rules as class {@link PriorityQueue} and supplies
35.47 + * blocking retrieval operations. While this queue is logically
35.48 + * unbounded, attempted additions may fail due to resource exhaustion
35.49 + * (causing {@code OutOfMemoryError}). This class does not permit
35.50 + * {@code null} elements. A priority queue relying on {@linkplain
35.51 + * Comparable natural ordering} also does not permit insertion of
35.52 + * non-comparable objects (doing so results in
35.53 + * {@code ClassCastException}).
35.54 + *
35.55 + * <p>This class and its iterator implement all of the
35.56 + * <em>optional</em> methods of the {@link Collection} and {@link
35.57 + * Iterator} interfaces. The Iterator provided in method {@link
35.58 + * #iterator()} is <em>not</em> guaranteed to traverse the elements of
35.59 + * the PriorityBlockingQueue in any particular order. If you need
35.60 + * ordered traversal, consider using
35.61 + * {@code Arrays.sort(pq.toArray())}. Also, method {@code drainTo}
35.62 + * can be used to <em>remove</em> some or all elements in priority
35.63 + * order and place them in another collection.
35.64 + *
35.65 + * <p>Operations on this class make no guarantees about the ordering
35.66 + * of elements with equal priority. If you need to enforce an
35.67 + * ordering, you can define custom classes or comparators that use a
35.68 + * secondary key to break ties in primary priority values. For
35.69 + * example, here is a class that applies first-in-first-out
35.70 + * tie-breaking to comparable elements. To use it, you would insert a
35.71 + * {@code new FIFOEntry(anEntry)} instead of a plain entry object.
35.72 + *
35.73 + * <pre> {@code
35.74 + * class FIFOEntry<E extends Comparable<? super E>>
35.75 + * implements Comparable<FIFOEntry<E>> {
35.76 + * static final AtomicLong seq = new AtomicLong(0);
35.77 + * final long seqNum;
35.78 + * final E entry;
35.79 + * public FIFOEntry(E entry) {
35.80 + * seqNum = seq.getAndIncrement();
35.81 + * this.entry = entry;
35.82 + * }
35.83 + * public E getEntry() { return entry; }
35.84 + * public int compareTo(FIFOEntry<E> other) {
35.85 + * int res = entry.compareTo(other.entry);
35.86 + * if (res == 0 && other.entry != this.entry)
35.87 + * res = (seqNum < other.seqNum ? -1 : 1);
35.88 + * return res;
35.89 + * }
35.90 + * }}</pre>
35.91 + *
35.92 + * <p>This class is a member of the
35.93 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
35.94 + * Java Collections Framework</a>.
35.95 + *
35.96 + * @since 1.5
35.97 + * @author Doug Lea
35.98 + * @param <E> the type of elements held in this collection
35.99 + */
35.100 +public class PriorityBlockingQueue<E> extends AbstractQueue<E>
35.101 + implements BlockingQueue<E>, java.io.Serializable {
35.102 + private static final long serialVersionUID = 5595510919245408276L;
35.103 +
35.104 + /*
35.105 + * The implementation uses an array-based binary heap, with public
35.106 + * operations protected with a single lock. However, allocation
35.107 + * during resizing uses a simple spinlock (used only while not
35.108 + * holding main lock) in order to allow takes to operate
35.109 + * concurrently with allocation. This avoids repeated
35.110 + * postponement of waiting consumers and consequent element
35.111 + * build-up. The need to back away from lock during allocation
35.112 + * makes it impossible to simply wrap delegated
35.113 + * java.util.PriorityQueue operations within a lock, as was done
35.114 + * in a previous version of this class. To maintain
35.115 + * interoperability, a plain PriorityQueue is still used during
35.116 + * serialization, which maintains compatibility at the espense of
35.117 + * transiently doubling overhead.
35.118 + */
35.119 +
35.120 + /**
35.121 + * Default array capacity.
35.122 + */
35.123 + private static final int DEFAULT_INITIAL_CAPACITY = 11;
35.124 +
35.125 + /**
35.126 + * The maximum size of array to allocate.
35.127 + * Some VMs reserve some header words in an array.
35.128 + * Attempts to allocate larger arrays may result in
35.129 + * OutOfMemoryError: Requested array size exceeds VM limit
35.130 + */
35.131 + private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
35.132 +
35.133 + /**
35.134 + * Priority queue represented as a balanced binary heap: the two
35.135 + * children of queue[n] are queue[2*n+1] and queue[2*(n+1)]. The
35.136 + * priority queue is ordered by comparator, or by the elements'
35.137 + * natural ordering, if comparator is null: For each node n in the
35.138 + * heap and each descendant d of n, n <= d. The element with the
35.139 + * lowest value is in queue[0], assuming the queue is nonempty.
35.140 + */
35.141 + private transient Object[] queue;
35.142 +
35.143 + /**
35.144 + * The number of elements in the priority queue.
35.145 + */
35.146 + private transient int size;
35.147 +
35.148 + /**
35.149 + * The comparator, or null if priority queue uses elements'
35.150 + * natural ordering.
35.151 + */
35.152 + private transient Comparator<? super E> comparator;
35.153 +
35.154 + /**
35.155 + * Lock used for all public operations
35.156 + */
35.157 + private final ReentrantLock lock;
35.158 +
35.159 + /**
35.160 + * Condition for blocking when empty
35.161 + */
35.162 + private final Condition notEmpty;
35.163 +
35.164 + /**
35.165 + * Spinlock for allocation, acquired via CAS.
35.166 + */
35.167 + private transient volatile int allocationSpinLock;
35.168 +
35.169 + /**
35.170 + * A plain PriorityQueue used only for serialization,
35.171 + * to maintain compatibility with previous versions
35.172 + * of this class. Non-null only during serialization/deserialization.
35.173 + */
35.174 + private PriorityQueue q;
35.175 +
35.176 + /**
35.177 + * Creates a {@code PriorityBlockingQueue} with the default
35.178 + * initial capacity (11) that orders its elements according to
35.179 + * their {@linkplain Comparable natural ordering}.
35.180 + */
35.181 + public PriorityBlockingQueue() {
35.182 + this(DEFAULT_INITIAL_CAPACITY, null);
35.183 + }
35.184 +
35.185 + /**
35.186 + * Creates a {@code PriorityBlockingQueue} with the specified
35.187 + * initial capacity that orders its elements according to their
35.188 + * {@linkplain Comparable natural ordering}.
35.189 + *
35.190 + * @param initialCapacity the initial capacity for this priority queue
35.191 + * @throws IllegalArgumentException if {@code initialCapacity} is less
35.192 + * than 1
35.193 + */
35.194 + public PriorityBlockingQueue(int initialCapacity) {
35.195 + this(initialCapacity, null);
35.196 + }
35.197 +
35.198 + /**
35.199 + * Creates a {@code PriorityBlockingQueue} with the specified initial
35.200 + * capacity that orders its elements according to the specified
35.201 + * comparator.
35.202 + *
35.203 + * @param initialCapacity the initial capacity for this priority queue
35.204 + * @param comparator the comparator that will be used to order this
35.205 + * priority queue. If {@code null}, the {@linkplain Comparable
35.206 + * natural ordering} of the elements will be used.
35.207 + * @throws IllegalArgumentException if {@code initialCapacity} is less
35.208 + * than 1
35.209 + */
35.210 + public PriorityBlockingQueue(int initialCapacity,
35.211 + Comparator<? super E> comparator) {
35.212 + if (initialCapacity < 1)
35.213 + throw new IllegalArgumentException();
35.214 + this.lock = new ReentrantLock();
35.215 + this.notEmpty = lock.newCondition();
35.216 + this.comparator = comparator;
35.217 + this.queue = new Object[initialCapacity];
35.218 + }
35.219 +
35.220 + /**
35.221 + * Creates a {@code PriorityBlockingQueue} containing the elements
35.222 + * in the specified collection. If the specified collection is a
35.223 + * {@link SortedSet} or a {@link PriorityQueue}, this
35.224 + * priority queue will be ordered according to the same ordering.
35.225 + * Otherwise, this priority queue will be ordered according to the
35.226 + * {@linkplain Comparable natural ordering} of its elements.
35.227 + *
35.228 + * @param c the collection whose elements are to be placed
35.229 + * into this priority queue
35.230 + * @throws ClassCastException if elements of the specified collection
35.231 + * cannot be compared to one another according to the priority
35.232 + * queue's ordering
35.233 + * @throws NullPointerException if the specified collection or any
35.234 + * of its elements are null
35.235 + */
35.236 + public PriorityBlockingQueue(Collection<? extends E> c) {
35.237 + this.lock = new ReentrantLock();
35.238 + this.notEmpty = lock.newCondition();
35.239 + boolean heapify = true; // true if not known to be in heap order
35.240 + boolean screen = true; // true if must screen for nulls
35.241 + if (c instanceof SortedSet<?>) {
35.242 + SortedSet<? extends E> ss = (SortedSet<? extends E>) c;
35.243 + this.comparator = (Comparator<? super E>) ss.comparator();
35.244 + heapify = false;
35.245 + }
35.246 + else if (c instanceof PriorityBlockingQueue<?>) {
35.247 + PriorityBlockingQueue<? extends E> pq =
35.248 + (PriorityBlockingQueue<? extends E>) c;
35.249 + this.comparator = (Comparator<? super E>) pq.comparator();
35.250 + screen = false;
35.251 + if (pq.getClass() == PriorityBlockingQueue.class) // exact match
35.252 + heapify = false;
35.253 + }
35.254 + Object[] a = c.toArray();
35.255 + int n = a.length;
35.256 + // If c.toArray incorrectly doesn't return Object[], copy it.
35.257 + if (a.getClass() != Object[].class)
35.258 + a = Arrays.copyOf(a, n, Object[].class);
35.259 + if (screen && (n == 1 || this.comparator != null)) {
35.260 + for (int i = 0; i < n; ++i)
35.261 + if (a[i] == null)
35.262 + throw new NullPointerException();
35.263 + }
35.264 + this.queue = a;
35.265 + this.size = n;
35.266 + if (heapify)
35.267 + heapify();
35.268 + }
35.269 +
35.270 + /**
35.271 + * Tries to grow array to accommodate at least one more element
35.272 + * (but normally expand by about 50%), giving up (allowing retry)
35.273 + * on contention (which we expect to be rare). Call only while
35.274 + * holding lock.
35.275 + *
35.276 + * @param array the heap array
35.277 + * @param oldCap the length of the array
35.278 + */
35.279 + private void tryGrow(Object[] array, int oldCap) {
35.280 + lock.unlock(); // must release and then re-acquire main lock
35.281 + Object[] newArray = null;
35.282 + if (allocationSpinLock == 0 &&
35.283 + UNSAFE.compareAndSwapInt(this, allocationSpinLockOffset,
35.284 + 0, 1)) {
35.285 + try {
35.286 + int newCap = oldCap + ((oldCap < 64) ?
35.287 + (oldCap + 2) : // grow faster if small
35.288 + (oldCap >> 1));
35.289 + if (newCap - MAX_ARRAY_SIZE > 0) { // possible overflow
35.290 + int minCap = oldCap + 1;
35.291 + if (minCap < 0 || minCap > MAX_ARRAY_SIZE)
35.292 + throw new OutOfMemoryError();
35.293 + newCap = MAX_ARRAY_SIZE;
35.294 + }
35.295 + if (newCap > oldCap && queue == array)
35.296 + newArray = new Object[newCap];
35.297 + } finally {
35.298 + allocationSpinLock = 0;
35.299 + }
35.300 + }
35.301 + if (newArray == null) // back off if another thread is allocating
35.302 + Thread.yield();
35.303 + lock.lock();
35.304 + if (newArray != null && queue == array) {
35.305 + queue = newArray;
35.306 + System.arraycopy(array, 0, newArray, 0, oldCap);
35.307 + }
35.308 + }
35.309 +
35.310 + /**
35.311 + * Mechanics for poll(). Call only while holding lock.
35.312 + */
35.313 + private E extract() {
35.314 + E result;
35.315 + int n = size - 1;
35.316 + if (n < 0)
35.317 + result = null;
35.318 + else {
35.319 + Object[] array = queue;
35.320 + result = (E) array[0];
35.321 + E x = (E) array[n];
35.322 + array[n] = null;
35.323 + Comparator<? super E> cmp = comparator;
35.324 + if (cmp == null)
35.325 + siftDownComparable(0, x, array, n);
35.326 + else
35.327 + siftDownUsingComparator(0, x, array, n, cmp);
35.328 + size = n;
35.329 + }
35.330 + return result;
35.331 + }
35.332 +
35.333 + /**
35.334 + * Inserts item x at position k, maintaining heap invariant by
35.335 + * promoting x up the tree until it is greater than or equal to
35.336 + * its parent, or is the root.
35.337 + *
35.338 + * To simplify and speed up coercions and comparisons. the
35.339 + * Comparable and Comparator versions are separated into different
35.340 + * methods that are otherwise identical. (Similarly for siftDown.)
35.341 + * These methods are static, with heap state as arguments, to
35.342 + * simplify use in light of possible comparator exceptions.
35.343 + *
35.344 + * @param k the position to fill
35.345 + * @param x the item to insert
35.346 + * @param array the heap array
35.347 + * @param n heap size
35.348 + */
35.349 + private static <T> void siftUpComparable(int k, T x, Object[] array) {
35.350 + Comparable<? super T> key = (Comparable<? super T>) x;
35.351 + while (k > 0) {
35.352 + int parent = (k - 1) >>> 1;
35.353 + Object e = array[parent];
35.354 + if (key.compareTo((T) e) >= 0)
35.355 + break;
35.356 + array[k] = e;
35.357 + k = parent;
35.358 + }
35.359 + array[k] = key;
35.360 + }
35.361 +
35.362 + private static <T> void siftUpUsingComparator(int k, T x, Object[] array,
35.363 + Comparator<? super T> cmp) {
35.364 + while (k > 0) {
35.365 + int parent = (k - 1) >>> 1;
35.366 + Object e = array[parent];
35.367 + if (cmp.compare(x, (T) e) >= 0)
35.368 + break;
35.369 + array[k] = e;
35.370 + k = parent;
35.371 + }
35.372 + array[k] = x;
35.373 + }
35.374 +
35.375 + /**
35.376 + * Inserts item x at position k, maintaining heap invariant by
35.377 + * demoting x down the tree repeatedly until it is less than or
35.378 + * equal to its children or is a leaf.
35.379 + *
35.380 + * @param k the position to fill
35.381 + * @param x the item to insert
35.382 + * @param array the heap array
35.383 + * @param n heap size
35.384 + */
35.385 + private static <T> void siftDownComparable(int k, T x, Object[] array,
35.386 + int n) {
35.387 + Comparable<? super T> key = (Comparable<? super T>)x;
35.388 + int half = n >>> 1; // loop while a non-leaf
35.389 + while (k < half) {
35.390 + int child = (k << 1) + 1; // assume left child is least
35.391 + Object c = array[child];
35.392 + int right = child + 1;
35.393 + if (right < n &&
35.394 + ((Comparable<? super T>) c).compareTo((T) array[right]) > 0)
35.395 + c = array[child = right];
35.396 + if (key.compareTo((T) c) <= 0)
35.397 + break;
35.398 + array[k] = c;
35.399 + k = child;
35.400 + }
35.401 + array[k] = key;
35.402 + }
35.403 +
35.404 + private static <T> void siftDownUsingComparator(int k, T x, Object[] array,
35.405 + int n,
35.406 + Comparator<? super T> cmp) {
35.407 + int half = n >>> 1;
35.408 + while (k < half) {
35.409 + int child = (k << 1) + 1;
35.410 + Object c = array[child];
35.411 + int right = child + 1;
35.412 + if (right < n && cmp.compare((T) c, (T) array[right]) > 0)
35.413 + c = array[child = right];
35.414 + if (cmp.compare(x, (T) c) <= 0)
35.415 + break;
35.416 + array[k] = c;
35.417 + k = child;
35.418 + }
35.419 + array[k] = x;
35.420 + }
35.421 +
35.422 + /**
35.423 + * Establishes the heap invariant (described above) in the entire tree,
35.424 + * assuming nothing about the order of the elements prior to the call.
35.425 + */
35.426 + private void heapify() {
35.427 + Object[] array = queue;
35.428 + int n = size;
35.429 + int half = (n >>> 1) - 1;
35.430 + Comparator<? super E> cmp = comparator;
35.431 + if (cmp == null) {
35.432 + for (int i = half; i >= 0; i--)
35.433 + siftDownComparable(i, (E) array[i], array, n);
35.434 + }
35.435 + else {
35.436 + for (int i = half; i >= 0; i--)
35.437 + siftDownUsingComparator(i, (E) array[i], array, n, cmp);
35.438 + }
35.439 + }
35.440 +
35.441 + /**
35.442 + * Inserts the specified element into this priority queue.
35.443 + *
35.444 + * @param e the element to add
35.445 + * @return {@code true} (as specified by {@link Collection#add})
35.446 + * @throws ClassCastException if the specified element cannot be compared
35.447 + * with elements currently in the priority queue according to the
35.448 + * priority queue's ordering
35.449 + * @throws NullPointerException if the specified element is null
35.450 + */
35.451 + public boolean add(E e) {
35.452 + return offer(e);
35.453 + }
35.454 +
35.455 + /**
35.456 + * Inserts the specified element into this priority queue.
35.457 + * As the queue is unbounded, this method will never return {@code false}.
35.458 + *
35.459 + * @param e the element to add
35.460 + * @return {@code true} (as specified by {@link Queue#offer})
35.461 + * @throws ClassCastException if the specified element cannot be compared
35.462 + * with elements currently in the priority queue according to the
35.463 + * priority queue's ordering
35.464 + * @throws NullPointerException if the specified element is null
35.465 + */
35.466 + public boolean offer(E e) {
35.467 + if (e == null)
35.468 + throw new NullPointerException();
35.469 + final ReentrantLock lock = this.lock;
35.470 + lock.lock();
35.471 + int n, cap;
35.472 + Object[] array;
35.473 + while ((n = size) >= (cap = (array = queue).length))
35.474 + tryGrow(array, cap);
35.475 + try {
35.476 + Comparator<? super E> cmp = comparator;
35.477 + if (cmp == null)
35.478 + siftUpComparable(n, e, array);
35.479 + else
35.480 + siftUpUsingComparator(n, e, array, cmp);
35.481 + size = n + 1;
35.482 + notEmpty.signal();
35.483 + } finally {
35.484 + lock.unlock();
35.485 + }
35.486 + return true;
35.487 + }
35.488 +
35.489 + /**
35.490 + * Inserts the specified element into this priority queue.
35.491 + * As the queue is unbounded, this method will never block.
35.492 + *
35.493 + * @param e the element to add
35.494 + * @throws ClassCastException if the specified element cannot be compared
35.495 + * with elements currently in the priority queue according to the
35.496 + * priority queue's ordering
35.497 + * @throws NullPointerException if the specified element is null
35.498 + */
35.499 + public void put(E e) {
35.500 + offer(e); // never need to block
35.501 + }
35.502 +
35.503 + /**
35.504 + * Inserts the specified element into this priority queue.
35.505 + * As the queue is unbounded, this method will never block or
35.506 + * return {@code false}.
35.507 + *
35.508 + * @param e the element to add
35.509 + * @param timeout This parameter is ignored as the method never blocks
35.510 + * @param unit This parameter is ignored as the method never blocks
35.511 + * @return {@code true} (as specified by
35.512 + * {@link BlockingQueue#offer(Object,long,TimeUnit) BlockingQueue.offer})
35.513 + * @throws ClassCastException if the specified element cannot be compared
35.514 + * with elements currently in the priority queue according to the
35.515 + * priority queue's ordering
35.516 + * @throws NullPointerException if the specified element is null
35.517 + */
35.518 + public boolean offer(E e, long timeout, TimeUnit unit) {
35.519 + return offer(e); // never need to block
35.520 + }
35.521 +
35.522 + public E poll() {
35.523 + final ReentrantLock lock = this.lock;
35.524 + lock.lock();
35.525 + E result;
35.526 + try {
35.527 + result = extract();
35.528 + } finally {
35.529 + lock.unlock();
35.530 + }
35.531 + return result;
35.532 + }
35.533 +
35.534 + public E take() throws InterruptedException {
35.535 + final ReentrantLock lock = this.lock;
35.536 + lock.lockInterruptibly();
35.537 + E result;
35.538 + try {
35.539 + while ( (result = extract()) == null)
35.540 + notEmpty.await();
35.541 + } finally {
35.542 + lock.unlock();
35.543 + }
35.544 + return result;
35.545 + }
35.546 +
35.547 + public E poll(long timeout, TimeUnit unit) throws InterruptedException {
35.548 + long nanos = unit.toNanos(timeout);
35.549 + final ReentrantLock lock = this.lock;
35.550 + lock.lockInterruptibly();
35.551 + E result;
35.552 + try {
35.553 + while ( (result = extract()) == null && nanos > 0)
35.554 + nanos = notEmpty.awaitNanos(nanos);
35.555 + } finally {
35.556 + lock.unlock();
35.557 + }
35.558 + return result;
35.559 + }
35.560 +
35.561 + public E peek() {
35.562 + final ReentrantLock lock = this.lock;
35.563 + lock.lock();
35.564 + E result;
35.565 + try {
35.566 + result = size > 0 ? (E) queue[0] : null;
35.567 + } finally {
35.568 + lock.unlock();
35.569 + }
35.570 + return result;
35.571 + }
35.572 +
35.573 + /**
35.574 + * Returns the comparator used to order the elements in this queue,
35.575 + * or {@code null} if this queue uses the {@linkplain Comparable
35.576 + * natural ordering} of its elements.
35.577 + *
35.578 + * @return the comparator used to order the elements in this queue,
35.579 + * or {@code null} if this queue uses the natural
35.580 + * ordering of its elements
35.581 + */
35.582 + public Comparator<? super E> comparator() {
35.583 + return comparator;
35.584 + }
35.585 +
35.586 + public int size() {
35.587 + final ReentrantLock lock = this.lock;
35.588 + lock.lock();
35.589 + try {
35.590 + return size;
35.591 + } finally {
35.592 + lock.unlock();
35.593 + }
35.594 + }
35.595 +
35.596 + /**
35.597 + * Always returns {@code Integer.MAX_VALUE} because
35.598 + * a {@code PriorityBlockingQueue} is not capacity constrained.
35.599 + * @return {@code Integer.MAX_VALUE} always
35.600 + */
35.601 + public int remainingCapacity() {
35.602 + return Integer.MAX_VALUE;
35.603 + }
35.604 +
35.605 + private int indexOf(Object o) {
35.606 + if (o != null) {
35.607 + Object[] array = queue;
35.608 + int n = size;
35.609 + for (int i = 0; i < n; i++)
35.610 + if (o.equals(array[i]))
35.611 + return i;
35.612 + }
35.613 + return -1;
35.614 + }
35.615 +
35.616 + /**
35.617 + * Removes the ith element from queue.
35.618 + */
35.619 + private void removeAt(int i) {
35.620 + Object[] array = queue;
35.621 + int n = size - 1;
35.622 + if (n == i) // removed last element
35.623 + array[i] = null;
35.624 + else {
35.625 + E moved = (E) array[n];
35.626 + array[n] = null;
35.627 + Comparator<? super E> cmp = comparator;
35.628 + if (cmp == null)
35.629 + siftDownComparable(i, moved, array, n);
35.630 + else
35.631 + siftDownUsingComparator(i, moved, array, n, cmp);
35.632 + if (array[i] == moved) {
35.633 + if (cmp == null)
35.634 + siftUpComparable(i, moved, array);
35.635 + else
35.636 + siftUpUsingComparator(i, moved, array, cmp);
35.637 + }
35.638 + }
35.639 + size = n;
35.640 + }
35.641 +
35.642 + /**
35.643 + * Removes a single instance of the specified element from this queue,
35.644 + * if it is present. More formally, removes an element {@code e} such
35.645 + * that {@code o.equals(e)}, if this queue contains one or more such
35.646 + * elements. Returns {@code true} if and only if this queue contained
35.647 + * the specified element (or equivalently, if this queue changed as a
35.648 + * result of the call).
35.649 + *
35.650 + * @param o element to be removed from this queue, if present
35.651 + * @return {@code true} if this queue changed as a result of the call
35.652 + */
35.653 + public boolean remove(Object o) {
35.654 + boolean removed = false;
35.655 + final ReentrantLock lock = this.lock;
35.656 + lock.lock();
35.657 + try {
35.658 + int i = indexOf(o);
35.659 + if (i != -1) {
35.660 + removeAt(i);
35.661 + removed = true;
35.662 + }
35.663 + } finally {
35.664 + lock.unlock();
35.665 + }
35.666 + return removed;
35.667 + }
35.668 +
35.669 +
35.670 + /**
35.671 + * Identity-based version for use in Itr.remove
35.672 + */
35.673 + private void removeEQ(Object o) {
35.674 + final ReentrantLock lock = this.lock;
35.675 + lock.lock();
35.676 + try {
35.677 + Object[] array = queue;
35.678 + int n = size;
35.679 + for (int i = 0; i < n; i++) {
35.680 + if (o == array[i]) {
35.681 + removeAt(i);
35.682 + break;
35.683 + }
35.684 + }
35.685 + } finally {
35.686 + lock.unlock();
35.687 + }
35.688 + }
35.689 +
35.690 + /**
35.691 + * Returns {@code true} if this queue contains the specified element.
35.692 + * More formally, returns {@code true} if and only if this queue contains
35.693 + * at least one element {@code e} such that {@code o.equals(e)}.
35.694 + *
35.695 + * @param o object to be checked for containment in this queue
35.696 + * @return {@code true} if this queue contains the specified element
35.697 + */
35.698 + public boolean contains(Object o) {
35.699 + int index;
35.700 + final ReentrantLock lock = this.lock;
35.701 + lock.lock();
35.702 + try {
35.703 + index = indexOf(o);
35.704 + } finally {
35.705 + lock.unlock();
35.706 + }
35.707 + return index != -1;
35.708 + }
35.709 +
35.710 + /**
35.711 + * Returns an array containing all of the elements in this queue.
35.712 + * The returned array elements are in no particular order.
35.713 + *
35.714 + * <p>The returned array will be "safe" in that no references to it are
35.715 + * maintained by this queue. (In other words, this method must allocate
35.716 + * a new array). The caller is thus free to modify the returned array.
35.717 + *
35.718 + * <p>This method acts as bridge between array-based and collection-based
35.719 + * APIs.
35.720 + *
35.721 + * @return an array containing all of the elements in this queue
35.722 + */
35.723 + public Object[] toArray() {
35.724 + final ReentrantLock lock = this.lock;
35.725 + lock.lock();
35.726 + try {
35.727 + return Arrays.copyOf(queue, size);
35.728 + } finally {
35.729 + lock.unlock();
35.730 + }
35.731 + }
35.732 +
35.733 +
35.734 + public String toString() {
35.735 + final ReentrantLock lock = this.lock;
35.736 + lock.lock();
35.737 + try {
35.738 + int n = size;
35.739 + if (n == 0)
35.740 + return "[]";
35.741 + StringBuilder sb = new StringBuilder();
35.742 + sb.append('[');
35.743 + for (int i = 0; i < n; ++i) {
35.744 + E e = (E)queue[i];
35.745 + sb.append(e == this ? "(this Collection)" : e);
35.746 + if (i != n - 1)
35.747 + sb.append(',').append(' ');
35.748 + }
35.749 + return sb.append(']').toString();
35.750 + } finally {
35.751 + lock.unlock();
35.752 + }
35.753 + }
35.754 +
35.755 + /**
35.756 + * @throws UnsupportedOperationException {@inheritDoc}
35.757 + * @throws ClassCastException {@inheritDoc}
35.758 + * @throws NullPointerException {@inheritDoc}
35.759 + * @throws IllegalArgumentException {@inheritDoc}
35.760 + */
35.761 + public int drainTo(Collection<? super E> c) {
35.762 + if (c == null)
35.763 + throw new NullPointerException();
35.764 + if (c == this)
35.765 + throw new IllegalArgumentException();
35.766 + final ReentrantLock lock = this.lock;
35.767 + lock.lock();
35.768 + try {
35.769 + int n = 0;
35.770 + E e;
35.771 + while ( (e = extract()) != null) {
35.772 + c.add(e);
35.773 + ++n;
35.774 + }
35.775 + return n;
35.776 + } finally {
35.777 + lock.unlock();
35.778 + }
35.779 + }
35.780 +
35.781 + /**
35.782 + * @throws UnsupportedOperationException {@inheritDoc}
35.783 + * @throws ClassCastException {@inheritDoc}
35.784 + * @throws NullPointerException {@inheritDoc}
35.785 + * @throws IllegalArgumentException {@inheritDoc}
35.786 + */
35.787 + public int drainTo(Collection<? super E> c, int maxElements) {
35.788 + if (c == null)
35.789 + throw new NullPointerException();
35.790 + if (c == this)
35.791 + throw new IllegalArgumentException();
35.792 + if (maxElements <= 0)
35.793 + return 0;
35.794 + final ReentrantLock lock = this.lock;
35.795 + lock.lock();
35.796 + try {
35.797 + int n = 0;
35.798 + E e;
35.799 + while (n < maxElements && (e = extract()) != null) {
35.800 + c.add(e);
35.801 + ++n;
35.802 + }
35.803 + return n;
35.804 + } finally {
35.805 + lock.unlock();
35.806 + }
35.807 + }
35.808 +
35.809 + /**
35.810 + * Atomically removes all of the elements from this queue.
35.811 + * The queue will be empty after this call returns.
35.812 + */
35.813 + public void clear() {
35.814 + final ReentrantLock lock = this.lock;
35.815 + lock.lock();
35.816 + try {
35.817 + Object[] array = queue;
35.818 + int n = size;
35.819 + size = 0;
35.820 + for (int i = 0; i < n; i++)
35.821 + array[i] = null;
35.822 + } finally {
35.823 + lock.unlock();
35.824 + }
35.825 + }
35.826 +
35.827 + /**
35.828 + * Returns an array containing all of the elements in this queue; the
35.829 + * runtime type of the returned array is that of the specified array.
35.830 + * The returned array elements are in no particular order.
35.831 + * If the queue fits in the specified array, it is returned therein.
35.832 + * Otherwise, a new array is allocated with the runtime type of the
35.833 + * specified array and the size of this queue.
35.834 + *
35.835 + * <p>If this queue fits in the specified array with room to spare
35.836 + * (i.e., the array has more elements than this queue), the element in
35.837 + * the array immediately following the end of the queue is set to
35.838 + * {@code null}.
35.839 + *
35.840 + * <p>Like the {@link #toArray()} method, this method acts as bridge between
35.841 + * array-based and collection-based APIs. Further, this method allows
35.842 + * precise control over the runtime type of the output array, and may,
35.843 + * under certain circumstances, be used to save allocation costs.
35.844 + *
35.845 + * <p>Suppose {@code x} is a queue known to contain only strings.
35.846 + * The following code can be used to dump the queue into a newly
35.847 + * allocated array of {@code String}:
35.848 + *
35.849 + * <pre>
35.850 + * String[] y = x.toArray(new String[0]);</pre>
35.851 + *
35.852 + * Note that {@code toArray(new Object[0])} is identical in function to
35.853 + * {@code toArray()}.
35.854 + *
35.855 + * @param a the array into which the elements of the queue are to
35.856 + * be stored, if it is big enough; otherwise, a new array of the
35.857 + * same runtime type is allocated for this purpose
35.858 + * @return an array containing all of the elements in this queue
35.859 + * @throws ArrayStoreException if the runtime type of the specified array
35.860 + * is not a supertype of the runtime type of every element in
35.861 + * this queue
35.862 + * @throws NullPointerException if the specified array is null
35.863 + */
35.864 + public <T> T[] toArray(T[] a) {
35.865 + final ReentrantLock lock = this.lock;
35.866 + lock.lock();
35.867 + try {
35.868 + int n = size;
35.869 + if (a.length < n)
35.870 + // Make a new array of a's runtime type, but my contents:
35.871 + return (T[]) Arrays.copyOf(queue, size, a.getClass());
35.872 + System.arraycopy(queue, 0, a, 0, n);
35.873 + if (a.length > n)
35.874 + a[n] = null;
35.875 + return a;
35.876 + } finally {
35.877 + lock.unlock();
35.878 + }
35.879 + }
35.880 +
35.881 + /**
35.882 + * Returns an iterator over the elements in this queue. The
35.883 + * iterator does not return the elements in any particular order.
35.884 + *
35.885 + * <p>The returned iterator is a "weakly consistent" iterator that
35.886 + * will never throw {@link java.util.ConcurrentModificationException
35.887 + * ConcurrentModificationException}, and guarantees to traverse
35.888 + * elements as they existed upon construction of the iterator, and
35.889 + * may (but is not guaranteed to) reflect any modifications
35.890 + * subsequent to construction.
35.891 + *
35.892 + * @return an iterator over the elements in this queue
35.893 + */
35.894 + public Iterator<E> iterator() {
35.895 + return new Itr(toArray());
35.896 + }
35.897 +
35.898 + /**
35.899 + * Snapshot iterator that works off copy of underlying q array.
35.900 + */
35.901 + final class Itr implements Iterator<E> {
35.902 + final Object[] array; // Array of all elements
35.903 + int cursor; // index of next element to return;
35.904 + int lastRet; // index of last element, or -1 if no such
35.905 +
35.906 + Itr(Object[] array) {
35.907 + lastRet = -1;
35.908 + this.array = array;
35.909 + }
35.910 +
35.911 + public boolean hasNext() {
35.912 + return cursor < array.length;
35.913 + }
35.914 +
35.915 + public E next() {
35.916 + if (cursor >= array.length)
35.917 + throw new NoSuchElementException();
35.918 + lastRet = cursor;
35.919 + return (E)array[cursor++];
35.920 + }
35.921 +
35.922 + public void remove() {
35.923 + if (lastRet < 0)
35.924 + throw new IllegalStateException();
35.925 + removeEQ(array[lastRet]);
35.926 + lastRet = -1;
35.927 + }
35.928 + }
35.929 +
35.930 + /**
35.931 + * Saves the state to a stream (that is, serializes it). For
35.932 + * compatibility with previous version of this class,
35.933 + * elements are first copied to a java.util.PriorityQueue,
35.934 + * which is then serialized.
35.935 + */
35.936 + private void writeObject(java.io.ObjectOutputStream s)
35.937 + throws java.io.IOException {
35.938 + lock.lock();
35.939 + try {
35.940 + int n = size; // avoid zero capacity argument
35.941 + q = new PriorityQueue<E>(n == 0 ? 1 : n, comparator);
35.942 + q.addAll(this);
35.943 + s.defaultWriteObject();
35.944 + } finally {
35.945 + q = null;
35.946 + lock.unlock();
35.947 + }
35.948 + }
35.949 +
35.950 + /**
35.951 + * Reconstitutes the {@code PriorityBlockingQueue} instance from a stream
35.952 + * (that is, deserializes it).
35.953 + *
35.954 + * @param s the stream
35.955 + */
35.956 + private void readObject(java.io.ObjectInputStream s)
35.957 + throws java.io.IOException, ClassNotFoundException {
35.958 + try {
35.959 + s.defaultReadObject();
35.960 + this.queue = new Object[q.size()];
35.961 + comparator = q.comparator();
35.962 + addAll(q);
35.963 + } finally {
35.964 + q = null;
35.965 + }
35.966 + }
35.967 +
35.968 + // Unsafe mechanics
35.969 + private static final sun.misc.Unsafe UNSAFE;
35.970 + private static final long allocationSpinLockOffset;
35.971 + static {
35.972 + try {
35.973 + UNSAFE = sun.misc.Unsafe.getUnsafe();
35.974 + Class k = PriorityBlockingQueue.class;
35.975 + allocationSpinLockOffset = UNSAFE.objectFieldOffset
35.976 + (k.getDeclaredField("allocationSpinLock"));
35.977 + } catch (Exception e) {
35.978 + throw new Error(e);
35.979 + }
35.980 + }
35.981 +}
36.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
36.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/RecursiveAction.java Sat Mar 19 10:46:31 2016 +0100
36.3 @@ -0,0 +1,181 @@
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 + * A recursive resultless {@link ForkJoinTask}. This class
36.43 + * establishes conventions to parameterize resultless actions as
36.44 + * {@code Void} {@code ForkJoinTask}s. Because {@code null} is the
36.45 + * only valid value of type {@code Void}, methods such as join always
36.46 + * return {@code null} upon completion.
36.47 + *
36.48 + * <p><b>Sample Usages.</b> Here is a sketch of a ForkJoin sort that
36.49 + * sorts a given {@code long[]} array:
36.50 + *
36.51 + * <pre> {@code
36.52 + * class SortTask extends RecursiveAction {
36.53 + * final long[] array; final int lo; final int hi;
36.54 + * SortTask(long[] array, int lo, int hi) {
36.55 + * this.array = array; this.lo = lo; this.hi = hi;
36.56 + * }
36.57 + * protected void compute() {
36.58 + * if (hi - lo < THRESHOLD)
36.59 + * sequentiallySort(array, lo, hi);
36.60 + * else {
36.61 + * int mid = (lo + hi) >>> 1;
36.62 + * invokeAll(new SortTask(array, lo, mid),
36.63 + * new SortTask(array, mid, hi));
36.64 + * merge(array, lo, hi);
36.65 + * }
36.66 + * }
36.67 + * }}</pre>
36.68 + *
36.69 + * You could then sort {@code anArray} by creating {@code new
36.70 + * SortTask(anArray, 0, anArray.length-1) } and invoking it in a
36.71 + * ForkJoinPool. As a more concrete simple example, the following
36.72 + * task increments each element of an array:
36.73 + * <pre> {@code
36.74 + * class IncrementTask extends RecursiveAction {
36.75 + * final long[] array; final int lo; final int hi;
36.76 + * IncrementTask(long[] array, int lo, int hi) {
36.77 + * this.array = array; this.lo = lo; this.hi = hi;
36.78 + * }
36.79 + * protected void compute() {
36.80 + * if (hi - lo < THRESHOLD) {
36.81 + * for (int i = lo; i < hi; ++i)
36.82 + * array[i]++;
36.83 + * }
36.84 + * else {
36.85 + * int mid = (lo + hi) >>> 1;
36.86 + * invokeAll(new IncrementTask(array, lo, mid),
36.87 + * new IncrementTask(array, mid, hi));
36.88 + * }
36.89 + * }
36.90 + * }}</pre>
36.91 + *
36.92 + * <p>The following example illustrates some refinements and idioms
36.93 + * that may lead to better performance: RecursiveActions need not be
36.94 + * fully recursive, so long as they maintain the basic
36.95 + * divide-and-conquer approach. Here is a class that sums the squares
36.96 + * of each element of a double array, by subdividing out only the
36.97 + * right-hand-sides of repeated divisions by two, and keeping track of
36.98 + * them with a chain of {@code next} references. It uses a dynamic
36.99 + * threshold based on method {@code getSurplusQueuedTaskCount}, but
36.100 + * counterbalances potential excess partitioning by directly
36.101 + * performing leaf actions on unstolen tasks rather than further
36.102 + * subdividing.
36.103 + *
36.104 + * <pre> {@code
36.105 + * double sumOfSquares(ForkJoinPool pool, double[] array) {
36.106 + * int n = array.length;
36.107 + * Applyer a = new Applyer(array, 0, n, null);
36.108 + * pool.invoke(a);
36.109 + * return a.result;
36.110 + * }
36.111 + *
36.112 + * class Applyer extends RecursiveAction {
36.113 + * final double[] array;
36.114 + * final int lo, hi;
36.115 + * double result;
36.116 + * Applyer next; // keeps track of right-hand-side tasks
36.117 + * Applyer(double[] array, int lo, int hi, Applyer next) {
36.118 + * this.array = array; this.lo = lo; this.hi = hi;
36.119 + * this.next = next;
36.120 + * }
36.121 + *
36.122 + * double atLeaf(int l, int h) {
36.123 + * double sum = 0;
36.124 + * for (int i = l; i < h; ++i) // perform leftmost base step
36.125 + * sum += array[i] * array[i];
36.126 + * return sum;
36.127 + * }
36.128 + *
36.129 + * protected void compute() {
36.130 + * int l = lo;
36.131 + * int h = hi;
36.132 + * Applyer right = null;
36.133 + * while (h - l > 1 && getSurplusQueuedTaskCount() <= 3) {
36.134 + * int mid = (l + h) >>> 1;
36.135 + * right = new Applyer(array, mid, h, right);
36.136 + * right.fork();
36.137 + * h = mid;
36.138 + * }
36.139 + * double sum = atLeaf(l, h);
36.140 + * while (right != null) {
36.141 + * if (right.tryUnfork()) // directly calculate if not stolen
36.142 + * sum += right.atLeaf(right.lo, right.hi);
36.143 + * else {
36.144 + * right.join();
36.145 + * sum += right.result;
36.146 + * }
36.147 + * right = right.next;
36.148 + * }
36.149 + * result = sum;
36.150 + * }
36.151 + * }}</pre>
36.152 + *
36.153 + * @since 1.7
36.154 + * @author Doug Lea
36.155 + */
36.156 +public abstract class RecursiveAction extends ForkJoinTask<Void> {
36.157 + private static final long serialVersionUID = 5232453952276485070L;
36.158 +
36.159 + /**
36.160 + * The main computation performed by this task.
36.161 + */
36.162 + protected abstract void compute();
36.163 +
36.164 + /**
36.165 + * Always returns {@code null}.
36.166 + *
36.167 + * @return {@code null} always
36.168 + */
36.169 + public final Void getRawResult() { return null; }
36.170 +
36.171 + /**
36.172 + * Requires null completion value.
36.173 + */
36.174 + protected final void setRawResult(Void mustBeNull) { }
36.175 +
36.176 + /**
36.177 + * Implements execution conventions for RecursiveActions.
36.178 + */
36.179 + protected final boolean exec() {
36.180 + compute();
36.181 + return true;
36.182 + }
36.183 +
36.184 +}
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
37.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/RecursiveTask.java Sat Mar 19 10:46:31 2016 +0100
37.3 @@ -0,0 +1,97 @@
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 recursive result-bearing {@link ForkJoinTask}.
37.43 + *
37.44 + * <p>For a classic example, here is a task computing Fibonacci numbers:
37.45 + *
37.46 + * <pre> {@code
37.47 + * class Fibonacci extends RecursiveTask<Integer> {
37.48 + * final int n;
37.49 + * Fibonacci(int n) { this.n = n; }
37.50 + * Integer compute() {
37.51 + * if (n <= 1)
37.52 + * return n;
37.53 + * Fibonacci f1 = new Fibonacci(n - 1);
37.54 + * f1.fork();
37.55 + * Fibonacci f2 = new Fibonacci(n - 2);
37.56 + * return f2.compute() + f1.join();
37.57 + * }
37.58 + * }}</pre>
37.59 + *
37.60 + * However, besides being a dumb way to compute Fibonacci functions
37.61 + * (there is a simple fast linear algorithm that you'd use in
37.62 + * practice), this is likely to perform poorly because the smallest
37.63 + * subtasks are too small to be worthwhile splitting up. Instead, as
37.64 + * is the case for nearly all fork/join applications, you'd pick some
37.65 + * minimum granularity size (for example 10 here) for which you always
37.66 + * sequentially solve rather than subdividing.
37.67 + *
37.68 + * @since 1.7
37.69 + * @author Doug Lea
37.70 + */
37.71 +public abstract class RecursiveTask<V> extends ForkJoinTask<V> {
37.72 + private static final long serialVersionUID = 5232453952276485270L;
37.73 +
37.74 + /**
37.75 + * The result of the computation.
37.76 + */
37.77 + V result;
37.78 +
37.79 + /**
37.80 + * The main computation performed by this task.
37.81 + */
37.82 + protected abstract V compute();
37.83 +
37.84 + public final V getRawResult() {
37.85 + return result;
37.86 + }
37.87 +
37.88 + protected final void setRawResult(V value) {
37.89 + result = value;
37.90 + }
37.91 +
37.92 + /**
37.93 + * Implements execution conventions for RecursiveTask.
37.94 + */
37.95 + protected final boolean exec() {
37.96 + result = compute();
37.97 + return true;
37.98 + }
37.99 +
37.100 +}
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
38.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/RejectedExecutionException.java Sat Mar 19 10:46:31 2016 +0100
38.3 @@ -0,0 +1,91 @@
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 + * Exception thrown by an {@link Executor} when a task cannot be
38.43 + * accepted for execution.
38.44 + *
38.45 + * @since 1.5
38.46 + * @author Doug Lea
38.47 + */
38.48 +public class RejectedExecutionException extends RuntimeException {
38.49 + private static final long serialVersionUID = -375805702767069545L;
38.50 +
38.51 + /**
38.52 + * Constructs a <tt>RejectedExecutionException</tt> with no detail message.
38.53 + * The cause is not initialized, and may subsequently be
38.54 + * initialized by a call to {@link #initCause(Throwable) initCause}.
38.55 + */
38.56 + public RejectedExecutionException() { }
38.57 +
38.58 + /**
38.59 + * Constructs a <tt>RejectedExecutionException</tt> with the
38.60 + * specified detail message. The cause is not initialized, and may
38.61 + * subsequently be initialized by a call to {@link
38.62 + * #initCause(Throwable) initCause}.
38.63 + *
38.64 + * @param message the detail message
38.65 + */
38.66 + public RejectedExecutionException(String message) {
38.67 + super(message);
38.68 + }
38.69 +
38.70 + /**
38.71 + * Constructs a <tt>RejectedExecutionException</tt> with the
38.72 + * specified detail message and cause.
38.73 + *
38.74 + * @param message the detail message
38.75 + * @param cause the cause (which is saved for later retrieval by the
38.76 + * {@link #getCause()} method)
38.77 + */
38.78 + public RejectedExecutionException(String message, Throwable cause) {
38.79 + super(message, cause);
38.80 + }
38.81 +
38.82 + /**
38.83 + * Constructs a <tt>RejectedExecutionException</tt> with the
38.84 + * specified cause. The detail message is set to: <pre> (cause ==
38.85 + * null ? null : cause.toString())</pre> (which typically contains
38.86 + * the class and detail message of <tt>cause</tt>).
38.87 + *
38.88 + * @param cause the cause (which is saved for later retrieval by the
38.89 + * {@link #getCause()} method)
38.90 + */
38.91 + public RejectedExecutionException(Throwable cause) {
38.92 + super(cause);
38.93 + }
38.94 +}
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
39.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/RejectedExecutionHandler.java Sat Mar 19 10:46:31 2016 +0100
39.3 @@ -0,0 +1,62 @@
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 handler for tasks that cannot be executed by a {@link ThreadPoolExecutor}.
39.43 + *
39.44 + * @since 1.5
39.45 + * @author Doug Lea
39.46 + */
39.47 +public interface RejectedExecutionHandler {
39.48 +
39.49 + /**
39.50 + * Method that may be invoked by a {@link ThreadPoolExecutor} when
39.51 + * {@link ThreadPoolExecutor#execute execute} cannot accept a
39.52 + * task. This may occur when no more threads or queue slots are
39.53 + * available because their bounds would be exceeded, or upon
39.54 + * shutdown of the Executor.
39.55 + *
39.56 + * <p>In the absence of other alternatives, the method may throw
39.57 + * an unchecked {@link RejectedExecutionException}, which will be
39.58 + * propagated to the caller of {@code execute}.
39.59 + *
39.60 + * @param r the runnable task requested to be executed
39.61 + * @param executor the executor attempting to execute this task
39.62 + * @throws RejectedExecutionException if there is no remedy
39.63 + */
39.64 + void rejectedExecution(Runnable r, ThreadPoolExecutor executor);
39.65 +}
40.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
40.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/RunnableFuture.java Sat Mar 19 10:46:31 2016 +0100
40.3 @@ -0,0 +1,54 @@
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 +
40.41 +/**
40.42 + * A {@link Future} that is {@link Runnable}. Successful execution of
40.43 + * the <tt>run</tt> method causes completion of the <tt>Future</tt>
40.44 + * and allows access to its results.
40.45 + * @see FutureTask
40.46 + * @see Executor
40.47 + * @since 1.6
40.48 + * @author Doug Lea
40.49 + * @param <V> The result type returned by this Future's <tt>get</tt> method
40.50 + */
40.51 +public interface RunnableFuture<V> extends Runnable, Future<V> {
40.52 + /**
40.53 + * Sets this Future to the result of its computation
40.54 + * unless it has been cancelled.
40.55 + */
40.56 + void run();
40.57 +}
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
41.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/RunnableScheduledFuture.java Sat Mar 19 10:46:31 2016 +0100
41.3 @@ -0,0 +1,58 @@
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 {@link ScheduledFuture} that is {@link Runnable}. Successful
41.43 + * execution of the <tt>run</tt> method causes completion of the
41.44 + * <tt>Future</tt> and allows access to its results.
41.45 + * @see FutureTask
41.46 + * @see Executor
41.47 + * @since 1.6
41.48 + * @author Doug Lea
41.49 + * @param <V> The result type returned by this Future's <tt>get</tt> method
41.50 + */
41.51 +public interface RunnableScheduledFuture<V> extends RunnableFuture<V>, ScheduledFuture<V> {
41.52 +
41.53 + /**
41.54 + * Returns true if this is a periodic task. A periodic task may
41.55 + * re-run according to some schedule. A non-periodic task can be
41.56 + * run only once.
41.57 + *
41.58 + * @return true if this task is periodic
41.59 + */
41.60 + boolean isPeriodic();
41.61 +}
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
42.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ScheduledExecutorService.java Sat Mar 19 10:46:31 2016 +0100
42.3 @@ -0,0 +1,187 @@
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.*;
42.42 +
42.43 +/**
42.44 + * An {@link ExecutorService} that can schedule commands to run after a given
42.45 + * delay, or to execute periodically.
42.46 + *
42.47 + * <p> The <tt>schedule</tt> methods create tasks with various delays
42.48 + * and return a task object that can be used to cancel or check
42.49 + * execution. The <tt>scheduleAtFixedRate</tt> and
42.50 + * <tt>scheduleWithFixedDelay</tt> methods create and execute tasks
42.51 + * that run periodically until cancelled.
42.52 + *
42.53 + * <p> Commands submitted using the {@link Executor#execute} and
42.54 + * {@link ExecutorService} <tt>submit</tt> methods are scheduled with
42.55 + * a requested delay of zero. Zero and negative delays (but not
42.56 + * periods) are also allowed in <tt>schedule</tt> methods, and are
42.57 + * treated as requests for immediate execution.
42.58 + *
42.59 + * <p>All <tt>schedule</tt> methods accept <em>relative</em> delays and
42.60 + * periods as arguments, not absolute times or dates. It is a simple
42.61 + * matter to transform an absolute time represented as a {@link
42.62 + * java.util.Date} to the required form. For example, to schedule at
42.63 + * a certain future <tt>date</tt>, you can use: <tt>schedule(task,
42.64 + * date.getTime() - System.currentTimeMillis(),
42.65 + * TimeUnit.MILLISECONDS)</tt>. Beware however that expiration of a
42.66 + * relative delay need not coincide with the current <tt>Date</tt> at
42.67 + * which the task is enabled due to network time synchronization
42.68 + * protocols, clock drift, or other factors.
42.69 + *
42.70 + * The {@link Executors} class provides convenient factory methods for
42.71 + * the ScheduledExecutorService implementations provided in this package.
42.72 + *
42.73 + * <h3>Usage Example</h3>
42.74 + *
42.75 + * Here is a class with a method that sets up a ScheduledExecutorService
42.76 + * to beep every ten seconds for an hour:
42.77 + *
42.78 + * <pre> {@code
42.79 + * import static java.util.concurrent.TimeUnit.*;
42.80 + * class BeeperControl {
42.81 + * private final ScheduledExecutorService scheduler =
42.82 + * Executors.newScheduledThreadPool(1);
42.83 + *
42.84 + * public void beepForAnHour() {
42.85 + * final Runnable beeper = new Runnable() {
42.86 + * public void run() { System.out.println("beep"); }
42.87 + * };
42.88 + * final ScheduledFuture<?> beeperHandle =
42.89 + * scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);
42.90 + * scheduler.schedule(new Runnable() {
42.91 + * public void run() { beeperHandle.cancel(true); }
42.92 + * }, 60 * 60, SECONDS);
42.93 + * }
42.94 + * }}</pre>
42.95 + *
42.96 + * @since 1.5
42.97 + * @author Doug Lea
42.98 + */
42.99 +public interface ScheduledExecutorService extends ExecutorService {
42.100 +
42.101 + /**
42.102 + * Creates and executes a one-shot action that becomes enabled
42.103 + * after the given delay.
42.104 + *
42.105 + * @param command the task to execute
42.106 + * @param delay the time from now to delay execution
42.107 + * @param unit the time unit of the delay parameter
42.108 + * @return a ScheduledFuture representing pending completion of
42.109 + * the task and whose <tt>get()</tt> method will return
42.110 + * <tt>null</tt> upon completion
42.111 + * @throws RejectedExecutionException if the task cannot be
42.112 + * scheduled for execution
42.113 + * @throws NullPointerException if command is null
42.114 + */
42.115 + public ScheduledFuture<?> schedule(Runnable command,
42.116 + long delay, TimeUnit unit);
42.117 +
42.118 + /**
42.119 + * Creates and executes a ScheduledFuture that becomes enabled after the
42.120 + * given delay.
42.121 + *
42.122 + * @param callable the function to execute
42.123 + * @param delay the time from now to delay execution
42.124 + * @param unit the time unit of the delay parameter
42.125 + * @return a ScheduledFuture that can be used to extract result or cancel
42.126 + * @throws RejectedExecutionException if the task cannot be
42.127 + * scheduled for execution
42.128 + * @throws NullPointerException if callable is null
42.129 + */
42.130 + public <V> ScheduledFuture<V> schedule(Callable<V> callable,
42.131 + long delay, TimeUnit unit);
42.132 +
42.133 + /**
42.134 + * Creates and executes a periodic action that becomes enabled first
42.135 + * after the given initial delay, and subsequently with the given
42.136 + * period; that is executions will commence after
42.137 + * <tt>initialDelay</tt> then <tt>initialDelay+period</tt>, then
42.138 + * <tt>initialDelay + 2 * period</tt>, and so on.
42.139 + * If any execution of the task
42.140 + * encounters an exception, subsequent executions are suppressed.
42.141 + * Otherwise, the task will only terminate via cancellation or
42.142 + * termination of the executor. If any execution of this task
42.143 + * takes longer than its period, then subsequent executions
42.144 + * may start late, but will not concurrently execute.
42.145 + *
42.146 + * @param command the task to execute
42.147 + * @param initialDelay the time to delay first execution
42.148 + * @param period the period between successive executions
42.149 + * @param unit the time unit of the initialDelay and period parameters
42.150 + * @return a ScheduledFuture representing pending completion of
42.151 + * the task, and whose <tt>get()</tt> method will throw an
42.152 + * exception upon cancellation
42.153 + * @throws RejectedExecutionException if the task cannot be
42.154 + * scheduled for execution
42.155 + * @throws NullPointerException if command is null
42.156 + * @throws IllegalArgumentException if period less than or equal to zero
42.157 + */
42.158 + public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
42.159 + long initialDelay,
42.160 + long period,
42.161 + TimeUnit unit);
42.162 +
42.163 + /**
42.164 + * Creates and executes a periodic action that becomes enabled first
42.165 + * after the given initial delay, and subsequently with the
42.166 + * given delay between the termination of one execution and the
42.167 + * commencement of the next. If any execution of the task
42.168 + * encounters an exception, subsequent executions are suppressed.
42.169 + * Otherwise, the task will only terminate via cancellation or
42.170 + * termination of the executor.
42.171 + *
42.172 + * @param command the task to execute
42.173 + * @param initialDelay the time to delay first execution
42.174 + * @param delay the delay between the termination of one
42.175 + * execution and the commencement of the next
42.176 + * @param unit the time unit of the initialDelay and delay parameters
42.177 + * @return a ScheduledFuture representing pending completion of
42.178 + * the task, and whose <tt>get()</tt> method will throw an
42.179 + * exception upon cancellation
42.180 + * @throws RejectedExecutionException if the task cannot be
42.181 + * scheduled for execution
42.182 + * @throws NullPointerException if command is null
42.183 + * @throws IllegalArgumentException if delay less than or equal to zero
42.184 + */
42.185 + public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
42.186 + long initialDelay,
42.187 + long delay,
42.188 + TimeUnit unit);
42.189 +
42.190 +}
43.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
43.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ScheduledFuture.java Sat Mar 19 10:46:31 2016 +0100
43.3 @@ -0,0 +1,48 @@
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 +
43.41 +/**
43.42 + * A delayed result-bearing action that can be cancelled.
43.43 + * Usually a scheduled future is the result of scheduling
43.44 + * a task with a {@link ScheduledExecutorService}.
43.45 + *
43.46 + * @since 1.5
43.47 + * @author Doug Lea
43.48 + * @param <V> The result type returned by this Future
43.49 + */
43.50 +public interface ScheduledFuture<V> extends Delayed, Future<V> {
43.51 +}
44.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
44.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ScheduledThreadPoolExecutor.java Sat Mar 19 10:46:31 2016 +0100
44.3 @@ -0,0 +1,1277 @@
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 with assistance from members of JCP JSR-166
44.35 + * Expert Group and released to the public domain, as explained at
44.36 + * http://creativecommons.org/publicdomain/zero/1.0/
44.37 + */
44.38 +
44.39 +package java.util.concurrent;
44.40 +import java.util.concurrent.atomic.*;
44.41 +import java.util.concurrent.locks.*;
44.42 +import java.util.*;
44.43 +
44.44 +/**
44.45 + * A {@link ThreadPoolExecutor} that can additionally schedule
44.46 + * commands to run after a given delay, or to execute
44.47 + * periodically. This class is preferable to {@link java.util.Timer}
44.48 + * when multiple worker threads are needed, or when the additional
44.49 + * flexibility or capabilities of {@link ThreadPoolExecutor} (which
44.50 + * this class extends) are required.
44.51 + *
44.52 + * <p>Delayed tasks execute no sooner than they are enabled, but
44.53 + * without any real-time guarantees about when, after they are
44.54 + * enabled, they will commence. Tasks scheduled for exactly the same
44.55 + * execution time are enabled in first-in-first-out (FIFO) order of
44.56 + * submission.
44.57 + *
44.58 + * <p>When a submitted task is cancelled before it is run, execution
44.59 + * is suppressed. By default, such a cancelled task is not
44.60 + * automatically removed from the work queue until its delay
44.61 + * elapses. While this enables further inspection and monitoring, it
44.62 + * may also cause unbounded retention of cancelled tasks. To avoid
44.63 + * this, set {@link #setRemoveOnCancelPolicy} to {@code true}, which
44.64 + * causes tasks to be immediately removed from the work queue at
44.65 + * time of cancellation.
44.66 + *
44.67 + * <p>Successive executions of a task scheduled via
44.68 + * {@code scheduleAtFixedRate} or
44.69 + * {@code scheduleWithFixedDelay} do not overlap. While different
44.70 + * executions may be performed by different threads, the effects of
44.71 + * prior executions <a
44.72 + * href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
44.73 + * those of subsequent ones.
44.74 + *
44.75 + * <p>While this class inherits from {@link ThreadPoolExecutor}, a few
44.76 + * of the inherited tuning methods are not useful for it. In
44.77 + * particular, because it acts as a fixed-sized pool using
44.78 + * {@code corePoolSize} threads and an unbounded queue, adjustments
44.79 + * to {@code maximumPoolSize} have no useful effect. Additionally, it
44.80 + * is almost never a good idea to set {@code corePoolSize} to zero or
44.81 + * use {@code allowCoreThreadTimeOut} because this may leave the pool
44.82 + * without threads to handle tasks once they become eligible to run.
44.83 + *
44.84 + * <p><b>Extension notes:</b> This class overrides the
44.85 + * {@link ThreadPoolExecutor#execute execute} and
44.86 + * {@link AbstractExecutorService#submit(Runnable) submit}
44.87 + * methods to generate internal {@link ScheduledFuture} objects to
44.88 + * control per-task delays and scheduling. To preserve
44.89 + * functionality, any further overrides of these methods in
44.90 + * subclasses must invoke superclass versions, which effectively
44.91 + * disables additional task customization. However, this class
44.92 + * provides alternative protected extension method
44.93 + * {@code decorateTask} (one version each for {@code Runnable} and
44.94 + * {@code Callable}) that can be used to customize the concrete task
44.95 + * types used to execute commands entered via {@code execute},
44.96 + * {@code submit}, {@code schedule}, {@code scheduleAtFixedRate},
44.97 + * and {@code scheduleWithFixedDelay}. By default, a
44.98 + * {@code ScheduledThreadPoolExecutor} uses a task type extending
44.99 + * {@link FutureTask}. However, this may be modified or replaced using
44.100 + * subclasses of the form:
44.101 + *
44.102 + * <pre> {@code
44.103 + * public class CustomScheduledExecutor extends ScheduledThreadPoolExecutor {
44.104 + *
44.105 + * static class CustomTask<V> implements RunnableScheduledFuture<V> { ... }
44.106 + *
44.107 + * protected <V> RunnableScheduledFuture<V> decorateTask(
44.108 + * Runnable r, RunnableScheduledFuture<V> task) {
44.109 + * return new CustomTask<V>(r, task);
44.110 + * }
44.111 + *
44.112 + * protected <V> RunnableScheduledFuture<V> decorateTask(
44.113 + * Callable<V> c, RunnableScheduledFuture<V> task) {
44.114 + * return new CustomTask<V>(c, task);
44.115 + * }
44.116 + * // ... add constructors, etc.
44.117 + * }}</pre>
44.118 + *
44.119 + * @since 1.5
44.120 + * @author Doug Lea
44.121 + */
44.122 +public class ScheduledThreadPoolExecutor
44.123 + extends ThreadPoolExecutor
44.124 + implements ScheduledExecutorService {
44.125 +
44.126 + /*
44.127 + * This class specializes ThreadPoolExecutor implementation by
44.128 + *
44.129 + * 1. Using a custom task type, ScheduledFutureTask for
44.130 + * tasks, even those that don't require scheduling (i.e.,
44.131 + * those submitted using ExecutorService execute, not
44.132 + * ScheduledExecutorService methods) which are treated as
44.133 + * delayed tasks with a delay of zero.
44.134 + *
44.135 + * 2. Using a custom queue (DelayedWorkQueue), a variant of
44.136 + * unbounded DelayQueue. The lack of capacity constraint and
44.137 + * the fact that corePoolSize and maximumPoolSize are
44.138 + * effectively identical simplifies some execution mechanics
44.139 + * (see delayedExecute) compared to ThreadPoolExecutor.
44.140 + *
44.141 + * 3. Supporting optional run-after-shutdown parameters, which
44.142 + * leads to overrides of shutdown methods to remove and cancel
44.143 + * tasks that should NOT be run after shutdown, as well as
44.144 + * different recheck logic when task (re)submission overlaps
44.145 + * with a shutdown.
44.146 + *
44.147 + * 4. Task decoration methods to allow interception and
44.148 + * instrumentation, which are needed because subclasses cannot
44.149 + * otherwise override submit methods to get this effect. These
44.150 + * don't have any impact on pool control logic though.
44.151 + */
44.152 +
44.153 + /**
44.154 + * False if should cancel/suppress periodic tasks on shutdown.
44.155 + */
44.156 + private volatile boolean continueExistingPeriodicTasksAfterShutdown;
44.157 +
44.158 + /**
44.159 + * False if should cancel non-periodic tasks on shutdown.
44.160 + */
44.161 + private volatile boolean executeExistingDelayedTasksAfterShutdown = true;
44.162 +
44.163 + /**
44.164 + * True if ScheduledFutureTask.cancel should remove from queue
44.165 + */
44.166 + private volatile boolean removeOnCancel = false;
44.167 +
44.168 + /**
44.169 + * Sequence number to break scheduling ties, and in turn to
44.170 + * guarantee FIFO order among tied entries.
44.171 + */
44.172 + private static final AtomicLong sequencer = new AtomicLong(0);
44.173 +
44.174 + /**
44.175 + * Returns current nanosecond time.
44.176 + */
44.177 + final long now() {
44.178 + return System.nanoTime();
44.179 + }
44.180 +
44.181 + private class ScheduledFutureTask<V>
44.182 + extends FutureTask<V> implements RunnableScheduledFuture<V> {
44.183 +
44.184 + /** Sequence number to break ties FIFO */
44.185 + private final long sequenceNumber;
44.186 +
44.187 + /** The time the task is enabled to execute in nanoTime units */
44.188 + private long time;
44.189 +
44.190 + /**
44.191 + * Period in nanoseconds for repeating tasks. A positive
44.192 + * value indicates fixed-rate execution. A negative value
44.193 + * indicates fixed-delay execution. A value of 0 indicates a
44.194 + * non-repeating task.
44.195 + */
44.196 + private final long period;
44.197 +
44.198 + /** The actual task to be re-enqueued by reExecutePeriodic */
44.199 + RunnableScheduledFuture<V> outerTask = this;
44.200 +
44.201 + /**
44.202 + * Index into delay queue, to support faster cancellation.
44.203 + */
44.204 + int heapIndex;
44.205 +
44.206 + /**
44.207 + * Creates a one-shot action with given nanoTime-based trigger time.
44.208 + */
44.209 + ScheduledFutureTask(Runnable r, V result, long ns) {
44.210 + super(r, result);
44.211 + this.time = ns;
44.212 + this.period = 0;
44.213 + this.sequenceNumber = sequencer.getAndIncrement();
44.214 + }
44.215 +
44.216 + /**
44.217 + * Creates a periodic action with given nano time and period.
44.218 + */
44.219 + ScheduledFutureTask(Runnable r, V result, long ns, long period) {
44.220 + super(r, result);
44.221 + this.time = ns;
44.222 + this.period = period;
44.223 + this.sequenceNumber = sequencer.getAndIncrement();
44.224 + }
44.225 +
44.226 + /**
44.227 + * Creates a one-shot action with given nanoTime-based trigger.
44.228 + */
44.229 + ScheduledFutureTask(Callable<V> callable, long ns) {
44.230 + super(callable);
44.231 + this.time = ns;
44.232 + this.period = 0;
44.233 + this.sequenceNumber = sequencer.getAndIncrement();
44.234 + }
44.235 +
44.236 + public long getDelay(TimeUnit unit) {
44.237 + return unit.convert(time - now(), TimeUnit.NANOSECONDS);
44.238 + }
44.239 +
44.240 + public int compareTo(Delayed other) {
44.241 + if (other == this) // compare zero ONLY if same object
44.242 + return 0;
44.243 + if (other instanceof ScheduledFutureTask) {
44.244 + ScheduledFutureTask<?> x = (ScheduledFutureTask<?>)other;
44.245 + long diff = time - x.time;
44.246 + if (diff < 0)
44.247 + return -1;
44.248 + else if (diff > 0)
44.249 + return 1;
44.250 + else if (sequenceNumber < x.sequenceNumber)
44.251 + return -1;
44.252 + else
44.253 + return 1;
44.254 + }
44.255 + long d = (getDelay(TimeUnit.NANOSECONDS) -
44.256 + other.getDelay(TimeUnit.NANOSECONDS));
44.257 + return (d == 0) ? 0 : ((d < 0) ? -1 : 1);
44.258 + }
44.259 +
44.260 + /**
44.261 + * Returns true if this is a periodic (not a one-shot) action.
44.262 + *
44.263 + * @return true if periodic
44.264 + */
44.265 + public boolean isPeriodic() {
44.266 + return period != 0;
44.267 + }
44.268 +
44.269 + /**
44.270 + * Sets the next time to run for a periodic task.
44.271 + */
44.272 + private void setNextRunTime() {
44.273 + long p = period;
44.274 + if (p > 0)
44.275 + time += p;
44.276 + else
44.277 + time = triggerTime(-p);
44.278 + }
44.279 +
44.280 + public boolean cancel(boolean mayInterruptIfRunning) {
44.281 + boolean cancelled = super.cancel(mayInterruptIfRunning);
44.282 + if (cancelled && removeOnCancel && heapIndex >= 0)
44.283 + remove(this);
44.284 + return cancelled;
44.285 + }
44.286 +
44.287 + /**
44.288 + * Overrides FutureTask version so as to reset/requeue if periodic.
44.289 + */
44.290 + public void run() {
44.291 + boolean periodic = isPeriodic();
44.292 + if (!canRunInCurrentRunState(periodic))
44.293 + cancel(false);
44.294 + else if (!periodic)
44.295 + ScheduledFutureTask.super.run();
44.296 + else if (ScheduledFutureTask.super.runAndReset()) {
44.297 + setNextRunTime();
44.298 + reExecutePeriodic(outerTask);
44.299 + }
44.300 + }
44.301 + }
44.302 +
44.303 + /**
44.304 + * Returns true if can run a task given current run state
44.305 + * and run-after-shutdown parameters.
44.306 + *
44.307 + * @param periodic true if this task periodic, false if delayed
44.308 + */
44.309 + boolean canRunInCurrentRunState(boolean periodic) {
44.310 + return isRunningOrShutdown(periodic ?
44.311 + continueExistingPeriodicTasksAfterShutdown :
44.312 + executeExistingDelayedTasksAfterShutdown);
44.313 + }
44.314 +
44.315 + /**
44.316 + * Main execution method for delayed or periodic tasks. If pool
44.317 + * is shut down, rejects the task. Otherwise adds task to queue
44.318 + * and starts a thread, if necessary, to run it. (We cannot
44.319 + * prestart the thread to run the task because the task (probably)
44.320 + * shouldn't be run yet,) If the pool is shut down while the task
44.321 + * is being added, cancel and remove it if required by state and
44.322 + * run-after-shutdown parameters.
44.323 + *
44.324 + * @param task the task
44.325 + */
44.326 + private void delayedExecute(RunnableScheduledFuture<?> task) {
44.327 + if (isShutdown())
44.328 + reject(task);
44.329 + else {
44.330 + super.getQueue().add(task);
44.331 + if (isShutdown() &&
44.332 + !canRunInCurrentRunState(task.isPeriodic()) &&
44.333 + remove(task))
44.334 + task.cancel(false);
44.335 + else
44.336 + prestartCoreThread();
44.337 + }
44.338 + }
44.339 +
44.340 + /**
44.341 + * Requeues a periodic task unless current run state precludes it.
44.342 + * Same idea as delayedExecute except drops task rather than rejecting.
44.343 + *
44.344 + * @param task the task
44.345 + */
44.346 + void reExecutePeriodic(RunnableScheduledFuture<?> task) {
44.347 + if (canRunInCurrentRunState(true)) {
44.348 + super.getQueue().add(task);
44.349 + if (!canRunInCurrentRunState(true) && remove(task))
44.350 + task.cancel(false);
44.351 + else
44.352 + prestartCoreThread();
44.353 + }
44.354 + }
44.355 +
44.356 + /**
44.357 + * Cancels and clears the queue of all tasks that should not be run
44.358 + * due to shutdown policy. Invoked within super.shutdown.
44.359 + */
44.360 + @Override void onShutdown() {
44.361 + BlockingQueue<Runnable> q = super.getQueue();
44.362 + boolean keepDelayed =
44.363 + getExecuteExistingDelayedTasksAfterShutdownPolicy();
44.364 + boolean keepPeriodic =
44.365 + getContinueExistingPeriodicTasksAfterShutdownPolicy();
44.366 + if (!keepDelayed && !keepPeriodic) {
44.367 + for (Object e : q.toArray())
44.368 + if (e instanceof RunnableScheduledFuture<?>)
44.369 + ((RunnableScheduledFuture<?>) e).cancel(false);
44.370 + q.clear();
44.371 + }
44.372 + else {
44.373 + // Traverse snapshot to avoid iterator exceptions
44.374 + for (Object e : q.toArray()) {
44.375 + if (e instanceof RunnableScheduledFuture) {
44.376 + RunnableScheduledFuture<?> t =
44.377 + (RunnableScheduledFuture<?>)e;
44.378 + if ((t.isPeriodic() ? !keepPeriodic : !keepDelayed) ||
44.379 + t.isCancelled()) { // also remove if already cancelled
44.380 + if (q.remove(t))
44.381 + t.cancel(false);
44.382 + }
44.383 + }
44.384 + }
44.385 + }
44.386 + tryTerminate();
44.387 + }
44.388 +
44.389 + /**
44.390 + * Modifies or replaces the task used to execute a runnable.
44.391 + * This method can be used to override the concrete
44.392 + * class used for managing internal tasks.
44.393 + * The default implementation simply returns the given task.
44.394 + *
44.395 + * @param runnable the submitted Runnable
44.396 + * @param task the task created to execute the runnable
44.397 + * @return a task that can execute the runnable
44.398 + * @since 1.6
44.399 + */
44.400 + protected <V> RunnableScheduledFuture<V> decorateTask(
44.401 + Runnable runnable, RunnableScheduledFuture<V> task) {
44.402 + return task;
44.403 + }
44.404 +
44.405 + /**
44.406 + * Modifies or replaces the task used to execute a callable.
44.407 + * This method can be used to override the concrete
44.408 + * class used for managing internal tasks.
44.409 + * The default implementation simply returns the given task.
44.410 + *
44.411 + * @param callable the submitted Callable
44.412 + * @param task the task created to execute the callable
44.413 + * @return a task that can execute the callable
44.414 + * @since 1.6
44.415 + */
44.416 + protected <V> RunnableScheduledFuture<V> decorateTask(
44.417 + Callable<V> callable, RunnableScheduledFuture<V> task) {
44.418 + return task;
44.419 + }
44.420 +
44.421 + /**
44.422 + * Creates a new {@code ScheduledThreadPoolExecutor} with the
44.423 + * given core pool size.
44.424 + *
44.425 + * @param corePoolSize the number of threads to keep in the pool, even
44.426 + * if they are idle, unless {@code allowCoreThreadTimeOut} is set
44.427 + * @throws IllegalArgumentException if {@code corePoolSize < 0}
44.428 + */
44.429 + public ScheduledThreadPoolExecutor(int corePoolSize) {
44.430 + super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
44.431 + new DelayedWorkQueue());
44.432 + }
44.433 +
44.434 + /**
44.435 + * Creates a new {@code ScheduledThreadPoolExecutor} with the
44.436 + * given initial parameters.
44.437 + *
44.438 + * @param corePoolSize the number of threads to keep in the pool, even
44.439 + * if they are idle, unless {@code allowCoreThreadTimeOut} is set
44.440 + * @param threadFactory the factory to use when the executor
44.441 + * creates a new thread
44.442 + * @throws IllegalArgumentException if {@code corePoolSize < 0}
44.443 + * @throws NullPointerException if {@code threadFactory} is null
44.444 + */
44.445 + public ScheduledThreadPoolExecutor(int corePoolSize,
44.446 + ThreadFactory threadFactory) {
44.447 + super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
44.448 + new DelayedWorkQueue(), threadFactory);
44.449 + }
44.450 +
44.451 + /**
44.452 + * Creates a new ScheduledThreadPoolExecutor with the given
44.453 + * initial parameters.
44.454 + *
44.455 + * @param corePoolSize the number of threads to keep in the pool, even
44.456 + * if they are idle, unless {@code allowCoreThreadTimeOut} is set
44.457 + * @param handler the handler to use when execution is blocked
44.458 + * because the thread bounds and queue capacities are reached
44.459 + * @throws IllegalArgumentException if {@code corePoolSize < 0}
44.460 + * @throws NullPointerException if {@code handler} is null
44.461 + */
44.462 + public ScheduledThreadPoolExecutor(int corePoolSize,
44.463 + RejectedExecutionHandler handler) {
44.464 + super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
44.465 + new DelayedWorkQueue(), handler);
44.466 + }
44.467 +
44.468 + /**
44.469 + * Creates a new ScheduledThreadPoolExecutor with the given
44.470 + * initial parameters.
44.471 + *
44.472 + * @param corePoolSize the number of threads to keep in the pool, even
44.473 + * if they are idle, unless {@code allowCoreThreadTimeOut} is set
44.474 + * @param threadFactory the factory to use when the executor
44.475 + * creates a new thread
44.476 + * @param handler the handler to use when execution is blocked
44.477 + * because the thread bounds and queue capacities are reached
44.478 + * @throws IllegalArgumentException if {@code corePoolSize < 0}
44.479 + * @throws NullPointerException if {@code threadFactory} or
44.480 + * {@code handler} is null
44.481 + */
44.482 + public ScheduledThreadPoolExecutor(int corePoolSize,
44.483 + ThreadFactory threadFactory,
44.484 + RejectedExecutionHandler handler) {
44.485 + super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
44.486 + new DelayedWorkQueue(), threadFactory, handler);
44.487 + }
44.488 +
44.489 + /**
44.490 + * Returns the trigger time of a delayed action.
44.491 + */
44.492 + private long triggerTime(long delay, TimeUnit unit) {
44.493 + return triggerTime(unit.toNanos((delay < 0) ? 0 : delay));
44.494 + }
44.495 +
44.496 + /**
44.497 + * Returns the trigger time of a delayed action.
44.498 + */
44.499 + long triggerTime(long delay) {
44.500 + return now() +
44.501 + ((delay < (Long.MAX_VALUE >> 1)) ? delay : overflowFree(delay));
44.502 + }
44.503 +
44.504 + /**
44.505 + * Constrains the values of all delays in the queue to be within
44.506 + * Long.MAX_VALUE of each other, to avoid overflow in compareTo.
44.507 + * This may occur if a task is eligible to be dequeued, but has
44.508 + * not yet been, while some other task is added with a delay of
44.509 + * Long.MAX_VALUE.
44.510 + */
44.511 + private long overflowFree(long delay) {
44.512 + Delayed head = (Delayed) super.getQueue().peek();
44.513 + if (head != null) {
44.514 + long headDelay = head.getDelay(TimeUnit.NANOSECONDS);
44.515 + if (headDelay < 0 && (delay - headDelay < 0))
44.516 + delay = Long.MAX_VALUE + headDelay;
44.517 + }
44.518 + return delay;
44.519 + }
44.520 +
44.521 + /**
44.522 + * @throws RejectedExecutionException {@inheritDoc}
44.523 + * @throws NullPointerException {@inheritDoc}
44.524 + */
44.525 + public ScheduledFuture<?> schedule(Runnable command,
44.526 + long delay,
44.527 + TimeUnit unit) {
44.528 + if (command == null || unit == null)
44.529 + throw new NullPointerException();
44.530 + RunnableScheduledFuture<?> t = decorateTask(command,
44.531 + new ScheduledFutureTask<Void>(command, null,
44.532 + triggerTime(delay, unit)));
44.533 + delayedExecute(t);
44.534 + return t;
44.535 + }
44.536 +
44.537 + /**
44.538 + * @throws RejectedExecutionException {@inheritDoc}
44.539 + * @throws NullPointerException {@inheritDoc}
44.540 + */
44.541 + public <V> ScheduledFuture<V> schedule(Callable<V> callable,
44.542 + long delay,
44.543 + TimeUnit unit) {
44.544 + if (callable == null || unit == null)
44.545 + throw new NullPointerException();
44.546 + RunnableScheduledFuture<V> t = decorateTask(callable,
44.547 + new ScheduledFutureTask<V>(callable,
44.548 + triggerTime(delay, unit)));
44.549 + delayedExecute(t);
44.550 + return t;
44.551 + }
44.552 +
44.553 + /**
44.554 + * @throws RejectedExecutionException {@inheritDoc}
44.555 + * @throws NullPointerException {@inheritDoc}
44.556 + * @throws IllegalArgumentException {@inheritDoc}
44.557 + */
44.558 + public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
44.559 + long initialDelay,
44.560 + long period,
44.561 + TimeUnit unit) {
44.562 + if (command == null || unit == null)
44.563 + throw new NullPointerException();
44.564 + if (period <= 0)
44.565 + throw new IllegalArgumentException();
44.566 + ScheduledFutureTask<Void> sft =
44.567 + new ScheduledFutureTask<Void>(command,
44.568 + null,
44.569 + triggerTime(initialDelay, unit),
44.570 + unit.toNanos(period));
44.571 + RunnableScheduledFuture<Void> t = decorateTask(command, sft);
44.572 + sft.outerTask = t;
44.573 + delayedExecute(t);
44.574 + return t;
44.575 + }
44.576 +
44.577 + /**
44.578 + * @throws RejectedExecutionException {@inheritDoc}
44.579 + * @throws NullPointerException {@inheritDoc}
44.580 + * @throws IllegalArgumentException {@inheritDoc}
44.581 + */
44.582 + public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
44.583 + long initialDelay,
44.584 + long delay,
44.585 + TimeUnit unit) {
44.586 + if (command == null || unit == null)
44.587 + throw new NullPointerException();
44.588 + if (delay <= 0)
44.589 + throw new IllegalArgumentException();
44.590 + ScheduledFutureTask<Void> sft =
44.591 + new ScheduledFutureTask<Void>(command,
44.592 + null,
44.593 + triggerTime(initialDelay, unit),
44.594 + unit.toNanos(-delay));
44.595 + RunnableScheduledFuture<Void> t = decorateTask(command, sft);
44.596 + sft.outerTask = t;
44.597 + delayedExecute(t);
44.598 + return t;
44.599 + }
44.600 +
44.601 + /**
44.602 + * Executes {@code command} with zero required delay.
44.603 + * This has effect equivalent to
44.604 + * {@link #schedule(Runnable,long,TimeUnit) schedule(command, 0, anyUnit)}.
44.605 + * Note that inspections of the queue and of the list returned by
44.606 + * {@code shutdownNow} will access the zero-delayed
44.607 + * {@link ScheduledFuture}, not the {@code command} itself.
44.608 + *
44.609 + * <p>A consequence of the use of {@code ScheduledFuture} objects is
44.610 + * that {@link ThreadPoolExecutor#afterExecute afterExecute} is always
44.611 + * called with a null second {@code Throwable} argument, even if the
44.612 + * {@code command} terminated abruptly. Instead, the {@code Throwable}
44.613 + * thrown by such a task can be obtained via {@link Future#get}.
44.614 + *
44.615 + * @throws RejectedExecutionException at discretion of
44.616 + * {@code RejectedExecutionHandler}, if the task
44.617 + * cannot be accepted for execution because the
44.618 + * executor has been shut down
44.619 + * @throws NullPointerException {@inheritDoc}
44.620 + */
44.621 + public void execute(Runnable command) {
44.622 + schedule(command, 0, TimeUnit.NANOSECONDS);
44.623 + }
44.624 +
44.625 + // Override AbstractExecutorService methods
44.626 +
44.627 + /**
44.628 + * @throws RejectedExecutionException {@inheritDoc}
44.629 + * @throws NullPointerException {@inheritDoc}
44.630 + */
44.631 + public Future<?> submit(Runnable task) {
44.632 + return schedule(task, 0, TimeUnit.NANOSECONDS);
44.633 + }
44.634 +
44.635 + /**
44.636 + * @throws RejectedExecutionException {@inheritDoc}
44.637 + * @throws NullPointerException {@inheritDoc}
44.638 + */
44.639 + public <T> Future<T> submit(Runnable task, T result) {
44.640 + return schedule(Executors.callable(task, result),
44.641 + 0, TimeUnit.NANOSECONDS);
44.642 + }
44.643 +
44.644 + /**
44.645 + * @throws RejectedExecutionException {@inheritDoc}
44.646 + * @throws NullPointerException {@inheritDoc}
44.647 + */
44.648 + public <T> Future<T> submit(Callable<T> task) {
44.649 + return schedule(task, 0, TimeUnit.NANOSECONDS);
44.650 + }
44.651 +
44.652 + /**
44.653 + * Sets the policy on whether to continue executing existing
44.654 + * periodic tasks even when this executor has been {@code shutdown}.
44.655 + * In this case, these tasks will only terminate upon
44.656 + * {@code shutdownNow} or after setting the policy to
44.657 + * {@code false} when already shutdown.
44.658 + * This value is by default {@code false}.
44.659 + *
44.660 + * @param value if {@code true}, continue after shutdown, else don't.
44.661 + * @see #getContinueExistingPeriodicTasksAfterShutdownPolicy
44.662 + */
44.663 + public void setContinueExistingPeriodicTasksAfterShutdownPolicy(boolean value) {
44.664 + continueExistingPeriodicTasksAfterShutdown = value;
44.665 + if (!value && isShutdown())
44.666 + onShutdown();
44.667 + }
44.668 +
44.669 + /**
44.670 + * Gets the policy on whether to continue executing existing
44.671 + * periodic tasks even when this executor has been {@code shutdown}.
44.672 + * In this case, these tasks will only terminate upon
44.673 + * {@code shutdownNow} or after setting the policy to
44.674 + * {@code false} when already shutdown.
44.675 + * This value is by default {@code false}.
44.676 + *
44.677 + * @return {@code true} if will continue after shutdown
44.678 + * @see #setContinueExistingPeriodicTasksAfterShutdownPolicy
44.679 + */
44.680 + public boolean getContinueExistingPeriodicTasksAfterShutdownPolicy() {
44.681 + return continueExistingPeriodicTasksAfterShutdown;
44.682 + }
44.683 +
44.684 + /**
44.685 + * Sets the policy on whether to execute existing delayed
44.686 + * tasks even when this executor has been {@code shutdown}.
44.687 + * In this case, these tasks will only terminate upon
44.688 + * {@code shutdownNow}, or after setting the policy to
44.689 + * {@code false} when already shutdown.
44.690 + * This value is by default {@code true}.
44.691 + *
44.692 + * @param value if {@code true}, execute after shutdown, else don't.
44.693 + * @see #getExecuteExistingDelayedTasksAfterShutdownPolicy
44.694 + */
44.695 + public void setExecuteExistingDelayedTasksAfterShutdownPolicy(boolean value) {
44.696 + executeExistingDelayedTasksAfterShutdown = value;
44.697 + if (!value && isShutdown())
44.698 + onShutdown();
44.699 + }
44.700 +
44.701 + /**
44.702 + * Gets the policy on whether to execute existing delayed
44.703 + * tasks even when this executor has been {@code shutdown}.
44.704 + * In this case, these tasks will only terminate upon
44.705 + * {@code shutdownNow}, or after setting the policy to
44.706 + * {@code false} when already shutdown.
44.707 + * This value is by default {@code true}.
44.708 + *
44.709 + * @return {@code true} if will execute after shutdown
44.710 + * @see #setExecuteExistingDelayedTasksAfterShutdownPolicy
44.711 + */
44.712 + public boolean getExecuteExistingDelayedTasksAfterShutdownPolicy() {
44.713 + return executeExistingDelayedTasksAfterShutdown;
44.714 + }
44.715 +
44.716 + /**
44.717 + * Sets the policy on whether cancelled tasks should be immediately
44.718 + * removed from the work queue at time of cancellation. This value is
44.719 + * by default {@code false}.
44.720 + *
44.721 + * @param value if {@code true}, remove on cancellation, else don't
44.722 + * @see #getRemoveOnCancelPolicy
44.723 + * @since 1.7
44.724 + */
44.725 + public void setRemoveOnCancelPolicy(boolean value) {
44.726 + removeOnCancel = value;
44.727 + }
44.728 +
44.729 + /**
44.730 + * Gets the policy on whether cancelled tasks should be immediately
44.731 + * removed from the work queue at time of cancellation. This value is
44.732 + * by default {@code false}.
44.733 + *
44.734 + * @return {@code true} if cancelled tasks are immediately removed
44.735 + * from the queue
44.736 + * @see #setRemoveOnCancelPolicy
44.737 + * @since 1.7
44.738 + */
44.739 + public boolean getRemoveOnCancelPolicy() {
44.740 + return removeOnCancel;
44.741 + }
44.742 +
44.743 + /**
44.744 + * Initiates an orderly shutdown in which previously submitted
44.745 + * tasks are executed, but no new tasks will be accepted.
44.746 + * Invocation has no additional effect if already shut down.
44.747 + *
44.748 + * <p>This method does not wait for previously submitted tasks to
44.749 + * complete execution. Use {@link #awaitTermination awaitTermination}
44.750 + * to do that.
44.751 + *
44.752 + * <p>If the {@code ExecuteExistingDelayedTasksAfterShutdownPolicy}
44.753 + * has been set {@code false}, existing delayed tasks whose delays
44.754 + * have not yet elapsed are cancelled. And unless the {@code
44.755 + * ContinueExistingPeriodicTasksAfterShutdownPolicy} has been set
44.756 + * {@code true}, future executions of existing periodic tasks will
44.757 + * be cancelled.
44.758 + *
44.759 + * @throws SecurityException {@inheritDoc}
44.760 + */
44.761 + public void shutdown() {
44.762 + super.shutdown();
44.763 + }
44.764 +
44.765 + /**
44.766 + * Attempts to stop all actively executing tasks, halts the
44.767 + * processing of waiting tasks, and returns a list of the tasks
44.768 + * that were awaiting execution.
44.769 + *
44.770 + * <p>This method does not wait for actively executing tasks to
44.771 + * terminate. Use {@link #awaitTermination awaitTermination} to
44.772 + * do that.
44.773 + *
44.774 + * <p>There are no guarantees beyond best-effort attempts to stop
44.775 + * processing actively executing tasks. This implementation
44.776 + * cancels tasks via {@link Thread#interrupt}, so any task that
44.777 + * fails to respond to interrupts may never terminate.
44.778 + *
44.779 + * @return list of tasks that never commenced execution.
44.780 + * Each element of this list is a {@link ScheduledFuture},
44.781 + * including those tasks submitted using {@code execute},
44.782 + * which are for scheduling purposes used as the basis of a
44.783 + * zero-delay {@code ScheduledFuture}.
44.784 + * @throws SecurityException {@inheritDoc}
44.785 + */
44.786 + public List<Runnable> shutdownNow() {
44.787 + return super.shutdownNow();
44.788 + }
44.789 +
44.790 + /**
44.791 + * Returns the task queue used by this executor. Each element of
44.792 + * this queue is a {@link ScheduledFuture}, including those
44.793 + * tasks submitted using {@code execute} which are for scheduling
44.794 + * purposes used as the basis of a zero-delay
44.795 + * {@code ScheduledFuture}. Iteration over this queue is
44.796 + * <em>not</em> guaranteed to traverse tasks in the order in
44.797 + * which they will execute.
44.798 + *
44.799 + * @return the task queue
44.800 + */
44.801 + public BlockingQueue<Runnable> getQueue() {
44.802 + return super.getQueue();
44.803 + }
44.804 +
44.805 + /**
44.806 + * Specialized delay queue. To mesh with TPE declarations, this
44.807 + * class must be declared as a BlockingQueue<Runnable> even though
44.808 + * it can only hold RunnableScheduledFutures.
44.809 + */
44.810 + static class DelayedWorkQueue extends AbstractQueue<Runnable>
44.811 + implements BlockingQueue<Runnable> {
44.812 +
44.813 + /*
44.814 + * A DelayedWorkQueue is based on a heap-based data structure
44.815 + * like those in DelayQueue and PriorityQueue, except that
44.816 + * every ScheduledFutureTask also records its index into the
44.817 + * heap array. This eliminates the need to find a task upon
44.818 + * cancellation, greatly speeding up removal (down from O(n)
44.819 + * to O(log n)), and reducing garbage retention that would
44.820 + * otherwise occur by waiting for the element to rise to top
44.821 + * before clearing. But because the queue may also hold
44.822 + * RunnableScheduledFutures that are not ScheduledFutureTasks,
44.823 + * we are not guaranteed to have such indices available, in
44.824 + * which case we fall back to linear search. (We expect that
44.825 + * most tasks will not be decorated, and that the faster cases
44.826 + * will be much more common.)
44.827 + *
44.828 + * All heap operations must record index changes -- mainly
44.829 + * within siftUp and siftDown. Upon removal, a task's
44.830 + * heapIndex is set to -1. Note that ScheduledFutureTasks can
44.831 + * appear at most once in the queue (this need not be true for
44.832 + * other kinds of tasks or work queues), so are uniquely
44.833 + * identified by heapIndex.
44.834 + */
44.835 +
44.836 + private static final int INITIAL_CAPACITY = 16;
44.837 + private RunnableScheduledFuture[] queue =
44.838 + new RunnableScheduledFuture[INITIAL_CAPACITY];
44.839 + private final ReentrantLock lock = new ReentrantLock();
44.840 + private int size = 0;
44.841 +
44.842 + /**
44.843 + * Thread designated to wait for the task at the head of the
44.844 + * queue. This variant of the Leader-Follower pattern
44.845 + * (http://www.cs.wustl.edu/~schmidt/POSA/POSA2/) serves to
44.846 + * minimize unnecessary timed waiting. When a thread becomes
44.847 + * the leader, it waits only for the next delay to elapse, but
44.848 + * other threads await indefinitely. The leader thread must
44.849 + * signal some other thread before returning from take() or
44.850 + * poll(...), unless some other thread becomes leader in the
44.851 + * interim. Whenever the head of the queue is replaced with a
44.852 + * task with an earlier expiration time, the leader field is
44.853 + * invalidated by being reset to null, and some waiting
44.854 + * thread, but not necessarily the current leader, is
44.855 + * signalled. So waiting threads must be prepared to acquire
44.856 + * and lose leadership while waiting.
44.857 + */
44.858 + private Thread leader = null;
44.859 +
44.860 + /**
44.861 + * Condition signalled when a newer task becomes available at the
44.862 + * head of the queue or a new thread may need to become leader.
44.863 + */
44.864 + private final Condition available = lock.newCondition();
44.865 +
44.866 + /**
44.867 + * Set f's heapIndex if it is a ScheduledFutureTask.
44.868 + */
44.869 + private void setIndex(RunnableScheduledFuture f, int idx) {
44.870 + if (f instanceof ScheduledFutureTask)
44.871 + ((ScheduledFutureTask)f).heapIndex = idx;
44.872 + }
44.873 +
44.874 + /**
44.875 + * Sift element added at bottom up to its heap-ordered spot.
44.876 + * Call only when holding lock.
44.877 + */
44.878 + private void siftUp(int k, RunnableScheduledFuture key) {
44.879 + while (k > 0) {
44.880 + int parent = (k - 1) >>> 1;
44.881 + RunnableScheduledFuture e = queue[parent];
44.882 + if (key.compareTo(e) >= 0)
44.883 + break;
44.884 + queue[k] = e;
44.885 + setIndex(e, k);
44.886 + k = parent;
44.887 + }
44.888 + queue[k] = key;
44.889 + setIndex(key, k);
44.890 + }
44.891 +
44.892 + /**
44.893 + * Sift element added at top down to its heap-ordered spot.
44.894 + * Call only when holding lock.
44.895 + */
44.896 + private void siftDown(int k, RunnableScheduledFuture key) {
44.897 + int half = size >>> 1;
44.898 + while (k < half) {
44.899 + int child = (k << 1) + 1;
44.900 + RunnableScheduledFuture c = queue[child];
44.901 + int right = child + 1;
44.902 + if (right < size && c.compareTo(queue[right]) > 0)
44.903 + c = queue[child = right];
44.904 + if (key.compareTo(c) <= 0)
44.905 + break;
44.906 + queue[k] = c;
44.907 + setIndex(c, k);
44.908 + k = child;
44.909 + }
44.910 + queue[k] = key;
44.911 + setIndex(key, k);
44.912 + }
44.913 +
44.914 + /**
44.915 + * Resize the heap array. Call only when holding lock.
44.916 + */
44.917 + private void grow() {
44.918 + int oldCapacity = queue.length;
44.919 + int newCapacity = oldCapacity + (oldCapacity >> 1); // grow 50%
44.920 + if (newCapacity < 0) // overflow
44.921 + newCapacity = Integer.MAX_VALUE;
44.922 + queue = Arrays.copyOf(queue, newCapacity);
44.923 + }
44.924 +
44.925 + /**
44.926 + * Find index of given object, or -1 if absent
44.927 + */
44.928 + private int indexOf(Object x) {
44.929 + if (x != null) {
44.930 + if (x instanceof ScheduledFutureTask) {
44.931 + int i = ((ScheduledFutureTask) x).heapIndex;
44.932 + // Sanity check; x could conceivably be a
44.933 + // ScheduledFutureTask from some other pool.
44.934 + if (i >= 0 && i < size && queue[i] == x)
44.935 + return i;
44.936 + } else {
44.937 + for (int i = 0; i < size; i++)
44.938 + if (x.equals(queue[i]))
44.939 + return i;
44.940 + }
44.941 + }
44.942 + return -1;
44.943 + }
44.944 +
44.945 + public boolean contains(Object x) {
44.946 + final ReentrantLock lock = this.lock;
44.947 + lock.lock();
44.948 + try {
44.949 + return indexOf(x) != -1;
44.950 + } finally {
44.951 + lock.unlock();
44.952 + }
44.953 + }
44.954 +
44.955 + public boolean remove(Object x) {
44.956 + final ReentrantLock lock = this.lock;
44.957 + lock.lock();
44.958 + try {
44.959 + int i = indexOf(x);
44.960 + if (i < 0)
44.961 + return false;
44.962 +
44.963 + setIndex(queue[i], -1);
44.964 + int s = --size;
44.965 + RunnableScheduledFuture replacement = queue[s];
44.966 + queue[s] = null;
44.967 + if (s != i) {
44.968 + siftDown(i, replacement);
44.969 + if (queue[i] == replacement)
44.970 + siftUp(i, replacement);
44.971 + }
44.972 + return true;
44.973 + } finally {
44.974 + lock.unlock();
44.975 + }
44.976 + }
44.977 +
44.978 + public int size() {
44.979 + final ReentrantLock lock = this.lock;
44.980 + lock.lock();
44.981 + try {
44.982 + return size;
44.983 + } finally {
44.984 + lock.unlock();
44.985 + }
44.986 + }
44.987 +
44.988 + public boolean isEmpty() {
44.989 + return size() == 0;
44.990 + }
44.991 +
44.992 + public int remainingCapacity() {
44.993 + return Integer.MAX_VALUE;
44.994 + }
44.995 +
44.996 + public RunnableScheduledFuture peek() {
44.997 + final ReentrantLock lock = this.lock;
44.998 + lock.lock();
44.999 + try {
44.1000 + return queue[0];
44.1001 + } finally {
44.1002 + lock.unlock();
44.1003 + }
44.1004 + }
44.1005 +
44.1006 + public boolean offer(Runnable x) {
44.1007 + if (x == null)
44.1008 + throw new NullPointerException();
44.1009 + RunnableScheduledFuture e = (RunnableScheduledFuture)x;
44.1010 + final ReentrantLock lock = this.lock;
44.1011 + lock.lock();
44.1012 + try {
44.1013 + int i = size;
44.1014 + if (i >= queue.length)
44.1015 + grow();
44.1016 + size = i + 1;
44.1017 + if (i == 0) {
44.1018 + queue[0] = e;
44.1019 + setIndex(e, 0);
44.1020 + } else {
44.1021 + siftUp(i, e);
44.1022 + }
44.1023 + if (queue[0] == e) {
44.1024 + leader = null;
44.1025 + available.signal();
44.1026 + }
44.1027 + } finally {
44.1028 + lock.unlock();
44.1029 + }
44.1030 + return true;
44.1031 + }
44.1032 +
44.1033 + public void put(Runnable e) {
44.1034 + offer(e);
44.1035 + }
44.1036 +
44.1037 + public boolean add(Runnable e) {
44.1038 + return offer(e);
44.1039 + }
44.1040 +
44.1041 + public boolean offer(Runnable e, long timeout, TimeUnit unit) {
44.1042 + return offer(e);
44.1043 + }
44.1044 +
44.1045 + /**
44.1046 + * Performs common bookkeeping for poll and take: Replaces
44.1047 + * first element with last and sifts it down. Call only when
44.1048 + * holding lock.
44.1049 + * @param f the task to remove and return
44.1050 + */
44.1051 + private RunnableScheduledFuture finishPoll(RunnableScheduledFuture f) {
44.1052 + int s = --size;
44.1053 + RunnableScheduledFuture x = queue[s];
44.1054 + queue[s] = null;
44.1055 + if (s != 0)
44.1056 + siftDown(0, x);
44.1057 + setIndex(f, -1);
44.1058 + return f;
44.1059 + }
44.1060 +
44.1061 + public RunnableScheduledFuture poll() {
44.1062 + final ReentrantLock lock = this.lock;
44.1063 + lock.lock();
44.1064 + try {
44.1065 + RunnableScheduledFuture first = queue[0];
44.1066 + if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
44.1067 + return null;
44.1068 + else
44.1069 + return finishPoll(first);
44.1070 + } finally {
44.1071 + lock.unlock();
44.1072 + }
44.1073 + }
44.1074 +
44.1075 + public RunnableScheduledFuture take() throws InterruptedException {
44.1076 + final ReentrantLock lock = this.lock;
44.1077 + lock.lockInterruptibly();
44.1078 + try {
44.1079 + for (;;) {
44.1080 + RunnableScheduledFuture first = queue[0];
44.1081 + if (first == null)
44.1082 + available.await();
44.1083 + else {
44.1084 + long delay = first.getDelay(TimeUnit.NANOSECONDS);
44.1085 + if (delay <= 0)
44.1086 + return finishPoll(first);
44.1087 + else if (leader != null)
44.1088 + available.await();
44.1089 + else {
44.1090 + Thread thisThread = Thread.currentThread();
44.1091 + leader = thisThread;
44.1092 + try {
44.1093 + available.awaitNanos(delay);
44.1094 + } finally {
44.1095 + if (leader == thisThread)
44.1096 + leader = null;
44.1097 + }
44.1098 + }
44.1099 + }
44.1100 + }
44.1101 + } finally {
44.1102 + if (leader == null && queue[0] != null)
44.1103 + available.signal();
44.1104 + lock.unlock();
44.1105 + }
44.1106 + }
44.1107 +
44.1108 + public RunnableScheduledFuture poll(long timeout, TimeUnit unit)
44.1109 + throws InterruptedException {
44.1110 + long nanos = unit.toNanos(timeout);
44.1111 + final ReentrantLock lock = this.lock;
44.1112 + lock.lockInterruptibly();
44.1113 + try {
44.1114 + for (;;) {
44.1115 + RunnableScheduledFuture first = queue[0];
44.1116 + if (first == null) {
44.1117 + if (nanos <= 0)
44.1118 + return null;
44.1119 + else
44.1120 + nanos = available.awaitNanos(nanos);
44.1121 + } else {
44.1122 + long delay = first.getDelay(TimeUnit.NANOSECONDS);
44.1123 + if (delay <= 0)
44.1124 + return finishPoll(first);
44.1125 + if (nanos <= 0)
44.1126 + return null;
44.1127 + if (nanos < delay || leader != null)
44.1128 + nanos = available.awaitNanos(nanos);
44.1129 + else {
44.1130 + Thread thisThread = Thread.currentThread();
44.1131 + leader = thisThread;
44.1132 + try {
44.1133 + long timeLeft = available.awaitNanos(delay);
44.1134 + nanos -= delay - timeLeft;
44.1135 + } finally {
44.1136 + if (leader == thisThread)
44.1137 + leader = null;
44.1138 + }
44.1139 + }
44.1140 + }
44.1141 + }
44.1142 + } finally {
44.1143 + if (leader == null && queue[0] != null)
44.1144 + available.signal();
44.1145 + lock.unlock();
44.1146 + }
44.1147 + }
44.1148 +
44.1149 + public void clear() {
44.1150 + final ReentrantLock lock = this.lock;
44.1151 + lock.lock();
44.1152 + try {
44.1153 + for (int i = 0; i < size; i++) {
44.1154 + RunnableScheduledFuture t = queue[i];
44.1155 + if (t != null) {
44.1156 + queue[i] = null;
44.1157 + setIndex(t, -1);
44.1158 + }
44.1159 + }
44.1160 + size = 0;
44.1161 + } finally {
44.1162 + lock.unlock();
44.1163 + }
44.1164 + }
44.1165 +
44.1166 + /**
44.1167 + * Return and remove first element only if it is expired.
44.1168 + * Used only by drainTo. Call only when holding lock.
44.1169 + */
44.1170 + private RunnableScheduledFuture pollExpired() {
44.1171 + RunnableScheduledFuture first = queue[0];
44.1172 + if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
44.1173 + return null;
44.1174 + return finishPoll(first);
44.1175 + }
44.1176 +
44.1177 + public int drainTo(Collection<? super Runnable> c) {
44.1178 + if (c == null)
44.1179 + throw new NullPointerException();
44.1180 + if (c == this)
44.1181 + throw new IllegalArgumentException();
44.1182 + final ReentrantLock lock = this.lock;
44.1183 + lock.lock();
44.1184 + try {
44.1185 + RunnableScheduledFuture first;
44.1186 + int n = 0;
44.1187 + while ((first = pollExpired()) != null) {
44.1188 + c.add(first);
44.1189 + ++n;
44.1190 + }
44.1191 + return n;
44.1192 + } finally {
44.1193 + lock.unlock();
44.1194 + }
44.1195 + }
44.1196 +
44.1197 + public int drainTo(Collection<? super Runnable> c, int maxElements) {
44.1198 + if (c == null)
44.1199 + throw new NullPointerException();
44.1200 + if (c == this)
44.1201 + throw new IllegalArgumentException();
44.1202 + if (maxElements <= 0)
44.1203 + return 0;
44.1204 + final ReentrantLock lock = this.lock;
44.1205 + lock.lock();
44.1206 + try {
44.1207 + RunnableScheduledFuture first;
44.1208 + int n = 0;
44.1209 + while (n < maxElements && (first = pollExpired()) != null) {
44.1210 + c.add(first);
44.1211 + ++n;
44.1212 + }
44.1213 + return n;
44.1214 + } finally {
44.1215 + lock.unlock();
44.1216 + }
44.1217 + }
44.1218 +
44.1219 + public Object[] toArray() {
44.1220 + final ReentrantLock lock = this.lock;
44.1221 + lock.lock();
44.1222 + try {
44.1223 + return Arrays.copyOf(queue, size, Object[].class);
44.1224 + } finally {
44.1225 + lock.unlock();
44.1226 + }
44.1227 + }
44.1228 +
44.1229 + @SuppressWarnings("unchecked")
44.1230 + public <T> T[] toArray(T[] a) {
44.1231 + final ReentrantLock lock = this.lock;
44.1232 + lock.lock();
44.1233 + try {
44.1234 + if (a.length < size)
44.1235 + return (T[]) Arrays.copyOf(queue, size, a.getClass());
44.1236 + System.arraycopy(queue, 0, a, 0, size);
44.1237 + if (a.length > size)
44.1238 + a[size] = null;
44.1239 + return a;
44.1240 + } finally {
44.1241 + lock.unlock();
44.1242 + }
44.1243 + }
44.1244 +
44.1245 + public Iterator<Runnable> iterator() {
44.1246 + return new Itr(Arrays.copyOf(queue, size));
44.1247 + }
44.1248 +
44.1249 + /**
44.1250 + * Snapshot iterator that works off copy of underlying q array.
44.1251 + */
44.1252 + private class Itr implements Iterator<Runnable> {
44.1253 + final RunnableScheduledFuture[] array;
44.1254 + int cursor = 0; // index of next element to return
44.1255 + int lastRet = -1; // index of last element, or -1 if no such
44.1256 +
44.1257 + Itr(RunnableScheduledFuture[] array) {
44.1258 + this.array = array;
44.1259 + }
44.1260 +
44.1261 + public boolean hasNext() {
44.1262 + return cursor < array.length;
44.1263 + }
44.1264 +
44.1265 + public Runnable next() {
44.1266 + if (cursor >= array.length)
44.1267 + throw new NoSuchElementException();
44.1268 + lastRet = cursor;
44.1269 + return array[cursor++];
44.1270 + }
44.1271 +
44.1272 + public void remove() {
44.1273 + if (lastRet < 0)
44.1274 + throw new IllegalStateException();
44.1275 + DelayedWorkQueue.this.remove(array[lastRet]);
44.1276 + lastRet = -1;
44.1277 + }
44.1278 + }
44.1279 + }
44.1280 +}
45.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
45.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/Semaphore.java Sat Mar 19 10:46:31 2016 +0100
45.3 @@ -0,0 +1,713 @@
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 +import java.util.*;
45.41 +import java.util.concurrent.locks.*;
45.42 +import java.util.concurrent.atomic.*;
45.43 +
45.44 +/**
45.45 + * A counting semaphore. Conceptually, a semaphore maintains a set of
45.46 + * permits. Each {@link #acquire} blocks if necessary until a permit is
45.47 + * available, and then takes it. Each {@link #release} adds a permit,
45.48 + * potentially releasing a blocking acquirer.
45.49 + * However, no actual permit objects are used; the {@code Semaphore} just
45.50 + * keeps a count of the number available and acts accordingly.
45.51 + *
45.52 + * <p>Semaphores are often used to restrict the number of threads than can
45.53 + * access some (physical or logical) resource. For example, here is
45.54 + * a class that uses a semaphore to control access to a pool of items:
45.55 + * <pre>
45.56 + * class Pool {
45.57 + * private static final int MAX_AVAILABLE = 100;
45.58 + * private final Semaphore available = new Semaphore(MAX_AVAILABLE, true);
45.59 + *
45.60 + * public Object getItem() throws InterruptedException {
45.61 + * available.acquire();
45.62 + * return getNextAvailableItem();
45.63 + * }
45.64 + *
45.65 + * public void putItem(Object x) {
45.66 + * if (markAsUnused(x))
45.67 + * available.release();
45.68 + * }
45.69 + *
45.70 + * // Not a particularly efficient data structure; just for demo
45.71 + *
45.72 + * protected Object[] items = ... whatever kinds of items being managed
45.73 + * protected boolean[] used = new boolean[MAX_AVAILABLE];
45.74 + *
45.75 + * protected synchronized Object getNextAvailableItem() {
45.76 + * for (int i = 0; i < MAX_AVAILABLE; ++i) {
45.77 + * if (!used[i]) {
45.78 + * used[i] = true;
45.79 + * return items[i];
45.80 + * }
45.81 + * }
45.82 + * return null; // not reached
45.83 + * }
45.84 + *
45.85 + * protected synchronized boolean markAsUnused(Object item) {
45.86 + * for (int i = 0; i < MAX_AVAILABLE; ++i) {
45.87 + * if (item == items[i]) {
45.88 + * if (used[i]) {
45.89 + * used[i] = false;
45.90 + * return true;
45.91 + * } else
45.92 + * return false;
45.93 + * }
45.94 + * }
45.95 + * return false;
45.96 + * }
45.97 + *
45.98 + * }
45.99 + * </pre>
45.100 + *
45.101 + * <p>Before obtaining an item each thread must acquire a permit from
45.102 + * the semaphore, guaranteeing that an item is available for use. When
45.103 + * the thread has finished with the item it is returned back to the
45.104 + * pool and a permit is returned to the semaphore, allowing another
45.105 + * thread to acquire that item. Note that no synchronization lock is
45.106 + * held when {@link #acquire} is called as that would prevent an item
45.107 + * from being returned to the pool. The semaphore encapsulates the
45.108 + * synchronization needed to restrict access to the pool, separately
45.109 + * from any synchronization needed to maintain the consistency of the
45.110 + * pool itself.
45.111 + *
45.112 + * <p>A semaphore initialized to one, and which is used such that it
45.113 + * only has at most one permit available, can serve as a mutual
45.114 + * exclusion lock. This is more commonly known as a <em>binary
45.115 + * semaphore</em>, because it only has two states: one permit
45.116 + * available, or zero permits available. When used in this way, the
45.117 + * binary semaphore has the property (unlike many {@link Lock}
45.118 + * implementations), that the "lock" can be released by a
45.119 + * thread other than the owner (as semaphores have no notion of
45.120 + * ownership). This can be useful in some specialized contexts, such
45.121 + * as deadlock recovery.
45.122 + *
45.123 + * <p> The constructor for this class optionally accepts a
45.124 + * <em>fairness</em> parameter. When set false, this class makes no
45.125 + * guarantees about the order in which threads acquire permits. In
45.126 + * particular, <em>barging</em> is permitted, that is, a thread
45.127 + * invoking {@link #acquire} can be allocated a permit ahead of a
45.128 + * thread that has been waiting - logically the new thread places itself at
45.129 + * the head of the queue of waiting threads. When fairness is set true, the
45.130 + * semaphore guarantees that threads invoking any of the {@link
45.131 + * #acquire() acquire} methods are selected to obtain permits in the order in
45.132 + * which their invocation of those methods was processed
45.133 + * (first-in-first-out; FIFO). Note that FIFO ordering necessarily
45.134 + * applies to specific internal points of execution within these
45.135 + * methods. So, it is possible for one thread to invoke
45.136 + * {@code acquire} before another, but reach the ordering point after
45.137 + * the other, and similarly upon return from the method.
45.138 + * Also note that the untimed {@link #tryAcquire() tryAcquire} methods do not
45.139 + * honor the fairness setting, but will take any permits that are
45.140 + * available.
45.141 + *
45.142 + * <p>Generally, semaphores used to control resource access should be
45.143 + * initialized as fair, to ensure that no thread is starved out from
45.144 + * accessing a resource. When using semaphores for other kinds of
45.145 + * synchronization control, the throughput advantages of non-fair
45.146 + * ordering often outweigh fairness considerations.
45.147 + *
45.148 + * <p>This class also provides convenience methods to {@link
45.149 + * #acquire(int) acquire} and {@link #release(int) release} multiple
45.150 + * permits at a time. Beware of the increased risk of indefinite
45.151 + * postponement when these methods are used without fairness set true.
45.152 + *
45.153 + * <p>Memory consistency effects: Actions in a thread prior to calling
45.154 + * a "release" method such as {@code release()}
45.155 + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
45.156 + * actions following a successful "acquire" method such as {@code acquire()}
45.157 + * in another thread.
45.158 + *
45.159 + * @since 1.5
45.160 + * @author Doug Lea
45.161 + *
45.162 + */
45.163 +
45.164 +public class Semaphore implements java.io.Serializable {
45.165 + private static final long serialVersionUID = -3222578661600680210L;
45.166 + /** All mechanics via AbstractQueuedSynchronizer subclass */
45.167 + private final Sync sync;
45.168 +
45.169 + /**
45.170 + * Synchronization implementation for semaphore. Uses AQS state
45.171 + * to represent permits. Subclassed into fair and nonfair
45.172 + * versions.
45.173 + */
45.174 + abstract static class Sync extends AbstractQueuedSynchronizer {
45.175 + private static final long serialVersionUID = 1192457210091910933L;
45.176 +
45.177 + Sync(int permits) {
45.178 + setState(permits);
45.179 + }
45.180 +
45.181 + final int getPermits() {
45.182 + return getState();
45.183 + }
45.184 +
45.185 + final int nonfairTryAcquireShared(int acquires) {
45.186 + for (;;) {
45.187 + int available = getState();
45.188 + int remaining = available - acquires;
45.189 + if (remaining < 0 ||
45.190 + compareAndSetState(available, remaining))
45.191 + return remaining;
45.192 + }
45.193 + }
45.194 +
45.195 + protected final boolean tryReleaseShared(int releases) {
45.196 + for (;;) {
45.197 + int current = getState();
45.198 + int next = current + releases;
45.199 + if (next < current) // overflow
45.200 + throw new Error("Maximum permit count exceeded");
45.201 + if (compareAndSetState(current, next))
45.202 + return true;
45.203 + }
45.204 + }
45.205 +
45.206 + final void reducePermits(int reductions) {
45.207 + for (;;) {
45.208 + int current = getState();
45.209 + int next = current - reductions;
45.210 + if (next > current) // underflow
45.211 + throw new Error("Permit count underflow");
45.212 + if (compareAndSetState(current, next))
45.213 + return;
45.214 + }
45.215 + }
45.216 +
45.217 + final int drainPermits() {
45.218 + for (;;) {
45.219 + int current = getState();
45.220 + if (current == 0 || compareAndSetState(current, 0))
45.221 + return current;
45.222 + }
45.223 + }
45.224 + }
45.225 +
45.226 + /**
45.227 + * NonFair version
45.228 + */
45.229 + static final class NonfairSync extends Sync {
45.230 + private static final long serialVersionUID = -2694183684443567898L;
45.231 +
45.232 + NonfairSync(int permits) {
45.233 + super(permits);
45.234 + }
45.235 +
45.236 + protected int tryAcquireShared(int acquires) {
45.237 + return nonfairTryAcquireShared(acquires);
45.238 + }
45.239 + }
45.240 +
45.241 + /**
45.242 + * Fair version
45.243 + */
45.244 + static final class FairSync extends Sync {
45.245 + private static final long serialVersionUID = 2014338818796000944L;
45.246 +
45.247 + FairSync(int permits) {
45.248 + super(permits);
45.249 + }
45.250 +
45.251 + protected int tryAcquireShared(int acquires) {
45.252 + for (;;) {
45.253 + if (hasQueuedPredecessors())
45.254 + return -1;
45.255 + int available = getState();
45.256 + int remaining = available - acquires;
45.257 + if (remaining < 0 ||
45.258 + compareAndSetState(available, remaining))
45.259 + return remaining;
45.260 + }
45.261 + }
45.262 + }
45.263 +
45.264 + /**
45.265 + * Creates a {@code Semaphore} with the given number of
45.266 + * permits and nonfair fairness setting.
45.267 + *
45.268 + * @param permits the initial number of permits available.
45.269 + * This value may be negative, in which case releases
45.270 + * must occur before any acquires will be granted.
45.271 + */
45.272 + public Semaphore(int permits) {
45.273 + sync = new NonfairSync(permits);
45.274 + }
45.275 +
45.276 + /**
45.277 + * Creates a {@code Semaphore} with the given number of
45.278 + * permits and the given fairness setting.
45.279 + *
45.280 + * @param permits the initial number of permits available.
45.281 + * This value may be negative, in which case releases
45.282 + * must occur before any acquires will be granted.
45.283 + * @param fair {@code true} if this semaphore will guarantee
45.284 + * first-in first-out granting of permits under contention,
45.285 + * else {@code false}
45.286 + */
45.287 + public Semaphore(int permits, boolean fair) {
45.288 + sync = fair ? new FairSync(permits) : new NonfairSync(permits);
45.289 + }
45.290 +
45.291 + /**
45.292 + * Acquires a permit from this semaphore, blocking until one is
45.293 + * available, or the thread is {@linkplain Thread#interrupt interrupted}.
45.294 + *
45.295 + * <p>Acquires a permit, if one is available and returns immediately,
45.296 + * reducing the number of available permits by one.
45.297 + *
45.298 + * <p>If no permit is available then the current thread becomes
45.299 + * disabled for thread scheduling purposes and lies dormant until
45.300 + * one of two things happens:
45.301 + * <ul>
45.302 + * <li>Some other thread invokes the {@link #release} method for this
45.303 + * semaphore and the current thread is next to be assigned a permit; or
45.304 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
45.305 + * the current thread.
45.306 + * </ul>
45.307 + *
45.308 + * <p>If the current thread:
45.309 + * <ul>
45.310 + * <li>has its interrupted status set on entry to this method; or
45.311 + * <li>is {@linkplain Thread#interrupt interrupted} while waiting
45.312 + * for a permit,
45.313 + * </ul>
45.314 + * then {@link InterruptedException} is thrown and the current thread's
45.315 + * interrupted status is cleared.
45.316 + *
45.317 + * @throws InterruptedException if the current thread is interrupted
45.318 + */
45.319 + public void acquire() throws InterruptedException {
45.320 + sync.acquireSharedInterruptibly(1);
45.321 + }
45.322 +
45.323 + /**
45.324 + * Acquires a permit from this semaphore, blocking until one is
45.325 + * available.
45.326 + *
45.327 + * <p>Acquires a permit, if one is available and returns immediately,
45.328 + * reducing the number of available permits by one.
45.329 + *
45.330 + * <p>If no permit is available then the current thread becomes
45.331 + * disabled for thread scheduling purposes and lies dormant until
45.332 + * some other thread invokes the {@link #release} method for this
45.333 + * semaphore and the current thread is next to be assigned a permit.
45.334 + *
45.335 + * <p>If the current thread is {@linkplain Thread#interrupt interrupted}
45.336 + * while waiting for a permit then it will continue to wait, but the
45.337 + * time at which the thread is assigned a permit may change compared to
45.338 + * the time it would have received the permit had no interruption
45.339 + * occurred. When the thread does return from this method its interrupt
45.340 + * status will be set.
45.341 + */
45.342 + public void acquireUninterruptibly() {
45.343 + sync.acquireShared(1);
45.344 + }
45.345 +
45.346 + /**
45.347 + * Acquires a permit from this semaphore, only if one is available at the
45.348 + * time of invocation.
45.349 + *
45.350 + * <p>Acquires a permit, if one is available and returns immediately,
45.351 + * with the value {@code true},
45.352 + * reducing the number of available permits by one.
45.353 + *
45.354 + * <p>If no permit is available then this method will return
45.355 + * immediately with the value {@code false}.
45.356 + *
45.357 + * <p>Even when this semaphore has been set to use a
45.358 + * fair ordering policy, a call to {@code tryAcquire()} <em>will</em>
45.359 + * immediately acquire a permit if one is available, whether or not
45.360 + * other threads are currently waiting.
45.361 + * This "barging" behavior can be useful in certain
45.362 + * circumstances, even though it breaks fairness. If you want to honor
45.363 + * the fairness setting, then use
45.364 + * {@link #tryAcquire(long, TimeUnit) tryAcquire(0, TimeUnit.SECONDS) }
45.365 + * which is almost equivalent (it also detects interruption).
45.366 + *
45.367 + * @return {@code true} if a permit was acquired and {@code false}
45.368 + * otherwise
45.369 + */
45.370 + public boolean tryAcquire() {
45.371 + return sync.nonfairTryAcquireShared(1) >= 0;
45.372 + }
45.373 +
45.374 + /**
45.375 + * Acquires a permit from this semaphore, if one becomes available
45.376 + * within the given waiting time and the current thread has not
45.377 + * been {@linkplain Thread#interrupt interrupted}.
45.378 + *
45.379 + * <p>Acquires a permit, if one is available and returns immediately,
45.380 + * with the value {@code true},
45.381 + * reducing the number of available permits by one.
45.382 + *
45.383 + * <p>If no permit is available then the current thread becomes
45.384 + * disabled for thread scheduling purposes and lies dormant until
45.385 + * one of three things happens:
45.386 + * <ul>
45.387 + * <li>Some other thread invokes the {@link #release} method for this
45.388 + * semaphore and the current thread is next to be assigned a permit; or
45.389 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
45.390 + * the current thread; or
45.391 + * <li>The specified waiting time elapses.
45.392 + * </ul>
45.393 + *
45.394 + * <p>If a permit is acquired then the value {@code true} is returned.
45.395 + *
45.396 + * <p>If the current thread:
45.397 + * <ul>
45.398 + * <li>has its interrupted status set on entry to this method; or
45.399 + * <li>is {@linkplain Thread#interrupt interrupted} while waiting
45.400 + * to acquire a permit,
45.401 + * </ul>
45.402 + * then {@link InterruptedException} is thrown and the current thread's
45.403 + * interrupted status is cleared.
45.404 + *
45.405 + * <p>If the specified waiting time elapses then the value {@code false}
45.406 + * is returned. If the time is less than or equal to zero, the method
45.407 + * will not wait at all.
45.408 + *
45.409 + * @param timeout the maximum time to wait for a permit
45.410 + * @param unit the time unit of the {@code timeout} argument
45.411 + * @return {@code true} if a permit was acquired and {@code false}
45.412 + * if the waiting time elapsed before a permit was acquired
45.413 + * @throws InterruptedException if the current thread is interrupted
45.414 + */
45.415 + public boolean tryAcquire(long timeout, TimeUnit unit)
45.416 + throws InterruptedException {
45.417 + return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
45.418 + }
45.419 +
45.420 + /**
45.421 + * Releases a permit, returning it to the semaphore.
45.422 + *
45.423 + * <p>Releases a permit, increasing the number of available permits by
45.424 + * one. If any threads are trying to acquire a permit, then one is
45.425 + * selected and given the permit that was just released. That thread
45.426 + * is (re)enabled for thread scheduling purposes.
45.427 + *
45.428 + * <p>There is no requirement that a thread that releases a permit must
45.429 + * have acquired that permit by calling {@link #acquire}.
45.430 + * Correct usage of a semaphore is established by programming convention
45.431 + * in the application.
45.432 + */
45.433 + public void release() {
45.434 + sync.releaseShared(1);
45.435 + }
45.436 +
45.437 + /**
45.438 + * Acquires the given number of permits from this semaphore,
45.439 + * blocking until all are available,
45.440 + * or the thread is {@linkplain Thread#interrupt interrupted}.
45.441 + *
45.442 + * <p>Acquires the given number of permits, if they are available,
45.443 + * and returns immediately, reducing the number of available permits
45.444 + * by the given amount.
45.445 + *
45.446 + * <p>If insufficient permits are available then the current thread becomes
45.447 + * disabled for thread scheduling purposes and lies dormant until
45.448 + * one of two things happens:
45.449 + * <ul>
45.450 + * <li>Some other thread invokes one of the {@link #release() release}
45.451 + * methods for this semaphore, the current thread is next to be assigned
45.452 + * permits and the number of available permits satisfies this request; or
45.453 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
45.454 + * the current thread.
45.455 + * </ul>
45.456 + *
45.457 + * <p>If the current thread:
45.458 + * <ul>
45.459 + * <li>has its interrupted status set on entry to this method; or
45.460 + * <li>is {@linkplain Thread#interrupt interrupted} while waiting
45.461 + * for a permit,
45.462 + * </ul>
45.463 + * then {@link InterruptedException} is thrown and the current thread's
45.464 + * interrupted status is cleared.
45.465 + * Any permits that were to be assigned to this thread are instead
45.466 + * assigned to other threads trying to acquire permits, as if
45.467 + * permits had been made available by a call to {@link #release()}.
45.468 + *
45.469 + * @param permits the number of permits to acquire
45.470 + * @throws InterruptedException if the current thread is interrupted
45.471 + * @throws IllegalArgumentException if {@code permits} is negative
45.472 + */
45.473 + public void acquire(int permits) throws InterruptedException {
45.474 + if (permits < 0) throw new IllegalArgumentException();
45.475 + sync.acquireSharedInterruptibly(permits);
45.476 + }
45.477 +
45.478 + /**
45.479 + * Acquires the given number of permits from this semaphore,
45.480 + * blocking until all are available.
45.481 + *
45.482 + * <p>Acquires the given number of permits, if they are available,
45.483 + * and returns immediately, reducing the number of available permits
45.484 + * by the given amount.
45.485 + *
45.486 + * <p>If insufficient permits are available then the current thread becomes
45.487 + * disabled for thread scheduling purposes and lies dormant until
45.488 + * some other thread invokes one of the {@link #release() release}
45.489 + * methods for this semaphore, the current thread is next to be assigned
45.490 + * permits and the number of available permits satisfies this request.
45.491 + *
45.492 + * <p>If the current thread is {@linkplain Thread#interrupt interrupted}
45.493 + * while waiting for permits then it will continue to wait and its
45.494 + * position in the queue is not affected. When the thread does return
45.495 + * from this method its interrupt status will be set.
45.496 + *
45.497 + * @param permits the number of permits to acquire
45.498 + * @throws IllegalArgumentException if {@code permits} is negative
45.499 + *
45.500 + */
45.501 + public void acquireUninterruptibly(int permits) {
45.502 + if (permits < 0) throw new IllegalArgumentException();
45.503 + sync.acquireShared(permits);
45.504 + }
45.505 +
45.506 + /**
45.507 + * Acquires the given number of permits from this semaphore, only
45.508 + * if all are available at the time of invocation.
45.509 + *
45.510 + * <p>Acquires the given number of permits, if they are available, and
45.511 + * returns immediately, with the value {@code true},
45.512 + * reducing the number of available permits by the given amount.
45.513 + *
45.514 + * <p>If insufficient permits are available then this method will return
45.515 + * immediately with the value {@code false} and the number of available
45.516 + * permits is unchanged.
45.517 + *
45.518 + * <p>Even when this semaphore has been set to use a fair ordering
45.519 + * policy, a call to {@code tryAcquire} <em>will</em>
45.520 + * immediately acquire a permit if one is available, whether or
45.521 + * not other threads are currently waiting. This
45.522 + * "barging" behavior can be useful in certain
45.523 + * circumstances, even though it breaks fairness. If you want to
45.524 + * honor the fairness setting, then use {@link #tryAcquire(int,
45.525 + * long, TimeUnit) tryAcquire(permits, 0, TimeUnit.SECONDS) }
45.526 + * which is almost equivalent (it also detects interruption).
45.527 + *
45.528 + * @param permits the number of permits to acquire
45.529 + * @return {@code true} if the permits were acquired and
45.530 + * {@code false} otherwise
45.531 + * @throws IllegalArgumentException if {@code permits} is negative
45.532 + */
45.533 + public boolean tryAcquire(int permits) {
45.534 + if (permits < 0) throw new IllegalArgumentException();
45.535 + return sync.nonfairTryAcquireShared(permits) >= 0;
45.536 + }
45.537 +
45.538 + /**
45.539 + * Acquires the given number of permits from this semaphore, if all
45.540 + * become available within the given waiting time and the current
45.541 + * thread has not been {@linkplain Thread#interrupt interrupted}.
45.542 + *
45.543 + * <p>Acquires the given number of permits, if they are available and
45.544 + * returns immediately, with the value {@code true},
45.545 + * reducing the number of available permits by the given amount.
45.546 + *
45.547 + * <p>If insufficient permits are available then
45.548 + * the current thread becomes disabled for thread scheduling
45.549 + * purposes and lies dormant until one of three things happens:
45.550 + * <ul>
45.551 + * <li>Some other thread invokes one of the {@link #release() release}
45.552 + * methods for this semaphore, the current thread is next to be assigned
45.553 + * permits and the number of available permits satisfies this request; or
45.554 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
45.555 + * the current thread; or
45.556 + * <li>The specified waiting time elapses.
45.557 + * </ul>
45.558 + *
45.559 + * <p>If the permits are acquired then the value {@code true} is returned.
45.560 + *
45.561 + * <p>If the current thread:
45.562 + * <ul>
45.563 + * <li>has its interrupted status set on entry to this method; or
45.564 + * <li>is {@linkplain Thread#interrupt interrupted} while waiting
45.565 + * to acquire the permits,
45.566 + * </ul>
45.567 + * then {@link InterruptedException} is thrown and the current thread's
45.568 + * interrupted status is cleared.
45.569 + * Any permits that were to be assigned to this thread, are instead
45.570 + * assigned to other threads trying to acquire permits, as if
45.571 + * the permits had been made available by a call to {@link #release()}.
45.572 + *
45.573 + * <p>If the specified waiting time elapses then the value {@code false}
45.574 + * is returned. If the time is less than or equal to zero, the method
45.575 + * will not wait at all. Any permits that were to be assigned to this
45.576 + * thread, are instead assigned to other threads trying to acquire
45.577 + * permits, as if the permits had been made available by a call to
45.578 + * {@link #release()}.
45.579 + *
45.580 + * @param permits the number of permits to acquire
45.581 + * @param timeout the maximum time to wait for the permits
45.582 + * @param unit the time unit of the {@code timeout} argument
45.583 + * @return {@code true} if all permits were acquired and {@code false}
45.584 + * if the waiting time elapsed before all permits were acquired
45.585 + * @throws InterruptedException if the current thread is interrupted
45.586 + * @throws IllegalArgumentException if {@code permits} is negative
45.587 + */
45.588 + public boolean tryAcquire(int permits, long timeout, TimeUnit unit)
45.589 + throws InterruptedException {
45.590 + if (permits < 0) throw new IllegalArgumentException();
45.591 + return sync.tryAcquireSharedNanos(permits, unit.toNanos(timeout));
45.592 + }
45.593 +
45.594 + /**
45.595 + * Releases the given number of permits, returning them to the semaphore.
45.596 + *
45.597 + * <p>Releases the given number of permits, increasing the number of
45.598 + * available permits by that amount.
45.599 + * If any threads are trying to acquire permits, then one
45.600 + * is selected and given the permits that were just released.
45.601 + * If the number of available permits satisfies that thread's request
45.602 + * then that thread is (re)enabled for thread scheduling purposes;
45.603 + * otherwise the thread will wait until sufficient permits are available.
45.604 + * If there are still permits available
45.605 + * after this thread's request has been satisfied, then those permits
45.606 + * are assigned in turn to other threads trying to acquire permits.
45.607 + *
45.608 + * <p>There is no requirement that a thread that releases a permit must
45.609 + * have acquired that permit by calling {@link Semaphore#acquire acquire}.
45.610 + * Correct usage of a semaphore is established by programming convention
45.611 + * in the application.
45.612 + *
45.613 + * @param permits the number of permits to release
45.614 + * @throws IllegalArgumentException if {@code permits} is negative
45.615 + */
45.616 + public void release(int permits) {
45.617 + if (permits < 0) throw new IllegalArgumentException();
45.618 + sync.releaseShared(permits);
45.619 + }
45.620 +
45.621 + /**
45.622 + * Returns the current number of permits available in this semaphore.
45.623 + *
45.624 + * <p>This method is typically used for debugging and testing purposes.
45.625 + *
45.626 + * @return the number of permits available in this semaphore
45.627 + */
45.628 + public int availablePermits() {
45.629 + return sync.getPermits();
45.630 + }
45.631 +
45.632 + /**
45.633 + * Acquires and returns all permits that are immediately available.
45.634 + *
45.635 + * @return the number of permits acquired
45.636 + */
45.637 + public int drainPermits() {
45.638 + return sync.drainPermits();
45.639 + }
45.640 +
45.641 + /**
45.642 + * Shrinks the number of available permits by the indicated
45.643 + * reduction. This method can be useful in subclasses that use
45.644 + * semaphores to track resources that become unavailable. This
45.645 + * method differs from {@code acquire} in that it does not block
45.646 + * waiting for permits to become available.
45.647 + *
45.648 + * @param reduction the number of permits to remove
45.649 + * @throws IllegalArgumentException if {@code reduction} is negative
45.650 + */
45.651 + protected void reducePermits(int reduction) {
45.652 + if (reduction < 0) throw new IllegalArgumentException();
45.653 + sync.reducePermits(reduction);
45.654 + }
45.655 +
45.656 + /**
45.657 + * Returns {@code true} if this semaphore has fairness set true.
45.658 + *
45.659 + * @return {@code true} if this semaphore has fairness set true
45.660 + */
45.661 + public boolean isFair() {
45.662 + return sync instanceof FairSync;
45.663 + }
45.664 +
45.665 + /**
45.666 + * Queries whether any threads are waiting to acquire. Note that
45.667 + * because cancellations may occur at any time, a {@code true}
45.668 + * return does not guarantee that any other thread will ever
45.669 + * acquire. This method is designed primarily for use in
45.670 + * monitoring of the system state.
45.671 + *
45.672 + * @return {@code true} if there may be other threads waiting to
45.673 + * acquire the lock
45.674 + */
45.675 + public final boolean hasQueuedThreads() {
45.676 + return sync.hasQueuedThreads();
45.677 + }
45.678 +
45.679 + /**
45.680 + * Returns an estimate of the number of threads waiting to acquire.
45.681 + * The value is only an estimate because the number of threads may
45.682 + * change dynamically while this method traverses internal data
45.683 + * structures. This method is designed for use in monitoring of the
45.684 + * system state, not for synchronization control.
45.685 + *
45.686 + * @return the estimated number of threads waiting for this lock
45.687 + */
45.688 + public final int getQueueLength() {
45.689 + return sync.getQueueLength();
45.690 + }
45.691 +
45.692 + /**
45.693 + * Returns a collection containing threads that may be waiting to acquire.
45.694 + * Because the actual set of threads may change dynamically while
45.695 + * constructing this result, the returned collection is only a best-effort
45.696 + * estimate. The elements of the returned collection are in no particular
45.697 + * order. This method is designed to facilitate construction of
45.698 + * subclasses that provide more extensive monitoring facilities.
45.699 + *
45.700 + * @return the collection of threads
45.701 + */
45.702 + protected Collection<Thread> getQueuedThreads() {
45.703 + return sync.getQueuedThreads();
45.704 + }
45.705 +
45.706 + /**
45.707 + * Returns a string identifying this semaphore, as well as its state.
45.708 + * The state, in brackets, includes the String {@code "Permits ="}
45.709 + * followed by the number of permits.
45.710 + *
45.711 + * @return a string identifying this semaphore, as well as its state
45.712 + */
45.713 + public String toString() {
45.714 + return super.toString() + "[Permits = " + sync.getPermits() + "]";
45.715 + }
45.716 +}
46.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
46.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/SynchronousQueue.java Sat Mar 19 10:46:31 2016 +0100
46.3 @@ -0,0 +1,1196 @@
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, Bill Scherer, and Michael Scott with
46.35 + * assistance from members of JCP JSR-166 Expert Group and released to
46.36 + * the public domain, as explained at
46.37 + * http://creativecommons.org/publicdomain/zero/1.0/
46.38 + */
46.39 +
46.40 +package java.util.concurrent;
46.41 +import java.util.concurrent.locks.*;
46.42 +import java.util.concurrent.atomic.*;
46.43 +import java.util.*;
46.44 +
46.45 +/**
46.46 + * A {@linkplain BlockingQueue blocking queue} in which each insert
46.47 + * operation must wait for a corresponding remove operation by another
46.48 + * thread, and vice versa. A synchronous queue does not have any
46.49 + * internal capacity, not even a capacity of one. You cannot
46.50 + * <tt>peek</tt> at a synchronous queue because an element is only
46.51 + * present when you try to remove it; you cannot insert an element
46.52 + * (using any method) unless another thread is trying to remove it;
46.53 + * you cannot iterate as there is nothing to iterate. The
46.54 + * <em>head</em> of the queue is the element that the first queued
46.55 + * inserting thread is trying to add to the queue; if there is no such
46.56 + * queued thread then no element is available for removal and
46.57 + * <tt>poll()</tt> will return <tt>null</tt>. For purposes of other
46.58 + * <tt>Collection</tt> methods (for example <tt>contains</tt>), a
46.59 + * <tt>SynchronousQueue</tt> acts as an empty collection. This queue
46.60 + * does not permit <tt>null</tt> elements.
46.61 + *
46.62 + * <p>Synchronous queues are similar to rendezvous channels used in
46.63 + * CSP and Ada. They are well suited for handoff designs, in which an
46.64 + * object running in one thread must sync up with an object running
46.65 + * in another thread in order to hand it some information, event, or
46.66 + * task.
46.67 + *
46.68 + * <p> This class supports an optional fairness policy for ordering
46.69 + * waiting producer and consumer threads. By default, this ordering
46.70 + * is not guaranteed. However, a queue constructed with fairness set
46.71 + * to <tt>true</tt> grants threads access in FIFO order.
46.72 + *
46.73 + * <p>This class and its iterator implement all of the
46.74 + * <em>optional</em> methods of the {@link Collection} and {@link
46.75 + * Iterator} interfaces.
46.76 + *
46.77 + * <p>This class is a member of the
46.78 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
46.79 + * Java Collections Framework</a>.
46.80 + *
46.81 + * @since 1.5
46.82 + * @author Doug Lea and Bill Scherer and Michael Scott
46.83 + * @param <E> the type of elements held in this collection
46.84 + */
46.85 +public class SynchronousQueue<E> extends AbstractQueue<E>
46.86 + implements BlockingQueue<E>, java.io.Serializable {
46.87 + private static final long serialVersionUID = -3223113410248163686L;
46.88 +
46.89 + /*
46.90 + * This class implements extensions of the dual stack and dual
46.91 + * queue algorithms described in "Nonblocking Concurrent Objects
46.92 + * with Condition Synchronization", by W. N. Scherer III and
46.93 + * M. L. Scott. 18th Annual Conf. on Distributed Computing,
46.94 + * Oct. 2004 (see also
46.95 + * http://www.cs.rochester.edu/u/scott/synchronization/pseudocode/duals.html).
46.96 + * The (Lifo) stack is used for non-fair mode, and the (Fifo)
46.97 + * queue for fair mode. The performance of the two is generally
46.98 + * similar. Fifo usually supports higher throughput under
46.99 + * contention but Lifo maintains higher thread locality in common
46.100 + * applications.
46.101 + *
46.102 + * A dual queue (and similarly stack) is one that at any given
46.103 + * time either holds "data" -- items provided by put operations,
46.104 + * or "requests" -- slots representing take operations, or is
46.105 + * empty. A call to "fulfill" (i.e., a call requesting an item
46.106 + * from a queue holding data or vice versa) dequeues a
46.107 + * complementary node. The most interesting feature of these
46.108 + * queues is that any operation can figure out which mode the
46.109 + * queue is in, and act accordingly without needing locks.
46.110 + *
46.111 + * Both the queue and stack extend abstract class Transferer
46.112 + * defining the single method transfer that does a put or a
46.113 + * take. These are unified into a single method because in dual
46.114 + * data structures, the put and take operations are symmetrical,
46.115 + * so nearly all code can be combined. The resulting transfer
46.116 + * methods are on the long side, but are easier to follow than
46.117 + * they would be if broken up into nearly-duplicated parts.
46.118 + *
46.119 + * The queue and stack data structures share many conceptual
46.120 + * similarities but very few concrete details. For simplicity,
46.121 + * they are kept distinct so that they can later evolve
46.122 + * separately.
46.123 + *
46.124 + * The algorithms here differ from the versions in the above paper
46.125 + * in extending them for use in synchronous queues, as well as
46.126 + * dealing with cancellation. The main differences include:
46.127 + *
46.128 + * 1. The original algorithms used bit-marked pointers, but
46.129 + * the ones here use mode bits in nodes, leading to a number
46.130 + * of further adaptations.
46.131 + * 2. SynchronousQueues must block threads waiting to become
46.132 + * fulfilled.
46.133 + * 3. Support for cancellation via timeout and interrupts,
46.134 + * including cleaning out cancelled nodes/threads
46.135 + * from lists to avoid garbage retention and memory depletion.
46.136 + *
46.137 + * Blocking is mainly accomplished using LockSupport park/unpark,
46.138 + * except that nodes that appear to be the next ones to become
46.139 + * fulfilled first spin a bit (on multiprocessors only). On very
46.140 + * busy synchronous queues, spinning can dramatically improve
46.141 + * throughput. And on less busy ones, the amount of spinning is
46.142 + * small enough not to be noticeable.
46.143 + *
46.144 + * Cleaning is done in different ways in queues vs stacks. For
46.145 + * queues, we can almost always remove a node immediately in O(1)
46.146 + * time (modulo retries for consistency checks) when it is
46.147 + * cancelled. But if it may be pinned as the current tail, it must
46.148 + * wait until some subsequent cancellation. For stacks, we need a
46.149 + * potentially O(n) traversal to be sure that we can remove the
46.150 + * node, but this can run concurrently with other threads
46.151 + * accessing the stack.
46.152 + *
46.153 + * While garbage collection takes care of most node reclamation
46.154 + * issues that otherwise complicate nonblocking algorithms, care
46.155 + * is taken to "forget" references to data, other nodes, and
46.156 + * threads that might be held on to long-term by blocked
46.157 + * threads. In cases where setting to null would otherwise
46.158 + * conflict with main algorithms, this is done by changing a
46.159 + * node's link to now point to the node itself. This doesn't arise
46.160 + * much for Stack nodes (because blocked threads do not hang on to
46.161 + * old head pointers), but references in Queue nodes must be
46.162 + * aggressively forgotten to avoid reachability of everything any
46.163 + * node has ever referred to since arrival.
46.164 + */
46.165 +
46.166 + /**
46.167 + * Shared internal API for dual stacks and queues.
46.168 + */
46.169 + abstract static class Transferer {
46.170 + /**
46.171 + * Performs a put or take.
46.172 + *
46.173 + * @param e if non-null, the item to be handed to a consumer;
46.174 + * if null, requests that transfer return an item
46.175 + * offered by producer.
46.176 + * @param timed if this operation should timeout
46.177 + * @param nanos the timeout, in nanoseconds
46.178 + * @return if non-null, the item provided or received; if null,
46.179 + * the operation failed due to timeout or interrupt --
46.180 + * the caller can distinguish which of these occurred
46.181 + * by checking Thread.interrupted.
46.182 + */
46.183 + abstract Object transfer(Object e, boolean timed, long nanos);
46.184 + }
46.185 +
46.186 + /** The number of CPUs, for spin control */
46.187 + static final int NCPUS = Runtime.getRuntime().availableProcessors();
46.188 +
46.189 + /**
46.190 + * The number of times to spin before blocking in timed waits.
46.191 + * The value is empirically derived -- it works well across a
46.192 + * variety of processors and OSes. Empirically, the best value
46.193 + * seems not to vary with number of CPUs (beyond 2) so is just
46.194 + * a constant.
46.195 + */
46.196 + static final int maxTimedSpins = (NCPUS < 2) ? 0 : 32;
46.197 +
46.198 + /**
46.199 + * The number of times to spin before blocking in untimed waits.
46.200 + * This is greater than timed value because untimed waits spin
46.201 + * faster since they don't need to check times on each spin.
46.202 + */
46.203 + static final int maxUntimedSpins = maxTimedSpins * 16;
46.204 +
46.205 + /**
46.206 + * The number of nanoseconds for which it is faster to spin
46.207 + * rather than to use timed park. A rough estimate suffices.
46.208 + */
46.209 + static final long spinForTimeoutThreshold = 1000L;
46.210 +
46.211 + /** Dual stack */
46.212 + static final class TransferStack extends Transferer {
46.213 + /*
46.214 + * This extends Scherer-Scott dual stack algorithm, differing,
46.215 + * among other ways, by using "covering" nodes rather than
46.216 + * bit-marked pointers: Fulfilling operations push on marker
46.217 + * nodes (with FULFILLING bit set in mode) to reserve a spot
46.218 + * to match a waiting node.
46.219 + */
46.220 +
46.221 + /* Modes for SNodes, ORed together in node fields */
46.222 + /** Node represents an unfulfilled consumer */
46.223 + static final int REQUEST = 0;
46.224 + /** Node represents an unfulfilled producer */
46.225 + static final int DATA = 1;
46.226 + /** Node is fulfilling another unfulfilled DATA or REQUEST */
46.227 + static final int FULFILLING = 2;
46.228 +
46.229 + /** Return true if m has fulfilling bit set */
46.230 + static boolean isFulfilling(int m) { return (m & FULFILLING) != 0; }
46.231 +
46.232 + /** Node class for TransferStacks. */
46.233 + static final class SNode {
46.234 + volatile SNode next; // next node in stack
46.235 + volatile SNode match; // the node matched to this
46.236 + volatile Thread waiter; // to control park/unpark
46.237 + Object item; // data; or null for REQUESTs
46.238 + int mode;
46.239 + // Note: item and mode fields don't need to be volatile
46.240 + // since they are always written before, and read after,
46.241 + // other volatile/atomic operations.
46.242 +
46.243 + SNode(Object item) {
46.244 + this.item = item;
46.245 + }
46.246 +
46.247 + boolean casNext(SNode cmp, SNode val) {
46.248 + return cmp == next &&
46.249 + UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
46.250 + }
46.251 +
46.252 + /**
46.253 + * Tries to match node s to this node, if so, waking up thread.
46.254 + * Fulfillers call tryMatch to identify their waiters.
46.255 + * Waiters block until they have been matched.
46.256 + *
46.257 + * @param s the node to match
46.258 + * @return true if successfully matched to s
46.259 + */
46.260 + boolean tryMatch(SNode s) {
46.261 + if (match == null &&
46.262 + UNSAFE.compareAndSwapObject(this, matchOffset, null, s)) {
46.263 + Thread w = waiter;
46.264 + if (w != null) { // waiters need at most one unpark
46.265 + waiter = null;
46.266 + LockSupport.unpark(w);
46.267 + }
46.268 + return true;
46.269 + }
46.270 + return match == s;
46.271 + }
46.272 +
46.273 + /**
46.274 + * Tries to cancel a wait by matching node to itself.
46.275 + */
46.276 + void tryCancel() {
46.277 + UNSAFE.compareAndSwapObject(this, matchOffset, null, this);
46.278 + }
46.279 +
46.280 + boolean isCancelled() {
46.281 + return match == this;
46.282 + }
46.283 +
46.284 + // Unsafe mechanics
46.285 + private static final sun.misc.Unsafe UNSAFE;
46.286 + private static final long matchOffset;
46.287 + private static final long nextOffset;
46.288 +
46.289 + static {
46.290 + try {
46.291 + UNSAFE = sun.misc.Unsafe.getUnsafe();
46.292 + Class k = SNode.class;
46.293 + matchOffset = UNSAFE.objectFieldOffset
46.294 + (k.getDeclaredField("match"));
46.295 + nextOffset = UNSAFE.objectFieldOffset
46.296 + (k.getDeclaredField("next"));
46.297 + } catch (Exception e) {
46.298 + throw new Error(e);
46.299 + }
46.300 + }
46.301 + }
46.302 +
46.303 + /** The head (top) of the stack */
46.304 + volatile SNode head;
46.305 +
46.306 + boolean casHead(SNode h, SNode nh) {
46.307 + return h == head &&
46.308 + UNSAFE.compareAndSwapObject(this, headOffset, h, nh);
46.309 + }
46.310 +
46.311 + /**
46.312 + * Creates or resets fields of a node. Called only from transfer
46.313 + * where the node to push on stack is lazily created and
46.314 + * reused when possible to help reduce intervals between reads
46.315 + * and CASes of head and to avoid surges of garbage when CASes
46.316 + * to push nodes fail due to contention.
46.317 + */
46.318 + static SNode snode(SNode s, Object e, SNode next, int mode) {
46.319 + if (s == null) s = new SNode(e);
46.320 + s.mode = mode;
46.321 + s.next = next;
46.322 + return s;
46.323 + }
46.324 +
46.325 + /**
46.326 + * Puts or takes an item.
46.327 + */
46.328 + Object transfer(Object e, boolean timed, long nanos) {
46.329 + /*
46.330 + * Basic algorithm is to loop trying one of three actions:
46.331 + *
46.332 + * 1. If apparently empty or already containing nodes of same
46.333 + * mode, try to push node on stack and wait for a match,
46.334 + * returning it, or null if cancelled.
46.335 + *
46.336 + * 2. If apparently containing node of complementary mode,
46.337 + * try to push a fulfilling node on to stack, match
46.338 + * with corresponding waiting node, pop both from
46.339 + * stack, and return matched item. The matching or
46.340 + * unlinking might not actually be necessary because of
46.341 + * other threads performing action 3:
46.342 + *
46.343 + * 3. If top of stack already holds another fulfilling node,
46.344 + * help it out by doing its match and/or pop
46.345 + * operations, and then continue. The code for helping
46.346 + * is essentially the same as for fulfilling, except
46.347 + * that it doesn't return the item.
46.348 + */
46.349 +
46.350 + SNode s = null; // constructed/reused as needed
46.351 + int mode = (e == null) ? REQUEST : DATA;
46.352 +
46.353 + for (;;) {
46.354 + SNode h = head;
46.355 + if (h == null || h.mode == mode) { // empty or same-mode
46.356 + if (timed && nanos <= 0) { // can't wait
46.357 + if (h != null && h.isCancelled())
46.358 + casHead(h, h.next); // pop cancelled node
46.359 + else
46.360 + return null;
46.361 + } else if (casHead(h, s = snode(s, e, h, mode))) {
46.362 + SNode m = awaitFulfill(s, timed, nanos);
46.363 + if (m == s) { // wait was cancelled
46.364 + clean(s);
46.365 + return null;
46.366 + }
46.367 + if ((h = head) != null && h.next == s)
46.368 + casHead(h, s.next); // help s's fulfiller
46.369 + return (mode == REQUEST) ? m.item : s.item;
46.370 + }
46.371 + } else if (!isFulfilling(h.mode)) { // try to fulfill
46.372 + if (h.isCancelled()) // already cancelled
46.373 + casHead(h, h.next); // pop and retry
46.374 + else if (casHead(h, s=snode(s, e, h, FULFILLING|mode))) {
46.375 + for (;;) { // loop until matched or waiters disappear
46.376 + SNode m = s.next; // m is s's match
46.377 + if (m == null) { // all waiters are gone
46.378 + casHead(s, null); // pop fulfill node
46.379 + s = null; // use new node next time
46.380 + break; // restart main loop
46.381 + }
46.382 + SNode mn = m.next;
46.383 + if (m.tryMatch(s)) {
46.384 + casHead(s, mn); // pop both s and m
46.385 + return (mode == REQUEST) ? m.item : s.item;
46.386 + } else // lost match
46.387 + s.casNext(m, mn); // help unlink
46.388 + }
46.389 + }
46.390 + } else { // help a fulfiller
46.391 + SNode m = h.next; // m is h's match
46.392 + if (m == null) // waiter is gone
46.393 + casHead(h, null); // pop fulfilling node
46.394 + else {
46.395 + SNode mn = m.next;
46.396 + if (m.tryMatch(h)) // help match
46.397 + casHead(h, mn); // pop both h and m
46.398 + else // lost match
46.399 + h.casNext(m, mn); // help unlink
46.400 + }
46.401 + }
46.402 + }
46.403 + }
46.404 +
46.405 + /**
46.406 + * Spins/blocks until node s is matched by a fulfill operation.
46.407 + *
46.408 + * @param s the waiting node
46.409 + * @param timed true if timed wait
46.410 + * @param nanos timeout value
46.411 + * @return matched node, or s if cancelled
46.412 + */
46.413 + SNode awaitFulfill(SNode s, boolean timed, long nanos) {
46.414 + /*
46.415 + * When a node/thread is about to block, it sets its waiter
46.416 + * field and then rechecks state at least one more time
46.417 + * before actually parking, thus covering race vs
46.418 + * fulfiller noticing that waiter is non-null so should be
46.419 + * woken.
46.420 + *
46.421 + * When invoked by nodes that appear at the point of call
46.422 + * to be at the head of the stack, calls to park are
46.423 + * preceded by spins to avoid blocking when producers and
46.424 + * consumers are arriving very close in time. This can
46.425 + * happen enough to bother only on multiprocessors.
46.426 + *
46.427 + * The order of checks for returning out of main loop
46.428 + * reflects fact that interrupts have precedence over
46.429 + * normal returns, which have precedence over
46.430 + * timeouts. (So, on timeout, one last check for match is
46.431 + * done before giving up.) Except that calls from untimed
46.432 + * SynchronousQueue.{poll/offer} don't check interrupts
46.433 + * and don't wait at all, so are trapped in transfer
46.434 + * method rather than calling awaitFulfill.
46.435 + */
46.436 + long lastTime = timed ? System.nanoTime() : 0;
46.437 + Thread w = Thread.currentThread();
46.438 + SNode h = head;
46.439 + int spins = (shouldSpin(s) ?
46.440 + (timed ? maxTimedSpins : maxUntimedSpins) : 0);
46.441 + for (;;) {
46.442 + if (w.isInterrupted())
46.443 + s.tryCancel();
46.444 + SNode m = s.match;
46.445 + if (m != null)
46.446 + return m;
46.447 + if (timed) {
46.448 + long now = System.nanoTime();
46.449 + nanos -= now - lastTime;
46.450 + lastTime = now;
46.451 + if (nanos <= 0) {
46.452 + s.tryCancel();
46.453 + continue;
46.454 + }
46.455 + }
46.456 + if (spins > 0)
46.457 + spins = shouldSpin(s) ? (spins-1) : 0;
46.458 + else if (s.waiter == null)
46.459 + s.waiter = w; // establish waiter so can park next iter
46.460 + else if (!timed)
46.461 + LockSupport.park(this);
46.462 + else if (nanos > spinForTimeoutThreshold)
46.463 + LockSupport.parkNanos(this, nanos);
46.464 + }
46.465 + }
46.466 +
46.467 + /**
46.468 + * Returns true if node s is at head or there is an active
46.469 + * fulfiller.
46.470 + */
46.471 + boolean shouldSpin(SNode s) {
46.472 + SNode h = head;
46.473 + return (h == s || h == null || isFulfilling(h.mode));
46.474 + }
46.475 +
46.476 + /**
46.477 + * Unlinks s from the stack.
46.478 + */
46.479 + void clean(SNode s) {
46.480 + s.item = null; // forget item
46.481 + s.waiter = null; // forget thread
46.482 +
46.483 + /*
46.484 + * At worst we may need to traverse entire stack to unlink
46.485 + * s. If there are multiple concurrent calls to clean, we
46.486 + * might not see s if another thread has already removed
46.487 + * it. But we can stop when we see any node known to
46.488 + * follow s. We use s.next unless it too is cancelled, in
46.489 + * which case we try the node one past. We don't check any
46.490 + * further because we don't want to doubly traverse just to
46.491 + * find sentinel.
46.492 + */
46.493 +
46.494 + SNode past = s.next;
46.495 + if (past != null && past.isCancelled())
46.496 + past = past.next;
46.497 +
46.498 + // Absorb cancelled nodes at head
46.499 + SNode p;
46.500 + while ((p = head) != null && p != past && p.isCancelled())
46.501 + casHead(p, p.next);
46.502 +
46.503 + // Unsplice embedded nodes
46.504 + while (p != null && p != past) {
46.505 + SNode n = p.next;
46.506 + if (n != null && n.isCancelled())
46.507 + p.casNext(n, n.next);
46.508 + else
46.509 + p = n;
46.510 + }
46.511 + }
46.512 +
46.513 + // Unsafe mechanics
46.514 + private static final sun.misc.Unsafe UNSAFE;
46.515 + private static final long headOffset;
46.516 + static {
46.517 + try {
46.518 + UNSAFE = sun.misc.Unsafe.getUnsafe();
46.519 + Class k = TransferStack.class;
46.520 + headOffset = UNSAFE.objectFieldOffset
46.521 + (k.getDeclaredField("head"));
46.522 + } catch (Exception e) {
46.523 + throw new Error(e);
46.524 + }
46.525 + }
46.526 + }
46.527 +
46.528 + /** Dual Queue */
46.529 + static final class TransferQueue extends Transferer {
46.530 + /*
46.531 + * This extends Scherer-Scott dual queue algorithm, differing,
46.532 + * among other ways, by using modes within nodes rather than
46.533 + * marked pointers. The algorithm is a little simpler than
46.534 + * that for stacks because fulfillers do not need explicit
46.535 + * nodes, and matching is done by CAS'ing QNode.item field
46.536 + * from non-null to null (for put) or vice versa (for take).
46.537 + */
46.538 +
46.539 + /** Node class for TransferQueue. */
46.540 + static final class QNode {
46.541 + volatile QNode next; // next node in queue
46.542 + volatile Object item; // CAS'ed to or from null
46.543 + volatile Thread waiter; // to control park/unpark
46.544 + final boolean isData;
46.545 +
46.546 + QNode(Object item, boolean isData) {
46.547 + this.item = item;
46.548 + this.isData = isData;
46.549 + }
46.550 +
46.551 + boolean casNext(QNode cmp, QNode val) {
46.552 + return next == cmp &&
46.553 + UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
46.554 + }
46.555 +
46.556 + boolean casItem(Object cmp, Object val) {
46.557 + return item == cmp &&
46.558 + UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);
46.559 + }
46.560 +
46.561 + /**
46.562 + * Tries to cancel by CAS'ing ref to this as item.
46.563 + */
46.564 + void tryCancel(Object cmp) {
46.565 + UNSAFE.compareAndSwapObject(this, itemOffset, cmp, this);
46.566 + }
46.567 +
46.568 + boolean isCancelled() {
46.569 + return item == this;
46.570 + }
46.571 +
46.572 + /**
46.573 + * Returns true if this node is known to be off the queue
46.574 + * because its next pointer has been forgotten due to
46.575 + * an advanceHead operation.
46.576 + */
46.577 + boolean isOffList() {
46.578 + return next == this;
46.579 + }
46.580 +
46.581 + // Unsafe mechanics
46.582 + private static final sun.misc.Unsafe UNSAFE;
46.583 + private static final long itemOffset;
46.584 + private static final long nextOffset;
46.585 +
46.586 + static {
46.587 + try {
46.588 + UNSAFE = sun.misc.Unsafe.getUnsafe();
46.589 + Class k = QNode.class;
46.590 + itemOffset = UNSAFE.objectFieldOffset
46.591 + (k.getDeclaredField("item"));
46.592 + nextOffset = UNSAFE.objectFieldOffset
46.593 + (k.getDeclaredField("next"));
46.594 + } catch (Exception e) {
46.595 + throw new Error(e);
46.596 + }
46.597 + }
46.598 + }
46.599 +
46.600 + /** Head of queue */
46.601 + transient volatile QNode head;
46.602 + /** Tail of queue */
46.603 + transient volatile QNode tail;
46.604 + /**
46.605 + * Reference to a cancelled node that might not yet have been
46.606 + * unlinked from queue because it was the last inserted node
46.607 + * when it cancelled.
46.608 + */
46.609 + transient volatile QNode cleanMe;
46.610 +
46.611 + TransferQueue() {
46.612 + QNode h = new QNode(null, false); // initialize to dummy node.
46.613 + head = h;
46.614 + tail = h;
46.615 + }
46.616 +
46.617 + /**
46.618 + * Tries to cas nh as new head; if successful, unlink
46.619 + * old head's next node to avoid garbage retention.
46.620 + */
46.621 + void advanceHead(QNode h, QNode nh) {
46.622 + if (h == head &&
46.623 + UNSAFE.compareAndSwapObject(this, headOffset, h, nh))
46.624 + h.next = h; // forget old next
46.625 + }
46.626 +
46.627 + /**
46.628 + * Tries to cas nt as new tail.
46.629 + */
46.630 + void advanceTail(QNode t, QNode nt) {
46.631 + if (tail == t)
46.632 + UNSAFE.compareAndSwapObject(this, tailOffset, t, nt);
46.633 + }
46.634 +
46.635 + /**
46.636 + * Tries to CAS cleanMe slot.
46.637 + */
46.638 + boolean casCleanMe(QNode cmp, QNode val) {
46.639 + return cleanMe == cmp &&
46.640 + UNSAFE.compareAndSwapObject(this, cleanMeOffset, cmp, val);
46.641 + }
46.642 +
46.643 + /**
46.644 + * Puts or takes an item.
46.645 + */
46.646 + Object transfer(Object e, boolean timed, long nanos) {
46.647 + /* Basic algorithm is to loop trying to take either of
46.648 + * two actions:
46.649 + *
46.650 + * 1. If queue apparently empty or holding same-mode nodes,
46.651 + * try to add node to queue of waiters, wait to be
46.652 + * fulfilled (or cancelled) and return matching item.
46.653 + *
46.654 + * 2. If queue apparently contains waiting items, and this
46.655 + * call is of complementary mode, try to fulfill by CAS'ing
46.656 + * item field of waiting node and dequeuing it, and then
46.657 + * returning matching item.
46.658 + *
46.659 + * In each case, along the way, check for and try to help
46.660 + * advance head and tail on behalf of other stalled/slow
46.661 + * threads.
46.662 + *
46.663 + * The loop starts off with a null check guarding against
46.664 + * seeing uninitialized head or tail values. This never
46.665 + * happens in current SynchronousQueue, but could if
46.666 + * callers held non-volatile/final ref to the
46.667 + * transferer. The check is here anyway because it places
46.668 + * null checks at top of loop, which is usually faster
46.669 + * than having them implicitly interspersed.
46.670 + */
46.671 +
46.672 + QNode s = null; // constructed/reused as needed
46.673 + boolean isData = (e != null);
46.674 +
46.675 + for (;;) {
46.676 + QNode t = tail;
46.677 + QNode h = head;
46.678 + if (t == null || h == null) // saw uninitialized value
46.679 + continue; // spin
46.680 +
46.681 + if (h == t || t.isData == isData) { // empty or same-mode
46.682 + QNode tn = t.next;
46.683 + if (t != tail) // inconsistent read
46.684 + continue;
46.685 + if (tn != null) { // lagging tail
46.686 + advanceTail(t, tn);
46.687 + continue;
46.688 + }
46.689 + if (timed && nanos <= 0) // can't wait
46.690 + return null;
46.691 + if (s == null)
46.692 + s = new QNode(e, isData);
46.693 + if (!t.casNext(null, s)) // failed to link in
46.694 + continue;
46.695 +
46.696 + advanceTail(t, s); // swing tail and wait
46.697 + Object x = awaitFulfill(s, e, timed, nanos);
46.698 + if (x == s) { // wait was cancelled
46.699 + clean(t, s);
46.700 + return null;
46.701 + }
46.702 +
46.703 + if (!s.isOffList()) { // not already unlinked
46.704 + advanceHead(t, s); // unlink if head
46.705 + if (x != null) // and forget fields
46.706 + s.item = s;
46.707 + s.waiter = null;
46.708 + }
46.709 + return (x != null) ? x : e;
46.710 +
46.711 + } else { // complementary-mode
46.712 + QNode m = h.next; // node to fulfill
46.713 + if (t != tail || m == null || h != head)
46.714 + continue; // inconsistent read
46.715 +
46.716 + Object x = m.item;
46.717 + if (isData == (x != null) || // m already fulfilled
46.718 + x == m || // m cancelled
46.719 + !m.casItem(x, e)) { // lost CAS
46.720 + advanceHead(h, m); // dequeue and retry
46.721 + continue;
46.722 + }
46.723 +
46.724 + advanceHead(h, m); // successfully fulfilled
46.725 + LockSupport.unpark(m.waiter);
46.726 + return (x != null) ? x : e;
46.727 + }
46.728 + }
46.729 + }
46.730 +
46.731 + /**
46.732 + * Spins/blocks until node s is fulfilled.
46.733 + *
46.734 + * @param s the waiting node
46.735 + * @param e the comparison value for checking match
46.736 + * @param timed true if timed wait
46.737 + * @param nanos timeout value
46.738 + * @return matched item, or s if cancelled
46.739 + */
46.740 + Object awaitFulfill(QNode s, Object e, boolean timed, long nanos) {
46.741 + /* Same idea as TransferStack.awaitFulfill */
46.742 + long lastTime = timed ? System.nanoTime() : 0;
46.743 + Thread w = Thread.currentThread();
46.744 + int spins = ((head.next == s) ?
46.745 + (timed ? maxTimedSpins : maxUntimedSpins) : 0);
46.746 + for (;;) {
46.747 + if (w.isInterrupted())
46.748 + s.tryCancel(e);
46.749 + Object x = s.item;
46.750 + if (x != e)
46.751 + return x;
46.752 + if (timed) {
46.753 + long now = System.nanoTime();
46.754 + nanos -= now - lastTime;
46.755 + lastTime = now;
46.756 + if (nanos <= 0) {
46.757 + s.tryCancel(e);
46.758 + continue;
46.759 + }
46.760 + }
46.761 + if (spins > 0)
46.762 + --spins;
46.763 + else if (s.waiter == null)
46.764 + s.waiter = w;
46.765 + else if (!timed)
46.766 + LockSupport.park(this);
46.767 + else if (nanos > spinForTimeoutThreshold)
46.768 + LockSupport.parkNanos(this, nanos);
46.769 + }
46.770 + }
46.771 +
46.772 + /**
46.773 + * Gets rid of cancelled node s with original predecessor pred.
46.774 + */
46.775 + void clean(QNode pred, QNode s) {
46.776 + s.waiter = null; // forget thread
46.777 + /*
46.778 + * At any given time, exactly one node on list cannot be
46.779 + * deleted -- the last inserted node. To accommodate this,
46.780 + * if we cannot delete s, we save its predecessor as
46.781 + * "cleanMe", deleting the previously saved version
46.782 + * first. At least one of node s or the node previously
46.783 + * saved can always be deleted, so this always terminates.
46.784 + */
46.785 + while (pred.next == s) { // Return early if already unlinked
46.786 + QNode h = head;
46.787 + QNode hn = h.next; // Absorb cancelled first node as head
46.788 + if (hn != null && hn.isCancelled()) {
46.789 + advanceHead(h, hn);
46.790 + continue;
46.791 + }
46.792 + QNode t = tail; // Ensure consistent read for tail
46.793 + if (t == h)
46.794 + return;
46.795 + QNode tn = t.next;
46.796 + if (t != tail)
46.797 + continue;
46.798 + if (tn != null) {
46.799 + advanceTail(t, tn);
46.800 + continue;
46.801 + }
46.802 + if (s != t) { // If not tail, try to unsplice
46.803 + QNode sn = s.next;
46.804 + if (sn == s || pred.casNext(s, sn))
46.805 + return;
46.806 + }
46.807 + QNode dp = cleanMe;
46.808 + if (dp != null) { // Try unlinking previous cancelled node
46.809 + QNode d = dp.next;
46.810 + QNode dn;
46.811 + if (d == null || // d is gone or
46.812 + d == dp || // d is off list or
46.813 + !d.isCancelled() || // d not cancelled or
46.814 + (d != t && // d not tail and
46.815 + (dn = d.next) != null && // has successor
46.816 + dn != d && // that is on list
46.817 + dp.casNext(d, dn))) // d unspliced
46.818 + casCleanMe(dp, null);
46.819 + if (dp == pred)
46.820 + return; // s is already saved node
46.821 + } else if (casCleanMe(null, pred))
46.822 + return; // Postpone cleaning s
46.823 + }
46.824 + }
46.825 +
46.826 + private static final sun.misc.Unsafe UNSAFE;
46.827 + private static final long headOffset;
46.828 + private static final long tailOffset;
46.829 + private static final long cleanMeOffset;
46.830 + static {
46.831 + try {
46.832 + UNSAFE = sun.misc.Unsafe.getUnsafe();
46.833 + Class k = TransferQueue.class;
46.834 + headOffset = UNSAFE.objectFieldOffset
46.835 + (k.getDeclaredField("head"));
46.836 + tailOffset = UNSAFE.objectFieldOffset
46.837 + (k.getDeclaredField("tail"));
46.838 + cleanMeOffset = UNSAFE.objectFieldOffset
46.839 + (k.getDeclaredField("cleanMe"));
46.840 + } catch (Exception e) {
46.841 + throw new Error(e);
46.842 + }
46.843 + }
46.844 + }
46.845 +
46.846 + /**
46.847 + * The transferer. Set only in constructor, but cannot be declared
46.848 + * as final without further complicating serialization. Since
46.849 + * this is accessed only at most once per public method, there
46.850 + * isn't a noticeable performance penalty for using volatile
46.851 + * instead of final here.
46.852 + */
46.853 + private transient volatile Transferer transferer;
46.854 +
46.855 + /**
46.856 + * Creates a <tt>SynchronousQueue</tt> with nonfair access policy.
46.857 + */
46.858 + public SynchronousQueue() {
46.859 + this(false);
46.860 + }
46.861 +
46.862 + /**
46.863 + * Creates a <tt>SynchronousQueue</tt> with the specified fairness policy.
46.864 + *
46.865 + * @param fair if true, waiting threads contend in FIFO order for
46.866 + * access; otherwise the order is unspecified.
46.867 + */
46.868 + public SynchronousQueue(boolean fair) {
46.869 + transferer = fair ? new TransferQueue() : new TransferStack();
46.870 + }
46.871 +
46.872 + /**
46.873 + * Adds the specified element to this queue, waiting if necessary for
46.874 + * another thread to receive it.
46.875 + *
46.876 + * @throws InterruptedException {@inheritDoc}
46.877 + * @throws NullPointerException {@inheritDoc}
46.878 + */
46.879 + public void put(E o) throws InterruptedException {
46.880 + if (o == null) throw new NullPointerException();
46.881 + if (transferer.transfer(o, false, 0) == null) {
46.882 + Thread.interrupted();
46.883 + throw new InterruptedException();
46.884 + }
46.885 + }
46.886 +
46.887 + /**
46.888 + * Inserts the specified element into this queue, waiting if necessary
46.889 + * up to the specified wait time for another thread to receive it.
46.890 + *
46.891 + * @return <tt>true</tt> if successful, or <tt>false</tt> if the
46.892 + * specified waiting time elapses before a consumer appears.
46.893 + * @throws InterruptedException {@inheritDoc}
46.894 + * @throws NullPointerException {@inheritDoc}
46.895 + */
46.896 + public boolean offer(E o, long timeout, TimeUnit unit)
46.897 + throws InterruptedException {
46.898 + if (o == null) throw new NullPointerException();
46.899 + if (transferer.transfer(o, true, unit.toNanos(timeout)) != null)
46.900 + return true;
46.901 + if (!Thread.interrupted())
46.902 + return false;
46.903 + throw new InterruptedException();
46.904 + }
46.905 +
46.906 + /**
46.907 + * Inserts the specified element into this queue, if another thread is
46.908 + * waiting to receive it.
46.909 + *
46.910 + * @param e the element to add
46.911 + * @return <tt>true</tt> if the element was added to this queue, else
46.912 + * <tt>false</tt>
46.913 + * @throws NullPointerException if the specified element is null
46.914 + */
46.915 + public boolean offer(E e) {
46.916 + if (e == null) throw new NullPointerException();
46.917 + return transferer.transfer(e, true, 0) != null;
46.918 + }
46.919 +
46.920 + /**
46.921 + * Retrieves and removes the head of this queue, waiting if necessary
46.922 + * for another thread to insert it.
46.923 + *
46.924 + * @return the head of this queue
46.925 + * @throws InterruptedException {@inheritDoc}
46.926 + */
46.927 + public E take() throws InterruptedException {
46.928 + Object e = transferer.transfer(null, false, 0);
46.929 + if (e != null)
46.930 + return (E)e;
46.931 + Thread.interrupted();
46.932 + throw new InterruptedException();
46.933 + }
46.934 +
46.935 + /**
46.936 + * Retrieves and removes the head of this queue, waiting
46.937 + * if necessary up to the specified wait time, for another thread
46.938 + * to insert it.
46.939 + *
46.940 + * @return the head of this queue, or <tt>null</tt> if the
46.941 + * specified waiting time elapses before an element is present.
46.942 + * @throws InterruptedException {@inheritDoc}
46.943 + */
46.944 + public E poll(long timeout, TimeUnit unit) throws InterruptedException {
46.945 + Object e = transferer.transfer(null, true, unit.toNanos(timeout));
46.946 + if (e != null || !Thread.interrupted())
46.947 + return (E)e;
46.948 + throw new InterruptedException();
46.949 + }
46.950 +
46.951 + /**
46.952 + * Retrieves and removes the head of this queue, if another thread
46.953 + * is currently making an element available.
46.954 + *
46.955 + * @return the head of this queue, or <tt>null</tt> if no
46.956 + * element is available.
46.957 + */
46.958 + public E poll() {
46.959 + return (E)transferer.transfer(null, true, 0);
46.960 + }
46.961 +
46.962 + /**
46.963 + * Always returns <tt>true</tt>.
46.964 + * A <tt>SynchronousQueue</tt> has no internal capacity.
46.965 + *
46.966 + * @return <tt>true</tt>
46.967 + */
46.968 + public boolean isEmpty() {
46.969 + return true;
46.970 + }
46.971 +
46.972 + /**
46.973 + * Always returns zero.
46.974 + * A <tt>SynchronousQueue</tt> has no internal capacity.
46.975 + *
46.976 + * @return zero.
46.977 + */
46.978 + public int size() {
46.979 + return 0;
46.980 + }
46.981 +
46.982 + /**
46.983 + * Always returns zero.
46.984 + * A <tt>SynchronousQueue</tt> has no internal capacity.
46.985 + *
46.986 + * @return zero.
46.987 + */
46.988 + public int remainingCapacity() {
46.989 + return 0;
46.990 + }
46.991 +
46.992 + /**
46.993 + * Does nothing.
46.994 + * A <tt>SynchronousQueue</tt> has no internal capacity.
46.995 + */
46.996 + public void clear() {
46.997 + }
46.998 +
46.999 + /**
46.1000 + * Always returns <tt>false</tt>.
46.1001 + * A <tt>SynchronousQueue</tt> has no internal capacity.
46.1002 + *
46.1003 + * @param o the element
46.1004 + * @return <tt>false</tt>
46.1005 + */
46.1006 + public boolean contains(Object o) {
46.1007 + return false;
46.1008 + }
46.1009 +
46.1010 + /**
46.1011 + * Always returns <tt>false</tt>.
46.1012 + * A <tt>SynchronousQueue</tt> has no internal capacity.
46.1013 + *
46.1014 + * @param o the element to remove
46.1015 + * @return <tt>false</tt>
46.1016 + */
46.1017 + public boolean remove(Object o) {
46.1018 + return false;
46.1019 + }
46.1020 +
46.1021 + /**
46.1022 + * Returns <tt>false</tt> unless the given collection is empty.
46.1023 + * A <tt>SynchronousQueue</tt> has no internal capacity.
46.1024 + *
46.1025 + * @param c the collection
46.1026 + * @return <tt>false</tt> unless given collection is empty
46.1027 + */
46.1028 + public boolean containsAll(Collection<?> c) {
46.1029 + return c.isEmpty();
46.1030 + }
46.1031 +
46.1032 + /**
46.1033 + * Always returns <tt>false</tt>.
46.1034 + * A <tt>SynchronousQueue</tt> has no internal capacity.
46.1035 + *
46.1036 + * @param c the collection
46.1037 + * @return <tt>false</tt>
46.1038 + */
46.1039 + public boolean removeAll(Collection<?> c) {
46.1040 + return false;
46.1041 + }
46.1042 +
46.1043 + /**
46.1044 + * Always returns <tt>false</tt>.
46.1045 + * A <tt>SynchronousQueue</tt> has no internal capacity.
46.1046 + *
46.1047 + * @param c the collection
46.1048 + * @return <tt>false</tt>
46.1049 + */
46.1050 + public boolean retainAll(Collection<?> c) {
46.1051 + return false;
46.1052 + }
46.1053 +
46.1054 + /**
46.1055 + * Always returns <tt>null</tt>.
46.1056 + * A <tt>SynchronousQueue</tt> does not return elements
46.1057 + * unless actively waited on.
46.1058 + *
46.1059 + * @return <tt>null</tt>
46.1060 + */
46.1061 + public E peek() {
46.1062 + return null;
46.1063 + }
46.1064 +
46.1065 + /**
46.1066 + * Returns an empty iterator in which <tt>hasNext</tt> always returns
46.1067 + * <tt>false</tt>.
46.1068 + *
46.1069 + * @return an empty iterator
46.1070 + */
46.1071 + public Iterator<E> iterator() {
46.1072 + return Collections.emptyIterator();
46.1073 + }
46.1074 +
46.1075 + /**
46.1076 + * Returns a zero-length array.
46.1077 + * @return a zero-length array
46.1078 + */
46.1079 + public Object[] toArray() {
46.1080 + return new Object[0];
46.1081 + }
46.1082 +
46.1083 + /**
46.1084 + * Sets the zeroeth element of the specified array to <tt>null</tt>
46.1085 + * (if the array has non-zero length) and returns it.
46.1086 + *
46.1087 + * @param a the array
46.1088 + * @return the specified array
46.1089 + * @throws NullPointerException if the specified array is null
46.1090 + */
46.1091 + public <T> T[] toArray(T[] a) {
46.1092 + if (a.length > 0)
46.1093 + a[0] = null;
46.1094 + return a;
46.1095 + }
46.1096 +
46.1097 + /**
46.1098 + * @throws UnsupportedOperationException {@inheritDoc}
46.1099 + * @throws ClassCastException {@inheritDoc}
46.1100 + * @throws NullPointerException {@inheritDoc}
46.1101 + * @throws IllegalArgumentException {@inheritDoc}
46.1102 + */
46.1103 + public int drainTo(Collection<? super E> c) {
46.1104 + if (c == null)
46.1105 + throw new NullPointerException();
46.1106 + if (c == this)
46.1107 + throw new IllegalArgumentException();
46.1108 + int n = 0;
46.1109 + E e;
46.1110 + while ( (e = poll()) != null) {
46.1111 + c.add(e);
46.1112 + ++n;
46.1113 + }
46.1114 + return n;
46.1115 + }
46.1116 +
46.1117 + /**
46.1118 + * @throws UnsupportedOperationException {@inheritDoc}
46.1119 + * @throws ClassCastException {@inheritDoc}
46.1120 + * @throws NullPointerException {@inheritDoc}
46.1121 + * @throws IllegalArgumentException {@inheritDoc}
46.1122 + */
46.1123 + public int drainTo(Collection<? super E> c, int maxElements) {
46.1124 + if (c == null)
46.1125 + throw new NullPointerException();
46.1126 + if (c == this)
46.1127 + throw new IllegalArgumentException();
46.1128 + int n = 0;
46.1129 + E e;
46.1130 + while (n < maxElements && (e = poll()) != null) {
46.1131 + c.add(e);
46.1132 + ++n;
46.1133 + }
46.1134 + return n;
46.1135 + }
46.1136 +
46.1137 + /*
46.1138 + * To cope with serialization strategy in the 1.5 version of
46.1139 + * SynchronousQueue, we declare some unused classes and fields
46.1140 + * that exist solely to enable serializability across versions.
46.1141 + * These fields are never used, so are initialized only if this
46.1142 + * object is ever serialized or deserialized.
46.1143 + */
46.1144 +
46.1145 + static class WaitQueue implements java.io.Serializable { }
46.1146 + static class LifoWaitQueue extends WaitQueue {
46.1147 + private static final long serialVersionUID = -3633113410248163686L;
46.1148 + }
46.1149 + static class FifoWaitQueue extends WaitQueue {
46.1150 + private static final long serialVersionUID = -3623113410248163686L;
46.1151 + }
46.1152 + private ReentrantLock qlock;
46.1153 + private WaitQueue waitingProducers;
46.1154 + private WaitQueue waitingConsumers;
46.1155 +
46.1156 + /**
46.1157 + * Save the state to a stream (that is, serialize it).
46.1158 + *
46.1159 + * @param s the stream
46.1160 + */
46.1161 + private void writeObject(java.io.ObjectOutputStream s)
46.1162 + throws java.io.IOException {
46.1163 + boolean fair = transferer instanceof TransferQueue;
46.1164 + if (fair) {
46.1165 + qlock = new ReentrantLock(true);
46.1166 + waitingProducers = new FifoWaitQueue();
46.1167 + waitingConsumers = new FifoWaitQueue();
46.1168 + }
46.1169 + else {
46.1170 + qlock = new ReentrantLock();
46.1171 + waitingProducers = new LifoWaitQueue();
46.1172 + waitingConsumers = new LifoWaitQueue();
46.1173 + }
46.1174 + s.defaultWriteObject();
46.1175 + }
46.1176 +
46.1177 + private void readObject(final java.io.ObjectInputStream s)
46.1178 + throws java.io.IOException, ClassNotFoundException {
46.1179 + s.defaultReadObject();
46.1180 + if (waitingProducers instanceof FifoWaitQueue)
46.1181 + transferer = new TransferQueue();
46.1182 + else
46.1183 + transferer = new TransferStack();
46.1184 + }
46.1185 +
46.1186 + // Unsafe mechanics
46.1187 + static long objectFieldOffset(sun.misc.Unsafe UNSAFE,
46.1188 + String field, Class<?> klazz) {
46.1189 + try {
46.1190 + return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field));
46.1191 + } catch (NoSuchFieldException e) {
46.1192 + // Convert Exception to corresponding Error
46.1193 + NoSuchFieldError error = new NoSuchFieldError(field);
46.1194 + error.initCause(e);
46.1195 + throw error;
46.1196 + }
46.1197 + }
46.1198 +
46.1199 +}
47.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
47.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ThreadFactory.java Sat Mar 19 10:46:31 2016 +0100
47.3 @@ -0,0 +1,70 @@
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 +
47.41 +/**
47.42 + * An object that creates new threads on demand. Using thread factories
47.43 + * removes hardwiring of calls to {@link Thread#Thread(Runnable) new Thread},
47.44 + * enabling applications to use special thread subclasses, priorities, etc.
47.45 + *
47.46 + * <p>
47.47 + * The simplest implementation of this interface is just:
47.48 + * <pre>
47.49 + * class SimpleThreadFactory implements ThreadFactory {
47.50 + * public Thread newThread(Runnable r) {
47.51 + * return new Thread(r);
47.52 + * }
47.53 + * }
47.54 + * </pre>
47.55 + *
47.56 + * The {@link Executors#defaultThreadFactory} method provides a more
47.57 + * useful simple implementation, that sets the created thread context
47.58 + * to known values before returning it.
47.59 + * @since 1.5
47.60 + * @author Doug Lea
47.61 + */
47.62 +public interface ThreadFactory {
47.63 +
47.64 + /**
47.65 + * Constructs a new {@code Thread}. Implementations may also initialize
47.66 + * priority, name, daemon status, {@code ThreadGroup}, etc.
47.67 + *
47.68 + * @param r a runnable to be executed by new thread instance
47.69 + * @return constructed thread, or {@code null} if the request to
47.70 + * create a thread is rejected
47.71 + */
47.72 + Thread newThread(Runnable r);
47.73 +}
48.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
48.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ThreadLocalRandom.java Sat Mar 19 10:46:31 2016 +0100
48.3 @@ -0,0 +1,226 @@
48.4 +/*
48.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
48.6 + *
48.7 + * This code is free software; you can redistribute it and/or modify it
48.8 + * under the terms of the GNU General Public License version 2 only, as
48.9 + * published by the Free Software Foundation. Oracle designates this
48.10 + * particular file as subject to the "Classpath" exception as provided
48.11 + * by Oracle in the LICENSE file that accompanied this code.
48.12 + *
48.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
48.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
48.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
48.16 + * version 2 for more details (a copy is included in the LICENSE file that
48.17 + * accompanied this code).
48.18 + *
48.19 + * You should have received a copy of the GNU General Public License version
48.20 + * 2 along with this work; if not, write to the Free Software Foundation,
48.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
48.22 + *
48.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
48.24 + * or visit www.oracle.com if you need additional information or have any
48.25 + * questions.
48.26 + */
48.27 +
48.28 +/*
48.29 + * This file is available under and governed by the GNU General Public
48.30 + * License version 2 only, as published by the Free Software Foundation.
48.31 + * However, the following notice accompanied the original version of this
48.32 + * file:
48.33 + *
48.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
48.35 + * Expert Group and released to the public domain, as explained at
48.36 + * http://creativecommons.org/publicdomain/zero/1.0/
48.37 + */
48.38 +
48.39 +package java.util.concurrent;
48.40 +
48.41 +import java.util.Random;
48.42 +
48.43 +/**
48.44 + * A random number generator isolated to the current thread. Like the
48.45 + * global {@link java.util.Random} generator used by the {@link
48.46 + * java.lang.Math} class, a {@code ThreadLocalRandom} is initialized
48.47 + * with an internally generated seed that may not otherwise be
48.48 + * modified. When applicable, use of {@code ThreadLocalRandom} rather
48.49 + * than shared {@code Random} objects in concurrent programs will
48.50 + * typically encounter much less overhead and contention. Use of
48.51 + * {@code ThreadLocalRandom} is particularly appropriate when multiple
48.52 + * tasks (for example, each a {@link ForkJoinTask}) use random numbers
48.53 + * in parallel in thread pools.
48.54 + *
48.55 + * <p>Usages of this class should typically be of the form:
48.56 + * {@code ThreadLocalRandom.current().nextX(...)} (where
48.57 + * {@code X} is {@code Int}, {@code Long}, etc).
48.58 + * When all usages are of this form, it is never possible to
48.59 + * accidently share a {@code ThreadLocalRandom} across multiple threads.
48.60 + *
48.61 + * <p>This class also provides additional commonly used bounded random
48.62 + * generation methods.
48.63 + *
48.64 + * @since 1.7
48.65 + * @author Doug Lea
48.66 + */
48.67 +public class ThreadLocalRandom extends Random {
48.68 + // same constants as Random, but must be redeclared because private
48.69 + private static final long multiplier = 0x5DEECE66DL;
48.70 + private static final long addend = 0xBL;
48.71 + private static final long mask = (1L << 48) - 1;
48.72 +
48.73 + /**
48.74 + * The random seed. We can't use super.seed.
48.75 + */
48.76 + private long rnd;
48.77 +
48.78 + /**
48.79 + * Initialization flag to permit calls to setSeed to succeed only
48.80 + * while executing the Random constructor. We can't allow others
48.81 + * since it would cause setting seed in one part of a program to
48.82 + * unintentionally impact other usages by the thread.
48.83 + */
48.84 + boolean initialized;
48.85 +
48.86 + // Padding to help avoid memory contention among seed updates in
48.87 + // different TLRs in the common case that they are located near
48.88 + // each other.
48.89 + private long pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7;
48.90 +
48.91 + /**
48.92 + * The actual ThreadLocal
48.93 + */
48.94 + private static final ThreadLocal<ThreadLocalRandom> localRandom =
48.95 + new ThreadLocal<ThreadLocalRandom>() {
48.96 + protected ThreadLocalRandom initialValue() {
48.97 + return new ThreadLocalRandom();
48.98 + }
48.99 + };
48.100 +
48.101 +
48.102 + /**
48.103 + * Constructor called only by localRandom.initialValue.
48.104 + */
48.105 + ThreadLocalRandom() {
48.106 + super();
48.107 + initialized = true;
48.108 + }
48.109 +
48.110 + /**
48.111 + * Returns the current thread's {@code ThreadLocalRandom}.
48.112 + *
48.113 + * @return the current thread's {@code ThreadLocalRandom}
48.114 + */
48.115 + public static ThreadLocalRandom current() {
48.116 + return localRandom.get();
48.117 + }
48.118 +
48.119 + /**
48.120 + * Throws {@code UnsupportedOperationException}. Setting seeds in
48.121 + * this generator is not supported.
48.122 + *
48.123 + * @throws UnsupportedOperationException always
48.124 + */
48.125 + public void setSeed(long seed) {
48.126 + if (initialized)
48.127 + throw new UnsupportedOperationException();
48.128 + rnd = (seed ^ multiplier) & mask;
48.129 + }
48.130 +
48.131 + protected int next(int bits) {
48.132 + rnd = (rnd * multiplier + addend) & mask;
48.133 + return (int) (rnd >>> (48-bits));
48.134 + }
48.135 +
48.136 + /**
48.137 + * Returns a pseudorandom, uniformly distributed value between the
48.138 + * given least value (inclusive) and bound (exclusive).
48.139 + *
48.140 + * @param least the least value returned
48.141 + * @param bound the upper bound (exclusive)
48.142 + * @throws IllegalArgumentException if least greater than or equal
48.143 + * to bound
48.144 + * @return the next value
48.145 + */
48.146 + public int nextInt(int least, int bound) {
48.147 + if (least >= bound)
48.148 + throw new IllegalArgumentException();
48.149 + return nextInt(bound - least) + least;
48.150 + }
48.151 +
48.152 + /**
48.153 + * Returns a pseudorandom, uniformly distributed value
48.154 + * between 0 (inclusive) and the specified value (exclusive).
48.155 + *
48.156 + * @param n the bound on the random number to be returned. Must be
48.157 + * positive.
48.158 + * @return the next value
48.159 + * @throws IllegalArgumentException if n is not positive
48.160 + */
48.161 + public long nextLong(long n) {
48.162 + if (n <= 0)
48.163 + throw new IllegalArgumentException("n must be positive");
48.164 + // Divide n by two until small enough for nextInt. On each
48.165 + // iteration (at most 31 of them but usually much less),
48.166 + // randomly choose both whether to include high bit in result
48.167 + // (offset) and whether to continue with the lower vs upper
48.168 + // half (which makes a difference only if odd).
48.169 + long offset = 0;
48.170 + while (n >= Integer.MAX_VALUE) {
48.171 + int bits = next(2);
48.172 + long half = n >>> 1;
48.173 + long nextn = ((bits & 2) == 0) ? half : n - half;
48.174 + if ((bits & 1) == 0)
48.175 + offset += n - nextn;
48.176 + n = nextn;
48.177 + }
48.178 + return offset + nextInt((int) n);
48.179 + }
48.180 +
48.181 + /**
48.182 + * Returns a pseudorandom, uniformly distributed value between the
48.183 + * given least value (inclusive) and bound (exclusive).
48.184 + *
48.185 + * @param least the least value returned
48.186 + * @param bound the upper bound (exclusive)
48.187 + * @return the next value
48.188 + * @throws IllegalArgumentException if least greater than or equal
48.189 + * to bound
48.190 + */
48.191 + public long nextLong(long least, long bound) {
48.192 + if (least >= bound)
48.193 + throw new IllegalArgumentException();
48.194 + return nextLong(bound - least) + least;
48.195 + }
48.196 +
48.197 + /**
48.198 + * Returns a pseudorandom, uniformly distributed {@code double} value
48.199 + * between 0 (inclusive) and the specified value (exclusive).
48.200 + *
48.201 + * @param n the bound on the random number to be returned. Must be
48.202 + * positive.
48.203 + * @return the next value
48.204 + * @throws IllegalArgumentException if n is not positive
48.205 + */
48.206 + public double nextDouble(double n) {
48.207 + if (n <= 0)
48.208 + throw new IllegalArgumentException("n must be positive");
48.209 + return nextDouble() * n;
48.210 + }
48.211 +
48.212 + /**
48.213 + * Returns a pseudorandom, uniformly distributed value between the
48.214 + * given least value (inclusive) and bound (exclusive).
48.215 + *
48.216 + * @param least the least value returned
48.217 + * @param bound the upper bound (exclusive)
48.218 + * @return the next value
48.219 + * @throws IllegalArgumentException if least greater than or equal
48.220 + * to bound
48.221 + */
48.222 + public double nextDouble(double least, double bound) {
48.223 + if (least >= bound)
48.224 + throw new IllegalArgumentException();
48.225 + return nextDouble() * (bound - least) + least;
48.226 + }
48.227 +
48.228 + private static final long serialVersionUID = -5851777807851030925L;
48.229 +}
49.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
49.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/ThreadPoolExecutor.java Sat Mar 19 10:46:31 2016 +0100
49.3 @@ -0,0 +1,2054 @@
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 +import java.util.concurrent.locks.*;
49.41 +import java.util.concurrent.atomic.*;
49.42 +import java.util.*;
49.43 +
49.44 +/**
49.45 + * An {@link ExecutorService} that executes each submitted task using
49.46 + * one of possibly several pooled threads, normally configured
49.47 + * using {@link Executors} factory methods.
49.48 + *
49.49 + * <p>Thread pools address two different problems: they usually
49.50 + * provide improved performance when executing large numbers of
49.51 + * asynchronous tasks, due to reduced per-task invocation overhead,
49.52 + * and they provide a means of bounding and managing the resources,
49.53 + * including threads, consumed when executing a collection of tasks.
49.54 + * Each {@code ThreadPoolExecutor} also maintains some basic
49.55 + * statistics, such as the number of completed tasks.
49.56 + *
49.57 + * <p>To be useful across a wide range of contexts, this class
49.58 + * provides many adjustable parameters and extensibility
49.59 + * hooks. However, programmers are urged to use the more convenient
49.60 + * {@link Executors} factory methods {@link
49.61 + * Executors#newCachedThreadPool} (unbounded thread pool, with
49.62 + * automatic thread reclamation), {@link Executors#newFixedThreadPool}
49.63 + * (fixed size thread pool) and {@link
49.64 + * Executors#newSingleThreadExecutor} (single background thread), that
49.65 + * preconfigure settings for the most common usage
49.66 + * scenarios. Otherwise, use the following guide when manually
49.67 + * configuring and tuning this class:
49.68 + *
49.69 + * <dl>
49.70 + *
49.71 + * <dt>Core and maximum pool sizes</dt>
49.72 + *
49.73 + * <dd>A {@code ThreadPoolExecutor} will automatically adjust the
49.74 + * pool size (see {@link #getPoolSize})
49.75 + * according to the bounds set by
49.76 + * corePoolSize (see {@link #getCorePoolSize}) and
49.77 + * maximumPoolSize (see {@link #getMaximumPoolSize}).
49.78 + *
49.79 + * When a new task is submitted in method {@link #execute}, and fewer
49.80 + * than corePoolSize threads are running, a new thread is created to
49.81 + * handle the request, even if other worker threads are idle. If
49.82 + * there are more than corePoolSize but less than maximumPoolSize
49.83 + * threads running, a new thread will be created only if the queue is
49.84 + * full. By setting corePoolSize and maximumPoolSize the same, you
49.85 + * create a fixed-size thread pool. By setting maximumPoolSize to an
49.86 + * essentially unbounded value such as {@code Integer.MAX_VALUE}, you
49.87 + * allow the pool to accommodate an arbitrary number of concurrent
49.88 + * tasks. Most typically, core and maximum pool sizes are set only
49.89 + * upon construction, but they may also be changed dynamically using
49.90 + * {@link #setCorePoolSize} and {@link #setMaximumPoolSize}. </dd>
49.91 + *
49.92 + * <dt>On-demand construction</dt>
49.93 + *
49.94 + * <dd> By default, even core threads are initially created and
49.95 + * started only when new tasks arrive, but this can be overridden
49.96 + * dynamically using method {@link #prestartCoreThread} or {@link
49.97 + * #prestartAllCoreThreads}. You probably want to prestart threads if
49.98 + * you construct the pool with a non-empty queue. </dd>
49.99 + *
49.100 + * <dt>Creating new threads</dt>
49.101 + *
49.102 + * <dd>New threads are created using a {@link ThreadFactory}. If not
49.103 + * otherwise specified, a {@link Executors#defaultThreadFactory} is
49.104 + * used, that creates threads to all be in the same {@link
49.105 + * ThreadGroup} and with the same {@code NORM_PRIORITY} priority and
49.106 + * non-daemon status. By supplying a different ThreadFactory, you can
49.107 + * alter the thread's name, thread group, priority, daemon status,
49.108 + * etc. If a {@code ThreadFactory} fails to create a thread when asked
49.109 + * by returning null from {@code newThread}, the executor will
49.110 + * continue, but might not be able to execute any tasks. Threads
49.111 + * should possess the "modifyThread" {@code RuntimePermission}. If
49.112 + * worker threads or other threads using the pool do not possess this
49.113 + * permission, service may be degraded: configuration changes may not
49.114 + * take effect in a timely manner, and a shutdown pool may remain in a
49.115 + * state in which termination is possible but not completed.</dd>
49.116 + *
49.117 + * <dt>Keep-alive times</dt>
49.118 + *
49.119 + * <dd>If the pool currently has more than corePoolSize threads,
49.120 + * excess threads will be terminated if they have been idle for more
49.121 + * than the keepAliveTime (see {@link #getKeepAliveTime}). This
49.122 + * provides a means of reducing resource consumption when the pool is
49.123 + * not being actively used. If the pool becomes more active later, new
49.124 + * threads will be constructed. This parameter can also be changed
49.125 + * dynamically using method {@link #setKeepAliveTime}. Using a value
49.126 + * of {@code Long.MAX_VALUE} {@link TimeUnit#NANOSECONDS} effectively
49.127 + * disables idle threads from ever terminating prior to shut down. By
49.128 + * default, the keep-alive policy applies only when there are more
49.129 + * than corePoolSizeThreads. But method {@link
49.130 + * #allowCoreThreadTimeOut(boolean)} can be used to apply this
49.131 + * time-out policy to core threads as well, so long as the
49.132 + * keepAliveTime value is non-zero. </dd>
49.133 + *
49.134 + * <dt>Queuing</dt>
49.135 + *
49.136 + * <dd>Any {@link BlockingQueue} may be used to transfer and hold
49.137 + * submitted tasks. The use of this queue interacts with pool sizing:
49.138 + *
49.139 + * <ul>
49.140 + *
49.141 + * <li> If fewer than corePoolSize threads are running, the Executor
49.142 + * always prefers adding a new thread
49.143 + * rather than queuing.</li>
49.144 + *
49.145 + * <li> If corePoolSize or more threads are running, the Executor
49.146 + * always prefers queuing a request rather than adding a new
49.147 + * thread.</li>
49.148 + *
49.149 + * <li> If a request cannot be queued, a new thread is created unless
49.150 + * this would exceed maximumPoolSize, in which case, the task will be
49.151 + * rejected.</li>
49.152 + *
49.153 + * </ul>
49.154 + *
49.155 + * There are three general strategies for queuing:
49.156 + * <ol>
49.157 + *
49.158 + * <li> <em> Direct handoffs.</em> A good default choice for a work
49.159 + * queue is a {@link SynchronousQueue} that hands off tasks to threads
49.160 + * without otherwise holding them. Here, an attempt to queue a task
49.161 + * will fail if no threads are immediately available to run it, so a
49.162 + * new thread will be constructed. This policy avoids lockups when
49.163 + * handling sets of requests that might have internal dependencies.
49.164 + * Direct handoffs generally require unbounded maximumPoolSizes to
49.165 + * avoid rejection of new submitted tasks. This in turn admits the
49.166 + * possibility of unbounded thread growth when commands continue to
49.167 + * arrive on average faster than they can be processed. </li>
49.168 + *
49.169 + * <li><em> Unbounded queues.</em> Using an unbounded queue (for
49.170 + * example a {@link LinkedBlockingQueue} without a predefined
49.171 + * capacity) will cause new tasks to wait in the queue when all
49.172 + * corePoolSize threads are busy. Thus, no more than corePoolSize
49.173 + * threads will ever be created. (And the value of the maximumPoolSize
49.174 + * therefore doesn't have any effect.) This may be appropriate when
49.175 + * each task is completely independent of others, so tasks cannot
49.176 + * affect each others execution; for example, in a web page server.
49.177 + * While this style of queuing can be useful in smoothing out
49.178 + * transient bursts of requests, it admits the possibility of
49.179 + * unbounded work queue growth when commands continue to arrive on
49.180 + * average faster than they can be processed. </li>
49.181 + *
49.182 + * <li><em>Bounded queues.</em> A bounded queue (for example, an
49.183 + * {@link ArrayBlockingQueue}) helps prevent resource exhaustion when
49.184 + * used with finite maximumPoolSizes, but can be more difficult to
49.185 + * tune and control. Queue sizes and maximum pool sizes may be traded
49.186 + * off for each other: Using large queues and small pools minimizes
49.187 + * CPU usage, OS resources, and context-switching overhead, but can
49.188 + * lead to artificially low throughput. If tasks frequently block (for
49.189 + * example if they are I/O bound), a system may be able to schedule
49.190 + * time for more threads than you otherwise allow. Use of small queues
49.191 + * generally requires larger pool sizes, which keeps CPUs busier but
49.192 + * may encounter unacceptable scheduling overhead, which also
49.193 + * decreases throughput. </li>
49.194 + *
49.195 + * </ol>
49.196 + *
49.197 + * </dd>
49.198 + *
49.199 + * <dt>Rejected tasks</dt>
49.200 + *
49.201 + * <dd> New tasks submitted in method {@link #execute} will be
49.202 + * <em>rejected</em> when the Executor has been shut down, and also
49.203 + * when the Executor uses finite bounds for both maximum threads and
49.204 + * work queue capacity, and is saturated. In either case, the {@code
49.205 + * execute} method invokes the {@link
49.206 + * RejectedExecutionHandler#rejectedExecution} method of its {@link
49.207 + * RejectedExecutionHandler}. Four predefined handler policies are
49.208 + * provided:
49.209 + *
49.210 + * <ol>
49.211 + *
49.212 + * <li> In the default {@link ThreadPoolExecutor.AbortPolicy}, the
49.213 + * handler throws a runtime {@link RejectedExecutionException} upon
49.214 + * rejection. </li>
49.215 + *
49.216 + * <li> In {@link ThreadPoolExecutor.CallerRunsPolicy}, the thread
49.217 + * that invokes {@code execute} itself runs the task. This provides a
49.218 + * simple feedback control mechanism that will slow down the rate that
49.219 + * new tasks are submitted. </li>
49.220 + *
49.221 + * <li> In {@link ThreadPoolExecutor.DiscardPolicy}, a task that
49.222 + * cannot be executed is simply dropped. </li>
49.223 + *
49.224 + * <li>In {@link ThreadPoolExecutor.DiscardOldestPolicy}, if the
49.225 + * executor is not shut down, the task at the head of the work queue
49.226 + * is dropped, and then execution is retried (which can fail again,
49.227 + * causing this to be repeated.) </li>
49.228 + *
49.229 + * </ol>
49.230 + *
49.231 + * It is possible to define and use other kinds of {@link
49.232 + * RejectedExecutionHandler} classes. Doing so requires some care
49.233 + * especially when policies are designed to work only under particular
49.234 + * capacity or queuing policies. </dd>
49.235 + *
49.236 + * <dt>Hook methods</dt>
49.237 + *
49.238 + * <dd>This class provides {@code protected} overridable {@link
49.239 + * #beforeExecute} and {@link #afterExecute} methods that are called
49.240 + * before and after execution of each task. These can be used to
49.241 + * manipulate the execution environment; for example, reinitializing
49.242 + * ThreadLocals, gathering statistics, or adding log
49.243 + * entries. Additionally, method {@link #terminated} can be overridden
49.244 + * to perform any special processing that needs to be done once the
49.245 + * Executor has fully terminated.
49.246 + *
49.247 + * <p>If hook or callback methods throw exceptions, internal worker
49.248 + * threads may in turn fail and abruptly terminate.</dd>
49.249 + *
49.250 + * <dt>Queue maintenance</dt>
49.251 + *
49.252 + * <dd> Method {@link #getQueue} allows access to the work queue for
49.253 + * purposes of monitoring and debugging. Use of this method for any
49.254 + * other purpose is strongly discouraged. Two supplied methods,
49.255 + * {@link #remove} and {@link #purge} are available to assist in
49.256 + * storage reclamation when large numbers of queued tasks become
49.257 + * cancelled.</dd>
49.258 + *
49.259 + * <dt>Finalization</dt>
49.260 + *
49.261 + * <dd> A pool that is no longer referenced in a program <em>AND</em>
49.262 + * has no remaining threads will be {@code shutdown} automatically. If
49.263 + * you would like to ensure that unreferenced pools are reclaimed even
49.264 + * if users forget to call {@link #shutdown}, then you must arrange
49.265 + * that unused threads eventually die, by setting appropriate
49.266 + * keep-alive times, using a lower bound of zero core threads and/or
49.267 + * setting {@link #allowCoreThreadTimeOut(boolean)}. </dd>
49.268 + *
49.269 + * </dl>
49.270 + *
49.271 + * <p> <b>Extension example</b>. Most extensions of this class
49.272 + * override one or more of the protected hook methods. For example,
49.273 + * here is a subclass that adds a simple pause/resume feature:
49.274 + *
49.275 + * <pre> {@code
49.276 + * class PausableThreadPoolExecutor extends ThreadPoolExecutor {
49.277 + * private boolean isPaused;
49.278 + * private ReentrantLock pauseLock = new ReentrantLock();
49.279 + * private Condition unpaused = pauseLock.newCondition();
49.280 + *
49.281 + * public PausableThreadPoolExecutor(...) { super(...); }
49.282 + *
49.283 + * protected void beforeExecute(Thread t, Runnable r) {
49.284 + * super.beforeExecute(t, r);
49.285 + * pauseLock.lock();
49.286 + * try {
49.287 + * while (isPaused) unpaused.await();
49.288 + * } catch (InterruptedException ie) {
49.289 + * t.interrupt();
49.290 + * } finally {
49.291 + * pauseLock.unlock();
49.292 + * }
49.293 + * }
49.294 + *
49.295 + * public void pause() {
49.296 + * pauseLock.lock();
49.297 + * try {
49.298 + * isPaused = true;
49.299 + * } finally {
49.300 + * pauseLock.unlock();
49.301 + * }
49.302 + * }
49.303 + *
49.304 + * public void resume() {
49.305 + * pauseLock.lock();
49.306 + * try {
49.307 + * isPaused = false;
49.308 + * unpaused.signalAll();
49.309 + * } finally {
49.310 + * pauseLock.unlock();
49.311 + * }
49.312 + * }
49.313 + * }}</pre>
49.314 + *
49.315 + * @since 1.5
49.316 + * @author Doug Lea
49.317 + */
49.318 +public class ThreadPoolExecutor extends AbstractExecutorService {
49.319 + /**
49.320 + * The main pool control state, ctl, is an atomic integer packing
49.321 + * two conceptual fields
49.322 + * workerCount, indicating the effective number of threads
49.323 + * runState, indicating whether running, shutting down etc
49.324 + *
49.325 + * In order to pack them into one int, we limit workerCount to
49.326 + * (2^29)-1 (about 500 million) threads rather than (2^31)-1 (2
49.327 + * billion) otherwise representable. If this is ever an issue in
49.328 + * the future, the variable can be changed to be an AtomicLong,
49.329 + * and the shift/mask constants below adjusted. But until the need
49.330 + * arises, this code is a bit faster and simpler using an int.
49.331 + *
49.332 + * The workerCount is the number of workers that have been
49.333 + * permitted to start and not permitted to stop. The value may be
49.334 + * transiently different from the actual number of live threads,
49.335 + * for example when a ThreadFactory fails to create a thread when
49.336 + * asked, and when exiting threads are still performing
49.337 + * bookkeeping before terminating. The user-visible pool size is
49.338 + * reported as the current size of the workers set.
49.339 + *
49.340 + * The runState provides the main lifecyle control, taking on values:
49.341 + *
49.342 + * RUNNING: Accept new tasks and process queued tasks
49.343 + * SHUTDOWN: Don't accept new tasks, but process queued tasks
49.344 + * STOP: Don't accept new tasks, don't process queued tasks,
49.345 + * and interrupt in-progress tasks
49.346 + * TIDYING: All tasks have terminated, workerCount is zero,
49.347 + * the thread transitioning to state TIDYING
49.348 + * will run the terminated() hook method
49.349 + * TERMINATED: terminated() has completed
49.350 + *
49.351 + * The numerical order among these values matters, to allow
49.352 + * ordered comparisons. The runState monotonically increases over
49.353 + * time, but need not hit each state. The transitions are:
49.354 + *
49.355 + * RUNNING -> SHUTDOWN
49.356 + * On invocation of shutdown(), perhaps implicitly in finalize()
49.357 + * (RUNNING or SHUTDOWN) -> STOP
49.358 + * On invocation of shutdownNow()
49.359 + * SHUTDOWN -> TIDYING
49.360 + * When both queue and pool are empty
49.361 + * STOP -> TIDYING
49.362 + * When pool is empty
49.363 + * TIDYING -> TERMINATED
49.364 + * When the terminated() hook method has completed
49.365 + *
49.366 + * Threads waiting in awaitTermination() will return when the
49.367 + * state reaches TERMINATED.
49.368 + *
49.369 + * Detecting the transition from SHUTDOWN to TIDYING is less
49.370 + * straightforward than you'd like because the queue may become
49.371 + * empty after non-empty and vice versa during SHUTDOWN state, but
49.372 + * we can only terminate if, after seeing that it is empty, we see
49.373 + * that workerCount is 0 (which sometimes entails a recheck -- see
49.374 + * below).
49.375 + */
49.376 + private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
49.377 + private static final int COUNT_BITS = Integer.SIZE - 3;
49.378 + private static final int CAPACITY = (1 << COUNT_BITS) - 1;
49.379 +
49.380 + // runState is stored in the high-order bits
49.381 + private static final int RUNNING = -1 << COUNT_BITS;
49.382 + private static final int SHUTDOWN = 0 << COUNT_BITS;
49.383 + private static final int STOP = 1 << COUNT_BITS;
49.384 + private static final int TIDYING = 2 << COUNT_BITS;
49.385 + private static final int TERMINATED = 3 << COUNT_BITS;
49.386 +
49.387 + // Packing and unpacking ctl
49.388 + private static int runStateOf(int c) { return c & ~CAPACITY; }
49.389 + private static int workerCountOf(int c) { return c & CAPACITY; }
49.390 + private static int ctlOf(int rs, int wc) { return rs | wc; }
49.391 +
49.392 + /*
49.393 + * Bit field accessors that don't require unpacking ctl.
49.394 + * These depend on the bit layout and on workerCount being never negative.
49.395 + */
49.396 +
49.397 + private static boolean runStateLessThan(int c, int s) {
49.398 + return c < s;
49.399 + }
49.400 +
49.401 + private static boolean runStateAtLeast(int c, int s) {
49.402 + return c >= s;
49.403 + }
49.404 +
49.405 + private static boolean isRunning(int c) {
49.406 + return c < SHUTDOWN;
49.407 + }
49.408 +
49.409 + /**
49.410 + * Attempt to CAS-increment the workerCount field of ctl.
49.411 + */
49.412 + private boolean compareAndIncrementWorkerCount(int expect) {
49.413 + return ctl.compareAndSet(expect, expect + 1);
49.414 + }
49.415 +
49.416 + /**
49.417 + * Attempt to CAS-decrement the workerCount field of ctl.
49.418 + */
49.419 + private boolean compareAndDecrementWorkerCount(int expect) {
49.420 + return ctl.compareAndSet(expect, expect - 1);
49.421 + }
49.422 +
49.423 + /**
49.424 + * Decrements the workerCount field of ctl. This is called only on
49.425 + * abrupt termination of a thread (see processWorkerExit). Other
49.426 + * decrements are performed within getTask.
49.427 + */
49.428 + private void decrementWorkerCount() {
49.429 + do {} while (! compareAndDecrementWorkerCount(ctl.get()));
49.430 + }
49.431 +
49.432 + /**
49.433 + * The queue used for holding tasks and handing off to worker
49.434 + * threads. We do not require that workQueue.poll() returning
49.435 + * null necessarily means that workQueue.isEmpty(), so rely
49.436 + * solely on isEmpty to see if the queue is empty (which we must
49.437 + * do for example when deciding whether to transition from
49.438 + * SHUTDOWN to TIDYING). This accommodates special-purpose
49.439 + * queues such as DelayQueues for which poll() is allowed to
49.440 + * return null even if it may later return non-null when delays
49.441 + * expire.
49.442 + */
49.443 + private final BlockingQueue<Runnable> workQueue;
49.444 +
49.445 + /**
49.446 + * Lock held on access to workers set and related bookkeeping.
49.447 + * While we could use a concurrent set of some sort, it turns out
49.448 + * to be generally preferable to use a lock. Among the reasons is
49.449 + * that this serializes interruptIdleWorkers, which avoids
49.450 + * unnecessary interrupt storms, especially during shutdown.
49.451 + * Otherwise exiting threads would concurrently interrupt those
49.452 + * that have not yet interrupted. It also simplifies some of the
49.453 + * associated statistics bookkeeping of largestPoolSize etc. We
49.454 + * also hold mainLock on shutdown and shutdownNow, for the sake of
49.455 + * ensuring workers set is stable while separately checking
49.456 + * permission to interrupt and actually interrupting.
49.457 + */
49.458 + private final ReentrantLock mainLock = new ReentrantLock();
49.459 +
49.460 + /**
49.461 + * Set containing all worker threads in pool. Accessed only when
49.462 + * holding mainLock.
49.463 + */
49.464 + private final HashSet<Worker> workers = new HashSet<Worker>();
49.465 +
49.466 + /**
49.467 + * Wait condition to support awaitTermination
49.468 + */
49.469 + private final Condition termination = mainLock.newCondition();
49.470 +
49.471 + /**
49.472 + * Tracks largest attained pool size. Accessed only under
49.473 + * mainLock.
49.474 + */
49.475 + private int largestPoolSize;
49.476 +
49.477 + /**
49.478 + * Counter for completed tasks. Updated only on termination of
49.479 + * worker threads. Accessed only under mainLock.
49.480 + */
49.481 + private long completedTaskCount;
49.482 +
49.483 + /*
49.484 + * All user control parameters are declared as volatiles so that
49.485 + * ongoing actions are based on freshest values, but without need
49.486 + * for locking, since no internal invariants depend on them
49.487 + * changing synchronously with respect to other actions.
49.488 + */
49.489 +
49.490 + /**
49.491 + * Factory for new threads. All threads are created using this
49.492 + * factory (via method addWorker). All callers must be prepared
49.493 + * for addWorker to fail, which may reflect a system or user's
49.494 + * policy limiting the number of threads. Even though it is not
49.495 + * treated as an error, failure to create threads may result in
49.496 + * new tasks being rejected or existing ones remaining stuck in
49.497 + * the queue. On the other hand, no special precautions exist to
49.498 + * handle OutOfMemoryErrors that might be thrown while trying to
49.499 + * create threads, since there is generally no recourse from
49.500 + * within this class.
49.501 + */
49.502 + private volatile ThreadFactory threadFactory;
49.503 +
49.504 + /**
49.505 + * Handler called when saturated or shutdown in execute.
49.506 + */
49.507 + private volatile RejectedExecutionHandler handler;
49.508 +
49.509 + /**
49.510 + * Timeout in nanoseconds for idle threads waiting for work.
49.511 + * Threads use this timeout when there are more than corePoolSize
49.512 + * present or if allowCoreThreadTimeOut. Otherwise they wait
49.513 + * forever for new work.
49.514 + */
49.515 + private volatile long keepAliveTime;
49.516 +
49.517 + /**
49.518 + * If false (default), core threads stay alive even when idle.
49.519 + * If true, core threads use keepAliveTime to time out waiting
49.520 + * for work.
49.521 + */
49.522 + private volatile boolean allowCoreThreadTimeOut;
49.523 +
49.524 + /**
49.525 + * Core pool size is the minimum number of workers to keep alive
49.526 + * (and not allow to time out etc) unless allowCoreThreadTimeOut
49.527 + * is set, in which case the minimum is zero.
49.528 + */
49.529 + private volatile int corePoolSize;
49.530 +
49.531 + /**
49.532 + * Maximum pool size. Note that the actual maximum is internally
49.533 + * bounded by CAPACITY.
49.534 + */
49.535 + private volatile int maximumPoolSize;
49.536 +
49.537 + /**
49.538 + * The default rejected execution handler
49.539 + */
49.540 + private static final RejectedExecutionHandler defaultHandler =
49.541 + new AbortPolicy();
49.542 +
49.543 + /**
49.544 + * Permission required for callers of shutdown and shutdownNow.
49.545 + * We additionally require (see checkShutdownAccess) that callers
49.546 + * have permission to actually interrupt threads in the worker set
49.547 + * (as governed by Thread.interrupt, which relies on
49.548 + * ThreadGroup.checkAccess, which in turn relies on
49.549 + * SecurityManager.checkAccess). Shutdowns are attempted only if
49.550 + * these checks pass.
49.551 + *
49.552 + * All actual invocations of Thread.interrupt (see
49.553 + * interruptIdleWorkers and interruptWorkers) ignore
49.554 + * SecurityExceptions, meaning that the attempted interrupts
49.555 + * silently fail. In the case of shutdown, they should not fail
49.556 + * unless the SecurityManager has inconsistent policies, sometimes
49.557 + * allowing access to a thread and sometimes not. In such cases,
49.558 + * failure to actually interrupt threads may disable or delay full
49.559 + * termination. Other uses of interruptIdleWorkers are advisory,
49.560 + * and failure to actually interrupt will merely delay response to
49.561 + * configuration changes so is not handled exceptionally.
49.562 + */
49.563 + private static final RuntimePermission shutdownPerm =
49.564 + new RuntimePermission("modifyThread");
49.565 +
49.566 + /**
49.567 + * Class Worker mainly maintains interrupt control state for
49.568 + * threads running tasks, along with other minor bookkeeping.
49.569 + * This class opportunistically extends AbstractQueuedSynchronizer
49.570 + * to simplify acquiring and releasing a lock surrounding each
49.571 + * task execution. This protects against interrupts that are
49.572 + * intended to wake up a worker thread waiting for a task from
49.573 + * instead interrupting a task being run. We implement a simple
49.574 + * non-reentrant mutual exclusion lock rather than use ReentrantLock
49.575 + * because we do not want worker tasks to be able to reacquire the
49.576 + * lock when they invoke pool control methods like setCorePoolSize.
49.577 + */
49.578 + private final class Worker
49.579 + extends AbstractQueuedSynchronizer
49.580 + implements Runnable
49.581 + {
49.582 + /**
49.583 + * This class will never be serialized, but we provide a
49.584 + * serialVersionUID to suppress a javac warning.
49.585 + */
49.586 + private static final long serialVersionUID = 6138294804551838833L;
49.587 +
49.588 + /** Thread this worker is running in. Null if factory fails. */
49.589 + final Thread thread;
49.590 + /** Initial task to run. Possibly null. */
49.591 + Runnable firstTask;
49.592 + /** Per-thread task counter */
49.593 + volatile long completedTasks;
49.594 +
49.595 + /**
49.596 + * Creates with given first task and thread from ThreadFactory.
49.597 + * @param firstTask the first task (null if none)
49.598 + */
49.599 + Worker(Runnable firstTask) {
49.600 + this.firstTask = firstTask;
49.601 + this.thread = getThreadFactory().newThread(this);
49.602 + }
49.603 +
49.604 + /** Delegates main run loop to outer runWorker */
49.605 + public void run() {
49.606 + runWorker(this);
49.607 + }
49.608 +
49.609 + // Lock methods
49.610 + //
49.611 + // The value 0 represents the unlocked state.
49.612 + // The value 1 represents the locked state.
49.613 +
49.614 + protected boolean isHeldExclusively() {
49.615 + return getState() == 1;
49.616 + }
49.617 +
49.618 + protected boolean tryAcquire(int unused) {
49.619 + if (compareAndSetState(0, 1)) {
49.620 + setExclusiveOwnerThread(Thread.currentThread());
49.621 + return true;
49.622 + }
49.623 + return false;
49.624 + }
49.625 +
49.626 + protected boolean tryRelease(int unused) {
49.627 + setExclusiveOwnerThread(null);
49.628 + setState(0);
49.629 + return true;
49.630 + }
49.631 +
49.632 + public void lock() { acquire(1); }
49.633 + public boolean tryLock() { return tryAcquire(1); }
49.634 + public void unlock() { release(1); }
49.635 + public boolean isLocked() { return isHeldExclusively(); }
49.636 + }
49.637 +
49.638 + /*
49.639 + * Methods for setting control state
49.640 + */
49.641 +
49.642 + /**
49.643 + * Transitions runState to given target, or leaves it alone if
49.644 + * already at least the given target.
49.645 + *
49.646 + * @param targetState the desired state, either SHUTDOWN or STOP
49.647 + * (but not TIDYING or TERMINATED -- use tryTerminate for that)
49.648 + */
49.649 + private void advanceRunState(int targetState) {
49.650 + for (;;) {
49.651 + int c = ctl.get();
49.652 + if (runStateAtLeast(c, targetState) ||
49.653 + ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))))
49.654 + break;
49.655 + }
49.656 + }
49.657 +
49.658 + /**
49.659 + * Transitions to TERMINATED state if either (SHUTDOWN and pool
49.660 + * and queue empty) or (STOP and pool empty). If otherwise
49.661 + * eligible to terminate but workerCount is nonzero, interrupts an
49.662 + * idle worker to ensure that shutdown signals propagate. This
49.663 + * method must be called following any action that might make
49.664 + * termination possible -- reducing worker count or removing tasks
49.665 + * from the queue during shutdown. The method is non-private to
49.666 + * allow access from ScheduledThreadPoolExecutor.
49.667 + */
49.668 + final void tryTerminate() {
49.669 + for (;;) {
49.670 + int c = ctl.get();
49.671 + if (isRunning(c) ||
49.672 + runStateAtLeast(c, TIDYING) ||
49.673 + (runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
49.674 + return;
49.675 + if (workerCountOf(c) != 0) { // Eligible to terminate
49.676 + interruptIdleWorkers(ONLY_ONE);
49.677 + return;
49.678 + }
49.679 +
49.680 + final ReentrantLock mainLock = this.mainLock;
49.681 + mainLock.lock();
49.682 + try {
49.683 + if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
49.684 + try {
49.685 + terminated();
49.686 + } finally {
49.687 + ctl.set(ctlOf(TERMINATED, 0));
49.688 + termination.signalAll();
49.689 + }
49.690 + return;
49.691 + }
49.692 + } finally {
49.693 + mainLock.unlock();
49.694 + }
49.695 + // else retry on failed CAS
49.696 + }
49.697 + }
49.698 +
49.699 + /*
49.700 + * Methods for controlling interrupts to worker threads.
49.701 + */
49.702 +
49.703 + /**
49.704 + * If there is a security manager, makes sure caller has
49.705 + * permission to shut down threads in general (see shutdownPerm).
49.706 + * If this passes, additionally makes sure the caller is allowed
49.707 + * to interrupt each worker thread. This might not be true even if
49.708 + * first check passed, if the SecurityManager treats some threads
49.709 + * specially.
49.710 + */
49.711 + private void checkShutdownAccess() {
49.712 + SecurityManager security = System.getSecurityManager();
49.713 + if (security != null) {
49.714 + security.checkPermission(shutdownPerm);
49.715 + final ReentrantLock mainLock = this.mainLock;
49.716 + mainLock.lock();
49.717 + try {
49.718 + for (Worker w : workers)
49.719 + security.checkAccess(w.thread);
49.720 + } finally {
49.721 + mainLock.unlock();
49.722 + }
49.723 + }
49.724 + }
49.725 +
49.726 + /**
49.727 + * Interrupts all threads, even if active. Ignores SecurityExceptions
49.728 + * (in which case some threads may remain uninterrupted).
49.729 + */
49.730 + private void interruptWorkers() {
49.731 + final ReentrantLock mainLock = this.mainLock;
49.732 + mainLock.lock();
49.733 + try {
49.734 + for (Worker w : workers) {
49.735 + try {
49.736 + w.thread.interrupt();
49.737 + } catch (SecurityException ignore) {
49.738 + }
49.739 + }
49.740 + } finally {
49.741 + mainLock.unlock();
49.742 + }
49.743 + }
49.744 +
49.745 + /**
49.746 + * Interrupts threads that might be waiting for tasks (as
49.747 + * indicated by not being locked) so they can check for
49.748 + * termination or configuration changes. Ignores
49.749 + * SecurityExceptions (in which case some threads may remain
49.750 + * uninterrupted).
49.751 + *
49.752 + * @param onlyOne If true, interrupt at most one worker. This is
49.753 + * called only from tryTerminate when termination is otherwise
49.754 + * enabled but there are still other workers. In this case, at
49.755 + * most one waiting worker is interrupted to propagate shutdown
49.756 + * signals in case all threads are currently waiting.
49.757 + * Interrupting any arbitrary thread ensures that newly arriving
49.758 + * workers since shutdown began will also eventually exit.
49.759 + * To guarantee eventual termination, it suffices to always
49.760 + * interrupt only one idle worker, but shutdown() interrupts all
49.761 + * idle workers so that redundant workers exit promptly, not
49.762 + * waiting for a straggler task to finish.
49.763 + */
49.764 + private void interruptIdleWorkers(boolean onlyOne) {
49.765 + final ReentrantLock mainLock = this.mainLock;
49.766 + mainLock.lock();
49.767 + try {
49.768 + for (Worker w : workers) {
49.769 + Thread t = w.thread;
49.770 + if (!t.isInterrupted() && w.tryLock()) {
49.771 + try {
49.772 + t.interrupt();
49.773 + } catch (SecurityException ignore) {
49.774 + } finally {
49.775 + w.unlock();
49.776 + }
49.777 + }
49.778 + if (onlyOne)
49.779 + break;
49.780 + }
49.781 + } finally {
49.782 + mainLock.unlock();
49.783 + }
49.784 + }
49.785 +
49.786 + /**
49.787 + * Common form of interruptIdleWorkers, to avoid having to
49.788 + * remember what the boolean argument means.
49.789 + */
49.790 + private void interruptIdleWorkers() {
49.791 + interruptIdleWorkers(false);
49.792 + }
49.793 +
49.794 + private static final boolean ONLY_ONE = true;
49.795 +
49.796 + /**
49.797 + * Ensures that unless the pool is stopping, the current thread
49.798 + * does not have its interrupt set. This requires a double-check
49.799 + * of state in case the interrupt was cleared concurrently with a
49.800 + * shutdownNow -- if so, the interrupt is re-enabled.
49.801 + */
49.802 + private void clearInterruptsForTaskRun() {
49.803 + if (runStateLessThan(ctl.get(), STOP) &&
49.804 + Thread.interrupted() &&
49.805 + runStateAtLeast(ctl.get(), STOP))
49.806 + Thread.currentThread().interrupt();
49.807 + }
49.808 +
49.809 + /*
49.810 + * Misc utilities, most of which are also exported to
49.811 + * ScheduledThreadPoolExecutor
49.812 + */
49.813 +
49.814 + /**
49.815 + * Invokes the rejected execution handler for the given command.
49.816 + * Package-protected for use by ScheduledThreadPoolExecutor.
49.817 + */
49.818 + final void reject(Runnable command) {
49.819 + handler.rejectedExecution(command, this);
49.820 + }
49.821 +
49.822 + /**
49.823 + * Performs any further cleanup following run state transition on
49.824 + * invocation of shutdown. A no-op here, but used by
49.825 + * ScheduledThreadPoolExecutor to cancel delayed tasks.
49.826 + */
49.827 + void onShutdown() {
49.828 + }
49.829 +
49.830 + /**
49.831 + * State check needed by ScheduledThreadPoolExecutor to
49.832 + * enable running tasks during shutdown.
49.833 + *
49.834 + * @param shutdownOK true if should return true if SHUTDOWN
49.835 + */
49.836 + final boolean isRunningOrShutdown(boolean shutdownOK) {
49.837 + int rs = runStateOf(ctl.get());
49.838 + return rs == RUNNING || (rs == SHUTDOWN && shutdownOK);
49.839 + }
49.840 +
49.841 + /**
49.842 + * Drains the task queue into a new list, normally using
49.843 + * drainTo. But if the queue is a DelayQueue or any other kind of
49.844 + * queue for which poll or drainTo may fail to remove some
49.845 + * elements, it deletes them one by one.
49.846 + */
49.847 + private List<Runnable> drainQueue() {
49.848 + BlockingQueue<Runnable> q = workQueue;
49.849 + List<Runnable> taskList = new ArrayList<Runnable>();
49.850 + q.drainTo(taskList);
49.851 + if (!q.isEmpty()) {
49.852 + for (Runnable r : q.toArray(new Runnable[0])) {
49.853 + if (q.remove(r))
49.854 + taskList.add(r);
49.855 + }
49.856 + }
49.857 + return taskList;
49.858 + }
49.859 +
49.860 + /*
49.861 + * Methods for creating, running and cleaning up after workers
49.862 + */
49.863 +
49.864 + /**
49.865 + * Checks if a new worker can be added with respect to current
49.866 + * pool state and the given bound (either core or maximum). If so,
49.867 + * the worker count is adjusted accordingly, and, if possible, a
49.868 + * new worker is created and started running firstTask as its
49.869 + * first task. This method returns false if the pool is stopped or
49.870 + * eligible to shut down. It also returns false if the thread
49.871 + * factory fails to create a thread when asked, which requires a
49.872 + * backout of workerCount, and a recheck for termination, in case
49.873 + * the existence of this worker was holding up termination.
49.874 + *
49.875 + * @param firstTask the task the new thread should run first (or
49.876 + * null if none). Workers are created with an initial first task
49.877 + * (in method execute()) to bypass queuing when there are fewer
49.878 + * than corePoolSize threads (in which case we always start one),
49.879 + * or when the queue is full (in which case we must bypass queue).
49.880 + * Initially idle threads are usually created via
49.881 + * prestartCoreThread or to replace other dying workers.
49.882 + *
49.883 + * @param core if true use corePoolSize as bound, else
49.884 + * maximumPoolSize. (A boolean indicator is used here rather than a
49.885 + * value to ensure reads of fresh values after checking other pool
49.886 + * state).
49.887 + * @return true if successful
49.888 + */
49.889 + private boolean addWorker(Runnable firstTask, boolean core) {
49.890 + retry:
49.891 + for (;;) {
49.892 + int c = ctl.get();
49.893 + int rs = runStateOf(c);
49.894 +
49.895 + // Check if queue empty only if necessary.
49.896 + if (rs >= SHUTDOWN &&
49.897 + ! (rs == SHUTDOWN &&
49.898 + firstTask == null &&
49.899 + ! workQueue.isEmpty()))
49.900 + return false;
49.901 +
49.902 + for (;;) {
49.903 + int wc = workerCountOf(c);
49.904 + if (wc >= CAPACITY ||
49.905 + wc >= (core ? corePoolSize : maximumPoolSize))
49.906 + return false;
49.907 + if (compareAndIncrementWorkerCount(c))
49.908 + break retry;
49.909 + c = ctl.get(); // Re-read ctl
49.910 + if (runStateOf(c) != rs)
49.911 + continue retry;
49.912 + // else CAS failed due to workerCount change; retry inner loop
49.913 + }
49.914 + }
49.915 +
49.916 + Worker w = new Worker(firstTask);
49.917 + Thread t = w.thread;
49.918 +
49.919 + final ReentrantLock mainLock = this.mainLock;
49.920 + mainLock.lock();
49.921 + try {
49.922 + // Recheck while holding lock.
49.923 + // Back out on ThreadFactory failure or if
49.924 + // shut down before lock acquired.
49.925 + int c = ctl.get();
49.926 + int rs = runStateOf(c);
49.927 +
49.928 + if (t == null ||
49.929 + (rs >= SHUTDOWN &&
49.930 + ! (rs == SHUTDOWN &&
49.931 + firstTask == null))) {
49.932 + decrementWorkerCount();
49.933 + tryTerminate();
49.934 + return false;
49.935 + }
49.936 +
49.937 + workers.add(w);
49.938 +
49.939 + int s = workers.size();
49.940 + if (s > largestPoolSize)
49.941 + largestPoolSize = s;
49.942 + } finally {
49.943 + mainLock.unlock();
49.944 + }
49.945 +
49.946 + t.start();
49.947 + // It is possible (but unlikely) for a thread to have been
49.948 + // added to workers, but not yet started, during transition to
49.949 + // STOP, which could result in a rare missed interrupt,
49.950 + // because Thread.interrupt is not guaranteed to have any effect
49.951 + // on a non-yet-started Thread (see Thread#interrupt).
49.952 + if (runStateOf(ctl.get()) == STOP && ! t.isInterrupted())
49.953 + t.interrupt();
49.954 +
49.955 + return true;
49.956 + }
49.957 +
49.958 + /**
49.959 + * Performs cleanup and bookkeeping for a dying worker. Called
49.960 + * only from worker threads. Unless completedAbruptly is set,
49.961 + * assumes that workerCount has already been adjusted to account
49.962 + * for exit. This method removes thread from worker set, and
49.963 + * possibly terminates the pool or replaces the worker if either
49.964 + * it exited due to user task exception or if fewer than
49.965 + * corePoolSize workers are running or queue is non-empty but
49.966 + * there are no workers.
49.967 + *
49.968 + * @param w the worker
49.969 + * @param completedAbruptly if the worker died due to user exception
49.970 + */
49.971 + private void processWorkerExit(Worker w, boolean completedAbruptly) {
49.972 + if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
49.973 + decrementWorkerCount();
49.974 +
49.975 + final ReentrantLock mainLock = this.mainLock;
49.976 + mainLock.lock();
49.977 + try {
49.978 + completedTaskCount += w.completedTasks;
49.979 + workers.remove(w);
49.980 + } finally {
49.981 + mainLock.unlock();
49.982 + }
49.983 +
49.984 + tryTerminate();
49.985 +
49.986 + int c = ctl.get();
49.987 + if (runStateLessThan(c, STOP)) {
49.988 + if (!completedAbruptly) {
49.989 + int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
49.990 + if (min == 0 && ! workQueue.isEmpty())
49.991 + min = 1;
49.992 + if (workerCountOf(c) >= min)
49.993 + return; // replacement not needed
49.994 + }
49.995 + addWorker(null, false);
49.996 + }
49.997 + }
49.998 +
49.999 + /**
49.1000 + * Performs blocking or timed wait for a task, depending on
49.1001 + * current configuration settings, or returns null if this worker
49.1002 + * must exit because of any of:
49.1003 + * 1. There are more than maximumPoolSize workers (due to
49.1004 + * a call to setMaximumPoolSize).
49.1005 + * 2. The pool is stopped.
49.1006 + * 3. The pool is shutdown and the queue is empty.
49.1007 + * 4. This worker timed out waiting for a task, and timed-out
49.1008 + * workers are subject to termination (that is,
49.1009 + * {@code allowCoreThreadTimeOut || workerCount > corePoolSize})
49.1010 + * both before and after the timed wait.
49.1011 + *
49.1012 + * @return task, or null if the worker must exit, in which case
49.1013 + * workerCount is decremented
49.1014 + */
49.1015 + private Runnable getTask() {
49.1016 + boolean timedOut = false; // Did the last poll() time out?
49.1017 +
49.1018 + retry:
49.1019 + for (;;) {
49.1020 + int c = ctl.get();
49.1021 + int rs = runStateOf(c);
49.1022 +
49.1023 + // Check if queue empty only if necessary.
49.1024 + if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
49.1025 + decrementWorkerCount();
49.1026 + return null;
49.1027 + }
49.1028 +
49.1029 + boolean timed; // Are workers subject to culling?
49.1030 +
49.1031 + for (;;) {
49.1032 + int wc = workerCountOf(c);
49.1033 + timed = allowCoreThreadTimeOut || wc > corePoolSize;
49.1034 +
49.1035 + if (wc <= maximumPoolSize && ! (timedOut && timed))
49.1036 + break;
49.1037 + if (compareAndDecrementWorkerCount(c))
49.1038 + return null;
49.1039 + c = ctl.get(); // Re-read ctl
49.1040 + if (runStateOf(c) != rs)
49.1041 + continue retry;
49.1042 + // else CAS failed due to workerCount change; retry inner loop
49.1043 + }
49.1044 +
49.1045 + try {
49.1046 + Runnable r = timed ?
49.1047 + workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
49.1048 + workQueue.take();
49.1049 + if (r != null)
49.1050 + return r;
49.1051 + timedOut = true;
49.1052 + } catch (InterruptedException retry) {
49.1053 + timedOut = false;
49.1054 + }
49.1055 + }
49.1056 + }
49.1057 +
49.1058 + /**
49.1059 + * Main worker run loop. Repeatedly gets tasks from queue and
49.1060 + * executes them, while coping with a number of issues:
49.1061 + *
49.1062 + * 1. We may start out with an initial task, in which case we
49.1063 + * don't need to get the first one. Otherwise, as long as pool is
49.1064 + * running, we get tasks from getTask. If it returns null then the
49.1065 + * worker exits due to changed pool state or configuration
49.1066 + * parameters. Other exits result from exception throws in
49.1067 + * external code, in which case completedAbruptly holds, which
49.1068 + * usually leads processWorkerExit to replace this thread.
49.1069 + *
49.1070 + * 2. Before running any task, the lock is acquired to prevent
49.1071 + * other pool interrupts while the task is executing, and
49.1072 + * clearInterruptsForTaskRun called to ensure that unless pool is
49.1073 + * stopping, this thread does not have its interrupt set.
49.1074 + *
49.1075 + * 3. Each task run is preceded by a call to beforeExecute, which
49.1076 + * might throw an exception, in which case we cause thread to die
49.1077 + * (breaking loop with completedAbruptly true) without processing
49.1078 + * the task.
49.1079 + *
49.1080 + * 4. Assuming beforeExecute completes normally, we run the task,
49.1081 + * gathering any of its thrown exceptions to send to
49.1082 + * afterExecute. We separately handle RuntimeException, Error
49.1083 + * (both of which the specs guarantee that we trap) and arbitrary
49.1084 + * Throwables. Because we cannot rethrow Throwables within
49.1085 + * Runnable.run, we wrap them within Errors on the way out (to the
49.1086 + * thread's UncaughtExceptionHandler). Any thrown exception also
49.1087 + * conservatively causes thread to die.
49.1088 + *
49.1089 + * 5. After task.run completes, we call afterExecute, which may
49.1090 + * also throw an exception, which will also cause thread to
49.1091 + * die. According to JLS Sec 14.20, this exception is the one that
49.1092 + * will be in effect even if task.run throws.
49.1093 + *
49.1094 + * The net effect of the exception mechanics is that afterExecute
49.1095 + * and the thread's UncaughtExceptionHandler have as accurate
49.1096 + * information as we can provide about any problems encountered by
49.1097 + * user code.
49.1098 + *
49.1099 + * @param w the worker
49.1100 + */
49.1101 + final void runWorker(Worker w) {
49.1102 + Runnable task = w.firstTask;
49.1103 + w.firstTask = null;
49.1104 + boolean completedAbruptly = true;
49.1105 + try {
49.1106 + while (task != null || (task = getTask()) != null) {
49.1107 + w.lock();
49.1108 + clearInterruptsForTaskRun();
49.1109 + try {
49.1110 + beforeExecute(w.thread, task);
49.1111 + Throwable thrown = null;
49.1112 + try {
49.1113 + task.run();
49.1114 + } catch (RuntimeException x) {
49.1115 + thrown = x; throw x;
49.1116 + } catch (Error x) {
49.1117 + thrown = x; throw x;
49.1118 + } catch (Throwable x) {
49.1119 + thrown = x; throw new Error(x);
49.1120 + } finally {
49.1121 + afterExecute(task, thrown);
49.1122 + }
49.1123 + } finally {
49.1124 + task = null;
49.1125 + w.completedTasks++;
49.1126 + w.unlock();
49.1127 + }
49.1128 + }
49.1129 + completedAbruptly = false;
49.1130 + } finally {
49.1131 + processWorkerExit(w, completedAbruptly);
49.1132 + }
49.1133 + }
49.1134 +
49.1135 + // Public constructors and methods
49.1136 +
49.1137 + /**
49.1138 + * Creates a new {@code ThreadPoolExecutor} with the given initial
49.1139 + * parameters and default thread factory and rejected execution handler.
49.1140 + * It may be more convenient to use one of the {@link Executors} factory
49.1141 + * methods instead of this general purpose constructor.
49.1142 + *
49.1143 + * @param corePoolSize the number of threads to keep in the pool, even
49.1144 + * if they are idle, unless {@code allowCoreThreadTimeOut} is set
49.1145 + * @param maximumPoolSize the maximum number of threads to allow in the
49.1146 + * pool
49.1147 + * @param keepAliveTime when the number of threads is greater than
49.1148 + * the core, this is the maximum time that excess idle threads
49.1149 + * will wait for new tasks before terminating.
49.1150 + * @param unit the time unit for the {@code keepAliveTime} argument
49.1151 + * @param workQueue the queue to use for holding tasks before they are
49.1152 + * executed. This queue will hold only the {@code Runnable}
49.1153 + * tasks submitted by the {@code execute} method.
49.1154 + * @throws IllegalArgumentException if one of the following holds:<br>
49.1155 + * {@code corePoolSize < 0}<br>
49.1156 + * {@code keepAliveTime < 0}<br>
49.1157 + * {@code maximumPoolSize <= 0}<br>
49.1158 + * {@code maximumPoolSize < corePoolSize}
49.1159 + * @throws NullPointerException if {@code workQueue} is null
49.1160 + */
49.1161 + public ThreadPoolExecutor(int corePoolSize,
49.1162 + int maximumPoolSize,
49.1163 + long keepAliveTime,
49.1164 + TimeUnit unit,
49.1165 + BlockingQueue<Runnable> workQueue) {
49.1166 + this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
49.1167 + Executors.defaultThreadFactory(), defaultHandler);
49.1168 + }
49.1169 +
49.1170 + /**
49.1171 + * Creates a new {@code ThreadPoolExecutor} with the given initial
49.1172 + * parameters and default rejected execution handler.
49.1173 + *
49.1174 + * @param corePoolSize the number of threads to keep in the pool, even
49.1175 + * if they are idle, unless {@code allowCoreThreadTimeOut} is set
49.1176 + * @param maximumPoolSize the maximum number of threads to allow in the
49.1177 + * pool
49.1178 + * @param keepAliveTime when the number of threads is greater than
49.1179 + * the core, this is the maximum time that excess idle threads
49.1180 + * will wait for new tasks before terminating.
49.1181 + * @param unit the time unit for the {@code keepAliveTime} argument
49.1182 + * @param workQueue the queue to use for holding tasks before they are
49.1183 + * executed. This queue will hold only the {@code Runnable}
49.1184 + * tasks submitted by the {@code execute} method.
49.1185 + * @param threadFactory the factory to use when the executor
49.1186 + * creates a new thread
49.1187 + * @throws IllegalArgumentException if one of the following holds:<br>
49.1188 + * {@code corePoolSize < 0}<br>
49.1189 + * {@code keepAliveTime < 0}<br>
49.1190 + * {@code maximumPoolSize <= 0}<br>
49.1191 + * {@code maximumPoolSize < corePoolSize}
49.1192 + * @throws NullPointerException if {@code workQueue}
49.1193 + * or {@code threadFactory} is null
49.1194 + */
49.1195 + public ThreadPoolExecutor(int corePoolSize,
49.1196 + int maximumPoolSize,
49.1197 + long keepAliveTime,
49.1198 + TimeUnit unit,
49.1199 + BlockingQueue<Runnable> workQueue,
49.1200 + ThreadFactory threadFactory) {
49.1201 + this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
49.1202 + threadFactory, defaultHandler);
49.1203 + }
49.1204 +
49.1205 + /**
49.1206 + * Creates a new {@code ThreadPoolExecutor} with the given initial
49.1207 + * parameters and default thread factory.
49.1208 + *
49.1209 + * @param corePoolSize the number of threads to keep in the pool, even
49.1210 + * if they are idle, unless {@code allowCoreThreadTimeOut} is set
49.1211 + * @param maximumPoolSize the maximum number of threads to allow in the
49.1212 + * pool
49.1213 + * @param keepAliveTime when the number of threads is greater than
49.1214 + * the core, this is the maximum time that excess idle threads
49.1215 + * will wait for new tasks before terminating.
49.1216 + * @param unit the time unit for the {@code keepAliveTime} argument
49.1217 + * @param workQueue the queue to use for holding tasks before they are
49.1218 + * executed. This queue will hold only the {@code Runnable}
49.1219 + * tasks submitted by the {@code execute} method.
49.1220 + * @param handler the handler to use when execution is blocked
49.1221 + * because the thread bounds and queue capacities are reached
49.1222 + * @throws IllegalArgumentException if one of the following holds:<br>
49.1223 + * {@code corePoolSize < 0}<br>
49.1224 + * {@code keepAliveTime < 0}<br>
49.1225 + * {@code maximumPoolSize <= 0}<br>
49.1226 + * {@code maximumPoolSize < corePoolSize}
49.1227 + * @throws NullPointerException if {@code workQueue}
49.1228 + * or {@code handler} is null
49.1229 + */
49.1230 + public ThreadPoolExecutor(int corePoolSize,
49.1231 + int maximumPoolSize,
49.1232 + long keepAliveTime,
49.1233 + TimeUnit unit,
49.1234 + BlockingQueue<Runnable> workQueue,
49.1235 + RejectedExecutionHandler handler) {
49.1236 + this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
49.1237 + Executors.defaultThreadFactory(), handler);
49.1238 + }
49.1239 +
49.1240 + /**
49.1241 + * Creates a new {@code ThreadPoolExecutor} with the given initial
49.1242 + * parameters.
49.1243 + *
49.1244 + * @param corePoolSize the number of threads to keep in the pool, even
49.1245 + * if they are idle, unless {@code allowCoreThreadTimeOut} is set
49.1246 + * @param maximumPoolSize the maximum number of threads to allow in the
49.1247 + * pool
49.1248 + * @param keepAliveTime when the number of threads is greater than
49.1249 + * the core, this is the maximum time that excess idle threads
49.1250 + * will wait for new tasks before terminating.
49.1251 + * @param unit the time unit for the {@code keepAliveTime} argument
49.1252 + * @param workQueue the queue to use for holding tasks before they are
49.1253 + * executed. This queue will hold only the {@code Runnable}
49.1254 + * tasks submitted by the {@code execute} method.
49.1255 + * @param threadFactory the factory to use when the executor
49.1256 + * creates a new thread
49.1257 + * @param handler the handler to use when execution is blocked
49.1258 + * because the thread bounds and queue capacities are reached
49.1259 + * @throws IllegalArgumentException if one of the following holds:<br>
49.1260 + * {@code corePoolSize < 0}<br>
49.1261 + * {@code keepAliveTime < 0}<br>
49.1262 + * {@code maximumPoolSize <= 0}<br>
49.1263 + * {@code maximumPoolSize < corePoolSize}
49.1264 + * @throws NullPointerException if {@code workQueue}
49.1265 + * or {@code threadFactory} or {@code handler} is null
49.1266 + */
49.1267 + public ThreadPoolExecutor(int corePoolSize,
49.1268 + int maximumPoolSize,
49.1269 + long keepAliveTime,
49.1270 + TimeUnit unit,
49.1271 + BlockingQueue<Runnable> workQueue,
49.1272 + ThreadFactory threadFactory,
49.1273 + RejectedExecutionHandler handler) {
49.1274 + if (corePoolSize < 0 ||
49.1275 + maximumPoolSize <= 0 ||
49.1276 + maximumPoolSize < corePoolSize ||
49.1277 + keepAliveTime < 0)
49.1278 + throw new IllegalArgumentException();
49.1279 + if (workQueue == null || threadFactory == null || handler == null)
49.1280 + throw new NullPointerException();
49.1281 + this.corePoolSize = corePoolSize;
49.1282 + this.maximumPoolSize = maximumPoolSize;
49.1283 + this.workQueue = workQueue;
49.1284 + this.keepAliveTime = unit.toNanos(keepAliveTime);
49.1285 + this.threadFactory = threadFactory;
49.1286 + this.handler = handler;
49.1287 + }
49.1288 +
49.1289 + /**
49.1290 + * Executes the given task sometime in the future. The task
49.1291 + * may execute in a new thread or in an existing pooled thread.
49.1292 + *
49.1293 + * If the task cannot be submitted for execution, either because this
49.1294 + * executor has been shutdown or because its capacity has been reached,
49.1295 + * the task is handled by the current {@code RejectedExecutionHandler}.
49.1296 + *
49.1297 + * @param command the task to execute
49.1298 + * @throws RejectedExecutionException at discretion of
49.1299 + * {@code RejectedExecutionHandler}, if the task
49.1300 + * cannot be accepted for execution
49.1301 + * @throws NullPointerException if {@code command} is null
49.1302 + */
49.1303 + public void execute(Runnable command) {
49.1304 + if (command == null)
49.1305 + throw new NullPointerException();
49.1306 + /*
49.1307 + * Proceed in 3 steps:
49.1308 + *
49.1309 + * 1. If fewer than corePoolSize threads are running, try to
49.1310 + * start a new thread with the given command as its first
49.1311 + * task. The call to addWorker atomically checks runState and
49.1312 + * workerCount, and so prevents false alarms that would add
49.1313 + * threads when it shouldn't, by returning false.
49.1314 + *
49.1315 + * 2. If a task can be successfully queued, then we still need
49.1316 + * to double-check whether we should have added a thread
49.1317 + * (because existing ones died since last checking) or that
49.1318 + * the pool shut down since entry into this method. So we
49.1319 + * recheck state and if necessary roll back the enqueuing if
49.1320 + * stopped, or start a new thread if there are none.
49.1321 + *
49.1322 + * 3. If we cannot queue task, then we try to add a new
49.1323 + * thread. If it fails, we know we are shut down or saturated
49.1324 + * and so reject the task.
49.1325 + */
49.1326 + int c = ctl.get();
49.1327 + if (workerCountOf(c) < corePoolSize) {
49.1328 + if (addWorker(command, true))
49.1329 + return;
49.1330 + c = ctl.get();
49.1331 + }
49.1332 + if (isRunning(c) && workQueue.offer(command)) {
49.1333 + int recheck = ctl.get();
49.1334 + if (! isRunning(recheck) && remove(command))
49.1335 + reject(command);
49.1336 + else if (workerCountOf(recheck) == 0)
49.1337 + addWorker(null, false);
49.1338 + }
49.1339 + else if (!addWorker(command, false))
49.1340 + reject(command);
49.1341 + }
49.1342 +
49.1343 + /**
49.1344 + * Initiates an orderly shutdown in which previously submitted
49.1345 + * tasks are executed, but no new tasks will be accepted.
49.1346 + * Invocation has no additional effect if already shut down.
49.1347 + *
49.1348 + * <p>This method does not wait for previously submitted tasks to
49.1349 + * complete execution. Use {@link #awaitTermination awaitTermination}
49.1350 + * to do that.
49.1351 + *
49.1352 + * @throws SecurityException {@inheritDoc}
49.1353 + */
49.1354 + public void shutdown() {
49.1355 + final ReentrantLock mainLock = this.mainLock;
49.1356 + mainLock.lock();
49.1357 + try {
49.1358 + checkShutdownAccess();
49.1359 + advanceRunState(SHUTDOWN);
49.1360 + interruptIdleWorkers();
49.1361 + onShutdown(); // hook for ScheduledThreadPoolExecutor
49.1362 + } finally {
49.1363 + mainLock.unlock();
49.1364 + }
49.1365 + tryTerminate();
49.1366 + }
49.1367 +
49.1368 + /**
49.1369 + * Attempts to stop all actively executing tasks, halts the
49.1370 + * processing of waiting tasks, and returns a list of the tasks
49.1371 + * that were awaiting execution. These tasks are drained (removed)
49.1372 + * from the task queue upon return from this method.
49.1373 + *
49.1374 + * <p>This method does not wait for actively executing tasks to
49.1375 + * terminate. Use {@link #awaitTermination awaitTermination} to
49.1376 + * do that.
49.1377 + *
49.1378 + * <p>There are no guarantees beyond best-effort attempts to stop
49.1379 + * processing actively executing tasks. This implementation
49.1380 + * cancels tasks via {@link Thread#interrupt}, so any task that
49.1381 + * fails to respond to interrupts may never terminate.
49.1382 + *
49.1383 + * @throws SecurityException {@inheritDoc}
49.1384 + */
49.1385 + public List<Runnable> shutdownNow() {
49.1386 + List<Runnable> tasks;
49.1387 + final ReentrantLock mainLock = this.mainLock;
49.1388 + mainLock.lock();
49.1389 + try {
49.1390 + checkShutdownAccess();
49.1391 + advanceRunState(STOP);
49.1392 + interruptWorkers();
49.1393 + tasks = drainQueue();
49.1394 + } finally {
49.1395 + mainLock.unlock();
49.1396 + }
49.1397 + tryTerminate();
49.1398 + return tasks;
49.1399 + }
49.1400 +
49.1401 + public boolean isShutdown() {
49.1402 + return ! isRunning(ctl.get());
49.1403 + }
49.1404 +
49.1405 + /**
49.1406 + * Returns true if this executor is in the process of terminating
49.1407 + * after {@link #shutdown} or {@link #shutdownNow} but has not
49.1408 + * completely terminated. This method may be useful for
49.1409 + * debugging. A return of {@code true} reported a sufficient
49.1410 + * period after shutdown may indicate that submitted tasks have
49.1411 + * ignored or suppressed interruption, causing this executor not
49.1412 + * to properly terminate.
49.1413 + *
49.1414 + * @return true if terminating but not yet terminated
49.1415 + */
49.1416 + public boolean isTerminating() {
49.1417 + int c = ctl.get();
49.1418 + return ! isRunning(c) && runStateLessThan(c, TERMINATED);
49.1419 + }
49.1420 +
49.1421 + public boolean isTerminated() {
49.1422 + return runStateAtLeast(ctl.get(), TERMINATED);
49.1423 + }
49.1424 +
49.1425 + public boolean awaitTermination(long timeout, TimeUnit unit)
49.1426 + throws InterruptedException {
49.1427 + long nanos = unit.toNanos(timeout);
49.1428 + final ReentrantLock mainLock = this.mainLock;
49.1429 + mainLock.lock();
49.1430 + try {
49.1431 + for (;;) {
49.1432 + if (runStateAtLeast(ctl.get(), TERMINATED))
49.1433 + return true;
49.1434 + if (nanos <= 0)
49.1435 + return false;
49.1436 + nanos = termination.awaitNanos(nanos);
49.1437 + }
49.1438 + } finally {
49.1439 + mainLock.unlock();
49.1440 + }
49.1441 + }
49.1442 +
49.1443 + /**
49.1444 + * Invokes {@code shutdown} when this executor is no longer
49.1445 + * referenced and it has no threads.
49.1446 + */
49.1447 + protected void finalize() {
49.1448 + shutdown();
49.1449 + }
49.1450 +
49.1451 + /**
49.1452 + * Sets the thread factory used to create new threads.
49.1453 + *
49.1454 + * @param threadFactory the new thread factory
49.1455 + * @throws NullPointerException if threadFactory is null
49.1456 + * @see #getThreadFactory
49.1457 + */
49.1458 + public void setThreadFactory(ThreadFactory threadFactory) {
49.1459 + if (threadFactory == null)
49.1460 + throw new NullPointerException();
49.1461 + this.threadFactory = threadFactory;
49.1462 + }
49.1463 +
49.1464 + /**
49.1465 + * Returns the thread factory used to create new threads.
49.1466 + *
49.1467 + * @return the current thread factory
49.1468 + * @see #setThreadFactory
49.1469 + */
49.1470 + public ThreadFactory getThreadFactory() {
49.1471 + return threadFactory;
49.1472 + }
49.1473 +
49.1474 + /**
49.1475 + * Sets a new handler for unexecutable tasks.
49.1476 + *
49.1477 + * @param handler the new handler
49.1478 + * @throws NullPointerException if handler is null
49.1479 + * @see #getRejectedExecutionHandler
49.1480 + */
49.1481 + public void setRejectedExecutionHandler(RejectedExecutionHandler handler) {
49.1482 + if (handler == null)
49.1483 + throw new NullPointerException();
49.1484 + this.handler = handler;
49.1485 + }
49.1486 +
49.1487 + /**
49.1488 + * Returns the current handler for unexecutable tasks.
49.1489 + *
49.1490 + * @return the current handler
49.1491 + * @see #setRejectedExecutionHandler
49.1492 + */
49.1493 + public RejectedExecutionHandler getRejectedExecutionHandler() {
49.1494 + return handler;
49.1495 + }
49.1496 +
49.1497 + /**
49.1498 + * Sets the core number of threads. This overrides any value set
49.1499 + * in the constructor. If the new value is smaller than the
49.1500 + * current value, excess existing threads will be terminated when
49.1501 + * they next become idle. If larger, new threads will, if needed,
49.1502 + * be started to execute any queued tasks.
49.1503 + *
49.1504 + * @param corePoolSize the new core size
49.1505 + * @throws IllegalArgumentException if {@code corePoolSize < 0}
49.1506 + * @see #getCorePoolSize
49.1507 + */
49.1508 + public void setCorePoolSize(int corePoolSize) {
49.1509 + if (corePoolSize < 0)
49.1510 + throw new IllegalArgumentException();
49.1511 + int delta = corePoolSize - this.corePoolSize;
49.1512 + this.corePoolSize = corePoolSize;
49.1513 + if (workerCountOf(ctl.get()) > corePoolSize)
49.1514 + interruptIdleWorkers();
49.1515 + else if (delta > 0) {
49.1516 + // We don't really know how many new threads are "needed".
49.1517 + // As a heuristic, prestart enough new workers (up to new
49.1518 + // core size) to handle the current number of tasks in
49.1519 + // queue, but stop if queue becomes empty while doing so.
49.1520 + int k = Math.min(delta, workQueue.size());
49.1521 + while (k-- > 0 && addWorker(null, true)) {
49.1522 + if (workQueue.isEmpty())
49.1523 + break;
49.1524 + }
49.1525 + }
49.1526 + }
49.1527 +
49.1528 + /**
49.1529 + * Returns the core number of threads.
49.1530 + *
49.1531 + * @return the core number of threads
49.1532 + * @see #setCorePoolSize
49.1533 + */
49.1534 + public int getCorePoolSize() {
49.1535 + return corePoolSize;
49.1536 + }
49.1537 +
49.1538 + /**
49.1539 + * Starts a core thread, causing it to idly wait for work. This
49.1540 + * overrides the default policy of starting core threads only when
49.1541 + * new tasks are executed. This method will return {@code false}
49.1542 + * if all core threads have already been started.
49.1543 + *
49.1544 + * @return {@code true} if a thread was started
49.1545 + */
49.1546 + public boolean prestartCoreThread() {
49.1547 + return workerCountOf(ctl.get()) < corePoolSize &&
49.1548 + addWorker(null, true);
49.1549 + }
49.1550 +
49.1551 + /**
49.1552 + * Starts all core threads, causing them to idly wait for work. This
49.1553 + * overrides the default policy of starting core threads only when
49.1554 + * new tasks are executed.
49.1555 + *
49.1556 + * @return the number of threads started
49.1557 + */
49.1558 + public int prestartAllCoreThreads() {
49.1559 + int n = 0;
49.1560 + while (addWorker(null, true))
49.1561 + ++n;
49.1562 + return n;
49.1563 + }
49.1564 +
49.1565 + /**
49.1566 + * Returns true if this pool allows core threads to time out and
49.1567 + * terminate if no tasks arrive within the keepAlive time, being
49.1568 + * replaced if needed when new tasks arrive. When true, the same
49.1569 + * keep-alive policy applying to non-core threads applies also to
49.1570 + * core threads. When false (the default), core threads are never
49.1571 + * terminated due to lack of incoming tasks.
49.1572 + *
49.1573 + * @return {@code true} if core threads are allowed to time out,
49.1574 + * else {@code false}
49.1575 + *
49.1576 + * @since 1.6
49.1577 + */
49.1578 + public boolean allowsCoreThreadTimeOut() {
49.1579 + return allowCoreThreadTimeOut;
49.1580 + }
49.1581 +
49.1582 + /**
49.1583 + * Sets the policy governing whether core threads may time out and
49.1584 + * terminate if no tasks arrive within the keep-alive time, being
49.1585 + * replaced if needed when new tasks arrive. When false, core
49.1586 + * threads are never terminated due to lack of incoming
49.1587 + * tasks. When true, the same keep-alive policy applying to
49.1588 + * non-core threads applies also to core threads. To avoid
49.1589 + * continual thread replacement, the keep-alive time must be
49.1590 + * greater than zero when setting {@code true}. This method
49.1591 + * should in general be called before the pool is actively used.
49.1592 + *
49.1593 + * @param value {@code true} if should time out, else {@code false}
49.1594 + * @throws IllegalArgumentException if value is {@code true}
49.1595 + * and the current keep-alive time is not greater than zero
49.1596 + *
49.1597 + * @since 1.6
49.1598 + */
49.1599 + public void allowCoreThreadTimeOut(boolean value) {
49.1600 + if (value && keepAliveTime <= 0)
49.1601 + throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
49.1602 + if (value != allowCoreThreadTimeOut) {
49.1603 + allowCoreThreadTimeOut = value;
49.1604 + if (value)
49.1605 + interruptIdleWorkers();
49.1606 + }
49.1607 + }
49.1608 +
49.1609 + /**
49.1610 + * Sets the maximum allowed number of threads. This overrides any
49.1611 + * value set in the constructor. If the new value is smaller than
49.1612 + * the current value, excess existing threads will be
49.1613 + * terminated when they next become idle.
49.1614 + *
49.1615 + * @param maximumPoolSize the new maximum
49.1616 + * @throws IllegalArgumentException if the new maximum is
49.1617 + * less than or equal to zero, or
49.1618 + * less than the {@linkplain #getCorePoolSize core pool size}
49.1619 + * @see #getMaximumPoolSize
49.1620 + */
49.1621 + public void setMaximumPoolSize(int maximumPoolSize) {
49.1622 + if (maximumPoolSize <= 0 || maximumPoolSize < corePoolSize)
49.1623 + throw new IllegalArgumentException();
49.1624 + this.maximumPoolSize = maximumPoolSize;
49.1625 + if (workerCountOf(ctl.get()) > maximumPoolSize)
49.1626 + interruptIdleWorkers();
49.1627 + }
49.1628 +
49.1629 + /**
49.1630 + * Returns the maximum allowed number of threads.
49.1631 + *
49.1632 + * @return the maximum allowed number of threads
49.1633 + * @see #setMaximumPoolSize
49.1634 + */
49.1635 + public int getMaximumPoolSize() {
49.1636 + return maximumPoolSize;
49.1637 + }
49.1638 +
49.1639 + /**
49.1640 + * Sets the time limit for which threads may remain idle before
49.1641 + * being terminated. If there are more than the core number of
49.1642 + * threads currently in the pool, after waiting this amount of
49.1643 + * time without processing a task, excess threads will be
49.1644 + * terminated. This overrides any value set in the constructor.
49.1645 + *
49.1646 + * @param time the time to wait. A time value of zero will cause
49.1647 + * excess threads to terminate immediately after executing tasks.
49.1648 + * @param unit the time unit of the {@code time} argument
49.1649 + * @throws IllegalArgumentException if {@code time} less than zero or
49.1650 + * if {@code time} is zero and {@code allowsCoreThreadTimeOut}
49.1651 + * @see #getKeepAliveTime
49.1652 + */
49.1653 + public void setKeepAliveTime(long time, TimeUnit unit) {
49.1654 + if (time < 0)
49.1655 + throw new IllegalArgumentException();
49.1656 + if (time == 0 && allowsCoreThreadTimeOut())
49.1657 + throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
49.1658 + long keepAliveTime = unit.toNanos(time);
49.1659 + long delta = keepAliveTime - this.keepAliveTime;
49.1660 + this.keepAliveTime = keepAliveTime;
49.1661 + if (delta < 0)
49.1662 + interruptIdleWorkers();
49.1663 + }
49.1664 +
49.1665 + /**
49.1666 + * Returns the thread keep-alive time, which is the amount of time
49.1667 + * that threads in excess of the core pool size may remain
49.1668 + * idle before being terminated.
49.1669 + *
49.1670 + * @param unit the desired time unit of the result
49.1671 + * @return the time limit
49.1672 + * @see #setKeepAliveTime
49.1673 + */
49.1674 + public long getKeepAliveTime(TimeUnit unit) {
49.1675 + return unit.convert(keepAliveTime, TimeUnit.NANOSECONDS);
49.1676 + }
49.1677 +
49.1678 + /* User-level queue utilities */
49.1679 +
49.1680 + /**
49.1681 + * Returns the task queue used by this executor. Access to the
49.1682 + * task queue is intended primarily for debugging and monitoring.
49.1683 + * This queue may be in active use. Retrieving the task queue
49.1684 + * does not prevent queued tasks from executing.
49.1685 + *
49.1686 + * @return the task queue
49.1687 + */
49.1688 + public BlockingQueue<Runnable> getQueue() {
49.1689 + return workQueue;
49.1690 + }
49.1691 +
49.1692 + /**
49.1693 + * Removes this task from the executor's internal queue if it is
49.1694 + * present, thus causing it not to be run if it has not already
49.1695 + * started.
49.1696 + *
49.1697 + * <p> This method may be useful as one part of a cancellation
49.1698 + * scheme. It may fail to remove tasks that have been converted
49.1699 + * into other forms before being placed on the internal queue. For
49.1700 + * example, a task entered using {@code submit} might be
49.1701 + * converted into a form that maintains {@code Future} status.
49.1702 + * However, in such cases, method {@link #purge} may be used to
49.1703 + * remove those Futures that have been cancelled.
49.1704 + *
49.1705 + * @param task the task to remove
49.1706 + * @return true if the task was removed
49.1707 + */
49.1708 + public boolean remove(Runnable task) {
49.1709 + boolean removed = workQueue.remove(task);
49.1710 + tryTerminate(); // In case SHUTDOWN and now empty
49.1711 + return removed;
49.1712 + }
49.1713 +
49.1714 + /**
49.1715 + * Tries to remove from the work queue all {@link Future}
49.1716 + * tasks that have been cancelled. This method can be useful as a
49.1717 + * storage reclamation operation, that has no other impact on
49.1718 + * functionality. Cancelled tasks are never executed, but may
49.1719 + * accumulate in work queues until worker threads can actively
49.1720 + * remove them. Invoking this method instead tries to remove them now.
49.1721 + * However, this method may fail to remove tasks in
49.1722 + * the presence of interference by other threads.
49.1723 + */
49.1724 + public void purge() {
49.1725 + final BlockingQueue<Runnable> q = workQueue;
49.1726 + try {
49.1727 + Iterator<Runnable> it = q.iterator();
49.1728 + while (it.hasNext()) {
49.1729 + Runnable r = it.next();
49.1730 + if (r instanceof Future<?> && ((Future<?>)r).isCancelled())
49.1731 + it.remove();
49.1732 + }
49.1733 + } catch (ConcurrentModificationException fallThrough) {
49.1734 + // Take slow path if we encounter interference during traversal.
49.1735 + // Make copy for traversal and call remove for cancelled entries.
49.1736 + // The slow path is more likely to be O(N*N).
49.1737 + for (Object r : q.toArray())
49.1738 + if (r instanceof Future<?> && ((Future<?>)r).isCancelled())
49.1739 + q.remove(r);
49.1740 + }
49.1741 +
49.1742 + tryTerminate(); // In case SHUTDOWN and now empty
49.1743 + }
49.1744 +
49.1745 + /* Statistics */
49.1746 +
49.1747 + /**
49.1748 + * Returns the current number of threads in the pool.
49.1749 + *
49.1750 + * @return the number of threads
49.1751 + */
49.1752 + public int getPoolSize() {
49.1753 + final ReentrantLock mainLock = this.mainLock;
49.1754 + mainLock.lock();
49.1755 + try {
49.1756 + // Remove rare and surprising possibility of
49.1757 + // isTerminated() && getPoolSize() > 0
49.1758 + return runStateAtLeast(ctl.get(), TIDYING) ? 0
49.1759 + : workers.size();
49.1760 + } finally {
49.1761 + mainLock.unlock();
49.1762 + }
49.1763 + }
49.1764 +
49.1765 + /**
49.1766 + * Returns the approximate number of threads that are actively
49.1767 + * executing tasks.
49.1768 + *
49.1769 + * @return the number of threads
49.1770 + */
49.1771 + public int getActiveCount() {
49.1772 + final ReentrantLock mainLock = this.mainLock;
49.1773 + mainLock.lock();
49.1774 + try {
49.1775 + int n = 0;
49.1776 + for (Worker w : workers)
49.1777 + if (w.isLocked())
49.1778 + ++n;
49.1779 + return n;
49.1780 + } finally {
49.1781 + mainLock.unlock();
49.1782 + }
49.1783 + }
49.1784 +
49.1785 + /**
49.1786 + * Returns the largest number of threads that have ever
49.1787 + * simultaneously been in the pool.
49.1788 + *
49.1789 + * @return the number of threads
49.1790 + */
49.1791 + public int getLargestPoolSize() {
49.1792 + final ReentrantLock mainLock = this.mainLock;
49.1793 + mainLock.lock();
49.1794 + try {
49.1795 + return largestPoolSize;
49.1796 + } finally {
49.1797 + mainLock.unlock();
49.1798 + }
49.1799 + }
49.1800 +
49.1801 + /**
49.1802 + * Returns the approximate total number of tasks that have ever been
49.1803 + * scheduled for execution. Because the states of tasks and
49.1804 + * threads may change dynamically during computation, the returned
49.1805 + * value is only an approximation.
49.1806 + *
49.1807 + * @return the number of tasks
49.1808 + */
49.1809 + public long getTaskCount() {
49.1810 + final ReentrantLock mainLock = this.mainLock;
49.1811 + mainLock.lock();
49.1812 + try {
49.1813 + long n = completedTaskCount;
49.1814 + for (Worker w : workers) {
49.1815 + n += w.completedTasks;
49.1816 + if (w.isLocked())
49.1817 + ++n;
49.1818 + }
49.1819 + return n + workQueue.size();
49.1820 + } finally {
49.1821 + mainLock.unlock();
49.1822 + }
49.1823 + }
49.1824 +
49.1825 + /**
49.1826 + * Returns the approximate total number of tasks that have
49.1827 + * completed execution. Because the states of tasks and threads
49.1828 + * may change dynamically during computation, the returned value
49.1829 + * is only an approximation, but one that does not ever decrease
49.1830 + * across successive calls.
49.1831 + *
49.1832 + * @return the number of tasks
49.1833 + */
49.1834 + public long getCompletedTaskCount() {
49.1835 + final ReentrantLock mainLock = this.mainLock;
49.1836 + mainLock.lock();
49.1837 + try {
49.1838 + long n = completedTaskCount;
49.1839 + for (Worker w : workers)
49.1840 + n += w.completedTasks;
49.1841 + return n;
49.1842 + } finally {
49.1843 + mainLock.unlock();
49.1844 + }
49.1845 + }
49.1846 +
49.1847 + /**
49.1848 + * Returns a string identifying this pool, as well as its state,
49.1849 + * including indications of run state and estimated worker and
49.1850 + * task counts.
49.1851 + *
49.1852 + * @return a string identifying this pool, as well as its state
49.1853 + */
49.1854 + public String toString() {
49.1855 + long ncompleted;
49.1856 + int nworkers, nactive;
49.1857 + final ReentrantLock mainLock = this.mainLock;
49.1858 + mainLock.lock();
49.1859 + try {
49.1860 + ncompleted = completedTaskCount;
49.1861 + nactive = 0;
49.1862 + nworkers = workers.size();
49.1863 + for (Worker w : workers) {
49.1864 + ncompleted += w.completedTasks;
49.1865 + if (w.isLocked())
49.1866 + ++nactive;
49.1867 + }
49.1868 + } finally {
49.1869 + mainLock.unlock();
49.1870 + }
49.1871 + int c = ctl.get();
49.1872 + String rs = (runStateLessThan(c, SHUTDOWN) ? "Running" :
49.1873 + (runStateAtLeast(c, TERMINATED) ? "Terminated" :
49.1874 + "Shutting down"));
49.1875 + return super.toString() +
49.1876 + "[" + rs +
49.1877 + ", pool size = " + nworkers +
49.1878 + ", active threads = " + nactive +
49.1879 + ", queued tasks = " + workQueue.size() +
49.1880 + ", completed tasks = " + ncompleted +
49.1881 + "]";
49.1882 + }
49.1883 +
49.1884 + /* Extension hooks */
49.1885 +
49.1886 + /**
49.1887 + * Method invoked prior to executing the given Runnable in the
49.1888 + * given thread. This method is invoked by thread {@code t} that
49.1889 + * will execute task {@code r}, and may be used to re-initialize
49.1890 + * ThreadLocals, or to perform logging.
49.1891 + *
49.1892 + * <p>This implementation does nothing, but may be customized in
49.1893 + * subclasses. Note: To properly nest multiple overridings, subclasses
49.1894 + * should generally invoke {@code super.beforeExecute} at the end of
49.1895 + * this method.
49.1896 + *
49.1897 + * @param t the thread that will run task {@code r}
49.1898 + * @param r the task that will be executed
49.1899 + */
49.1900 + protected void beforeExecute(Thread t, Runnable r) { }
49.1901 +
49.1902 + /**
49.1903 + * Method invoked upon completion of execution of the given Runnable.
49.1904 + * This method is invoked by the thread that executed the task. If
49.1905 + * non-null, the Throwable is the uncaught {@code RuntimeException}
49.1906 + * or {@code Error} that caused execution to terminate abruptly.
49.1907 + *
49.1908 + * <p>This implementation does nothing, but may be customized in
49.1909 + * subclasses. Note: To properly nest multiple overridings, subclasses
49.1910 + * should generally invoke {@code super.afterExecute} at the
49.1911 + * beginning of this method.
49.1912 + *
49.1913 + * <p><b>Note:</b> When actions are enclosed in tasks (such as
49.1914 + * {@link FutureTask}) either explicitly or via methods such as
49.1915 + * {@code submit}, these task objects catch and maintain
49.1916 + * computational exceptions, and so they do not cause abrupt
49.1917 + * termination, and the internal exceptions are <em>not</em>
49.1918 + * passed to this method. If you would like to trap both kinds of
49.1919 + * failures in this method, you can further probe for such cases,
49.1920 + * as in this sample subclass that prints either the direct cause
49.1921 + * or the underlying exception if a task has been aborted:
49.1922 + *
49.1923 + * <pre> {@code
49.1924 + * class ExtendedExecutor extends ThreadPoolExecutor {
49.1925 + * // ...
49.1926 + * protected void afterExecute(Runnable r, Throwable t) {
49.1927 + * super.afterExecute(r, t);
49.1928 + * if (t == null && r instanceof Future<?>) {
49.1929 + * try {
49.1930 + * Object result = ((Future<?>) r).get();
49.1931 + * } catch (CancellationException ce) {
49.1932 + * t = ce;
49.1933 + * } catch (ExecutionException ee) {
49.1934 + * t = ee.getCause();
49.1935 + * } catch (InterruptedException ie) {
49.1936 + * Thread.currentThread().interrupt(); // ignore/reset
49.1937 + * }
49.1938 + * }
49.1939 + * if (t != null)
49.1940 + * System.out.println(t);
49.1941 + * }
49.1942 + * }}</pre>
49.1943 + *
49.1944 + * @param r the runnable that has completed
49.1945 + * @param t the exception that caused termination, or null if
49.1946 + * execution completed normally
49.1947 + */
49.1948 + protected void afterExecute(Runnable r, Throwable t) { }
49.1949 +
49.1950 + /**
49.1951 + * Method invoked when the Executor has terminated. Default
49.1952 + * implementation does nothing. Note: To properly nest multiple
49.1953 + * overridings, subclasses should generally invoke
49.1954 + * {@code super.terminated} within this method.
49.1955 + */
49.1956 + protected void terminated() { }
49.1957 +
49.1958 + /* Predefined RejectedExecutionHandlers */
49.1959 +
49.1960 + /**
49.1961 + * A handler for rejected tasks that runs the rejected task
49.1962 + * directly in the calling thread of the {@code execute} method,
49.1963 + * unless the executor has been shut down, in which case the task
49.1964 + * is discarded.
49.1965 + */
49.1966 + public static class CallerRunsPolicy implements RejectedExecutionHandler {
49.1967 + /**
49.1968 + * Creates a {@code CallerRunsPolicy}.
49.1969 + */
49.1970 + public CallerRunsPolicy() { }
49.1971 +
49.1972 + /**
49.1973 + * Executes task r in the caller's thread, unless the executor
49.1974 + * has been shut down, in which case the task is discarded.
49.1975 + *
49.1976 + * @param r the runnable task requested to be executed
49.1977 + * @param e the executor attempting to execute this task
49.1978 + */
49.1979 + public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
49.1980 + if (!e.isShutdown()) {
49.1981 + r.run();
49.1982 + }
49.1983 + }
49.1984 + }
49.1985 +
49.1986 + /**
49.1987 + * A handler for rejected tasks that throws a
49.1988 + * {@code RejectedExecutionException}.
49.1989 + */
49.1990 + public static class AbortPolicy implements RejectedExecutionHandler {
49.1991 + /**
49.1992 + * Creates an {@code AbortPolicy}.
49.1993 + */
49.1994 + public AbortPolicy() { }
49.1995 +
49.1996 + /**
49.1997 + * Always throws RejectedExecutionException.
49.1998 + *
49.1999 + * @param r the runnable task requested to be executed
49.2000 + * @param e the executor attempting to execute this task
49.2001 + * @throws RejectedExecutionException always.
49.2002 + */
49.2003 + public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
49.2004 + throw new RejectedExecutionException("Task " + r.toString() +
49.2005 + " rejected from " +
49.2006 + e.toString());
49.2007 + }
49.2008 + }
49.2009 +
49.2010 + /**
49.2011 + * A handler for rejected tasks that silently discards the
49.2012 + * rejected task.
49.2013 + */
49.2014 + public static class DiscardPolicy implements RejectedExecutionHandler {
49.2015 + /**
49.2016 + * Creates a {@code DiscardPolicy}.
49.2017 + */
49.2018 + public DiscardPolicy() { }
49.2019 +
49.2020 + /**
49.2021 + * Does nothing, which has the effect of discarding task r.
49.2022 + *
49.2023 + * @param r the runnable task requested to be executed
49.2024 + * @param e the executor attempting to execute this task
49.2025 + */
49.2026 + public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
49.2027 + }
49.2028 + }
49.2029 +
49.2030 + /**
49.2031 + * A handler for rejected tasks that discards the oldest unhandled
49.2032 + * request and then retries {@code execute}, unless the executor
49.2033 + * is shut down, in which case the task is discarded.
49.2034 + */
49.2035 + public static class DiscardOldestPolicy implements RejectedExecutionHandler {
49.2036 + /**
49.2037 + * Creates a {@code DiscardOldestPolicy} for the given executor.
49.2038 + */
49.2039 + public DiscardOldestPolicy() { }
49.2040 +
49.2041 + /**
49.2042 + * Obtains and ignores the next task that the executor
49.2043 + * would otherwise execute, if one is immediately available,
49.2044 + * and then retries execution of task r, unless the executor
49.2045 + * is shut down, in which case task r is instead discarded.
49.2046 + *
49.2047 + * @param r the runnable task requested to be executed
49.2048 + * @param e the executor attempting to execute this task
49.2049 + */
49.2050 + public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
49.2051 + if (!e.isShutdown()) {
49.2052 + e.getQueue().poll();
49.2053 + e.execute(r);
49.2054 + }
49.2055 + }
49.2056 + }
49.2057 +}
50.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
50.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/TimeUnit.java Sat Mar 19 10:46:31 2016 +0100
50.3 @@ -0,0 +1,364 @@
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 <tt>TimeUnit</tt> represents time durations at a given unit of
50.43 + * granularity and provides utility methods to convert across units,
50.44 + * and to perform timing and delay operations in these units. A
50.45 + * <tt>TimeUnit</tt> does not maintain time information, but only
50.46 + * helps organize and use time representations that may be maintained
50.47 + * separately across various contexts. A nanosecond is defined as one
50.48 + * thousandth of a microsecond, a microsecond as one thousandth of a
50.49 + * millisecond, a millisecond as one thousandth of a second, a minute
50.50 + * as sixty seconds, an hour as sixty minutes, and a day as twenty four
50.51 + * hours.
50.52 + *
50.53 + * <p>A <tt>TimeUnit</tt> is mainly used to inform time-based methods
50.54 + * how a given timing parameter should be interpreted. For example,
50.55 + * the following code will timeout in 50 milliseconds if the {@link
50.56 + * java.util.concurrent.locks.Lock lock} is not available:
50.57 + *
50.58 + * <pre> Lock lock = ...;
50.59 + * if (lock.tryLock(50L, TimeUnit.MILLISECONDS)) ...
50.60 + * </pre>
50.61 + * while this code will timeout in 50 seconds:
50.62 + * <pre>
50.63 + * Lock lock = ...;
50.64 + * if (lock.tryLock(50L, TimeUnit.SECONDS)) ...
50.65 + * </pre>
50.66 + *
50.67 + * Note however, that there is no guarantee that a particular timeout
50.68 + * implementation will be able to notice the passage of time at the
50.69 + * same granularity as the given <tt>TimeUnit</tt>.
50.70 + *
50.71 + * @since 1.5
50.72 + * @author Doug Lea
50.73 + */
50.74 +public enum TimeUnit {
50.75 + NANOSECONDS {
50.76 + public long toNanos(long d) { return d; }
50.77 + public long toMicros(long d) { return d/(C1/C0); }
50.78 + public long toMillis(long d) { return d/(C2/C0); }
50.79 + public long toSeconds(long d) { return d/(C3/C0); }
50.80 + public long toMinutes(long d) { return d/(C4/C0); }
50.81 + public long toHours(long d) { return d/(C5/C0); }
50.82 + public long toDays(long d) { return d/(C6/C0); }
50.83 + public long convert(long d, TimeUnit u) { return u.toNanos(d); }
50.84 + int excessNanos(long d, long m) { return (int)(d - (m*C2)); }
50.85 + },
50.86 + MICROSECONDS {
50.87 + public long toNanos(long d) { return x(d, C1/C0, MAX/(C1/C0)); }
50.88 + public long toMicros(long d) { return d; }
50.89 + public long toMillis(long d) { return d/(C2/C1); }
50.90 + public long toSeconds(long d) { return d/(C3/C1); }
50.91 + public long toMinutes(long d) { return d/(C4/C1); }
50.92 + public long toHours(long d) { return d/(C5/C1); }
50.93 + public long toDays(long d) { return d/(C6/C1); }
50.94 + public long convert(long d, TimeUnit u) { return u.toMicros(d); }
50.95 + int excessNanos(long d, long m) { return (int)((d*C1) - (m*C2)); }
50.96 + },
50.97 + MILLISECONDS {
50.98 + public long toNanos(long d) { return x(d, C2/C0, MAX/(C2/C0)); }
50.99 + public long toMicros(long d) { return x(d, C2/C1, MAX/(C2/C1)); }
50.100 + public long toMillis(long d) { return d; }
50.101 + public long toSeconds(long d) { return d/(C3/C2); }
50.102 + public long toMinutes(long d) { return d/(C4/C2); }
50.103 + public long toHours(long d) { return d/(C5/C2); }
50.104 + public long toDays(long d) { return d/(C6/C2); }
50.105 + public long convert(long d, TimeUnit u) { return u.toMillis(d); }
50.106 + int excessNanos(long d, long m) { return 0; }
50.107 + },
50.108 + SECONDS {
50.109 + public long toNanos(long d) { return x(d, C3/C0, MAX/(C3/C0)); }
50.110 + public long toMicros(long d) { return x(d, C3/C1, MAX/(C3/C1)); }
50.111 + public long toMillis(long d) { return x(d, C3/C2, MAX/(C3/C2)); }
50.112 + public long toSeconds(long d) { return d; }
50.113 + public long toMinutes(long d) { return d/(C4/C3); }
50.114 + public long toHours(long d) { return d/(C5/C3); }
50.115 + public long toDays(long d) { return d/(C6/C3); }
50.116 + public long convert(long d, TimeUnit u) { return u.toSeconds(d); }
50.117 + int excessNanos(long d, long m) { return 0; }
50.118 + },
50.119 + MINUTES {
50.120 + public long toNanos(long d) { return x(d, C4/C0, MAX/(C4/C0)); }
50.121 + public long toMicros(long d) { return x(d, C4/C1, MAX/(C4/C1)); }
50.122 + public long toMillis(long d) { return x(d, C4/C2, MAX/(C4/C2)); }
50.123 + public long toSeconds(long d) { return x(d, C4/C3, MAX/(C4/C3)); }
50.124 + public long toMinutes(long d) { return d; }
50.125 + public long toHours(long d) { return d/(C5/C4); }
50.126 + public long toDays(long d) { return d/(C6/C4); }
50.127 + public long convert(long d, TimeUnit u) { return u.toMinutes(d); }
50.128 + int excessNanos(long d, long m) { return 0; }
50.129 + },
50.130 + HOURS {
50.131 + public long toNanos(long d) { return x(d, C5/C0, MAX/(C5/C0)); }
50.132 + public long toMicros(long d) { return x(d, C5/C1, MAX/(C5/C1)); }
50.133 + public long toMillis(long d) { return x(d, C5/C2, MAX/(C5/C2)); }
50.134 + public long toSeconds(long d) { return x(d, C5/C3, MAX/(C5/C3)); }
50.135 + public long toMinutes(long d) { return x(d, C5/C4, MAX/(C5/C4)); }
50.136 + public long toHours(long d) { return d; }
50.137 + public long toDays(long d) { return d/(C6/C5); }
50.138 + public long convert(long d, TimeUnit u) { return u.toHours(d); }
50.139 + int excessNanos(long d, long m) { return 0; }
50.140 + },
50.141 + DAYS {
50.142 + public long toNanos(long d) { return x(d, C6/C0, MAX/(C6/C0)); }
50.143 + public long toMicros(long d) { return x(d, C6/C1, MAX/(C6/C1)); }
50.144 + public long toMillis(long d) { return x(d, C6/C2, MAX/(C6/C2)); }
50.145 + public long toSeconds(long d) { return x(d, C6/C3, MAX/(C6/C3)); }
50.146 + public long toMinutes(long d) { return x(d, C6/C4, MAX/(C6/C4)); }
50.147 + public long toHours(long d) { return x(d, C6/C5, MAX/(C6/C5)); }
50.148 + public long toDays(long d) { return d; }
50.149 + public long convert(long d, TimeUnit u) { return u.toDays(d); }
50.150 + int excessNanos(long d, long m) { return 0; }
50.151 + };
50.152 +
50.153 + // Handy constants for conversion methods
50.154 + static final long C0 = 1L;
50.155 + static final long C1 = C0 * 1000L;
50.156 + static final long C2 = C1 * 1000L;
50.157 + static final long C3 = C2 * 1000L;
50.158 + static final long C4 = C3 * 60L;
50.159 + static final long C5 = C4 * 60L;
50.160 + static final long C6 = C5 * 24L;
50.161 +
50.162 + static final long MAX = Long.MAX_VALUE;
50.163 +
50.164 + /**
50.165 + * Scale d by m, checking for overflow.
50.166 + * This has a short name to make above code more readable.
50.167 + */
50.168 + static long x(long d, long m, long over) {
50.169 + if (d > over) return Long.MAX_VALUE;
50.170 + if (d < -over) return Long.MIN_VALUE;
50.171 + return d * m;
50.172 + }
50.173 +
50.174 + // To maintain full signature compatibility with 1.5, and to improve the
50.175 + // clarity of the generated javadoc (see 6287639: Abstract methods in
50.176 + // enum classes should not be listed as abstract), method convert
50.177 + // etc. are not declared abstract but otherwise act as abstract methods.
50.178 +
50.179 + /**
50.180 + * Convert the given time duration in the given unit to this
50.181 + * unit. Conversions from finer to coarser granularities
50.182 + * truncate, so lose precision. For example converting
50.183 + * <tt>999</tt> milliseconds to seconds results in
50.184 + * <tt>0</tt>. Conversions from coarser to finer granularities
50.185 + * with arguments that would numerically overflow saturate to
50.186 + * <tt>Long.MIN_VALUE</tt> if negative or <tt>Long.MAX_VALUE</tt>
50.187 + * if positive.
50.188 + *
50.189 + * <p>For example, to convert 10 minutes to milliseconds, use:
50.190 + * <tt>TimeUnit.MILLISECONDS.convert(10L, TimeUnit.MINUTES)</tt>
50.191 + *
50.192 + * @param sourceDuration the time duration in the given <tt>sourceUnit</tt>
50.193 + * @param sourceUnit the unit of the <tt>sourceDuration</tt> argument
50.194 + * @return the converted duration in this unit,
50.195 + * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
50.196 + * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
50.197 + */
50.198 + public long convert(long sourceDuration, TimeUnit sourceUnit) {
50.199 + throw new AbstractMethodError();
50.200 + }
50.201 +
50.202 + /**
50.203 + * Equivalent to <tt>NANOSECONDS.convert(duration, this)</tt>.
50.204 + * @param duration the duration
50.205 + * @return the converted duration,
50.206 + * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
50.207 + * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
50.208 + * @see #convert
50.209 + */
50.210 + public long toNanos(long duration) {
50.211 + throw new AbstractMethodError();
50.212 + }
50.213 +
50.214 + /**
50.215 + * Equivalent to <tt>MICROSECONDS.convert(duration, this)</tt>.
50.216 + * @param duration the duration
50.217 + * @return the converted duration,
50.218 + * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
50.219 + * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
50.220 + * @see #convert
50.221 + */
50.222 + public long toMicros(long duration) {
50.223 + throw new AbstractMethodError();
50.224 + }
50.225 +
50.226 + /**
50.227 + * Equivalent to <tt>MILLISECONDS.convert(duration, this)</tt>.
50.228 + * @param duration the duration
50.229 + * @return the converted duration,
50.230 + * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
50.231 + * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
50.232 + * @see #convert
50.233 + */
50.234 + public long toMillis(long duration) {
50.235 + throw new AbstractMethodError();
50.236 + }
50.237 +
50.238 + /**
50.239 + * Equivalent to <tt>SECONDS.convert(duration, this)</tt>.
50.240 + * @param duration the duration
50.241 + * @return the converted duration,
50.242 + * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
50.243 + * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
50.244 + * @see #convert
50.245 + */
50.246 + public long toSeconds(long duration) {
50.247 + throw new AbstractMethodError();
50.248 + }
50.249 +
50.250 + /**
50.251 + * Equivalent to <tt>MINUTES.convert(duration, this)</tt>.
50.252 + * @param duration the duration
50.253 + * @return the converted duration,
50.254 + * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
50.255 + * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
50.256 + * @see #convert
50.257 + * @since 1.6
50.258 + */
50.259 + public long toMinutes(long duration) {
50.260 + throw new AbstractMethodError();
50.261 + }
50.262 +
50.263 + /**
50.264 + * Equivalent to <tt>HOURS.convert(duration, this)</tt>.
50.265 + * @param duration the duration
50.266 + * @return the converted duration,
50.267 + * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
50.268 + * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
50.269 + * @see #convert
50.270 + * @since 1.6
50.271 + */
50.272 + public long toHours(long duration) {
50.273 + throw new AbstractMethodError();
50.274 + }
50.275 +
50.276 + /**
50.277 + * Equivalent to <tt>DAYS.convert(duration, this)</tt>.
50.278 + * @param duration the duration
50.279 + * @return the converted duration
50.280 + * @see #convert
50.281 + * @since 1.6
50.282 + */
50.283 + public long toDays(long duration) {
50.284 + throw new AbstractMethodError();
50.285 + }
50.286 +
50.287 + /**
50.288 + * Utility to compute the excess-nanosecond argument to wait,
50.289 + * sleep, join.
50.290 + * @param d the duration
50.291 + * @param m the number of milliseconds
50.292 + * @return the number of nanoseconds
50.293 + */
50.294 + abstract int excessNanos(long d, long m);
50.295 +
50.296 + /**
50.297 + * Performs a timed {@link Object#wait(long, int) Object.wait}
50.298 + * using this time unit.
50.299 + * This is a convenience method that converts timeout arguments
50.300 + * into the form required by the <tt>Object.wait</tt> method.
50.301 + *
50.302 + * <p>For example, you could implement a blocking <tt>poll</tt>
50.303 + * method (see {@link BlockingQueue#poll BlockingQueue.poll})
50.304 + * using:
50.305 + *
50.306 + * <pre> {@code
50.307 + * public synchronized Object poll(long timeout, TimeUnit unit)
50.308 + * throws InterruptedException {
50.309 + * while (empty) {
50.310 + * unit.timedWait(this, timeout);
50.311 + * ...
50.312 + * }
50.313 + * }}</pre>
50.314 + *
50.315 + * @param obj the object to wait on
50.316 + * @param timeout the maximum time to wait. If less than
50.317 + * or equal to zero, do not wait at all.
50.318 + * @throws InterruptedException if interrupted while waiting
50.319 + */
50.320 + public void timedWait(Object obj, long timeout)
50.321 + throws InterruptedException {
50.322 + if (timeout > 0) {
50.323 + long ms = toMillis(timeout);
50.324 + int ns = excessNanos(timeout, ms);
50.325 + obj.wait(ms, ns);
50.326 + }
50.327 + }
50.328 +
50.329 + /**
50.330 + * Performs a timed {@link Thread#join(long, int) Thread.join}
50.331 + * using this time unit.
50.332 + * This is a convenience method that converts time arguments into the
50.333 + * form required by the <tt>Thread.join</tt> method.
50.334 + *
50.335 + * @param thread the thread to wait for
50.336 + * @param timeout the maximum time to wait. If less than
50.337 + * or equal to zero, do not wait at all.
50.338 + * @throws InterruptedException if interrupted while waiting
50.339 + */
50.340 + public void timedJoin(Thread thread, long timeout)
50.341 + throws InterruptedException {
50.342 + if (timeout > 0) {
50.343 + long ms = toMillis(timeout);
50.344 + int ns = excessNanos(timeout, ms);
50.345 + thread.join(ms, ns);
50.346 + }
50.347 + }
50.348 +
50.349 + /**
50.350 + * Performs a {@link Thread#sleep(long, int) Thread.sleep} using
50.351 + * this time unit.
50.352 + * This is a convenience method that converts time arguments into the
50.353 + * form required by the <tt>Thread.sleep</tt> method.
50.354 + *
50.355 + * @param timeout the minimum time to sleep. If less than
50.356 + * or equal to zero, do not sleep at all.
50.357 + * @throws InterruptedException if interrupted while sleeping
50.358 + */
50.359 + public void sleep(long timeout) throws InterruptedException {
50.360 + if (timeout > 0) {
50.361 + long ms = toMillis(timeout);
50.362 + int ns = excessNanos(timeout, ms);
50.363 + Thread.sleep(ms, ns);
50.364 + }
50.365 + }
50.366 +
50.367 +}
51.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
51.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/TimeoutException.java Sat Mar 19 10:46:31 2016 +0100
51.3 @@ -0,0 +1,67 @@
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;
51.40 +
51.41 +/**
51.42 + * Exception thrown when a blocking operation times out. Blocking
51.43 + * operations for which a timeout is specified need a means to
51.44 + * indicate that the timeout has occurred. For many such operations it
51.45 + * is possible to return a value that indicates timeout; when that is
51.46 + * not possible or desirable then <tt>TimeoutException</tt> should be
51.47 + * declared and thrown.
51.48 + *
51.49 + * @since 1.5
51.50 + * @author Doug Lea
51.51 + */
51.52 +public class TimeoutException extends Exception {
51.53 + private static final long serialVersionUID = 1900926677490660714L;
51.54 +
51.55 + /**
51.56 + * Constructs a <tt>TimeoutException</tt> with no specified detail
51.57 + * message.
51.58 + */
51.59 + public TimeoutException() {}
51.60 +
51.61 + /**
51.62 + * Constructs a <tt>TimeoutException</tt> with the specified detail
51.63 + * message.
51.64 + *
51.65 + * @param message the detail message
51.66 + */
51.67 + public TimeoutException(String message) {
51.68 + super(message);
51.69 + }
51.70 +}
52.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
52.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/TransferQueue.java Sat Mar 19 10:46:31 2016 +0100
52.3 @@ -0,0 +1,161 @@
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;
52.40 +
52.41 +/**
52.42 + * A {@link BlockingQueue} in which producers may wait for consumers
52.43 + * to receive elements. A {@code TransferQueue} may be useful for
52.44 + * example in message passing applications in which producers
52.45 + * sometimes (using method {@link #transfer}) await receipt of
52.46 + * elements by consumers invoking {@code take} or {@code poll}, while
52.47 + * at other times enqueue elements (via method {@code put}) without
52.48 + * waiting for receipt.
52.49 + * {@linkplain #tryTransfer(Object) Non-blocking} and
52.50 + * {@linkplain #tryTransfer(Object,long,TimeUnit) time-out} versions of
52.51 + * {@code tryTransfer} are also available.
52.52 + * A {@code TransferQueue} may also be queried, via {@link
52.53 + * #hasWaitingConsumer}, whether there are any threads waiting for
52.54 + * items, which is a converse analogy to a {@code peek} operation.
52.55 + *
52.56 + * <p>Like other blocking queues, a {@code TransferQueue} may be
52.57 + * capacity bounded. If so, an attempted transfer operation may
52.58 + * initially block waiting for available space, and/or subsequently
52.59 + * block waiting for reception by a consumer. Note that in a queue
52.60 + * with zero capacity, such as {@link SynchronousQueue}, {@code put}
52.61 + * and {@code transfer} are effectively synonymous.
52.62 + *
52.63 + * <p>This interface is a member of the
52.64 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
52.65 + * Java Collections Framework</a>.
52.66 + *
52.67 + * @since 1.7
52.68 + * @author Doug Lea
52.69 + * @param <E> the type of elements held in this collection
52.70 + */
52.71 +public interface TransferQueue<E> extends BlockingQueue<E> {
52.72 + /**
52.73 + * Transfers the element to a waiting consumer immediately, if possible.
52.74 + *
52.75 + * <p>More precisely, transfers the specified element immediately
52.76 + * if there exists a consumer already waiting to receive it (in
52.77 + * {@link #take} or timed {@link #poll(long,TimeUnit) poll}),
52.78 + * otherwise returning {@code false} without enqueuing the element.
52.79 + *
52.80 + * @param e the element to transfer
52.81 + * @return {@code true} if the element was transferred, else
52.82 + * {@code false}
52.83 + * @throws ClassCastException if the class of the specified element
52.84 + * prevents it from being added to this queue
52.85 + * @throws NullPointerException if the specified element is null
52.86 + * @throws IllegalArgumentException if some property of the specified
52.87 + * element prevents it from being added to this queue
52.88 + */
52.89 + boolean tryTransfer(E e);
52.90 +
52.91 + /**
52.92 + * Transfers the element to a consumer, waiting if necessary to do so.
52.93 + *
52.94 + * <p>More precisely, transfers the specified element immediately
52.95 + * if there exists a consumer already waiting to receive it (in
52.96 + * {@link #take} or timed {@link #poll(long,TimeUnit) poll}),
52.97 + * else waits until the element is received by a consumer.
52.98 + *
52.99 + * @param e the element to transfer
52.100 + * @throws InterruptedException if interrupted while waiting,
52.101 + * in which case the element is not left enqueued
52.102 + * @throws ClassCastException if the class of the specified element
52.103 + * prevents it from being added to this queue
52.104 + * @throws NullPointerException if the specified element is null
52.105 + * @throws IllegalArgumentException if some property of the specified
52.106 + * element prevents it from being added to this queue
52.107 + */
52.108 + void transfer(E e) throws InterruptedException;
52.109 +
52.110 + /**
52.111 + * Transfers the element to a consumer if it is possible to do so
52.112 + * before the timeout elapses.
52.113 + *
52.114 + * <p>More precisely, transfers the specified element immediately
52.115 + * if there exists a consumer already waiting to receive it (in
52.116 + * {@link #take} or timed {@link #poll(long,TimeUnit) poll}),
52.117 + * else waits until the element is received by a consumer,
52.118 + * returning {@code false} if the specified wait time elapses
52.119 + * before the element can be transferred.
52.120 + *
52.121 + * @param e the element to transfer
52.122 + * @param timeout how long to wait before giving up, in units of
52.123 + * {@code unit}
52.124 + * @param unit a {@code TimeUnit} determining how to interpret the
52.125 + * {@code timeout} parameter
52.126 + * @return {@code true} if successful, or {@code false} if
52.127 + * the specified waiting time elapses before completion,
52.128 + * in which case the element is not left enqueued
52.129 + * @throws InterruptedException if interrupted while waiting,
52.130 + * in which case the element is not left enqueued
52.131 + * @throws ClassCastException if the class of the specified element
52.132 + * prevents it from being added to this queue
52.133 + * @throws NullPointerException if the specified element is null
52.134 + * @throws IllegalArgumentException if some property of the specified
52.135 + * element prevents it from being added to this queue
52.136 + */
52.137 + boolean tryTransfer(E e, long timeout, TimeUnit unit)
52.138 + throws InterruptedException;
52.139 +
52.140 + /**
52.141 + * Returns {@code true} if there is at least one consumer waiting
52.142 + * to receive an element via {@link #take} or
52.143 + * timed {@link #poll(long,TimeUnit) poll}.
52.144 + * The return value represents a momentary state of affairs.
52.145 + *
52.146 + * @return {@code true} if there is at least one waiting consumer
52.147 + */
52.148 + boolean hasWaitingConsumer();
52.149 +
52.150 + /**
52.151 + * Returns an estimate of the number of consumers waiting to
52.152 + * receive elements via {@link #take} or timed
52.153 + * {@link #poll(long,TimeUnit) poll}. The return value is an
52.154 + * approximation of a momentary state of affairs, that may be
52.155 + * inaccurate if consumers have completed or given up waiting.
52.156 + * The value may be useful for monitoring and heuristics, but
52.157 + * not for synchronization control. Implementations of this
52.158 + * method are likely to be noticeably slower than those for
52.159 + * {@link #hasWaitingConsumer}.
52.160 + *
52.161 + * @return the number of consumers waiting to receive elements
52.162 + */
52.163 + int getWaitingConsumerCount();
52.164 +}
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/AbstractOwnableSynchronizer.java Sat Mar 19 10:46:31 2016 +0100
53.3 @@ -0,0 +1,86 @@
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 +
53.41 +/**
53.42 + * A synchronizer that may be exclusively owned by a thread. This
53.43 + * class provides a basis for creating locks and related synchronizers
53.44 + * that may entail a notion of ownership. The
53.45 + * <tt>AbstractOwnableSynchronizer</tt> class itself does not manage or
53.46 + * use this information. However, subclasses and tools may use
53.47 + * appropriately maintained values to help control and monitor access
53.48 + * and provide diagnostics.
53.49 + *
53.50 + * @since 1.6
53.51 + * @author Doug Lea
53.52 + */
53.53 +public abstract class AbstractOwnableSynchronizer
53.54 + implements java.io.Serializable {
53.55 +
53.56 + /** Use serial ID even though all fields transient. */
53.57 + private static final long serialVersionUID = 3737899427754241961L;
53.58 +
53.59 + /**
53.60 + * Empty constructor for use by subclasses.
53.61 + */
53.62 + protected AbstractOwnableSynchronizer() { }
53.63 +
53.64 + /**
53.65 + * The current owner of exclusive mode synchronization.
53.66 + */
53.67 + private transient Thread exclusiveOwnerThread;
53.68 +
53.69 + /**
53.70 + * Sets the thread that currently owns exclusive access. A
53.71 + * <tt>null</tt> argument indicates that no thread owns access.
53.72 + * This method does not otherwise impose any synchronization or
53.73 + * <tt>volatile</tt> field accesses.
53.74 + */
53.75 + protected final void setExclusiveOwnerThread(Thread t) {
53.76 + exclusiveOwnerThread = t;
53.77 + }
53.78 +
53.79 + /**
53.80 + * Returns the thread last set by
53.81 + * <tt>setExclusiveOwnerThread</tt>, or <tt>null</tt> if never
53.82 + * set. This method does not otherwise impose any synchronization
53.83 + * or <tt>volatile</tt> field accesses.
53.84 + * @return the owner thread
53.85 + */
53.86 + protected final Thread getExclusiveOwnerThread() {
53.87 + return exclusiveOwnerThread;
53.88 + }
53.89 +}
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/AbstractQueuedLongSynchronizer.java Sat Mar 19 10:46:31 2016 +0100
54.3 @@ -0,0 +1,2109 @@
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.*;
54.41 +import java.util.concurrent.*;
54.42 +import java.util.concurrent.atomic.*;
54.43 +import sun.misc.Unsafe;
54.44 +
54.45 +/**
54.46 + * A version of {@link AbstractQueuedSynchronizer} in
54.47 + * which synchronization state is maintained as a <tt>long</tt>.
54.48 + * This class has exactly the same structure, properties, and methods
54.49 + * as <tt>AbstractQueuedSynchronizer</tt> with the exception
54.50 + * that all state-related parameters and results are defined
54.51 + * as <tt>long</tt> rather than <tt>int</tt>. This class
54.52 + * may be useful when creating synchronizers such as
54.53 + * multilevel locks and barriers that require
54.54 + * 64 bits of state.
54.55 + *
54.56 + * <p>See {@link AbstractQueuedSynchronizer} for usage
54.57 + * notes and examples.
54.58 + *
54.59 + * @since 1.6
54.60 + * @author Doug Lea
54.61 + */
54.62 +public abstract class AbstractQueuedLongSynchronizer
54.63 + extends AbstractOwnableSynchronizer
54.64 + implements java.io.Serializable {
54.65 +
54.66 + private static final long serialVersionUID = 7373984972572414692L;
54.67 +
54.68 + /*
54.69 + To keep sources in sync, the remainder of this source file is
54.70 + exactly cloned from AbstractQueuedSynchronizer, replacing class
54.71 + name and changing ints related with sync state to longs. Please
54.72 + keep it that way.
54.73 + */
54.74 +
54.75 + /**
54.76 + * Creates a new <tt>AbstractQueuedLongSynchronizer</tt> instance
54.77 + * with initial synchronization state of zero.
54.78 + */
54.79 + protected AbstractQueuedLongSynchronizer() { }
54.80 +
54.81 + /**
54.82 + * Wait queue node class.
54.83 + *
54.84 + * <p>The wait queue is a variant of a "CLH" (Craig, Landin, and
54.85 + * Hagersten) lock queue. CLH locks are normally used for
54.86 + * spinlocks. We instead use them for blocking synchronizers, but
54.87 + * use the same basic tactic of holding some of the control
54.88 + * information about a thread in the predecessor of its node. A
54.89 + * "status" field in each node keeps track of whether a thread
54.90 + * should block. A node is signalled when its predecessor
54.91 + * releases. Each node of the queue otherwise serves as a
54.92 + * specific-notification-style monitor holding a single waiting
54.93 + * thread. The status field does NOT control whether threads are
54.94 + * granted locks etc though. A thread may try to acquire if it is
54.95 + * first in the queue. But being first does not guarantee success;
54.96 + * it only gives the right to contend. So the currently released
54.97 + * contender thread may need to rewait.
54.98 + *
54.99 + * <p>To enqueue into a CLH lock, you atomically splice it in as new
54.100 + * tail. To dequeue, you just set the head field.
54.101 + * <pre>
54.102 + * +------+ prev +-----+ +-----+
54.103 + * head | | <---- | | <---- | | tail
54.104 + * +------+ +-----+ +-----+
54.105 + * </pre>
54.106 + *
54.107 + * <p>Insertion into a CLH queue requires only a single atomic
54.108 + * operation on "tail", so there is a simple atomic point of
54.109 + * demarcation from unqueued to queued. Similarly, dequeing
54.110 + * involves only updating the "head". However, it takes a bit
54.111 + * more work for nodes to determine who their successors are,
54.112 + * in part to deal with possible cancellation due to timeouts
54.113 + * and interrupts.
54.114 + *
54.115 + * <p>The "prev" links (not used in original CLH locks), are mainly
54.116 + * needed to handle cancellation. If a node is cancelled, its
54.117 + * successor is (normally) relinked to a non-cancelled
54.118 + * predecessor. For explanation of similar mechanics in the case
54.119 + * of spin locks, see the papers by Scott and Scherer at
54.120 + * http://www.cs.rochester.edu/u/scott/synchronization/
54.121 + *
54.122 + * <p>We also use "next" links to implement blocking mechanics.
54.123 + * The thread id for each node is kept in its own node, so a
54.124 + * predecessor signals the next node to wake up by traversing
54.125 + * next link to determine which thread it is. Determination of
54.126 + * successor must avoid races with newly queued nodes to set
54.127 + * the "next" fields of their predecessors. This is solved
54.128 + * when necessary by checking backwards from the atomically
54.129 + * updated "tail" when a node's successor appears to be null.
54.130 + * (Or, said differently, the next-links are an optimization
54.131 + * so that we don't usually need a backward scan.)
54.132 + *
54.133 + * <p>Cancellation introduces some conservatism to the basic
54.134 + * algorithms. Since we must poll for cancellation of other
54.135 + * nodes, we can miss noticing whether a cancelled node is
54.136 + * ahead or behind us. This is dealt with by always unparking
54.137 + * successors upon cancellation, allowing them to stabilize on
54.138 + * a new predecessor, unless we can identify an uncancelled
54.139 + * predecessor who will carry this responsibility.
54.140 + *
54.141 + * <p>CLH queues need a dummy header node to get started. But
54.142 + * we don't create them on construction, because it would be wasted
54.143 + * effort if there is never contention. Instead, the node
54.144 + * is constructed and head and tail pointers are set upon first
54.145 + * contention.
54.146 + *
54.147 + * <p>Threads waiting on Conditions use the same nodes, but
54.148 + * use an additional link. Conditions only need to link nodes
54.149 + * in simple (non-concurrent) linked queues because they are
54.150 + * only accessed when exclusively held. Upon await, a node is
54.151 + * inserted into a condition queue. Upon signal, the node is
54.152 + * transferred to the main queue. A special value of status
54.153 + * field is used to mark which queue a node is on.
54.154 + *
54.155 + * <p>Thanks go to Dave Dice, Mark Moir, Victor Luchangco, Bill
54.156 + * Scherer and Michael Scott, along with members of JSR-166
54.157 + * expert group, for helpful ideas, discussions, and critiques
54.158 + * on the design of this class.
54.159 + */
54.160 + static final class Node {
54.161 + /** Marker to indicate a node is waiting in shared mode */
54.162 + static final Node SHARED = new Node();
54.163 + /** Marker to indicate a node is waiting in exclusive mode */
54.164 + static final Node EXCLUSIVE = null;
54.165 +
54.166 + /** waitStatus value to indicate thread has cancelled */
54.167 + static final int CANCELLED = 1;
54.168 + /** waitStatus value to indicate successor's thread needs unparking */
54.169 + static final int SIGNAL = -1;
54.170 + /** waitStatus value to indicate thread is waiting on condition */
54.171 + static final int CONDITION = -2;
54.172 + /**
54.173 + * waitStatus value to indicate the next acquireShared should
54.174 + * unconditionally propagate
54.175 + */
54.176 + static final int PROPAGATE = -3;
54.177 +
54.178 + /**
54.179 + * Status field, taking on only the values:
54.180 + * SIGNAL: The successor of this node is (or will soon be)
54.181 + * blocked (via park), so the current node must
54.182 + * unpark its successor when it releases or
54.183 + * cancels. To avoid races, acquire methods must
54.184 + * first indicate they need a signal,
54.185 + * then retry the atomic acquire, and then,
54.186 + * on failure, block.
54.187 + * CANCELLED: This node is cancelled due to timeout or interrupt.
54.188 + * Nodes never leave this state. In particular,
54.189 + * a thread with cancelled node never again blocks.
54.190 + * CONDITION: This node is currently on a condition queue.
54.191 + * It will not be used as a sync queue node
54.192 + * until transferred, at which time the status
54.193 + * will be set to 0. (Use of this value here has
54.194 + * nothing to do with the other uses of the
54.195 + * field, but simplifies mechanics.)
54.196 + * PROPAGATE: A releaseShared should be propagated to other
54.197 + * nodes. This is set (for head node only) in
54.198 + * doReleaseShared to ensure propagation
54.199 + * continues, even if other operations have
54.200 + * since intervened.
54.201 + * 0: None of the above
54.202 + *
54.203 + * The values are arranged numerically to simplify use.
54.204 + * Non-negative values mean that a node doesn't need to
54.205 + * signal. So, most code doesn't need to check for particular
54.206 + * values, just for sign.
54.207 + *
54.208 + * The field is initialized to 0 for normal sync nodes, and
54.209 + * CONDITION for condition nodes. It is modified using CAS
54.210 + * (or when possible, unconditional volatile writes).
54.211 + */
54.212 + volatile int waitStatus;
54.213 +
54.214 + /**
54.215 + * Link to predecessor node that current node/thread relies on
54.216 + * for checking waitStatus. Assigned during enqueing, and nulled
54.217 + * out (for sake of GC) only upon dequeuing. Also, upon
54.218 + * cancellation of a predecessor, we short-circuit while
54.219 + * finding a non-cancelled one, which will always exist
54.220 + * because the head node is never cancelled: A node becomes
54.221 + * head only as a result of successful acquire. A
54.222 + * cancelled thread never succeeds in acquiring, and a thread only
54.223 + * cancels itself, not any other node.
54.224 + */
54.225 + volatile Node prev;
54.226 +
54.227 + /**
54.228 + * Link to the successor node that the current node/thread
54.229 + * unparks upon release. Assigned during enqueuing, adjusted
54.230 + * when bypassing cancelled predecessors, and nulled out (for
54.231 + * sake of GC) when dequeued. The enq operation does not
54.232 + * assign next field of a predecessor until after attachment,
54.233 + * so seeing a null next field does not necessarily mean that
54.234 + * node is at end of queue. However, if a next field appears
54.235 + * to be null, we can scan prev's from the tail to
54.236 + * double-check. The next field of cancelled nodes is set to
54.237 + * point to the node itself instead of null, to make life
54.238 + * easier for isOnSyncQueue.
54.239 + */
54.240 + volatile Node next;
54.241 +
54.242 + /**
54.243 + * The thread that enqueued this node. Initialized on
54.244 + * construction and nulled out after use.
54.245 + */
54.246 + volatile Thread thread;
54.247 +
54.248 + /**
54.249 + * Link to next node waiting on condition, or the special
54.250 + * value SHARED. Because condition queues are accessed only
54.251 + * when holding in exclusive mode, we just need a simple
54.252 + * linked queue to hold nodes while they are waiting on
54.253 + * conditions. They are then transferred to the queue to
54.254 + * re-acquire. And because conditions can only be exclusive,
54.255 + * we save a field by using special value to indicate shared
54.256 + * mode.
54.257 + */
54.258 + Node nextWaiter;
54.259 +
54.260 + /**
54.261 + * Returns true if node is waiting in shared mode
54.262 + */
54.263 + final boolean isShared() {
54.264 + return nextWaiter == SHARED;
54.265 + }
54.266 +
54.267 + /**
54.268 + * Returns previous node, or throws NullPointerException if null.
54.269 + * Use when predecessor cannot be null. The null check could
54.270 + * be elided, but is present to help the VM.
54.271 + *
54.272 + * @return the predecessor of this node
54.273 + */
54.274 + final Node predecessor() throws NullPointerException {
54.275 + Node p = prev;
54.276 + if (p == null)
54.277 + throw new NullPointerException();
54.278 + else
54.279 + return p;
54.280 + }
54.281 +
54.282 + Node() { // Used to establish initial head or SHARED marker
54.283 + }
54.284 +
54.285 + Node(Thread thread, Node mode) { // Used by addWaiter
54.286 + this.nextWaiter = mode;
54.287 + this.thread = thread;
54.288 + }
54.289 +
54.290 + Node(Thread thread, int waitStatus) { // Used by Condition
54.291 + this.waitStatus = waitStatus;
54.292 + this.thread = thread;
54.293 + }
54.294 + }
54.295 +
54.296 + /**
54.297 + * Head of the wait queue, lazily initialized. Except for
54.298 + * initialization, it is modified only via method setHead. Note:
54.299 + * If head exists, its waitStatus is guaranteed not to be
54.300 + * CANCELLED.
54.301 + */
54.302 + private transient volatile Node head;
54.303 +
54.304 + /**
54.305 + * Tail of the wait queue, lazily initialized. Modified only via
54.306 + * method enq to add new wait node.
54.307 + */
54.308 + private transient volatile Node tail;
54.309 +
54.310 + /**
54.311 + * The synchronization state.
54.312 + */
54.313 + private volatile long state;
54.314 +
54.315 + /**
54.316 + * Returns the current value of synchronization state.
54.317 + * This operation has memory semantics of a <tt>volatile</tt> read.
54.318 + * @return current state value
54.319 + */
54.320 + protected final long getState() {
54.321 + return state;
54.322 + }
54.323 +
54.324 + /**
54.325 + * Sets the value of synchronization state.
54.326 + * This operation has memory semantics of a <tt>volatile</tt> write.
54.327 + * @param newState the new state value
54.328 + */
54.329 + protected final void setState(long newState) {
54.330 + state = newState;
54.331 + }
54.332 +
54.333 + /**
54.334 + * Atomically sets synchronization state to the given updated
54.335 + * value if the current state value equals the expected value.
54.336 + * This operation has memory semantics of a <tt>volatile</tt> read
54.337 + * and write.
54.338 + *
54.339 + * @param expect the expected value
54.340 + * @param update the new value
54.341 + * @return true if successful. False return indicates that the actual
54.342 + * value was not equal to the expected value.
54.343 + */
54.344 + protected final boolean compareAndSetState(long expect, long update) {
54.345 + // See below for intrinsics setup to support this
54.346 + return unsafe.compareAndSwapLong(this, stateOffset, expect, update);
54.347 + }
54.348 +
54.349 + // Queuing utilities
54.350 +
54.351 + /**
54.352 + * The number of nanoseconds for which it is faster to spin
54.353 + * rather than to use timed park. A rough estimate suffices
54.354 + * to improve responsiveness with very short timeouts.
54.355 + */
54.356 + static final long spinForTimeoutThreshold = 1000L;
54.357 +
54.358 + /**
54.359 + * Inserts node into queue, initializing if necessary. See picture above.
54.360 + * @param node the node to insert
54.361 + * @return node's predecessor
54.362 + */
54.363 + private Node enq(final Node node) {
54.364 + for (;;) {
54.365 + Node t = tail;
54.366 + if (t == null) { // Must initialize
54.367 + if (compareAndSetHead(new Node()))
54.368 + tail = head;
54.369 + } else {
54.370 + node.prev = t;
54.371 + if (compareAndSetTail(t, node)) {
54.372 + t.next = node;
54.373 + return t;
54.374 + }
54.375 + }
54.376 + }
54.377 + }
54.378 +
54.379 + /**
54.380 + * Creates and enqueues node for current thread and given mode.
54.381 + *
54.382 + * @param mode Node.EXCLUSIVE for exclusive, Node.SHARED for shared
54.383 + * @return the new node
54.384 + */
54.385 + private Node addWaiter(Node mode) {
54.386 + Node node = new Node(Thread.currentThread(), mode);
54.387 + // Try the fast path of enq; backup to full enq on failure
54.388 + Node pred = tail;
54.389 + if (pred != null) {
54.390 + node.prev = pred;
54.391 + if (compareAndSetTail(pred, node)) {
54.392 + pred.next = node;
54.393 + return node;
54.394 + }
54.395 + }
54.396 + enq(node);
54.397 + return node;
54.398 + }
54.399 +
54.400 + /**
54.401 + * Sets head of queue to be node, thus dequeuing. Called only by
54.402 + * acquire methods. Also nulls out unused fields for sake of GC
54.403 + * and to suppress unnecessary signals and traversals.
54.404 + *
54.405 + * @param node the node
54.406 + */
54.407 + private void setHead(Node node) {
54.408 + head = node;
54.409 + node.thread = null;
54.410 + node.prev = null;
54.411 + }
54.412 +
54.413 + /**
54.414 + * Wakes up node's successor, if one exists.
54.415 + *
54.416 + * @param node the node
54.417 + */
54.418 + private void unparkSuccessor(Node node) {
54.419 + /*
54.420 + * If status is negative (i.e., possibly needing signal) try
54.421 + * to clear in anticipation of signalling. It is OK if this
54.422 + * fails or if status is changed by waiting thread.
54.423 + */
54.424 + int ws = node.waitStatus;
54.425 + if (ws < 0)
54.426 + compareAndSetWaitStatus(node, ws, 0);
54.427 +
54.428 + /*
54.429 + * Thread to unpark is held in successor, which is normally
54.430 + * just the next node. But if cancelled or apparently null,
54.431 + * traverse backwards from tail to find the actual
54.432 + * non-cancelled successor.
54.433 + */
54.434 + Node s = node.next;
54.435 + if (s == null || s.waitStatus > 0) {
54.436 + s = null;
54.437 + for (Node t = tail; t != null && t != node; t = t.prev)
54.438 + if (t.waitStatus <= 0)
54.439 + s = t;
54.440 + }
54.441 + if (s != null)
54.442 + LockSupport.unpark(s.thread);
54.443 + }
54.444 +
54.445 + /**
54.446 + * Release action for shared mode -- signal successor and ensure
54.447 + * propagation. (Note: For exclusive mode, release just amounts
54.448 + * to calling unparkSuccessor of head if it needs signal.)
54.449 + */
54.450 + private void doReleaseShared() {
54.451 + /*
54.452 + * Ensure that a release propagates, even if there are other
54.453 + * in-progress acquires/releases. This proceeds in the usual
54.454 + * way of trying to unparkSuccessor of head if it needs
54.455 + * signal. But if it does not, status is set to PROPAGATE to
54.456 + * ensure that upon release, propagation continues.
54.457 + * Additionally, we must loop in case a new node is added
54.458 + * while we are doing this. Also, unlike other uses of
54.459 + * unparkSuccessor, we need to know if CAS to reset status
54.460 + * fails, if so rechecking.
54.461 + */
54.462 + for (;;) {
54.463 + Node h = head;
54.464 + if (h != null && h != tail) {
54.465 + int ws = h.waitStatus;
54.466 + if (ws == Node.SIGNAL) {
54.467 + if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))
54.468 + continue; // loop to recheck cases
54.469 + unparkSuccessor(h);
54.470 + }
54.471 + else if (ws == 0 &&
54.472 + !compareAndSetWaitStatus(h, 0, Node.PROPAGATE))
54.473 + continue; // loop on failed CAS
54.474 + }
54.475 + if (h == head) // loop if head changed
54.476 + break;
54.477 + }
54.478 + }
54.479 +
54.480 + /**
54.481 + * Sets head of queue, and checks if successor may be waiting
54.482 + * in shared mode, if so propagating if either propagate > 0 or
54.483 + * PROPAGATE status was set.
54.484 + *
54.485 + * @param node the node
54.486 + * @param propagate the return value from a tryAcquireShared
54.487 + */
54.488 + private void setHeadAndPropagate(Node node, long propagate) {
54.489 + Node h = head; // Record old head for check below
54.490 + setHead(node);
54.491 + /*
54.492 + * Try to signal next queued node if:
54.493 + * Propagation was indicated by caller,
54.494 + * or was recorded (as h.waitStatus) by a previous operation
54.495 + * (note: this uses sign-check of waitStatus because
54.496 + * PROPAGATE status may transition to SIGNAL.)
54.497 + * and
54.498 + * The next node is waiting in shared mode,
54.499 + * or we don't know, because it appears null
54.500 + *
54.501 + * The conservatism in both of these checks may cause
54.502 + * unnecessary wake-ups, but only when there are multiple
54.503 + * racing acquires/releases, so most need signals now or soon
54.504 + * anyway.
54.505 + */
54.506 + if (propagate > 0 || h == null || h.waitStatus < 0) {
54.507 + Node s = node.next;
54.508 + if (s == null || s.isShared())
54.509 + doReleaseShared();
54.510 + }
54.511 + }
54.512 +
54.513 + // Utilities for various versions of acquire
54.514 +
54.515 + /**
54.516 + * Cancels an ongoing attempt to acquire.
54.517 + *
54.518 + * @param node the node
54.519 + */
54.520 + private void cancelAcquire(Node node) {
54.521 + // Ignore if node doesn't exist
54.522 + if (node == null)
54.523 + return;
54.524 +
54.525 + node.thread = null;
54.526 +
54.527 + // Skip cancelled predecessors
54.528 + Node pred = node.prev;
54.529 + while (pred.waitStatus > 0)
54.530 + node.prev = pred = pred.prev;
54.531 +
54.532 + // predNext is the apparent node to unsplice. CASes below will
54.533 + // fail if not, in which case, we lost race vs another cancel
54.534 + // or signal, so no further action is necessary.
54.535 + Node predNext = pred.next;
54.536 +
54.537 + // Can use unconditional write instead of CAS here.
54.538 + // After this atomic step, other Nodes can skip past us.
54.539 + // Before, we are free of interference from other threads.
54.540 + node.waitStatus = Node.CANCELLED;
54.541 +
54.542 + // If we are the tail, remove ourselves.
54.543 + if (node == tail && compareAndSetTail(node, pred)) {
54.544 + compareAndSetNext(pred, predNext, null);
54.545 + } else {
54.546 + // If successor needs signal, try to set pred's next-link
54.547 + // so it will get one. Otherwise wake it up to propagate.
54.548 + int ws;
54.549 + if (pred != head &&
54.550 + ((ws = pred.waitStatus) == Node.SIGNAL ||
54.551 + (ws <= 0 && compareAndSetWaitStatus(pred, ws, Node.SIGNAL))) &&
54.552 + pred.thread != null) {
54.553 + Node next = node.next;
54.554 + if (next != null && next.waitStatus <= 0)
54.555 + compareAndSetNext(pred, predNext, next);
54.556 + } else {
54.557 + unparkSuccessor(node);
54.558 + }
54.559 +
54.560 + node.next = node; // help GC
54.561 + }
54.562 + }
54.563 +
54.564 + /**
54.565 + * Checks and updates status for a node that failed to acquire.
54.566 + * Returns true if thread should block. This is the main signal
54.567 + * control in all acquire loops. Requires that pred == node.prev
54.568 + *
54.569 + * @param pred node's predecessor holding status
54.570 + * @param node the node
54.571 + * @return {@code true} if thread should block
54.572 + */
54.573 + private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
54.574 + int ws = pred.waitStatus;
54.575 + if (ws == Node.SIGNAL)
54.576 + /*
54.577 + * This node has already set status asking a release
54.578 + * to signal it, so it can safely park.
54.579 + */
54.580 + return true;
54.581 + if (ws > 0) {
54.582 + /*
54.583 + * Predecessor was cancelled. Skip over predecessors and
54.584 + * indicate retry.
54.585 + */
54.586 + do {
54.587 + node.prev = pred = pred.prev;
54.588 + } while (pred.waitStatus > 0);
54.589 + pred.next = node;
54.590 + } else {
54.591 + /*
54.592 + * waitStatus must be 0 or PROPAGATE. Indicate that we
54.593 + * need a signal, but don't park yet. Caller will need to
54.594 + * retry to make sure it cannot acquire before parking.
54.595 + */
54.596 + compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
54.597 + }
54.598 + return false;
54.599 + }
54.600 +
54.601 + /**
54.602 + * Convenience method to interrupt current thread.
54.603 + */
54.604 + private static void selfInterrupt() {
54.605 + Thread.currentThread().interrupt();
54.606 + }
54.607 +
54.608 + /**
54.609 + * Convenience method to park and then check if interrupted
54.610 + *
54.611 + * @return {@code true} if interrupted
54.612 + */
54.613 + private final boolean parkAndCheckInterrupt() {
54.614 + LockSupport.park(this);
54.615 + return Thread.interrupted();
54.616 + }
54.617 +
54.618 + /*
54.619 + * Various flavors of acquire, varying in exclusive/shared and
54.620 + * control modes. Each is mostly the same, but annoyingly
54.621 + * different. Only a little bit of factoring is possible due to
54.622 + * interactions of exception mechanics (including ensuring that we
54.623 + * cancel if tryAcquire throws exception) and other control, at
54.624 + * least not without hurting performance too much.
54.625 + */
54.626 +
54.627 + /**
54.628 + * Acquires in exclusive uninterruptible mode for thread already in
54.629 + * queue. Used by condition wait methods as well as acquire.
54.630 + *
54.631 + * @param node the node
54.632 + * @param arg the acquire argument
54.633 + * @return {@code true} if interrupted while waiting
54.634 + */
54.635 + final boolean acquireQueued(final Node node, long arg) {
54.636 + boolean failed = true;
54.637 + try {
54.638 + boolean interrupted = false;
54.639 + for (;;) {
54.640 + final Node p = node.predecessor();
54.641 + if (p == head && tryAcquire(arg)) {
54.642 + setHead(node);
54.643 + p.next = null; // help GC
54.644 + failed = false;
54.645 + return interrupted;
54.646 + }
54.647 + if (shouldParkAfterFailedAcquire(p, node) &&
54.648 + parkAndCheckInterrupt())
54.649 + interrupted = true;
54.650 + }
54.651 + } finally {
54.652 + if (failed)
54.653 + cancelAcquire(node);
54.654 + }
54.655 + }
54.656 +
54.657 + /**
54.658 + * Acquires in exclusive interruptible mode.
54.659 + * @param arg the acquire argument
54.660 + */
54.661 + private void doAcquireInterruptibly(long arg)
54.662 + throws InterruptedException {
54.663 + final Node node = addWaiter(Node.EXCLUSIVE);
54.664 + boolean failed = true;
54.665 + try {
54.666 + for (;;) {
54.667 + final Node p = node.predecessor();
54.668 + if (p == head && tryAcquire(arg)) {
54.669 + setHead(node);
54.670 + p.next = null; // help GC
54.671 + failed = false;
54.672 + return;
54.673 + }
54.674 + if (shouldParkAfterFailedAcquire(p, node) &&
54.675 + parkAndCheckInterrupt())
54.676 + throw new InterruptedException();
54.677 + }
54.678 + } finally {
54.679 + if (failed)
54.680 + cancelAcquire(node);
54.681 + }
54.682 + }
54.683 +
54.684 + /**
54.685 + * Acquires in exclusive timed mode.
54.686 + *
54.687 + * @param arg the acquire argument
54.688 + * @param nanosTimeout max wait time
54.689 + * @return {@code true} if acquired
54.690 + */
54.691 + private boolean doAcquireNanos(long arg, long nanosTimeout)
54.692 + throws InterruptedException {
54.693 + long lastTime = System.nanoTime();
54.694 + final Node node = addWaiter(Node.EXCLUSIVE);
54.695 + boolean failed = true;
54.696 + try {
54.697 + for (;;) {
54.698 + final Node p = node.predecessor();
54.699 + if (p == head && tryAcquire(arg)) {
54.700 + setHead(node);
54.701 + p.next = null; // help GC
54.702 + failed = false;
54.703 + return true;
54.704 + }
54.705 + if (nanosTimeout <= 0)
54.706 + return false;
54.707 + if (shouldParkAfterFailedAcquire(p, node) &&
54.708 + nanosTimeout > spinForTimeoutThreshold)
54.709 + LockSupport.parkNanos(this, nanosTimeout);
54.710 + long now = System.nanoTime();
54.711 + nanosTimeout -= now - lastTime;
54.712 + lastTime = now;
54.713 + if (Thread.interrupted())
54.714 + throw new InterruptedException();
54.715 + }
54.716 + } finally {
54.717 + if (failed)
54.718 + cancelAcquire(node);
54.719 + }
54.720 + }
54.721 +
54.722 + /**
54.723 + * Acquires in shared uninterruptible mode.
54.724 + * @param arg the acquire argument
54.725 + */
54.726 + private void doAcquireShared(long arg) {
54.727 + final Node node = addWaiter(Node.SHARED);
54.728 + boolean failed = true;
54.729 + try {
54.730 + boolean interrupted = false;
54.731 + for (;;) {
54.732 + final Node p = node.predecessor();
54.733 + if (p == head) {
54.734 + long r = tryAcquireShared(arg);
54.735 + if (r >= 0) {
54.736 + setHeadAndPropagate(node, r);
54.737 + p.next = null; // help GC
54.738 + if (interrupted)
54.739 + selfInterrupt();
54.740 + failed = false;
54.741 + return;
54.742 + }
54.743 + }
54.744 + if (shouldParkAfterFailedAcquire(p, node) &&
54.745 + parkAndCheckInterrupt())
54.746 + interrupted = true;
54.747 + }
54.748 + } finally {
54.749 + if (failed)
54.750 + cancelAcquire(node);
54.751 + }
54.752 + }
54.753 +
54.754 + /**
54.755 + * Acquires in shared interruptible mode.
54.756 + * @param arg the acquire argument
54.757 + */
54.758 + private void doAcquireSharedInterruptibly(long arg)
54.759 + throws InterruptedException {
54.760 + final Node node = addWaiter(Node.SHARED);
54.761 + boolean failed = true;
54.762 + try {
54.763 + for (;;) {
54.764 + final Node p = node.predecessor();
54.765 + if (p == head) {
54.766 + long r = tryAcquireShared(arg);
54.767 + if (r >= 0) {
54.768 + setHeadAndPropagate(node, r);
54.769 + p.next = null; // help GC
54.770 + failed = false;
54.771 + return;
54.772 + }
54.773 + }
54.774 + if (shouldParkAfterFailedAcquire(p, node) &&
54.775 + parkAndCheckInterrupt())
54.776 + throw new InterruptedException();
54.777 + }
54.778 + } finally {
54.779 + if (failed)
54.780 + cancelAcquire(node);
54.781 + }
54.782 + }
54.783 +
54.784 + /**
54.785 + * Acquires in shared timed mode.
54.786 + *
54.787 + * @param arg the acquire argument
54.788 + * @param nanosTimeout max wait time
54.789 + * @return {@code true} if acquired
54.790 + */
54.791 + private boolean doAcquireSharedNanos(long arg, long nanosTimeout)
54.792 + throws InterruptedException {
54.793 +
54.794 + long lastTime = System.nanoTime();
54.795 + final Node node = addWaiter(Node.SHARED);
54.796 + boolean failed = true;
54.797 + try {
54.798 + for (;;) {
54.799 + final Node p = node.predecessor();
54.800 + if (p == head) {
54.801 + long r = tryAcquireShared(arg);
54.802 + if (r >= 0) {
54.803 + setHeadAndPropagate(node, r);
54.804 + p.next = null; // help GC
54.805 + failed = false;
54.806 + return true;
54.807 + }
54.808 + }
54.809 + if (nanosTimeout <= 0)
54.810 + return false;
54.811 + if (shouldParkAfterFailedAcquire(p, node) &&
54.812 + nanosTimeout > spinForTimeoutThreshold)
54.813 + LockSupport.parkNanos(this, nanosTimeout);
54.814 + long now = System.nanoTime();
54.815 + nanosTimeout -= now - lastTime;
54.816 + lastTime = now;
54.817 + if (Thread.interrupted())
54.818 + throw new InterruptedException();
54.819 + }
54.820 + } finally {
54.821 + if (failed)
54.822 + cancelAcquire(node);
54.823 + }
54.824 + }
54.825 +
54.826 + // Main exported methods
54.827 +
54.828 + /**
54.829 + * Attempts to acquire in exclusive mode. This method should query
54.830 + * if the state of the object permits it to be acquired in the
54.831 + * exclusive mode, and if so to acquire it.
54.832 + *
54.833 + * <p>This method is always invoked by the thread performing
54.834 + * acquire. If this method reports failure, the acquire method
54.835 + * may queue the thread, if it is not already queued, until it is
54.836 + * signalled by a release from some other thread. This can be used
54.837 + * to implement method {@link Lock#tryLock()}.
54.838 + *
54.839 + * <p>The default
54.840 + * implementation throws {@link UnsupportedOperationException}.
54.841 + *
54.842 + * @param arg the acquire argument. This value is always the one
54.843 + * passed to an acquire method, or is the value saved on entry
54.844 + * to a condition wait. The value is otherwise uninterpreted
54.845 + * and can represent anything you like.
54.846 + * @return {@code true} if successful. Upon success, this object has
54.847 + * been acquired.
54.848 + * @throws IllegalMonitorStateException if acquiring would place this
54.849 + * synchronizer in an illegal state. This exception must be
54.850 + * thrown in a consistent fashion for synchronization to work
54.851 + * correctly.
54.852 + * @throws UnsupportedOperationException if exclusive mode is not supported
54.853 + */
54.854 + protected boolean tryAcquire(long arg) {
54.855 + throw new UnsupportedOperationException();
54.856 + }
54.857 +
54.858 + /**
54.859 + * Attempts to set the state to reflect a release in exclusive
54.860 + * mode.
54.861 + *
54.862 + * <p>This method is always invoked by the thread performing release.
54.863 + *
54.864 + * <p>The default implementation throws
54.865 + * {@link UnsupportedOperationException}.
54.866 + *
54.867 + * @param arg the release argument. This value is always the one
54.868 + * passed to a release method, or the current state value upon
54.869 + * entry to a condition wait. The value is otherwise
54.870 + * uninterpreted and can represent anything you like.
54.871 + * @return {@code true} if this object is now in a fully released
54.872 + * state, so that any waiting threads may attempt to acquire;
54.873 + * and {@code false} otherwise.
54.874 + * @throws IllegalMonitorStateException if releasing would place this
54.875 + * synchronizer in an illegal state. This exception must be
54.876 + * thrown in a consistent fashion for synchronization to work
54.877 + * correctly.
54.878 + * @throws UnsupportedOperationException if exclusive mode is not supported
54.879 + */
54.880 + protected boolean tryRelease(long arg) {
54.881 + throw new UnsupportedOperationException();
54.882 + }
54.883 +
54.884 + /**
54.885 + * Attempts to acquire in shared mode. This method should query if
54.886 + * the state of the object permits it to be acquired in the shared
54.887 + * mode, and if so to acquire it.
54.888 + *
54.889 + * <p>This method is always invoked by the thread performing
54.890 + * acquire. If this method reports failure, the acquire method
54.891 + * may queue the thread, if it is not already queued, until it is
54.892 + * signalled by a release from some other thread.
54.893 + *
54.894 + * <p>The default implementation throws {@link
54.895 + * UnsupportedOperationException}.
54.896 + *
54.897 + * @param arg the acquire argument. This value is always the one
54.898 + * passed to an acquire method, or is the value saved on entry
54.899 + * to a condition wait. The value is otherwise uninterpreted
54.900 + * and can represent anything you like.
54.901 + * @return a negative value on failure; zero if acquisition in shared
54.902 + * mode succeeded but no subsequent shared-mode acquire can
54.903 + * succeed; and a positive value if acquisition in shared
54.904 + * mode succeeded and subsequent shared-mode acquires might
54.905 + * also succeed, in which case a subsequent waiting thread
54.906 + * must check availability. (Support for three different
54.907 + * return values enables this method to be used in contexts
54.908 + * where acquires only sometimes act exclusively.) Upon
54.909 + * success, this object has been acquired.
54.910 + * @throws IllegalMonitorStateException if acquiring would place this
54.911 + * synchronizer in an illegal state. This exception must be
54.912 + * thrown in a consistent fashion for synchronization to work
54.913 + * correctly.
54.914 + * @throws UnsupportedOperationException if shared mode is not supported
54.915 + */
54.916 + protected long tryAcquireShared(long arg) {
54.917 + throw new UnsupportedOperationException();
54.918 + }
54.919 +
54.920 + /**
54.921 + * Attempts to set the state to reflect a release in shared mode.
54.922 + *
54.923 + * <p>This method is always invoked by the thread performing release.
54.924 + *
54.925 + * <p>The default implementation throws
54.926 + * {@link UnsupportedOperationException}.
54.927 + *
54.928 + * @param arg the release argument. This value is always the one
54.929 + * passed to a release method, or the current state value upon
54.930 + * entry to a condition wait. The value is otherwise
54.931 + * uninterpreted and can represent anything you like.
54.932 + * @return {@code true} if this release of shared mode may permit a
54.933 + * waiting acquire (shared or exclusive) to succeed; and
54.934 + * {@code false} otherwise
54.935 + * @throws IllegalMonitorStateException if releasing would place this
54.936 + * synchronizer in an illegal state. This exception must be
54.937 + * thrown in a consistent fashion for synchronization to work
54.938 + * correctly.
54.939 + * @throws UnsupportedOperationException if shared mode is not supported
54.940 + */
54.941 + protected boolean tryReleaseShared(long arg) {
54.942 + throw new UnsupportedOperationException();
54.943 + }
54.944 +
54.945 + /**
54.946 + * Returns {@code true} if synchronization is held exclusively with
54.947 + * respect to the current (calling) thread. This method is invoked
54.948 + * upon each call to a non-waiting {@link ConditionObject} method.
54.949 + * (Waiting methods instead invoke {@link #release}.)
54.950 + *
54.951 + * <p>The default implementation throws {@link
54.952 + * UnsupportedOperationException}. This method is invoked
54.953 + * internally only within {@link ConditionObject} methods, so need
54.954 + * not be defined if conditions are not used.
54.955 + *
54.956 + * @return {@code true} if synchronization is held exclusively;
54.957 + * {@code false} otherwise
54.958 + * @throws UnsupportedOperationException if conditions are not supported
54.959 + */
54.960 + protected boolean isHeldExclusively() {
54.961 + throw new UnsupportedOperationException();
54.962 + }
54.963 +
54.964 + /**
54.965 + * Acquires in exclusive mode, ignoring interrupts. Implemented
54.966 + * by invoking at least once {@link #tryAcquire},
54.967 + * returning on success. Otherwise the thread is queued, possibly
54.968 + * repeatedly blocking and unblocking, invoking {@link
54.969 + * #tryAcquire} until success. This method can be used
54.970 + * to implement method {@link Lock#lock}.
54.971 + *
54.972 + * @param arg the acquire argument. This value is conveyed to
54.973 + * {@link #tryAcquire} but is otherwise uninterpreted and
54.974 + * can represent anything you like.
54.975 + */
54.976 + public final void acquire(long arg) {
54.977 + if (!tryAcquire(arg) &&
54.978 + acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
54.979 + selfInterrupt();
54.980 + }
54.981 +
54.982 + /**
54.983 + * Acquires in exclusive mode, aborting if interrupted.
54.984 + * Implemented by first checking interrupt status, then invoking
54.985 + * at least once {@link #tryAcquire}, returning on
54.986 + * success. Otherwise the thread is queued, possibly repeatedly
54.987 + * blocking and unblocking, invoking {@link #tryAcquire}
54.988 + * until success or the thread is interrupted. This method can be
54.989 + * used to implement method {@link Lock#lockInterruptibly}.
54.990 + *
54.991 + * @param arg the acquire argument. This value is conveyed to
54.992 + * {@link #tryAcquire} but is otherwise uninterpreted and
54.993 + * can represent anything you like.
54.994 + * @throws InterruptedException if the current thread is interrupted
54.995 + */
54.996 + public final void acquireInterruptibly(long arg)
54.997 + throws InterruptedException {
54.998 + if (Thread.interrupted())
54.999 + throw new InterruptedException();
54.1000 + if (!tryAcquire(arg))
54.1001 + doAcquireInterruptibly(arg);
54.1002 + }
54.1003 +
54.1004 + /**
54.1005 + * Attempts to acquire in exclusive mode, aborting if interrupted,
54.1006 + * and failing if the given timeout elapses. Implemented by first
54.1007 + * checking interrupt status, then invoking at least once {@link
54.1008 + * #tryAcquire}, returning on success. Otherwise, the thread is
54.1009 + * queued, possibly repeatedly blocking and unblocking, invoking
54.1010 + * {@link #tryAcquire} until success or the thread is interrupted
54.1011 + * or the timeout elapses. This method can be used to implement
54.1012 + * method {@link Lock#tryLock(long, TimeUnit)}.
54.1013 + *
54.1014 + * @param arg the acquire argument. This value is conveyed to
54.1015 + * {@link #tryAcquire} but is otherwise uninterpreted and
54.1016 + * can represent anything you like.
54.1017 + * @param nanosTimeout the maximum number of nanoseconds to wait
54.1018 + * @return {@code true} if acquired; {@code false} if timed out
54.1019 + * @throws InterruptedException if the current thread is interrupted
54.1020 + */
54.1021 + public final boolean tryAcquireNanos(long arg, long nanosTimeout)
54.1022 + throws InterruptedException {
54.1023 + if (Thread.interrupted())
54.1024 + throw new InterruptedException();
54.1025 + return tryAcquire(arg) ||
54.1026 + doAcquireNanos(arg, nanosTimeout);
54.1027 + }
54.1028 +
54.1029 + /**
54.1030 + * Releases in exclusive mode. Implemented by unblocking one or
54.1031 + * more threads if {@link #tryRelease} returns true.
54.1032 + * This method can be used to implement method {@link Lock#unlock}.
54.1033 + *
54.1034 + * @param arg the release argument. This value is conveyed to
54.1035 + * {@link #tryRelease} but is otherwise uninterpreted and
54.1036 + * can represent anything you like.
54.1037 + * @return the value returned from {@link #tryRelease}
54.1038 + */
54.1039 + public final boolean release(long arg) {
54.1040 + if (tryRelease(arg)) {
54.1041 + Node h = head;
54.1042 + if (h != null && h.waitStatus != 0)
54.1043 + unparkSuccessor(h);
54.1044 + return true;
54.1045 + }
54.1046 + return false;
54.1047 + }
54.1048 +
54.1049 + /**
54.1050 + * Acquires in shared mode, ignoring interrupts. Implemented by
54.1051 + * first invoking at least once {@link #tryAcquireShared},
54.1052 + * returning on success. Otherwise the thread is queued, possibly
54.1053 + * repeatedly blocking and unblocking, invoking {@link
54.1054 + * #tryAcquireShared} until success.
54.1055 + *
54.1056 + * @param arg the acquire argument. This value is conveyed to
54.1057 + * {@link #tryAcquireShared} but is otherwise uninterpreted
54.1058 + * and can represent anything you like.
54.1059 + */
54.1060 + public final void acquireShared(long arg) {
54.1061 + if (tryAcquireShared(arg) < 0)
54.1062 + doAcquireShared(arg);
54.1063 + }
54.1064 +
54.1065 + /**
54.1066 + * Acquires in shared mode, aborting if interrupted. Implemented
54.1067 + * by first checking interrupt status, then invoking at least once
54.1068 + * {@link #tryAcquireShared}, returning on success. Otherwise the
54.1069 + * thread is queued, possibly repeatedly blocking and unblocking,
54.1070 + * invoking {@link #tryAcquireShared} until success or the thread
54.1071 + * is interrupted.
54.1072 + * @param arg the acquire argument
54.1073 + * This value is conveyed to {@link #tryAcquireShared} but is
54.1074 + * otherwise uninterpreted and can represent anything
54.1075 + * you like.
54.1076 + * @throws InterruptedException if the current thread is interrupted
54.1077 + */
54.1078 + public final void acquireSharedInterruptibly(long arg)
54.1079 + throws InterruptedException {
54.1080 + if (Thread.interrupted())
54.1081 + throw new InterruptedException();
54.1082 + if (tryAcquireShared(arg) < 0)
54.1083 + doAcquireSharedInterruptibly(arg);
54.1084 + }
54.1085 +
54.1086 + /**
54.1087 + * Attempts to acquire in shared mode, aborting if interrupted, and
54.1088 + * failing if the given timeout elapses. Implemented by first
54.1089 + * checking interrupt status, then invoking at least once {@link
54.1090 + * #tryAcquireShared}, returning on success. Otherwise, the
54.1091 + * thread is queued, possibly repeatedly blocking and unblocking,
54.1092 + * invoking {@link #tryAcquireShared} until success or the thread
54.1093 + * is interrupted or the timeout elapses.
54.1094 + *
54.1095 + * @param arg the acquire argument. This value is conveyed to
54.1096 + * {@link #tryAcquireShared} but is otherwise uninterpreted
54.1097 + * and can represent anything you like.
54.1098 + * @param nanosTimeout the maximum number of nanoseconds to wait
54.1099 + * @return {@code true} if acquired; {@code false} if timed out
54.1100 + * @throws InterruptedException if the current thread is interrupted
54.1101 + */
54.1102 + public final boolean tryAcquireSharedNanos(long arg, long nanosTimeout)
54.1103 + throws InterruptedException {
54.1104 + if (Thread.interrupted())
54.1105 + throw new InterruptedException();
54.1106 + return tryAcquireShared(arg) >= 0 ||
54.1107 + doAcquireSharedNanos(arg, nanosTimeout);
54.1108 + }
54.1109 +
54.1110 + /**
54.1111 + * Releases in shared mode. Implemented by unblocking one or more
54.1112 + * threads if {@link #tryReleaseShared} returns true.
54.1113 + *
54.1114 + * @param arg the release argument. This value is conveyed to
54.1115 + * {@link #tryReleaseShared} but is otherwise uninterpreted
54.1116 + * and can represent anything you like.
54.1117 + * @return the value returned from {@link #tryReleaseShared}
54.1118 + */
54.1119 + public final boolean releaseShared(long arg) {
54.1120 + if (tryReleaseShared(arg)) {
54.1121 + doReleaseShared();
54.1122 + return true;
54.1123 + }
54.1124 + return false;
54.1125 + }
54.1126 +
54.1127 + // Queue inspection methods
54.1128 +
54.1129 + /**
54.1130 + * Queries whether any threads are waiting to acquire. Note that
54.1131 + * because cancellations due to interrupts and timeouts may occur
54.1132 + * at any time, a {@code true} return does not guarantee that any
54.1133 + * other thread will ever acquire.
54.1134 + *
54.1135 + * <p>In this implementation, this operation returns in
54.1136 + * constant time.
54.1137 + *
54.1138 + * @return {@code true} if there may be other threads waiting to acquire
54.1139 + */
54.1140 + public final boolean hasQueuedThreads() {
54.1141 + return head != tail;
54.1142 + }
54.1143 +
54.1144 + /**
54.1145 + * Queries whether any threads have ever contended to acquire this
54.1146 + * synchronizer; that is if an acquire method has ever blocked.
54.1147 + *
54.1148 + * <p>In this implementation, this operation returns in
54.1149 + * constant time.
54.1150 + *
54.1151 + * @return {@code true} if there has ever been contention
54.1152 + */
54.1153 + public final boolean hasContended() {
54.1154 + return head != null;
54.1155 + }
54.1156 +
54.1157 + /**
54.1158 + * Returns the first (longest-waiting) thread in the queue, or
54.1159 + * {@code null} if no threads are currently queued.
54.1160 + *
54.1161 + * <p>In this implementation, this operation normally returns in
54.1162 + * constant time, but may iterate upon contention if other threads are
54.1163 + * concurrently modifying the queue.
54.1164 + *
54.1165 + * @return the first (longest-waiting) thread in the queue, or
54.1166 + * {@code null} if no threads are currently queued
54.1167 + */
54.1168 + public final Thread getFirstQueuedThread() {
54.1169 + // handle only fast path, else relay
54.1170 + return (head == tail) ? null : fullGetFirstQueuedThread();
54.1171 + }
54.1172 +
54.1173 + /**
54.1174 + * Version of getFirstQueuedThread called when fastpath fails
54.1175 + */
54.1176 + private Thread fullGetFirstQueuedThread() {
54.1177 + /*
54.1178 + * The first node is normally head.next. Try to get its
54.1179 + * thread field, ensuring consistent reads: If thread
54.1180 + * field is nulled out or s.prev is no longer head, then
54.1181 + * some other thread(s) concurrently performed setHead in
54.1182 + * between some of our reads. We try this twice before
54.1183 + * resorting to traversal.
54.1184 + */
54.1185 + Node h, s;
54.1186 + Thread st;
54.1187 + if (((h = head) != null && (s = h.next) != null &&
54.1188 + s.prev == head && (st = s.thread) != null) ||
54.1189 + ((h = head) != null && (s = h.next) != null &&
54.1190 + s.prev == head && (st = s.thread) != null))
54.1191 + return st;
54.1192 +
54.1193 + /*
54.1194 + * Head's next field might not have been set yet, or may have
54.1195 + * been unset after setHead. So we must check to see if tail
54.1196 + * is actually first node. If not, we continue on, safely
54.1197 + * traversing from tail back to head to find first,
54.1198 + * guaranteeing termination.
54.1199 + */
54.1200 +
54.1201 + Node t = tail;
54.1202 + Thread firstThread = null;
54.1203 + while (t != null && t != head) {
54.1204 + Thread tt = t.thread;
54.1205 + if (tt != null)
54.1206 + firstThread = tt;
54.1207 + t = t.prev;
54.1208 + }
54.1209 + return firstThread;
54.1210 + }
54.1211 +
54.1212 + /**
54.1213 + * Returns true if the given thread is currently queued.
54.1214 + *
54.1215 + * <p>This implementation traverses the queue to determine
54.1216 + * presence of the given thread.
54.1217 + *
54.1218 + * @param thread the thread
54.1219 + * @return {@code true} if the given thread is on the queue
54.1220 + * @throws NullPointerException if the thread is null
54.1221 + */
54.1222 + public final boolean isQueued(Thread thread) {
54.1223 + if (thread == null)
54.1224 + throw new NullPointerException();
54.1225 + for (Node p = tail; p != null; p = p.prev)
54.1226 + if (p.thread == thread)
54.1227 + return true;
54.1228 + return false;
54.1229 + }
54.1230 +
54.1231 + /**
54.1232 + * Returns {@code true} if the apparent first queued thread, if one
54.1233 + * exists, is waiting in exclusive mode. If this method returns
54.1234 + * {@code true}, and the current thread is attempting to acquire in
54.1235 + * shared mode (that is, this method is invoked from {@link
54.1236 + * #tryAcquireShared}) then it is guaranteed that the current thread
54.1237 + * is not the first queued thread. Used only as a heuristic in
54.1238 + * ReentrantReadWriteLock.
54.1239 + */
54.1240 + final boolean apparentlyFirstQueuedIsExclusive() {
54.1241 + Node h, s;
54.1242 + return (h = head) != null &&
54.1243 + (s = h.next) != null &&
54.1244 + !s.isShared() &&
54.1245 + s.thread != null;
54.1246 + }
54.1247 +
54.1248 + /**
54.1249 + * Queries whether any threads have been waiting to acquire longer
54.1250 + * than the current thread.
54.1251 + *
54.1252 + * <p>An invocation of this method is equivalent to (but may be
54.1253 + * more efficient than):
54.1254 + * <pre> {@code
54.1255 + * getFirstQueuedThread() != Thread.currentThread() &&
54.1256 + * hasQueuedThreads()}</pre>
54.1257 + *
54.1258 + * <p>Note that because cancellations due to interrupts and
54.1259 + * timeouts may occur at any time, a {@code true} return does not
54.1260 + * guarantee that some other thread will acquire before the current
54.1261 + * thread. Likewise, it is possible for another thread to win a
54.1262 + * race to enqueue after this method has returned {@code false},
54.1263 + * due to the queue being empty.
54.1264 + *
54.1265 + * <p>This method is designed to be used by a fair synchronizer to
54.1266 + * avoid <a href="AbstractQueuedSynchronizer#barging">barging</a>.
54.1267 + * Such a synchronizer's {@link #tryAcquire} method should return
54.1268 + * {@code false}, and its {@link #tryAcquireShared} method should
54.1269 + * return a negative value, if this method returns {@code true}
54.1270 + * (unless this is a reentrant acquire). For example, the {@code
54.1271 + * tryAcquire} method for a fair, reentrant, exclusive mode
54.1272 + * synchronizer might look like this:
54.1273 + *
54.1274 + * <pre> {@code
54.1275 + * protected boolean tryAcquire(int arg) {
54.1276 + * if (isHeldExclusively()) {
54.1277 + * // A reentrant acquire; increment hold count
54.1278 + * return true;
54.1279 + * } else if (hasQueuedPredecessors()) {
54.1280 + * return false;
54.1281 + * } else {
54.1282 + * // try to acquire normally
54.1283 + * }
54.1284 + * }}</pre>
54.1285 + *
54.1286 + * @return {@code true} if there is a queued thread preceding the
54.1287 + * current thread, and {@code false} if the current thread
54.1288 + * is at the head of the queue or the queue is empty
54.1289 + * @since 1.7
54.1290 + */
54.1291 + public final boolean hasQueuedPredecessors() {
54.1292 + // The correctness of this depends on head being initialized
54.1293 + // before tail and on head.next being accurate if the current
54.1294 + // thread is first in queue.
54.1295 + Node t = tail; // Read fields in reverse initialization order
54.1296 + Node h = head;
54.1297 + Node s;
54.1298 + return h != t &&
54.1299 + ((s = h.next) == null || s.thread != Thread.currentThread());
54.1300 + }
54.1301 +
54.1302 +
54.1303 + // Instrumentation and monitoring methods
54.1304 +
54.1305 + /**
54.1306 + * Returns an estimate of the number of threads waiting to
54.1307 + * acquire. The value is only an estimate because the number of
54.1308 + * threads may change dynamically while this method traverses
54.1309 + * internal data structures. This method is designed for use in
54.1310 + * monitoring system state, not for synchronization
54.1311 + * control.
54.1312 + *
54.1313 + * @return the estimated number of threads waiting to acquire
54.1314 + */
54.1315 + public final int getQueueLength() {
54.1316 + int n = 0;
54.1317 + for (Node p = tail; p != null; p = p.prev) {
54.1318 + if (p.thread != null)
54.1319 + ++n;
54.1320 + }
54.1321 + return n;
54.1322 + }
54.1323 +
54.1324 + /**
54.1325 + * Returns a collection containing threads that may be waiting to
54.1326 + * acquire. Because the actual set of threads may change
54.1327 + * dynamically while constructing this result, the returned
54.1328 + * collection is only a best-effort estimate. The elements of the
54.1329 + * returned collection are in no particular order. This method is
54.1330 + * designed to facilitate construction of subclasses that provide
54.1331 + * more extensive monitoring facilities.
54.1332 + *
54.1333 + * @return the collection of threads
54.1334 + */
54.1335 + public final Collection<Thread> getQueuedThreads() {
54.1336 + ArrayList<Thread> list = new ArrayList<Thread>();
54.1337 + for (Node p = tail; p != null; p = p.prev) {
54.1338 + Thread t = p.thread;
54.1339 + if (t != null)
54.1340 + list.add(t);
54.1341 + }
54.1342 + return list;
54.1343 + }
54.1344 +
54.1345 + /**
54.1346 + * Returns a collection containing threads that may be waiting to
54.1347 + * acquire in exclusive mode. This has the same properties
54.1348 + * as {@link #getQueuedThreads} except that it only returns
54.1349 + * those threads waiting due to an exclusive acquire.
54.1350 + *
54.1351 + * @return the collection of threads
54.1352 + */
54.1353 + public final Collection<Thread> getExclusiveQueuedThreads() {
54.1354 + ArrayList<Thread> list = new ArrayList<Thread>();
54.1355 + for (Node p = tail; p != null; p = p.prev) {
54.1356 + if (!p.isShared()) {
54.1357 + Thread t = p.thread;
54.1358 + if (t != null)
54.1359 + list.add(t);
54.1360 + }
54.1361 + }
54.1362 + return list;
54.1363 + }
54.1364 +
54.1365 + /**
54.1366 + * Returns a collection containing threads that may be waiting to
54.1367 + * acquire in shared mode. This has the same properties
54.1368 + * as {@link #getQueuedThreads} except that it only returns
54.1369 + * those threads waiting due to a shared acquire.
54.1370 + *
54.1371 + * @return the collection of threads
54.1372 + */
54.1373 + public final Collection<Thread> getSharedQueuedThreads() {
54.1374 + ArrayList<Thread> list = new ArrayList<Thread>();
54.1375 + for (Node p = tail; p != null; p = p.prev) {
54.1376 + if (p.isShared()) {
54.1377 + Thread t = p.thread;
54.1378 + if (t != null)
54.1379 + list.add(t);
54.1380 + }
54.1381 + }
54.1382 + return list;
54.1383 + }
54.1384 +
54.1385 + /**
54.1386 + * Returns a string identifying this synchronizer, as well as its state.
54.1387 + * The state, in brackets, includes the String {@code "State ="}
54.1388 + * followed by the current value of {@link #getState}, and either
54.1389 + * {@code "nonempty"} or {@code "empty"} depending on whether the
54.1390 + * queue is empty.
54.1391 + *
54.1392 + * @return a string identifying this synchronizer, as well as its state
54.1393 + */
54.1394 + public String toString() {
54.1395 + long s = getState();
54.1396 + String q = hasQueuedThreads() ? "non" : "";
54.1397 + return super.toString() +
54.1398 + "[State = " + s + ", " + q + "empty queue]";
54.1399 + }
54.1400 +
54.1401 +
54.1402 + // Internal support methods for Conditions
54.1403 +
54.1404 + /**
54.1405 + * Returns true if a node, always one that was initially placed on
54.1406 + * a condition queue, is now waiting to reacquire on sync queue.
54.1407 + * @param node the node
54.1408 + * @return true if is reacquiring
54.1409 + */
54.1410 + final boolean isOnSyncQueue(Node node) {
54.1411 + if (node.waitStatus == Node.CONDITION || node.prev == null)
54.1412 + return false;
54.1413 + if (node.next != null) // If has successor, it must be on queue
54.1414 + return true;
54.1415 + /*
54.1416 + * node.prev can be non-null, but not yet on queue because
54.1417 + * the CAS to place it on queue can fail. So we have to
54.1418 + * traverse from tail to make sure it actually made it. It
54.1419 + * will always be near the tail in calls to this method, and
54.1420 + * unless the CAS failed (which is unlikely), it will be
54.1421 + * there, so we hardly ever traverse much.
54.1422 + */
54.1423 + return findNodeFromTail(node);
54.1424 + }
54.1425 +
54.1426 + /**
54.1427 + * Returns true if node is on sync queue by searching backwards from tail.
54.1428 + * Called only when needed by isOnSyncQueue.
54.1429 + * @return true if present
54.1430 + */
54.1431 + private boolean findNodeFromTail(Node node) {
54.1432 + Node t = tail;
54.1433 + for (;;) {
54.1434 + if (t == node)
54.1435 + return true;
54.1436 + if (t == null)
54.1437 + return false;
54.1438 + t = t.prev;
54.1439 + }
54.1440 + }
54.1441 +
54.1442 + /**
54.1443 + * Transfers a node from a condition queue onto sync queue.
54.1444 + * Returns true if successful.
54.1445 + * @param node the node
54.1446 + * @return true if successfully transferred (else the node was
54.1447 + * cancelled before signal).
54.1448 + */
54.1449 + final boolean transferForSignal(Node node) {
54.1450 + /*
54.1451 + * If cannot change waitStatus, the node has been cancelled.
54.1452 + */
54.1453 + if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))
54.1454 + return false;
54.1455 +
54.1456 + /*
54.1457 + * Splice onto queue and try to set waitStatus of predecessor to
54.1458 + * indicate that thread is (probably) waiting. If cancelled or
54.1459 + * attempt to set waitStatus fails, wake up to resync (in which
54.1460 + * case the waitStatus can be transiently and harmlessly wrong).
54.1461 + */
54.1462 + Node p = enq(node);
54.1463 + int ws = p.waitStatus;
54.1464 + if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))
54.1465 + LockSupport.unpark(node.thread);
54.1466 + return true;
54.1467 + }
54.1468 +
54.1469 + /**
54.1470 + * Transfers node, if necessary, to sync queue after a cancelled
54.1471 + * wait. Returns true if thread was cancelled before being
54.1472 + * signalled.
54.1473 + * @param current the waiting thread
54.1474 + * @param node its node
54.1475 + * @return true if cancelled before the node was signalled
54.1476 + */
54.1477 + final boolean transferAfterCancelledWait(Node node) {
54.1478 + if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) {
54.1479 + enq(node);
54.1480 + return true;
54.1481 + }
54.1482 + /*
54.1483 + * If we lost out to a signal(), then we can't proceed
54.1484 + * until it finishes its enq(). Cancelling during an
54.1485 + * incomplete transfer is both rare and transient, so just
54.1486 + * spin.
54.1487 + */
54.1488 + while (!isOnSyncQueue(node))
54.1489 + Thread.yield();
54.1490 + return false;
54.1491 + }
54.1492 +
54.1493 + /**
54.1494 + * Invokes release with current state value; returns saved state.
54.1495 + * Cancels node and throws exception on failure.
54.1496 + * @param node the condition node for this wait
54.1497 + * @return previous sync state
54.1498 + */
54.1499 + final long fullyRelease(Node node) {
54.1500 + boolean failed = true;
54.1501 + try {
54.1502 + long savedState = getState();
54.1503 + if (release(savedState)) {
54.1504 + failed = false;
54.1505 + return savedState;
54.1506 + } else {
54.1507 + throw new IllegalMonitorStateException();
54.1508 + }
54.1509 + } finally {
54.1510 + if (failed)
54.1511 + node.waitStatus = Node.CANCELLED;
54.1512 + }
54.1513 + }
54.1514 +
54.1515 + // Instrumentation methods for conditions
54.1516 +
54.1517 + /**
54.1518 + * Queries whether the given ConditionObject
54.1519 + * uses this synchronizer as its lock.
54.1520 + *
54.1521 + * @param condition the condition
54.1522 + * @return <tt>true</tt> if owned
54.1523 + * @throws NullPointerException if the condition is null
54.1524 + */
54.1525 + public final boolean owns(ConditionObject condition) {
54.1526 + if (condition == null)
54.1527 + throw new NullPointerException();
54.1528 + return condition.isOwnedBy(this);
54.1529 + }
54.1530 +
54.1531 + /**
54.1532 + * Queries whether any threads are waiting on the given condition
54.1533 + * associated with this synchronizer. Note that because timeouts
54.1534 + * and interrupts may occur at any time, a <tt>true</tt> return
54.1535 + * does not guarantee that a future <tt>signal</tt> will awaken
54.1536 + * any threads. This method is designed primarily for use in
54.1537 + * monitoring of the system state.
54.1538 + *
54.1539 + * @param condition the condition
54.1540 + * @return <tt>true</tt> if there are any waiting threads
54.1541 + * @throws IllegalMonitorStateException if exclusive synchronization
54.1542 + * is not held
54.1543 + * @throws IllegalArgumentException if the given condition is
54.1544 + * not associated with this synchronizer
54.1545 + * @throws NullPointerException if the condition is null
54.1546 + */
54.1547 + public final boolean hasWaiters(ConditionObject condition) {
54.1548 + if (!owns(condition))
54.1549 + throw new IllegalArgumentException("Not owner");
54.1550 + return condition.hasWaiters();
54.1551 + }
54.1552 +
54.1553 + /**
54.1554 + * Returns an estimate of the number of threads waiting on the
54.1555 + * given condition associated with this synchronizer. Note that
54.1556 + * because timeouts and interrupts may occur at any time, the
54.1557 + * estimate serves only as an upper bound on the actual number of
54.1558 + * waiters. This method is designed for use in monitoring of the
54.1559 + * system state, not for synchronization control.
54.1560 + *
54.1561 + * @param condition the condition
54.1562 + * @return the estimated number of waiting threads
54.1563 + * @throws IllegalMonitorStateException if exclusive synchronization
54.1564 + * is not held
54.1565 + * @throws IllegalArgumentException if the given condition is
54.1566 + * not associated with this synchronizer
54.1567 + * @throws NullPointerException if the condition is null
54.1568 + */
54.1569 + public final int getWaitQueueLength(ConditionObject condition) {
54.1570 + if (!owns(condition))
54.1571 + throw new IllegalArgumentException("Not owner");
54.1572 + return condition.getWaitQueueLength();
54.1573 + }
54.1574 +
54.1575 + /**
54.1576 + * Returns a collection containing those threads that may be
54.1577 + * waiting on the given condition associated with this
54.1578 + * synchronizer. Because the actual set of threads may change
54.1579 + * dynamically while constructing this result, the returned
54.1580 + * collection is only a best-effort estimate. The elements of the
54.1581 + * returned collection are in no particular order.
54.1582 + *
54.1583 + * @param condition the condition
54.1584 + * @return the collection of threads
54.1585 + * @throws IllegalMonitorStateException if exclusive synchronization
54.1586 + * is not held
54.1587 + * @throws IllegalArgumentException if the given condition is
54.1588 + * not associated with this synchronizer
54.1589 + * @throws NullPointerException if the condition is null
54.1590 + */
54.1591 + public final Collection<Thread> getWaitingThreads(ConditionObject condition) {
54.1592 + if (!owns(condition))
54.1593 + throw new IllegalArgumentException("Not owner");
54.1594 + return condition.getWaitingThreads();
54.1595 + }
54.1596 +
54.1597 + /**
54.1598 + * Condition implementation for a {@link
54.1599 + * AbstractQueuedLongSynchronizer} serving as the basis of a {@link
54.1600 + * Lock} implementation.
54.1601 + *
54.1602 + * <p>Method documentation for this class describes mechanics,
54.1603 + * not behavioral specifications from the point of view of Lock
54.1604 + * and Condition users. Exported versions of this class will in
54.1605 + * general need to be accompanied by documentation describing
54.1606 + * condition semantics that rely on those of the associated
54.1607 + * <tt>AbstractQueuedLongSynchronizer</tt>.
54.1608 + *
54.1609 + * <p>This class is Serializable, but all fields are transient,
54.1610 + * so deserialized conditions have no waiters.
54.1611 + *
54.1612 + * @since 1.6
54.1613 + */
54.1614 + public class ConditionObject implements Condition, java.io.Serializable {
54.1615 + private static final long serialVersionUID = 1173984872572414699L;
54.1616 + /** First node of condition queue. */
54.1617 + private transient Node firstWaiter;
54.1618 + /** Last node of condition queue. */
54.1619 + private transient Node lastWaiter;
54.1620 +
54.1621 + /**
54.1622 + * Creates a new <tt>ConditionObject</tt> instance.
54.1623 + */
54.1624 + public ConditionObject() { }
54.1625 +
54.1626 + // Internal methods
54.1627 +
54.1628 + /**
54.1629 + * Adds a new waiter to wait queue.
54.1630 + * @return its new wait node
54.1631 + */
54.1632 + private Node addConditionWaiter() {
54.1633 + Node t = lastWaiter;
54.1634 + // If lastWaiter is cancelled, clean out.
54.1635 + if (t != null && t.waitStatus != Node.CONDITION) {
54.1636 + unlinkCancelledWaiters();
54.1637 + t = lastWaiter;
54.1638 + }
54.1639 + Node node = new Node(Thread.currentThread(), Node.CONDITION);
54.1640 + if (t == null)
54.1641 + firstWaiter = node;
54.1642 + else
54.1643 + t.nextWaiter = node;
54.1644 + lastWaiter = node;
54.1645 + return node;
54.1646 + }
54.1647 +
54.1648 + /**
54.1649 + * Removes and transfers nodes until hit non-cancelled one or
54.1650 + * null. Split out from signal in part to encourage compilers
54.1651 + * to inline the case of no waiters.
54.1652 + * @param first (non-null) the first node on condition queue
54.1653 + */
54.1654 + private void doSignal(Node first) {
54.1655 + do {
54.1656 + if ( (firstWaiter = first.nextWaiter) == null)
54.1657 + lastWaiter = null;
54.1658 + first.nextWaiter = null;
54.1659 + } while (!transferForSignal(first) &&
54.1660 + (first = firstWaiter) != null);
54.1661 + }
54.1662 +
54.1663 + /**
54.1664 + * Removes and transfers all nodes.
54.1665 + * @param first (non-null) the first node on condition queue
54.1666 + */
54.1667 + private void doSignalAll(Node first) {
54.1668 + lastWaiter = firstWaiter = null;
54.1669 + do {
54.1670 + Node next = first.nextWaiter;
54.1671 + first.nextWaiter = null;
54.1672 + transferForSignal(first);
54.1673 + first = next;
54.1674 + } while (first != null);
54.1675 + }
54.1676 +
54.1677 + /**
54.1678 + * Unlinks cancelled waiter nodes from condition queue.
54.1679 + * Called only while holding lock. This is called when
54.1680 + * cancellation occurred during condition wait, and upon
54.1681 + * insertion of a new waiter when lastWaiter is seen to have
54.1682 + * been cancelled. This method is needed to avoid garbage
54.1683 + * retention in the absence of signals. So even though it may
54.1684 + * require a full traversal, it comes into play only when
54.1685 + * timeouts or cancellations occur in the absence of
54.1686 + * signals. It traverses all nodes rather than stopping at a
54.1687 + * particular target to unlink all pointers to garbage nodes
54.1688 + * without requiring many re-traversals during cancellation
54.1689 + * storms.
54.1690 + */
54.1691 + private void unlinkCancelledWaiters() {
54.1692 + Node t = firstWaiter;
54.1693 + Node trail = null;
54.1694 + while (t != null) {
54.1695 + Node next = t.nextWaiter;
54.1696 + if (t.waitStatus != Node.CONDITION) {
54.1697 + t.nextWaiter = null;
54.1698 + if (trail == null)
54.1699 + firstWaiter = next;
54.1700 + else
54.1701 + trail.nextWaiter = next;
54.1702 + if (next == null)
54.1703 + lastWaiter = trail;
54.1704 + }
54.1705 + else
54.1706 + trail = t;
54.1707 + t = next;
54.1708 + }
54.1709 + }
54.1710 +
54.1711 + // public methods
54.1712 +
54.1713 + /**
54.1714 + * Moves the longest-waiting thread, if one exists, from the
54.1715 + * wait queue for this condition to the wait queue for the
54.1716 + * owning lock.
54.1717 + *
54.1718 + * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
54.1719 + * returns {@code false}
54.1720 + */
54.1721 + public final void signal() {
54.1722 + if (!isHeldExclusively())
54.1723 + throw new IllegalMonitorStateException();
54.1724 + Node first = firstWaiter;
54.1725 + if (first != null)
54.1726 + doSignal(first);
54.1727 + }
54.1728 +
54.1729 + /**
54.1730 + * Moves all threads from the wait queue for this condition to
54.1731 + * the wait queue for the owning lock.
54.1732 + *
54.1733 + * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
54.1734 + * returns {@code false}
54.1735 + */
54.1736 + public final void signalAll() {
54.1737 + if (!isHeldExclusively())
54.1738 + throw new IllegalMonitorStateException();
54.1739 + Node first = firstWaiter;
54.1740 + if (first != null)
54.1741 + doSignalAll(first);
54.1742 + }
54.1743 +
54.1744 + /**
54.1745 + * Implements uninterruptible condition wait.
54.1746 + * <ol>
54.1747 + * <li> Save lock state returned by {@link #getState}.
54.1748 + * <li> Invoke {@link #release} with
54.1749 + * saved state as argument, throwing
54.1750 + * IllegalMonitorStateException if it fails.
54.1751 + * <li> Block until signalled.
54.1752 + * <li> Reacquire by invoking specialized version of
54.1753 + * {@link #acquire} with saved state as argument.
54.1754 + * </ol>
54.1755 + */
54.1756 + public final void awaitUninterruptibly() {
54.1757 + Node node = addConditionWaiter();
54.1758 + long savedState = fullyRelease(node);
54.1759 + boolean interrupted = false;
54.1760 + while (!isOnSyncQueue(node)) {
54.1761 + LockSupport.park(this);
54.1762 + if (Thread.interrupted())
54.1763 + interrupted = true;
54.1764 + }
54.1765 + if (acquireQueued(node, savedState) || interrupted)
54.1766 + selfInterrupt();
54.1767 + }
54.1768 +
54.1769 + /*
54.1770 + * For interruptible waits, we need to track whether to throw
54.1771 + * InterruptedException, if interrupted while blocked on
54.1772 + * condition, versus reinterrupt current thread, if
54.1773 + * interrupted while blocked waiting to re-acquire.
54.1774 + */
54.1775 +
54.1776 + /** Mode meaning to reinterrupt on exit from wait */
54.1777 + private static final int REINTERRUPT = 1;
54.1778 + /** Mode meaning to throw InterruptedException on exit from wait */
54.1779 + private static final int THROW_IE = -1;
54.1780 +
54.1781 + /**
54.1782 + * Checks for interrupt, returning THROW_IE if interrupted
54.1783 + * before signalled, REINTERRUPT if after signalled, or
54.1784 + * 0 if not interrupted.
54.1785 + */
54.1786 + private int checkInterruptWhileWaiting(Node node) {
54.1787 + return Thread.interrupted() ?
54.1788 + (transferAfterCancelledWait(node) ? THROW_IE : REINTERRUPT) :
54.1789 + 0;
54.1790 + }
54.1791 +
54.1792 + /**
54.1793 + * Throws InterruptedException, reinterrupts current thread, or
54.1794 + * does nothing, depending on mode.
54.1795 + */
54.1796 + private void reportInterruptAfterWait(int interruptMode)
54.1797 + throws InterruptedException {
54.1798 + if (interruptMode == THROW_IE)
54.1799 + throw new InterruptedException();
54.1800 + else if (interruptMode == REINTERRUPT)
54.1801 + selfInterrupt();
54.1802 + }
54.1803 +
54.1804 + /**
54.1805 + * Implements interruptible condition wait.
54.1806 + * <ol>
54.1807 + * <li> If current thread is interrupted, throw InterruptedException.
54.1808 + * <li> Save lock state returned by {@link #getState}.
54.1809 + * <li> Invoke {@link #release} with
54.1810 + * saved state as argument, throwing
54.1811 + * IllegalMonitorStateException if it fails.
54.1812 + * <li> Block until signalled or interrupted.
54.1813 + * <li> Reacquire by invoking specialized version of
54.1814 + * {@link #acquire} with saved state as argument.
54.1815 + * <li> If interrupted while blocked in step 4, throw InterruptedException.
54.1816 + * </ol>
54.1817 + */
54.1818 + public final void await() throws InterruptedException {
54.1819 + if (Thread.interrupted())
54.1820 + throw new InterruptedException();
54.1821 + Node node = addConditionWaiter();
54.1822 + long savedState = fullyRelease(node);
54.1823 + int interruptMode = 0;
54.1824 + while (!isOnSyncQueue(node)) {
54.1825 + LockSupport.park(this);
54.1826 + if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
54.1827 + break;
54.1828 + }
54.1829 + if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
54.1830 + interruptMode = REINTERRUPT;
54.1831 + if (node.nextWaiter != null) // clean up if cancelled
54.1832 + unlinkCancelledWaiters();
54.1833 + if (interruptMode != 0)
54.1834 + reportInterruptAfterWait(interruptMode);
54.1835 + }
54.1836 +
54.1837 + /**
54.1838 + * Implements timed condition wait.
54.1839 + * <ol>
54.1840 + * <li> If current thread is interrupted, throw InterruptedException.
54.1841 + * <li> Save lock state returned by {@link #getState}.
54.1842 + * <li> Invoke {@link #release} with
54.1843 + * saved state as argument, throwing
54.1844 + * IllegalMonitorStateException if it fails.
54.1845 + * <li> Block until signalled, interrupted, or timed out.
54.1846 + * <li> Reacquire by invoking specialized version of
54.1847 + * {@link #acquire} with saved state as argument.
54.1848 + * <li> If interrupted while blocked in step 4, throw InterruptedException.
54.1849 + * </ol>
54.1850 + */
54.1851 + public final long awaitNanos(long nanosTimeout)
54.1852 + throws InterruptedException {
54.1853 + if (Thread.interrupted())
54.1854 + throw new InterruptedException();
54.1855 + Node node = addConditionWaiter();
54.1856 + long savedState = fullyRelease(node);
54.1857 + long lastTime = System.nanoTime();
54.1858 + int interruptMode = 0;
54.1859 + while (!isOnSyncQueue(node)) {
54.1860 + if (nanosTimeout <= 0L) {
54.1861 + transferAfterCancelledWait(node);
54.1862 + break;
54.1863 + }
54.1864 + LockSupport.parkNanos(this, nanosTimeout);
54.1865 + if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
54.1866 + break;
54.1867 +
54.1868 + long now = System.nanoTime();
54.1869 + nanosTimeout -= now - lastTime;
54.1870 + lastTime = now;
54.1871 + }
54.1872 + if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
54.1873 + interruptMode = REINTERRUPT;
54.1874 + if (node.nextWaiter != null)
54.1875 + unlinkCancelledWaiters();
54.1876 + if (interruptMode != 0)
54.1877 + reportInterruptAfterWait(interruptMode);
54.1878 + return nanosTimeout - (System.nanoTime() - lastTime);
54.1879 + }
54.1880 +
54.1881 + /**
54.1882 + * Implements absolute timed condition wait.
54.1883 + * <ol>
54.1884 + * <li> If current thread is interrupted, throw InterruptedException.
54.1885 + * <li> Save lock state returned by {@link #getState}.
54.1886 + * <li> Invoke {@link #release} with
54.1887 + * saved state as argument, throwing
54.1888 + * IllegalMonitorStateException if it fails.
54.1889 + * <li> Block until signalled, interrupted, or timed out.
54.1890 + * <li> Reacquire by invoking specialized version of
54.1891 + * {@link #acquire} with saved state as argument.
54.1892 + * <li> If interrupted while blocked in step 4, throw InterruptedException.
54.1893 + * <li> If timed out while blocked in step 4, return false, else true.
54.1894 + * </ol>
54.1895 + */
54.1896 + public final boolean awaitUntil(Date deadline)
54.1897 + throws InterruptedException {
54.1898 + if (deadline == null)
54.1899 + throw new NullPointerException();
54.1900 + long abstime = deadline.getTime();
54.1901 + if (Thread.interrupted())
54.1902 + throw new InterruptedException();
54.1903 + Node node = addConditionWaiter();
54.1904 + long savedState = fullyRelease(node);
54.1905 + boolean timedout = false;
54.1906 + int interruptMode = 0;
54.1907 + while (!isOnSyncQueue(node)) {
54.1908 + if (System.currentTimeMillis() > abstime) {
54.1909 + timedout = transferAfterCancelledWait(node);
54.1910 + break;
54.1911 + }
54.1912 + LockSupport.parkUntil(this, abstime);
54.1913 + if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
54.1914 + break;
54.1915 + }
54.1916 + if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
54.1917 + interruptMode = REINTERRUPT;
54.1918 + if (node.nextWaiter != null)
54.1919 + unlinkCancelledWaiters();
54.1920 + if (interruptMode != 0)
54.1921 + reportInterruptAfterWait(interruptMode);
54.1922 + return !timedout;
54.1923 + }
54.1924 +
54.1925 + /**
54.1926 + * Implements timed condition wait.
54.1927 + * <ol>
54.1928 + * <li> If current thread is interrupted, throw InterruptedException.
54.1929 + * <li> Save lock state returned by {@link #getState}.
54.1930 + * <li> Invoke {@link #release} with
54.1931 + * saved state as argument, throwing
54.1932 + * IllegalMonitorStateException if it fails.
54.1933 + * <li> Block until signalled, interrupted, or timed out.
54.1934 + * <li> Reacquire by invoking specialized version of
54.1935 + * {@link #acquire} with saved state as argument.
54.1936 + * <li> If interrupted while blocked in step 4, throw InterruptedException.
54.1937 + * <li> If timed out while blocked in step 4, return false, else true.
54.1938 + * </ol>
54.1939 + */
54.1940 + public final boolean await(long time, TimeUnit unit)
54.1941 + throws InterruptedException {
54.1942 + if (unit == null)
54.1943 + throw new NullPointerException();
54.1944 + long nanosTimeout = unit.toNanos(time);
54.1945 + if (Thread.interrupted())
54.1946 + throw new InterruptedException();
54.1947 + Node node = addConditionWaiter();
54.1948 + long savedState = fullyRelease(node);
54.1949 + long lastTime = System.nanoTime();
54.1950 + boolean timedout = false;
54.1951 + int interruptMode = 0;
54.1952 + while (!isOnSyncQueue(node)) {
54.1953 + if (nanosTimeout <= 0L) {
54.1954 + timedout = transferAfterCancelledWait(node);
54.1955 + break;
54.1956 + }
54.1957 + if (nanosTimeout >= spinForTimeoutThreshold)
54.1958 + LockSupport.parkNanos(this, nanosTimeout);
54.1959 + if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
54.1960 + break;
54.1961 + long now = System.nanoTime();
54.1962 + nanosTimeout -= now - lastTime;
54.1963 + lastTime = now;
54.1964 + }
54.1965 + if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
54.1966 + interruptMode = REINTERRUPT;
54.1967 + if (node.nextWaiter != null)
54.1968 + unlinkCancelledWaiters();
54.1969 + if (interruptMode != 0)
54.1970 + reportInterruptAfterWait(interruptMode);
54.1971 + return !timedout;
54.1972 + }
54.1973 +
54.1974 + // support for instrumentation
54.1975 +
54.1976 + /**
54.1977 + * Returns true if this condition was created by the given
54.1978 + * synchronization object.
54.1979 + *
54.1980 + * @return {@code true} if owned
54.1981 + */
54.1982 + final boolean isOwnedBy(AbstractQueuedLongSynchronizer sync) {
54.1983 + return sync == AbstractQueuedLongSynchronizer.this;
54.1984 + }
54.1985 +
54.1986 + /**
54.1987 + * Queries whether any threads are waiting on this condition.
54.1988 + * Implements {@link AbstractQueuedLongSynchronizer#hasWaiters}.
54.1989 + *
54.1990 + * @return {@code true} if there are any waiting threads
54.1991 + * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
54.1992 + * returns {@code false}
54.1993 + */
54.1994 + protected final boolean hasWaiters() {
54.1995 + if (!isHeldExclusively())
54.1996 + throw new IllegalMonitorStateException();
54.1997 + for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
54.1998 + if (w.waitStatus == Node.CONDITION)
54.1999 + return true;
54.2000 + }
54.2001 + return false;
54.2002 + }
54.2003 +
54.2004 + /**
54.2005 + * Returns an estimate of the number of threads waiting on
54.2006 + * this condition.
54.2007 + * Implements {@link AbstractQueuedLongSynchronizer#getWaitQueueLength}.
54.2008 + *
54.2009 + * @return the estimated number of waiting threads
54.2010 + * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
54.2011 + * returns {@code false}
54.2012 + */
54.2013 + protected final int getWaitQueueLength() {
54.2014 + if (!isHeldExclusively())
54.2015 + throw new IllegalMonitorStateException();
54.2016 + int n = 0;
54.2017 + for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
54.2018 + if (w.waitStatus == Node.CONDITION)
54.2019 + ++n;
54.2020 + }
54.2021 + return n;
54.2022 + }
54.2023 +
54.2024 + /**
54.2025 + * Returns a collection containing those threads that may be
54.2026 + * waiting on this Condition.
54.2027 + * Implements {@link AbstractQueuedLongSynchronizer#getWaitingThreads}.
54.2028 + *
54.2029 + * @return the collection of threads
54.2030 + * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
54.2031 + * returns {@code false}
54.2032 + */
54.2033 + protected final Collection<Thread> getWaitingThreads() {
54.2034 + if (!isHeldExclusively())
54.2035 + throw new IllegalMonitorStateException();
54.2036 + ArrayList<Thread> list = new ArrayList<Thread>();
54.2037 + for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
54.2038 + if (w.waitStatus == Node.CONDITION) {
54.2039 + Thread t = w.thread;
54.2040 + if (t != null)
54.2041 + list.add(t);
54.2042 + }
54.2043 + }
54.2044 + return list;
54.2045 + }
54.2046 + }
54.2047 +
54.2048 + /**
54.2049 + * Setup to support compareAndSet. We need to natively implement
54.2050 + * this here: For the sake of permitting future enhancements, we
54.2051 + * cannot explicitly subclass AtomicLong, which would be
54.2052 + * efficient and useful otherwise. So, as the lesser of evils, we
54.2053 + * natively implement using hotspot intrinsics API. And while we
54.2054 + * are at it, we do the same for other CASable fields (which could
54.2055 + * otherwise be done with atomic field updaters).
54.2056 + */
54.2057 + private static final Unsafe unsafe = Unsafe.getUnsafe();
54.2058 + private static final long stateOffset;
54.2059 + private static final long headOffset;
54.2060 + private static final long tailOffset;
54.2061 + private static final long waitStatusOffset;
54.2062 + private static final long nextOffset;
54.2063 +
54.2064 + static {
54.2065 + try {
54.2066 + stateOffset = unsafe.objectFieldOffset
54.2067 + (AbstractQueuedLongSynchronizer.class.getDeclaredField("state"));
54.2068 + headOffset = unsafe.objectFieldOffset
54.2069 + (AbstractQueuedLongSynchronizer.class.getDeclaredField("head"));
54.2070 + tailOffset = unsafe.objectFieldOffset
54.2071 + (AbstractQueuedLongSynchronizer.class.getDeclaredField("tail"));
54.2072 + waitStatusOffset = unsafe.objectFieldOffset
54.2073 + (Node.class.getDeclaredField("waitStatus"));
54.2074 + nextOffset = unsafe.objectFieldOffset
54.2075 + (Node.class.getDeclaredField("next"));
54.2076 +
54.2077 + } catch (Exception ex) { throw new Error(ex); }
54.2078 + }
54.2079 +
54.2080 + /**
54.2081 + * CAS head field. Used only by enq.
54.2082 + */
54.2083 + private final boolean compareAndSetHead(Node update) {
54.2084 + return unsafe.compareAndSwapObject(this, headOffset, null, update);
54.2085 + }
54.2086 +
54.2087 + /**
54.2088 + * CAS tail field. Used only by enq.
54.2089 + */
54.2090 + private final boolean compareAndSetTail(Node expect, Node update) {
54.2091 + return unsafe.compareAndSwapObject(this, tailOffset, expect, update);
54.2092 + }
54.2093 +
54.2094 + /**
54.2095 + * CAS waitStatus field of a node.
54.2096 + */
54.2097 + private static final boolean compareAndSetWaitStatus(Node node,
54.2098 + int expect,
54.2099 + int update) {
54.2100 + return unsafe.compareAndSwapInt(node, waitStatusOffset,
54.2101 + expect, update);
54.2102 + }
54.2103 +
54.2104 + /**
54.2105 + * CAS next field of a node.
54.2106 + */
54.2107 + private static final boolean compareAndSetNext(Node node,
54.2108 + Node expect,
54.2109 + Node update) {
54.2110 + return unsafe.compareAndSwapObject(node, nextOffset, expect, update);
54.2111 + }
54.2112 +}
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/AbstractQueuedSynchronizer.java Sat Mar 19 10:46:31 2016 +0100
55.3 @@ -0,0 +1,2330 @@
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.*;
55.41 +import java.util.concurrent.*;
55.42 +import java.util.concurrent.atomic.*;
55.43 +import sun.misc.Unsafe;
55.44 +
55.45 +/**
55.46 + * Provides a framework for implementing blocking locks and related
55.47 + * synchronizers (semaphores, events, etc) that rely on
55.48 + * first-in-first-out (FIFO) wait queues. This class is designed to
55.49 + * be a useful basis for most kinds of synchronizers that rely on a
55.50 + * single atomic <tt>int</tt> value to represent state. Subclasses
55.51 + * must define the protected methods that change this state, and which
55.52 + * define what that state means in terms of this object being acquired
55.53 + * or released. Given these, the other methods in this class carry
55.54 + * out all queuing and blocking mechanics. Subclasses can maintain
55.55 + * other state fields, but only the atomically updated <tt>int</tt>
55.56 + * value manipulated using methods {@link #getState}, {@link
55.57 + * #setState} and {@link #compareAndSetState} is tracked with respect
55.58 + * to synchronization.
55.59 + *
55.60 + * <p>Subclasses should be defined as non-public internal helper
55.61 + * classes that are used to implement the synchronization properties
55.62 + * of their enclosing class. Class
55.63 + * <tt>AbstractQueuedSynchronizer</tt> does not implement any
55.64 + * synchronization interface. Instead it defines methods such as
55.65 + * {@link #acquireInterruptibly} that can be invoked as
55.66 + * appropriate by concrete locks and related synchronizers to
55.67 + * implement their public methods.
55.68 + *
55.69 + * <p>This class supports either or both a default <em>exclusive</em>
55.70 + * mode and a <em>shared</em> mode. When acquired in exclusive mode,
55.71 + * attempted acquires by other threads cannot succeed. Shared mode
55.72 + * acquires by multiple threads may (but need not) succeed. This class
55.73 + * does not "understand" these differences except in the
55.74 + * mechanical sense that when a shared mode acquire succeeds, the next
55.75 + * waiting thread (if one exists) must also determine whether it can
55.76 + * acquire as well. Threads waiting in the different modes share the
55.77 + * same FIFO queue. Usually, implementation subclasses support only
55.78 + * one of these modes, but both can come into play for example in a
55.79 + * {@link ReadWriteLock}. Subclasses that support only exclusive or
55.80 + * only shared modes need not define the methods supporting the unused mode.
55.81 + *
55.82 + * <p>This class defines a nested {@link ConditionObject} class that
55.83 + * can be used as a {@link Condition} implementation by subclasses
55.84 + * supporting exclusive mode for which method {@link
55.85 + * #isHeldExclusively} reports whether synchronization is exclusively
55.86 + * held with respect to the current thread, method {@link #release}
55.87 + * invoked with the current {@link #getState} value fully releases
55.88 + * this object, and {@link #acquire}, given this saved state value,
55.89 + * eventually restores this object to its previous acquired state. No
55.90 + * <tt>AbstractQueuedSynchronizer</tt> method otherwise creates such a
55.91 + * condition, so if this constraint cannot be met, do not use it. The
55.92 + * behavior of {@link ConditionObject} depends of course on the
55.93 + * semantics of its synchronizer implementation.
55.94 + *
55.95 + * <p>This class provides inspection, instrumentation, and monitoring
55.96 + * methods for the internal queue, as well as similar methods for
55.97 + * condition objects. These can be exported as desired into classes
55.98 + * using an <tt>AbstractQueuedSynchronizer</tt> for their
55.99 + * synchronization mechanics.
55.100 + *
55.101 + * <p>Serialization of this class stores only the underlying atomic
55.102 + * integer maintaining state, so deserialized objects have empty
55.103 + * thread queues. Typical subclasses requiring serializability will
55.104 + * define a <tt>readObject</tt> method that restores this to a known
55.105 + * initial state upon deserialization.
55.106 + *
55.107 + * <h3>Usage</h3>
55.108 + *
55.109 + * <p>To use this class as the basis of a synchronizer, redefine the
55.110 + * following methods, as applicable, by inspecting and/or modifying
55.111 + * the synchronization state using {@link #getState}, {@link
55.112 + * #setState} and/or {@link #compareAndSetState}:
55.113 + *
55.114 + * <ul>
55.115 + * <li> {@link #tryAcquire}
55.116 + * <li> {@link #tryRelease}
55.117 + * <li> {@link #tryAcquireShared}
55.118 + * <li> {@link #tryReleaseShared}
55.119 + * <li> {@link #isHeldExclusively}
55.120 + *</ul>
55.121 + *
55.122 + * Each of these methods by default throws {@link
55.123 + * UnsupportedOperationException}. Implementations of these methods
55.124 + * must be internally thread-safe, and should in general be short and
55.125 + * not block. Defining these methods is the <em>only</em> supported
55.126 + * means of using this class. All other methods are declared
55.127 + * <tt>final</tt> because they cannot be independently varied.
55.128 + *
55.129 + * <p>You may also find the inherited methods from {@link
55.130 + * AbstractOwnableSynchronizer} useful to keep track of the thread
55.131 + * owning an exclusive synchronizer. You are encouraged to use them
55.132 + * -- this enables monitoring and diagnostic tools to assist users in
55.133 + * determining which threads hold locks.
55.134 + *
55.135 + * <p>Even though this class is based on an internal FIFO queue, it
55.136 + * does not automatically enforce FIFO acquisition policies. The core
55.137 + * of exclusive synchronization takes the form:
55.138 + *
55.139 + * <pre>
55.140 + * Acquire:
55.141 + * while (!tryAcquire(arg)) {
55.142 + * <em>enqueue thread if it is not already queued</em>;
55.143 + * <em>possibly block current thread</em>;
55.144 + * }
55.145 + *
55.146 + * Release:
55.147 + * if (tryRelease(arg))
55.148 + * <em>unblock the first queued thread</em>;
55.149 + * </pre>
55.150 + *
55.151 + * (Shared mode is similar but may involve cascading signals.)
55.152 + *
55.153 + * <p><a name="barging">Because checks in acquire are invoked before
55.154 + * enqueuing, a newly acquiring thread may <em>barge</em> ahead of
55.155 + * others that are blocked and queued. However, you can, if desired,
55.156 + * define <tt>tryAcquire</tt> and/or <tt>tryAcquireShared</tt> to
55.157 + * disable barging by internally invoking one or more of the inspection
55.158 + * methods, thereby providing a <em>fair</em> FIFO acquisition order.
55.159 + * In particular, most fair synchronizers can define <tt>tryAcquire</tt>
55.160 + * to return <tt>false</tt> if {@link #hasQueuedPredecessors} (a method
55.161 + * specifically designed to be used by fair synchronizers) returns
55.162 + * <tt>true</tt>. Other variations are possible.
55.163 + *
55.164 + * <p>Throughput and scalability are generally highest for the
55.165 + * default barging (also known as <em>greedy</em>,
55.166 + * <em>renouncement</em>, and <em>convoy-avoidance</em>) strategy.
55.167 + * While this is not guaranteed to be fair or starvation-free, earlier
55.168 + * queued threads are allowed to recontend before later queued
55.169 + * threads, and each recontention has an unbiased chance to succeed
55.170 + * against incoming threads. Also, while acquires do not
55.171 + * "spin" in the usual sense, they may perform multiple
55.172 + * invocations of <tt>tryAcquire</tt> interspersed with other
55.173 + * computations before blocking. This gives most of the benefits of
55.174 + * spins when exclusive synchronization is only briefly held, without
55.175 + * most of the liabilities when it isn't. If so desired, you can
55.176 + * augment this by preceding calls to acquire methods with
55.177 + * "fast-path" checks, possibly prechecking {@link #hasContended}
55.178 + * and/or {@link #hasQueuedThreads} to only do so if the synchronizer
55.179 + * is likely not to be contended.
55.180 + *
55.181 + * <p>This class provides an efficient and scalable basis for
55.182 + * synchronization in part by specializing its range of use to
55.183 + * synchronizers that can rely on <tt>int</tt> state, acquire, and
55.184 + * release parameters, and an internal FIFO wait queue. When this does
55.185 + * not suffice, you can build synchronizers from a lower level using
55.186 + * {@link java.util.concurrent.atomic atomic} classes, your own custom
55.187 + * {@link java.util.Queue} classes, and {@link LockSupport} blocking
55.188 + * support.
55.189 + *
55.190 + * <h3>Usage Examples</h3>
55.191 + *
55.192 + * <p>Here is a non-reentrant mutual exclusion lock class that uses
55.193 + * the value zero to represent the unlocked state, and one to
55.194 + * represent the locked state. While a non-reentrant lock
55.195 + * does not strictly require recording of the current owner
55.196 + * thread, this class does so anyway to make usage easier to monitor.
55.197 + * It also supports conditions and exposes
55.198 + * one of the instrumentation methods:
55.199 + *
55.200 + * <pre>
55.201 + * class Mutex implements Lock, java.io.Serializable {
55.202 + *
55.203 + * // Our internal helper class
55.204 + * private static class Sync extends AbstractQueuedSynchronizer {
55.205 + * // Report whether in locked state
55.206 + * protected boolean isHeldExclusively() {
55.207 + * return getState() == 1;
55.208 + * }
55.209 + *
55.210 + * // Acquire the lock if state is zero
55.211 + * public boolean tryAcquire(int acquires) {
55.212 + * assert acquires == 1; // Otherwise unused
55.213 + * if (compareAndSetState(0, 1)) {
55.214 + * setExclusiveOwnerThread(Thread.currentThread());
55.215 + * return true;
55.216 + * }
55.217 + * return false;
55.218 + * }
55.219 + *
55.220 + * // Release the lock by setting state to zero
55.221 + * protected boolean tryRelease(int releases) {
55.222 + * assert releases == 1; // Otherwise unused
55.223 + * if (getState() == 0) throw new IllegalMonitorStateException();
55.224 + * setExclusiveOwnerThread(null);
55.225 + * setState(0);
55.226 + * return true;
55.227 + * }
55.228 + *
55.229 + * // Provide a Condition
55.230 + * Condition newCondition() { return new ConditionObject(); }
55.231 + *
55.232 + * // Deserialize properly
55.233 + * private void readObject(ObjectInputStream s)
55.234 + * throws IOException, ClassNotFoundException {
55.235 + * s.defaultReadObject();
55.236 + * setState(0); // reset to unlocked state
55.237 + * }
55.238 + * }
55.239 + *
55.240 + * // The sync object does all the hard work. We just forward to it.
55.241 + * private final Sync sync = new Sync();
55.242 + *
55.243 + * public void lock() { sync.acquire(1); }
55.244 + * public boolean tryLock() { return sync.tryAcquire(1); }
55.245 + * public void unlock() { sync.release(1); }
55.246 + * public Condition newCondition() { return sync.newCondition(); }
55.247 + * public boolean isLocked() { return sync.isHeldExclusively(); }
55.248 + * public boolean hasQueuedThreads() { return sync.hasQueuedThreads(); }
55.249 + * public void lockInterruptibly() throws InterruptedException {
55.250 + * sync.acquireInterruptibly(1);
55.251 + * }
55.252 + * public boolean tryLock(long timeout, TimeUnit unit)
55.253 + * throws InterruptedException {
55.254 + * return sync.tryAcquireNanos(1, unit.toNanos(timeout));
55.255 + * }
55.256 + * }
55.257 + * </pre>
55.258 + *
55.259 + * <p>Here is a latch class that is like a {@link CountDownLatch}
55.260 + * except that it only requires a single <tt>signal</tt> to
55.261 + * fire. Because a latch is non-exclusive, it uses the <tt>shared</tt>
55.262 + * acquire and release methods.
55.263 + *
55.264 + * <pre>
55.265 + * class BooleanLatch {
55.266 + *
55.267 + * private static class Sync extends AbstractQueuedSynchronizer {
55.268 + * boolean isSignalled() { return getState() != 0; }
55.269 + *
55.270 + * protected int tryAcquireShared(int ignore) {
55.271 + * return isSignalled() ? 1 : -1;
55.272 + * }
55.273 + *
55.274 + * protected boolean tryReleaseShared(int ignore) {
55.275 + * setState(1);
55.276 + * return true;
55.277 + * }
55.278 + * }
55.279 + *
55.280 + * private final Sync sync = new Sync();
55.281 + * public boolean isSignalled() { return sync.isSignalled(); }
55.282 + * public void signal() { sync.releaseShared(1); }
55.283 + * public void await() throws InterruptedException {
55.284 + * sync.acquireSharedInterruptibly(1);
55.285 + * }
55.286 + * }
55.287 + * </pre>
55.288 + *
55.289 + * @since 1.5
55.290 + * @author Doug Lea
55.291 + */
55.292 +public abstract class AbstractQueuedSynchronizer
55.293 + extends AbstractOwnableSynchronizer
55.294 + implements java.io.Serializable {
55.295 +
55.296 + private static final long serialVersionUID = 7373984972572414691L;
55.297 +
55.298 + /**
55.299 + * Creates a new <tt>AbstractQueuedSynchronizer</tt> instance
55.300 + * with initial synchronization state of zero.
55.301 + */
55.302 + protected AbstractQueuedSynchronizer() { }
55.303 +
55.304 + /**
55.305 + * Wait queue node class.
55.306 + *
55.307 + * <p>The wait queue is a variant of a "CLH" (Craig, Landin, and
55.308 + * Hagersten) lock queue. CLH locks are normally used for
55.309 + * spinlocks. We instead use them for blocking synchronizers, but
55.310 + * use the same basic tactic of holding some of the control
55.311 + * information about a thread in the predecessor of its node. A
55.312 + * "status" field in each node keeps track of whether a thread
55.313 + * should block. A node is signalled when its predecessor
55.314 + * releases. Each node of the queue otherwise serves as a
55.315 + * specific-notification-style monitor holding a single waiting
55.316 + * thread. The status field does NOT control whether threads are
55.317 + * granted locks etc though. A thread may try to acquire if it is
55.318 + * first in the queue. But being first does not guarantee success;
55.319 + * it only gives the right to contend. So the currently released
55.320 + * contender thread may need to rewait.
55.321 + *
55.322 + * <p>To enqueue into a CLH lock, you atomically splice it in as new
55.323 + * tail. To dequeue, you just set the head field.
55.324 + * <pre>
55.325 + * +------+ prev +-----+ +-----+
55.326 + * head | | <---- | | <---- | | tail
55.327 + * +------+ +-----+ +-----+
55.328 + * </pre>
55.329 + *
55.330 + * <p>Insertion into a CLH queue requires only a single atomic
55.331 + * operation on "tail", so there is a simple atomic point of
55.332 + * demarcation from unqueued to queued. Similarly, dequeing
55.333 + * involves only updating the "head". However, it takes a bit
55.334 + * more work for nodes to determine who their successors are,
55.335 + * in part to deal with possible cancellation due to timeouts
55.336 + * and interrupts.
55.337 + *
55.338 + * <p>The "prev" links (not used in original CLH locks), are mainly
55.339 + * needed to handle cancellation. If a node is cancelled, its
55.340 + * successor is (normally) relinked to a non-cancelled
55.341 + * predecessor. For explanation of similar mechanics in the case
55.342 + * of spin locks, see the papers by Scott and Scherer at
55.343 + * http://www.cs.rochester.edu/u/scott/synchronization/
55.344 + *
55.345 + * <p>We also use "next" links to implement blocking mechanics.
55.346 + * The thread id for each node is kept in its own node, so a
55.347 + * predecessor signals the next node to wake up by traversing
55.348 + * next link to determine which thread it is. Determination of
55.349 + * successor must avoid races with newly queued nodes to set
55.350 + * the "next" fields of their predecessors. This is solved
55.351 + * when necessary by checking backwards from the atomically
55.352 + * updated "tail" when a node's successor appears to be null.
55.353 + * (Or, said differently, the next-links are an optimization
55.354 + * so that we don't usually need a backward scan.)
55.355 + *
55.356 + * <p>Cancellation introduces some conservatism to the basic
55.357 + * algorithms. Since we must poll for cancellation of other
55.358 + * nodes, we can miss noticing whether a cancelled node is
55.359 + * ahead or behind us. This is dealt with by always unparking
55.360 + * successors upon cancellation, allowing them to stabilize on
55.361 + * a new predecessor, unless we can identify an uncancelled
55.362 + * predecessor who will carry this responsibility.
55.363 + *
55.364 + * <p>CLH queues need a dummy header node to get started. But
55.365 + * we don't create them on construction, because it would be wasted
55.366 + * effort if there is never contention. Instead, the node
55.367 + * is constructed and head and tail pointers are set upon first
55.368 + * contention.
55.369 + *
55.370 + * <p>Threads waiting on Conditions use the same nodes, but
55.371 + * use an additional link. Conditions only need to link nodes
55.372 + * in simple (non-concurrent) linked queues because they are
55.373 + * only accessed when exclusively held. Upon await, a node is
55.374 + * inserted into a condition queue. Upon signal, the node is
55.375 + * transferred to the main queue. A special value of status
55.376 + * field is used to mark which queue a node is on.
55.377 + *
55.378 + * <p>Thanks go to Dave Dice, Mark Moir, Victor Luchangco, Bill
55.379 + * Scherer and Michael Scott, along with members of JSR-166
55.380 + * expert group, for helpful ideas, discussions, and critiques
55.381 + * on the design of this class.
55.382 + */
55.383 + static final class Node {
55.384 + /** Marker to indicate a node is waiting in shared mode */
55.385 + static final Node SHARED = new Node();
55.386 + /** Marker to indicate a node is waiting in exclusive mode */
55.387 + static final Node EXCLUSIVE = null;
55.388 +
55.389 + /** waitStatus value to indicate thread has cancelled */
55.390 + static final int CANCELLED = 1;
55.391 + /** waitStatus value to indicate successor's thread needs unparking */
55.392 + static final int SIGNAL = -1;
55.393 + /** waitStatus value to indicate thread is waiting on condition */
55.394 + static final int CONDITION = -2;
55.395 + /**
55.396 + * waitStatus value to indicate the next acquireShared should
55.397 + * unconditionally propagate
55.398 + */
55.399 + static final int PROPAGATE = -3;
55.400 +
55.401 + /**
55.402 + * Status field, taking on only the values:
55.403 + * SIGNAL: The successor of this node is (or will soon be)
55.404 + * blocked (via park), so the current node must
55.405 + * unpark its successor when it releases or
55.406 + * cancels. To avoid races, acquire methods must
55.407 + * first indicate they need a signal,
55.408 + * then retry the atomic acquire, and then,
55.409 + * on failure, block.
55.410 + * CANCELLED: This node is cancelled due to timeout or interrupt.
55.411 + * Nodes never leave this state. In particular,
55.412 + * a thread with cancelled node never again blocks.
55.413 + * CONDITION: This node is currently on a condition queue.
55.414 + * It will not be used as a sync queue node
55.415 + * until transferred, at which time the status
55.416 + * will be set to 0. (Use of this value here has
55.417 + * nothing to do with the other uses of the
55.418 + * field, but simplifies mechanics.)
55.419 + * PROPAGATE: A releaseShared should be propagated to other
55.420 + * nodes. This is set (for head node only) in
55.421 + * doReleaseShared to ensure propagation
55.422 + * continues, even if other operations have
55.423 + * since intervened.
55.424 + * 0: None of the above
55.425 + *
55.426 + * The values are arranged numerically to simplify use.
55.427 + * Non-negative values mean that a node doesn't need to
55.428 + * signal. So, most code doesn't need to check for particular
55.429 + * values, just for sign.
55.430 + *
55.431 + * The field is initialized to 0 for normal sync nodes, and
55.432 + * CONDITION for condition nodes. It is modified using CAS
55.433 + * (or when possible, unconditional volatile writes).
55.434 + */
55.435 + volatile int waitStatus;
55.436 +
55.437 + /**
55.438 + * Link to predecessor node that current node/thread relies on
55.439 + * for checking waitStatus. Assigned during enqueing, and nulled
55.440 + * out (for sake of GC) only upon dequeuing. Also, upon
55.441 + * cancellation of a predecessor, we short-circuit while
55.442 + * finding a non-cancelled one, which will always exist
55.443 + * because the head node is never cancelled: A node becomes
55.444 + * head only as a result of successful acquire. A
55.445 + * cancelled thread never succeeds in acquiring, and a thread only
55.446 + * cancels itself, not any other node.
55.447 + */
55.448 + volatile Node prev;
55.449 +
55.450 + /**
55.451 + * Link to the successor node that the current node/thread
55.452 + * unparks upon release. Assigned during enqueuing, adjusted
55.453 + * when bypassing cancelled predecessors, and nulled out (for
55.454 + * sake of GC) when dequeued. The enq operation does not
55.455 + * assign next field of a predecessor until after attachment,
55.456 + * so seeing a null next field does not necessarily mean that
55.457 + * node is at end of queue. However, if a next field appears
55.458 + * to be null, we can scan prev's from the tail to
55.459 + * double-check. The next field of cancelled nodes is set to
55.460 + * point to the node itself instead of null, to make life
55.461 + * easier for isOnSyncQueue.
55.462 + */
55.463 + volatile Node next;
55.464 +
55.465 + /**
55.466 + * The thread that enqueued this node. Initialized on
55.467 + * construction and nulled out after use.
55.468 + */
55.469 + volatile Thread thread;
55.470 +
55.471 + /**
55.472 + * Link to next node waiting on condition, or the special
55.473 + * value SHARED. Because condition queues are accessed only
55.474 + * when holding in exclusive mode, we just need a simple
55.475 + * linked queue to hold nodes while they are waiting on
55.476 + * conditions. They are then transferred to the queue to
55.477 + * re-acquire. And because conditions can only be exclusive,
55.478 + * we save a field by using special value to indicate shared
55.479 + * mode.
55.480 + */
55.481 + Node nextWaiter;
55.482 +
55.483 + /**
55.484 + * Returns true if node is waiting in shared mode
55.485 + */
55.486 + final boolean isShared() {
55.487 + return nextWaiter == SHARED;
55.488 + }
55.489 +
55.490 + /**
55.491 + * Returns previous node, or throws NullPointerException if null.
55.492 + * Use when predecessor cannot be null. The null check could
55.493 + * be elided, but is present to help the VM.
55.494 + *
55.495 + * @return the predecessor of this node
55.496 + */
55.497 + final Node predecessor() throws NullPointerException {
55.498 + Node p = prev;
55.499 + if (p == null)
55.500 + throw new NullPointerException();
55.501 + else
55.502 + return p;
55.503 + }
55.504 +
55.505 + Node() { // Used to establish initial head or SHARED marker
55.506 + }
55.507 +
55.508 + Node(Thread thread, Node mode) { // Used by addWaiter
55.509 + this.nextWaiter = mode;
55.510 + this.thread = thread;
55.511 + }
55.512 +
55.513 + Node(Thread thread, int waitStatus) { // Used by Condition
55.514 + this.waitStatus = waitStatus;
55.515 + this.thread = thread;
55.516 + }
55.517 + }
55.518 +
55.519 + /**
55.520 + * Head of the wait queue, lazily initialized. Except for
55.521 + * initialization, it is modified only via method setHead. Note:
55.522 + * If head exists, its waitStatus is guaranteed not to be
55.523 + * CANCELLED.
55.524 + */
55.525 + private transient volatile Node head;
55.526 +
55.527 + /**
55.528 + * Tail of the wait queue, lazily initialized. Modified only via
55.529 + * method enq to add new wait node.
55.530 + */
55.531 + private transient volatile Node tail;
55.532 +
55.533 + /**
55.534 + * The synchronization state.
55.535 + */
55.536 + private volatile int state;
55.537 +
55.538 + /**
55.539 + * Returns the current value of synchronization state.
55.540 + * This operation has memory semantics of a <tt>volatile</tt> read.
55.541 + * @return current state value
55.542 + */
55.543 + protected final int getState() {
55.544 + return state;
55.545 + }
55.546 +
55.547 + /**
55.548 + * Sets the value of synchronization state.
55.549 + * This operation has memory semantics of a <tt>volatile</tt> write.
55.550 + * @param newState the new state value
55.551 + */
55.552 + protected final void setState(int newState) {
55.553 + state = newState;
55.554 + }
55.555 +
55.556 + /**
55.557 + * Atomically sets synchronization state to the given updated
55.558 + * value if the current state value equals the expected value.
55.559 + * This operation has memory semantics of a <tt>volatile</tt> read
55.560 + * and write.
55.561 + *
55.562 + * @param expect the expected value
55.563 + * @param update the new value
55.564 + * @return true if successful. False return indicates that the actual
55.565 + * value was not equal to the expected value.
55.566 + */
55.567 + protected final boolean compareAndSetState(int expect, int update) {
55.568 + // See below for intrinsics setup to support this
55.569 + return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
55.570 + }
55.571 +
55.572 + // Queuing utilities
55.573 +
55.574 + /**
55.575 + * The number of nanoseconds for which it is faster to spin
55.576 + * rather than to use timed park. A rough estimate suffices
55.577 + * to improve responsiveness with very short timeouts.
55.578 + */
55.579 + static final long spinForTimeoutThreshold = 1000L;
55.580 +
55.581 + /**
55.582 + * Inserts node into queue, initializing if necessary. See picture above.
55.583 + * @param node the node to insert
55.584 + * @return node's predecessor
55.585 + */
55.586 + private Node enq(final Node node) {
55.587 + for (;;) {
55.588 + Node t = tail;
55.589 + if (t == null) { // Must initialize
55.590 + if (compareAndSetHead(new Node()))
55.591 + tail = head;
55.592 + } else {
55.593 + node.prev = t;
55.594 + if (compareAndSetTail(t, node)) {
55.595 + t.next = node;
55.596 + return t;
55.597 + }
55.598 + }
55.599 + }
55.600 + }
55.601 +
55.602 + /**
55.603 + * Creates and enqueues node for current thread and given mode.
55.604 + *
55.605 + * @param mode Node.EXCLUSIVE for exclusive, Node.SHARED for shared
55.606 + * @return the new node
55.607 + */
55.608 + private Node addWaiter(Node mode) {
55.609 + Node node = new Node(Thread.currentThread(), mode);
55.610 + // Try the fast path of enq; backup to full enq on failure
55.611 + Node pred = tail;
55.612 + if (pred != null) {
55.613 + node.prev = pred;
55.614 + if (compareAndSetTail(pred, node)) {
55.615 + pred.next = node;
55.616 + return node;
55.617 + }
55.618 + }
55.619 + enq(node);
55.620 + return node;
55.621 + }
55.622 +
55.623 + /**
55.624 + * Sets head of queue to be node, thus dequeuing. Called only by
55.625 + * acquire methods. Also nulls out unused fields for sake of GC
55.626 + * and to suppress unnecessary signals and traversals.
55.627 + *
55.628 + * @param node the node
55.629 + */
55.630 + private void setHead(Node node) {
55.631 + head = node;
55.632 + node.thread = null;
55.633 + node.prev = null;
55.634 + }
55.635 +
55.636 + /**
55.637 + * Wakes up node's successor, if one exists.
55.638 + *
55.639 + * @param node the node
55.640 + */
55.641 + private void unparkSuccessor(Node node) {
55.642 + /*
55.643 + * If status is negative (i.e., possibly needing signal) try
55.644 + * to clear in anticipation of signalling. It is OK if this
55.645 + * fails or if status is changed by waiting thread.
55.646 + */
55.647 + int ws = node.waitStatus;
55.648 + if (ws < 0)
55.649 + compareAndSetWaitStatus(node, ws, 0);
55.650 +
55.651 + /*
55.652 + * Thread to unpark is held in successor, which is normally
55.653 + * just the next node. But if cancelled or apparently null,
55.654 + * traverse backwards from tail to find the actual
55.655 + * non-cancelled successor.
55.656 + */
55.657 + Node s = node.next;
55.658 + if (s == null || s.waitStatus > 0) {
55.659 + s = null;
55.660 + for (Node t = tail; t != null && t != node; t = t.prev)
55.661 + if (t.waitStatus <= 0)
55.662 + s = t;
55.663 + }
55.664 + if (s != null)
55.665 + LockSupport.unpark(s.thread);
55.666 + }
55.667 +
55.668 + /**
55.669 + * Release action for shared mode -- signal successor and ensure
55.670 + * propagation. (Note: For exclusive mode, release just amounts
55.671 + * to calling unparkSuccessor of head if it needs signal.)
55.672 + */
55.673 + private void doReleaseShared() {
55.674 + /*
55.675 + * Ensure that a release propagates, even if there are other
55.676 + * in-progress acquires/releases. This proceeds in the usual
55.677 + * way of trying to unparkSuccessor of head if it needs
55.678 + * signal. But if it does not, status is set to PROPAGATE to
55.679 + * ensure that upon release, propagation continues.
55.680 + * Additionally, we must loop in case a new node is added
55.681 + * while we are doing this. Also, unlike other uses of
55.682 + * unparkSuccessor, we need to know if CAS to reset status
55.683 + * fails, if so rechecking.
55.684 + */
55.685 + for (;;) {
55.686 + Node h = head;
55.687 + if (h != null && h != tail) {
55.688 + int ws = h.waitStatus;
55.689 + if (ws == Node.SIGNAL) {
55.690 + if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))
55.691 + continue; // loop to recheck cases
55.692 + unparkSuccessor(h);
55.693 + }
55.694 + else if (ws == 0 &&
55.695 + !compareAndSetWaitStatus(h, 0, Node.PROPAGATE))
55.696 + continue; // loop on failed CAS
55.697 + }
55.698 + if (h == head) // loop if head changed
55.699 + break;
55.700 + }
55.701 + }
55.702 +
55.703 + /**
55.704 + * Sets head of queue, and checks if successor may be waiting
55.705 + * in shared mode, if so propagating if either propagate > 0 or
55.706 + * PROPAGATE status was set.
55.707 + *
55.708 + * @param node the node
55.709 + * @param propagate the return value from a tryAcquireShared
55.710 + */
55.711 + private void setHeadAndPropagate(Node node, int propagate) {
55.712 + Node h = head; // Record old head for check below
55.713 + setHead(node);
55.714 + /*
55.715 + * Try to signal next queued node if:
55.716 + * Propagation was indicated by caller,
55.717 + * or was recorded (as h.waitStatus) by a previous operation
55.718 + * (note: this uses sign-check of waitStatus because
55.719 + * PROPAGATE status may transition to SIGNAL.)
55.720 + * and
55.721 + * The next node is waiting in shared mode,
55.722 + * or we don't know, because it appears null
55.723 + *
55.724 + * The conservatism in both of these checks may cause
55.725 + * unnecessary wake-ups, but only when there are multiple
55.726 + * racing acquires/releases, so most need signals now or soon
55.727 + * anyway.
55.728 + */
55.729 + if (propagate > 0 || h == null || h.waitStatus < 0) {
55.730 + Node s = node.next;
55.731 + if (s == null || s.isShared())
55.732 + doReleaseShared();
55.733 + }
55.734 + }
55.735 +
55.736 + // Utilities for various versions of acquire
55.737 +
55.738 + /**
55.739 + * Cancels an ongoing attempt to acquire.
55.740 + *
55.741 + * @param node the node
55.742 + */
55.743 + private void cancelAcquire(Node node) {
55.744 + // Ignore if node doesn't exist
55.745 + if (node == null)
55.746 + return;
55.747 +
55.748 + node.thread = null;
55.749 +
55.750 + // Skip cancelled predecessors
55.751 + Node pred = node.prev;
55.752 + while (pred.waitStatus > 0)
55.753 + node.prev = pred = pred.prev;
55.754 +
55.755 + // predNext is the apparent node to unsplice. CASes below will
55.756 + // fail if not, in which case, we lost race vs another cancel
55.757 + // or signal, so no further action is necessary.
55.758 + Node predNext = pred.next;
55.759 +
55.760 + // Can use unconditional write instead of CAS here.
55.761 + // After this atomic step, other Nodes can skip past us.
55.762 + // Before, we are free of interference from other threads.
55.763 + node.waitStatus = Node.CANCELLED;
55.764 +
55.765 + // If we are the tail, remove ourselves.
55.766 + if (node == tail && compareAndSetTail(node, pred)) {
55.767 + compareAndSetNext(pred, predNext, null);
55.768 + } else {
55.769 + // If successor needs signal, try to set pred's next-link
55.770 + // so it will get one. Otherwise wake it up to propagate.
55.771 + int ws;
55.772 + if (pred != head &&
55.773 + ((ws = pred.waitStatus) == Node.SIGNAL ||
55.774 + (ws <= 0 && compareAndSetWaitStatus(pred, ws, Node.SIGNAL))) &&
55.775 + pred.thread != null) {
55.776 + Node next = node.next;
55.777 + if (next != null && next.waitStatus <= 0)
55.778 + compareAndSetNext(pred, predNext, next);
55.779 + } else {
55.780 + unparkSuccessor(node);
55.781 + }
55.782 +
55.783 + node.next = node; // help GC
55.784 + }
55.785 + }
55.786 +
55.787 + /**
55.788 + * Checks and updates status for a node that failed to acquire.
55.789 + * Returns true if thread should block. This is the main signal
55.790 + * control in all acquire loops. Requires that pred == node.prev
55.791 + *
55.792 + * @param pred node's predecessor holding status
55.793 + * @param node the node
55.794 + * @return {@code true} if thread should block
55.795 + */
55.796 + private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
55.797 + int ws = pred.waitStatus;
55.798 + if (ws == Node.SIGNAL)
55.799 + /*
55.800 + * This node has already set status asking a release
55.801 + * to signal it, so it can safely park.
55.802 + */
55.803 + return true;
55.804 + if (ws > 0) {
55.805 + /*
55.806 + * Predecessor was cancelled. Skip over predecessors and
55.807 + * indicate retry.
55.808 + */
55.809 + do {
55.810 + node.prev = pred = pred.prev;
55.811 + } while (pred.waitStatus > 0);
55.812 + pred.next = node;
55.813 + } else {
55.814 + /*
55.815 + * waitStatus must be 0 or PROPAGATE. Indicate that we
55.816 + * need a signal, but don't park yet. Caller will need to
55.817 + * retry to make sure it cannot acquire before parking.
55.818 + */
55.819 + compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
55.820 + }
55.821 + return false;
55.822 + }
55.823 +
55.824 + /**
55.825 + * Convenience method to interrupt current thread.
55.826 + */
55.827 + private static void selfInterrupt() {
55.828 + Thread.currentThread().interrupt();
55.829 + }
55.830 +
55.831 + /**
55.832 + * Convenience method to park and then check if interrupted
55.833 + *
55.834 + * @return {@code true} if interrupted
55.835 + */
55.836 + private final boolean parkAndCheckInterrupt() {
55.837 + LockSupport.park(this);
55.838 + return Thread.interrupted();
55.839 + }
55.840 +
55.841 + /*
55.842 + * Various flavors of acquire, varying in exclusive/shared and
55.843 + * control modes. Each is mostly the same, but annoyingly
55.844 + * different. Only a little bit of factoring is possible due to
55.845 + * interactions of exception mechanics (including ensuring that we
55.846 + * cancel if tryAcquire throws exception) and other control, at
55.847 + * least not without hurting performance too much.
55.848 + */
55.849 +
55.850 + /**
55.851 + * Acquires in exclusive uninterruptible mode for thread already in
55.852 + * queue. Used by condition wait methods as well as acquire.
55.853 + *
55.854 + * @param node the node
55.855 + * @param arg the acquire argument
55.856 + * @return {@code true} if interrupted while waiting
55.857 + */
55.858 + final boolean acquireQueued(final Node node, int arg) {
55.859 + boolean failed = true;
55.860 + try {
55.861 + boolean interrupted = false;
55.862 + for (;;) {
55.863 + final Node p = node.predecessor();
55.864 + if (p == head && tryAcquire(arg)) {
55.865 + setHead(node);
55.866 + p.next = null; // help GC
55.867 + failed = false;
55.868 + return interrupted;
55.869 + }
55.870 + if (shouldParkAfterFailedAcquire(p, node) &&
55.871 + parkAndCheckInterrupt())
55.872 + interrupted = true;
55.873 + }
55.874 + } finally {
55.875 + if (failed)
55.876 + cancelAcquire(node);
55.877 + }
55.878 + }
55.879 +
55.880 + /**
55.881 + * Acquires in exclusive interruptible mode.
55.882 + * @param arg the acquire argument
55.883 + */
55.884 + private void doAcquireInterruptibly(int arg)
55.885 + throws InterruptedException {
55.886 + final Node node = addWaiter(Node.EXCLUSIVE);
55.887 + boolean failed = true;
55.888 + try {
55.889 + for (;;) {
55.890 + final Node p = node.predecessor();
55.891 + if (p == head && tryAcquire(arg)) {
55.892 + setHead(node);
55.893 + p.next = null; // help GC
55.894 + failed = false;
55.895 + return;
55.896 + }
55.897 + if (shouldParkAfterFailedAcquire(p, node) &&
55.898 + parkAndCheckInterrupt())
55.899 + throw new InterruptedException();
55.900 + }
55.901 + } finally {
55.902 + if (failed)
55.903 + cancelAcquire(node);
55.904 + }
55.905 + }
55.906 +
55.907 + /**
55.908 + * Acquires in exclusive timed mode.
55.909 + *
55.910 + * @param arg the acquire argument
55.911 + * @param nanosTimeout max wait time
55.912 + * @return {@code true} if acquired
55.913 + */
55.914 + private boolean doAcquireNanos(int arg, long nanosTimeout)
55.915 + throws InterruptedException {
55.916 + long lastTime = System.nanoTime();
55.917 + final Node node = addWaiter(Node.EXCLUSIVE);
55.918 + boolean failed = true;
55.919 + try {
55.920 + for (;;) {
55.921 + final Node p = node.predecessor();
55.922 + if (p == head && tryAcquire(arg)) {
55.923 + setHead(node);
55.924 + p.next = null; // help GC
55.925 + failed = false;
55.926 + return true;
55.927 + }
55.928 + if (nanosTimeout <= 0)
55.929 + return false;
55.930 + if (shouldParkAfterFailedAcquire(p, node) &&
55.931 + nanosTimeout > spinForTimeoutThreshold)
55.932 + LockSupport.parkNanos(this, nanosTimeout);
55.933 + long now = System.nanoTime();
55.934 + nanosTimeout -= now - lastTime;
55.935 + lastTime = now;
55.936 + if (Thread.interrupted())
55.937 + throw new InterruptedException();
55.938 + }
55.939 + } finally {
55.940 + if (failed)
55.941 + cancelAcquire(node);
55.942 + }
55.943 + }
55.944 +
55.945 + /**
55.946 + * Acquires in shared uninterruptible mode.
55.947 + * @param arg the acquire argument
55.948 + */
55.949 + private void doAcquireShared(int arg) {
55.950 + final Node node = addWaiter(Node.SHARED);
55.951 + boolean failed = true;
55.952 + try {
55.953 + boolean interrupted = false;
55.954 + for (;;) {
55.955 + final Node p = node.predecessor();
55.956 + if (p == head) {
55.957 + int r = tryAcquireShared(arg);
55.958 + if (r >= 0) {
55.959 + setHeadAndPropagate(node, r);
55.960 + p.next = null; // help GC
55.961 + if (interrupted)
55.962 + selfInterrupt();
55.963 + failed = false;
55.964 + return;
55.965 + }
55.966 + }
55.967 + if (shouldParkAfterFailedAcquire(p, node) &&
55.968 + parkAndCheckInterrupt())
55.969 + interrupted = true;
55.970 + }
55.971 + } finally {
55.972 + if (failed)
55.973 + cancelAcquire(node);
55.974 + }
55.975 + }
55.976 +
55.977 + /**
55.978 + * Acquires in shared interruptible mode.
55.979 + * @param arg the acquire argument
55.980 + */
55.981 + private void doAcquireSharedInterruptibly(int arg)
55.982 + throws InterruptedException {
55.983 + final Node node = addWaiter(Node.SHARED);
55.984 + boolean failed = true;
55.985 + try {
55.986 + for (;;) {
55.987 + final Node p = node.predecessor();
55.988 + if (p == head) {
55.989 + int r = tryAcquireShared(arg);
55.990 + if (r >= 0) {
55.991 + setHeadAndPropagate(node, r);
55.992 + p.next = null; // help GC
55.993 + failed = false;
55.994 + return;
55.995 + }
55.996 + }
55.997 + if (shouldParkAfterFailedAcquire(p, node) &&
55.998 + parkAndCheckInterrupt())
55.999 + throw new InterruptedException();
55.1000 + }
55.1001 + } finally {
55.1002 + if (failed)
55.1003 + cancelAcquire(node);
55.1004 + }
55.1005 + }
55.1006 +
55.1007 + /**
55.1008 + * Acquires in shared timed mode.
55.1009 + *
55.1010 + * @param arg the acquire argument
55.1011 + * @param nanosTimeout max wait time
55.1012 + * @return {@code true} if acquired
55.1013 + */
55.1014 + private boolean doAcquireSharedNanos(int arg, long nanosTimeout)
55.1015 + throws InterruptedException {
55.1016 +
55.1017 + long lastTime = System.nanoTime();
55.1018 + final Node node = addWaiter(Node.SHARED);
55.1019 + boolean failed = true;
55.1020 + try {
55.1021 + for (;;) {
55.1022 + final Node p = node.predecessor();
55.1023 + if (p == head) {
55.1024 + int r = tryAcquireShared(arg);
55.1025 + if (r >= 0) {
55.1026 + setHeadAndPropagate(node, r);
55.1027 + p.next = null; // help GC
55.1028 + failed = false;
55.1029 + return true;
55.1030 + }
55.1031 + }
55.1032 + if (nanosTimeout <= 0)
55.1033 + return false;
55.1034 + if (shouldParkAfterFailedAcquire(p, node) &&
55.1035 + nanosTimeout > spinForTimeoutThreshold)
55.1036 + LockSupport.parkNanos(this, nanosTimeout);
55.1037 + long now = System.nanoTime();
55.1038 + nanosTimeout -= now - lastTime;
55.1039 + lastTime = now;
55.1040 + if (Thread.interrupted())
55.1041 + throw new InterruptedException();
55.1042 + }
55.1043 + } finally {
55.1044 + if (failed)
55.1045 + cancelAcquire(node);
55.1046 + }
55.1047 + }
55.1048 +
55.1049 + // Main exported methods
55.1050 +
55.1051 + /**
55.1052 + * Attempts to acquire in exclusive mode. This method should query
55.1053 + * if the state of the object permits it to be acquired in the
55.1054 + * exclusive mode, and if so to acquire it.
55.1055 + *
55.1056 + * <p>This method is always invoked by the thread performing
55.1057 + * acquire. If this method reports failure, the acquire method
55.1058 + * may queue the thread, if it is not already queued, until it is
55.1059 + * signalled by a release from some other thread. This can be used
55.1060 + * to implement method {@link Lock#tryLock()}.
55.1061 + *
55.1062 + * <p>The default
55.1063 + * implementation throws {@link UnsupportedOperationException}.
55.1064 + *
55.1065 + * @param arg the acquire argument. This value is always the one
55.1066 + * passed to an acquire method, or is the value saved on entry
55.1067 + * to a condition wait. The value is otherwise uninterpreted
55.1068 + * and can represent anything you like.
55.1069 + * @return {@code true} if successful. Upon success, this object has
55.1070 + * been acquired.
55.1071 + * @throws IllegalMonitorStateException if acquiring would place this
55.1072 + * synchronizer in an illegal state. This exception must be
55.1073 + * thrown in a consistent fashion for synchronization to work
55.1074 + * correctly.
55.1075 + * @throws UnsupportedOperationException if exclusive mode is not supported
55.1076 + */
55.1077 + protected boolean tryAcquire(int arg) {
55.1078 + throw new UnsupportedOperationException();
55.1079 + }
55.1080 +
55.1081 + /**
55.1082 + * Attempts to set the state to reflect a release in exclusive
55.1083 + * mode.
55.1084 + *
55.1085 + * <p>This method is always invoked by the thread performing release.
55.1086 + *
55.1087 + * <p>The default implementation throws
55.1088 + * {@link UnsupportedOperationException}.
55.1089 + *
55.1090 + * @param arg the release argument. This value is always the one
55.1091 + * passed to a release method, or the current state value upon
55.1092 + * entry to a condition wait. The value is otherwise
55.1093 + * uninterpreted and can represent anything you like.
55.1094 + * @return {@code true} if this object is now in a fully released
55.1095 + * state, so that any waiting threads may attempt to acquire;
55.1096 + * and {@code false} otherwise.
55.1097 + * @throws IllegalMonitorStateException if releasing would place this
55.1098 + * synchronizer in an illegal state. This exception must be
55.1099 + * thrown in a consistent fashion for synchronization to work
55.1100 + * correctly.
55.1101 + * @throws UnsupportedOperationException if exclusive mode is not supported
55.1102 + */
55.1103 + protected boolean tryRelease(int arg) {
55.1104 + throw new UnsupportedOperationException();
55.1105 + }
55.1106 +
55.1107 + /**
55.1108 + * Attempts to acquire in shared mode. This method should query if
55.1109 + * the state of the object permits it to be acquired in the shared
55.1110 + * mode, and if so to acquire it.
55.1111 + *
55.1112 + * <p>This method is always invoked by the thread performing
55.1113 + * acquire. If this method reports failure, the acquire method
55.1114 + * may queue the thread, if it is not already queued, until it is
55.1115 + * signalled by a release from some other thread.
55.1116 + *
55.1117 + * <p>The default implementation throws {@link
55.1118 + * UnsupportedOperationException}.
55.1119 + *
55.1120 + * @param arg the acquire argument. This value is always the one
55.1121 + * passed to an acquire method, or is the value saved on entry
55.1122 + * to a condition wait. The value is otherwise uninterpreted
55.1123 + * and can represent anything you like.
55.1124 + * @return a negative value on failure; zero if acquisition in shared
55.1125 + * mode succeeded but no subsequent shared-mode acquire can
55.1126 + * succeed; and a positive value if acquisition in shared
55.1127 + * mode succeeded and subsequent shared-mode acquires might
55.1128 + * also succeed, in which case a subsequent waiting thread
55.1129 + * must check availability. (Support for three different
55.1130 + * return values enables this method to be used in contexts
55.1131 + * where acquires only sometimes act exclusively.) Upon
55.1132 + * success, this object has been acquired.
55.1133 + * @throws IllegalMonitorStateException if acquiring would place this
55.1134 + * synchronizer in an illegal state. This exception must be
55.1135 + * thrown in a consistent fashion for synchronization to work
55.1136 + * correctly.
55.1137 + * @throws UnsupportedOperationException if shared mode is not supported
55.1138 + */
55.1139 + protected int tryAcquireShared(int arg) {
55.1140 + throw new UnsupportedOperationException();
55.1141 + }
55.1142 +
55.1143 + /**
55.1144 + * Attempts to set the state to reflect a release in shared mode.
55.1145 + *
55.1146 + * <p>This method is always invoked by the thread performing release.
55.1147 + *
55.1148 + * <p>The default implementation throws
55.1149 + * {@link UnsupportedOperationException}.
55.1150 + *
55.1151 + * @param arg the release argument. This value is always the one
55.1152 + * passed to a release method, or the current state value upon
55.1153 + * entry to a condition wait. The value is otherwise
55.1154 + * uninterpreted and can represent anything you like.
55.1155 + * @return {@code true} if this release of shared mode may permit a
55.1156 + * waiting acquire (shared or exclusive) to succeed; and
55.1157 + * {@code false} otherwise
55.1158 + * @throws IllegalMonitorStateException if releasing would place this
55.1159 + * synchronizer in an illegal state. This exception must be
55.1160 + * thrown in a consistent fashion for synchronization to work
55.1161 + * correctly.
55.1162 + * @throws UnsupportedOperationException if shared mode is not supported
55.1163 + */
55.1164 + protected boolean tryReleaseShared(int arg) {
55.1165 + throw new UnsupportedOperationException();
55.1166 + }
55.1167 +
55.1168 + /**
55.1169 + * Returns {@code true} if synchronization is held exclusively with
55.1170 + * respect to the current (calling) thread. This method is invoked
55.1171 + * upon each call to a non-waiting {@link ConditionObject} method.
55.1172 + * (Waiting methods instead invoke {@link #release}.)
55.1173 + *
55.1174 + * <p>The default implementation throws {@link
55.1175 + * UnsupportedOperationException}. This method is invoked
55.1176 + * internally only within {@link ConditionObject} methods, so need
55.1177 + * not be defined if conditions are not used.
55.1178 + *
55.1179 + * @return {@code true} if synchronization is held exclusively;
55.1180 + * {@code false} otherwise
55.1181 + * @throws UnsupportedOperationException if conditions are not supported
55.1182 + */
55.1183 + protected boolean isHeldExclusively() {
55.1184 + throw new UnsupportedOperationException();
55.1185 + }
55.1186 +
55.1187 + /**
55.1188 + * Acquires in exclusive mode, ignoring interrupts. Implemented
55.1189 + * by invoking at least once {@link #tryAcquire},
55.1190 + * returning on success. Otherwise the thread is queued, possibly
55.1191 + * repeatedly blocking and unblocking, invoking {@link
55.1192 + * #tryAcquire} until success. This method can be used
55.1193 + * to implement method {@link Lock#lock}.
55.1194 + *
55.1195 + * @param arg the acquire argument. This value is conveyed to
55.1196 + * {@link #tryAcquire} but is otherwise uninterpreted and
55.1197 + * can represent anything you like.
55.1198 + */
55.1199 + public final void acquire(int arg) {
55.1200 + if (!tryAcquire(arg) &&
55.1201 + acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
55.1202 + selfInterrupt();
55.1203 + }
55.1204 +
55.1205 + /**
55.1206 + * Acquires in exclusive mode, aborting if interrupted.
55.1207 + * Implemented by first checking interrupt status, then invoking
55.1208 + * at least once {@link #tryAcquire}, returning on
55.1209 + * success. Otherwise the thread is queued, possibly repeatedly
55.1210 + * blocking and unblocking, invoking {@link #tryAcquire}
55.1211 + * until success or the thread is interrupted. This method can be
55.1212 + * used to implement method {@link Lock#lockInterruptibly}.
55.1213 + *
55.1214 + * @param arg the acquire argument. This value is conveyed to
55.1215 + * {@link #tryAcquire} but is otherwise uninterpreted and
55.1216 + * can represent anything you like.
55.1217 + * @throws InterruptedException if the current thread is interrupted
55.1218 + */
55.1219 + public final void acquireInterruptibly(int arg)
55.1220 + throws InterruptedException {
55.1221 + if (Thread.interrupted())
55.1222 + throw new InterruptedException();
55.1223 + if (!tryAcquire(arg))
55.1224 + doAcquireInterruptibly(arg);
55.1225 + }
55.1226 +
55.1227 + /**
55.1228 + * Attempts to acquire in exclusive mode, aborting if interrupted,
55.1229 + * and failing if the given timeout elapses. Implemented by first
55.1230 + * checking interrupt status, then invoking at least once {@link
55.1231 + * #tryAcquire}, returning on success. Otherwise, the thread is
55.1232 + * queued, possibly repeatedly blocking and unblocking, invoking
55.1233 + * {@link #tryAcquire} until success or the thread is interrupted
55.1234 + * or the timeout elapses. This method can be used to implement
55.1235 + * method {@link Lock#tryLock(long, TimeUnit)}.
55.1236 + *
55.1237 + * @param arg the acquire argument. This value is conveyed to
55.1238 + * {@link #tryAcquire} but is otherwise uninterpreted and
55.1239 + * can represent anything you like.
55.1240 + * @param nanosTimeout the maximum number of nanoseconds to wait
55.1241 + * @return {@code true} if acquired; {@code false} if timed out
55.1242 + * @throws InterruptedException if the current thread is interrupted
55.1243 + */
55.1244 + public final boolean tryAcquireNanos(int arg, long nanosTimeout)
55.1245 + throws InterruptedException {
55.1246 + if (Thread.interrupted())
55.1247 + throw new InterruptedException();
55.1248 + return tryAcquire(arg) ||
55.1249 + doAcquireNanos(arg, nanosTimeout);
55.1250 + }
55.1251 +
55.1252 + /**
55.1253 + * Releases in exclusive mode. Implemented by unblocking one or
55.1254 + * more threads if {@link #tryRelease} returns true.
55.1255 + * This method can be used to implement method {@link Lock#unlock}.
55.1256 + *
55.1257 + * @param arg the release argument. This value is conveyed to
55.1258 + * {@link #tryRelease} but is otherwise uninterpreted and
55.1259 + * can represent anything you like.
55.1260 + * @return the value returned from {@link #tryRelease}
55.1261 + */
55.1262 + public final boolean release(int arg) {
55.1263 + if (tryRelease(arg)) {
55.1264 + Node h = head;
55.1265 + if (h != null && h.waitStatus != 0)
55.1266 + unparkSuccessor(h);
55.1267 + return true;
55.1268 + }
55.1269 + return false;
55.1270 + }
55.1271 +
55.1272 + /**
55.1273 + * Acquires in shared mode, ignoring interrupts. Implemented by
55.1274 + * first invoking at least once {@link #tryAcquireShared},
55.1275 + * returning on success. Otherwise the thread is queued, possibly
55.1276 + * repeatedly blocking and unblocking, invoking {@link
55.1277 + * #tryAcquireShared} until success.
55.1278 + *
55.1279 + * @param arg the acquire argument. This value is conveyed to
55.1280 + * {@link #tryAcquireShared} but is otherwise uninterpreted
55.1281 + * and can represent anything you like.
55.1282 + */
55.1283 + public final void acquireShared(int arg) {
55.1284 + if (tryAcquireShared(arg) < 0)
55.1285 + doAcquireShared(arg);
55.1286 + }
55.1287 +
55.1288 + /**
55.1289 + * Acquires in shared mode, aborting if interrupted. Implemented
55.1290 + * by first checking interrupt status, then invoking at least once
55.1291 + * {@link #tryAcquireShared}, returning on success. Otherwise the
55.1292 + * thread is queued, possibly repeatedly blocking and unblocking,
55.1293 + * invoking {@link #tryAcquireShared} until success or the thread
55.1294 + * is interrupted.
55.1295 + * @param arg the acquire argument
55.1296 + * This value is conveyed to {@link #tryAcquireShared} but is
55.1297 + * otherwise uninterpreted and can represent anything
55.1298 + * you like.
55.1299 + * @throws InterruptedException if the current thread is interrupted
55.1300 + */
55.1301 + public final void acquireSharedInterruptibly(int arg)
55.1302 + throws InterruptedException {
55.1303 + if (Thread.interrupted())
55.1304 + throw new InterruptedException();
55.1305 + if (tryAcquireShared(arg) < 0)
55.1306 + doAcquireSharedInterruptibly(arg);
55.1307 + }
55.1308 +
55.1309 + /**
55.1310 + * Attempts to acquire in shared mode, aborting if interrupted, and
55.1311 + * failing if the given timeout elapses. Implemented by first
55.1312 + * checking interrupt status, then invoking at least once {@link
55.1313 + * #tryAcquireShared}, returning on success. Otherwise, the
55.1314 + * thread is queued, possibly repeatedly blocking and unblocking,
55.1315 + * invoking {@link #tryAcquireShared} until success or the thread
55.1316 + * is interrupted or the timeout elapses.
55.1317 + *
55.1318 + * @param arg the acquire argument. This value is conveyed to
55.1319 + * {@link #tryAcquireShared} but is otherwise uninterpreted
55.1320 + * and can represent anything you like.
55.1321 + * @param nanosTimeout the maximum number of nanoseconds to wait
55.1322 + * @return {@code true} if acquired; {@code false} if timed out
55.1323 + * @throws InterruptedException if the current thread is interrupted
55.1324 + */
55.1325 + public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout)
55.1326 + throws InterruptedException {
55.1327 + if (Thread.interrupted())
55.1328 + throw new InterruptedException();
55.1329 + return tryAcquireShared(arg) >= 0 ||
55.1330 + doAcquireSharedNanos(arg, nanosTimeout);
55.1331 + }
55.1332 +
55.1333 + /**
55.1334 + * Releases in shared mode. Implemented by unblocking one or more
55.1335 + * threads if {@link #tryReleaseShared} returns true.
55.1336 + *
55.1337 + * @param arg the release argument. This value is conveyed to
55.1338 + * {@link #tryReleaseShared} but is otherwise uninterpreted
55.1339 + * and can represent anything you like.
55.1340 + * @return the value returned from {@link #tryReleaseShared}
55.1341 + */
55.1342 + public final boolean releaseShared(int arg) {
55.1343 + if (tryReleaseShared(arg)) {
55.1344 + doReleaseShared();
55.1345 + return true;
55.1346 + }
55.1347 + return false;
55.1348 + }
55.1349 +
55.1350 + // Queue inspection methods
55.1351 +
55.1352 + /**
55.1353 + * Queries whether any threads are waiting to acquire. Note that
55.1354 + * because cancellations due to interrupts and timeouts may occur
55.1355 + * at any time, a {@code true} return does not guarantee that any
55.1356 + * other thread will ever acquire.
55.1357 + *
55.1358 + * <p>In this implementation, this operation returns in
55.1359 + * constant time.
55.1360 + *
55.1361 + * @return {@code true} if there may be other threads waiting to acquire
55.1362 + */
55.1363 + public final boolean hasQueuedThreads() {
55.1364 + return head != tail;
55.1365 + }
55.1366 +
55.1367 + /**
55.1368 + * Queries whether any threads have ever contended to acquire this
55.1369 + * synchronizer; that is if an acquire method has ever blocked.
55.1370 + *
55.1371 + * <p>In this implementation, this operation returns in
55.1372 + * constant time.
55.1373 + *
55.1374 + * @return {@code true} if there has ever been contention
55.1375 + */
55.1376 + public final boolean hasContended() {
55.1377 + return head != null;
55.1378 + }
55.1379 +
55.1380 + /**
55.1381 + * Returns the first (longest-waiting) thread in the queue, or
55.1382 + * {@code null} if no threads are currently queued.
55.1383 + *
55.1384 + * <p>In this implementation, this operation normally returns in
55.1385 + * constant time, but may iterate upon contention if other threads are
55.1386 + * concurrently modifying the queue.
55.1387 + *
55.1388 + * @return the first (longest-waiting) thread in the queue, or
55.1389 + * {@code null} if no threads are currently queued
55.1390 + */
55.1391 + public final Thread getFirstQueuedThread() {
55.1392 + // handle only fast path, else relay
55.1393 + return (head == tail) ? null : fullGetFirstQueuedThread();
55.1394 + }
55.1395 +
55.1396 + /**
55.1397 + * Version of getFirstQueuedThread called when fastpath fails
55.1398 + */
55.1399 + private Thread fullGetFirstQueuedThread() {
55.1400 + /*
55.1401 + * The first node is normally head.next. Try to get its
55.1402 + * thread field, ensuring consistent reads: If thread
55.1403 + * field is nulled out or s.prev is no longer head, then
55.1404 + * some other thread(s) concurrently performed setHead in
55.1405 + * between some of our reads. We try this twice before
55.1406 + * resorting to traversal.
55.1407 + */
55.1408 + Node h, s;
55.1409 + Thread st;
55.1410 + if (((h = head) != null && (s = h.next) != null &&
55.1411 + s.prev == head && (st = s.thread) != null) ||
55.1412 + ((h = head) != null && (s = h.next) != null &&
55.1413 + s.prev == head && (st = s.thread) != null))
55.1414 + return st;
55.1415 +
55.1416 + /*
55.1417 + * Head's next field might not have been set yet, or may have
55.1418 + * been unset after setHead. So we must check to see if tail
55.1419 + * is actually first node. If not, we continue on, safely
55.1420 + * traversing from tail back to head to find first,
55.1421 + * guaranteeing termination.
55.1422 + */
55.1423 +
55.1424 + Node t = tail;
55.1425 + Thread firstThread = null;
55.1426 + while (t != null && t != head) {
55.1427 + Thread tt = t.thread;
55.1428 + if (tt != null)
55.1429 + firstThread = tt;
55.1430 + t = t.prev;
55.1431 + }
55.1432 + return firstThread;
55.1433 + }
55.1434 +
55.1435 + /**
55.1436 + * Returns true if the given thread is currently queued.
55.1437 + *
55.1438 + * <p>This implementation traverses the queue to determine
55.1439 + * presence of the given thread.
55.1440 + *
55.1441 + * @param thread the thread
55.1442 + * @return {@code true} if the given thread is on the queue
55.1443 + * @throws NullPointerException if the thread is null
55.1444 + */
55.1445 + public final boolean isQueued(Thread thread) {
55.1446 + if (thread == null)
55.1447 + throw new NullPointerException();
55.1448 + for (Node p = tail; p != null; p = p.prev)
55.1449 + if (p.thread == thread)
55.1450 + return true;
55.1451 + return false;
55.1452 + }
55.1453 +
55.1454 + /**
55.1455 + * Returns {@code true} if the apparent first queued thread, if one
55.1456 + * exists, is waiting in exclusive mode. If this method returns
55.1457 + * {@code true}, and the current thread is attempting to acquire in
55.1458 + * shared mode (that is, this method is invoked from {@link
55.1459 + * #tryAcquireShared}) then it is guaranteed that the current thread
55.1460 + * is not the first queued thread. Used only as a heuristic in
55.1461 + * ReentrantReadWriteLock.
55.1462 + */
55.1463 + final boolean apparentlyFirstQueuedIsExclusive() {
55.1464 + Node h, s;
55.1465 + return (h = head) != null &&
55.1466 + (s = h.next) != null &&
55.1467 + !s.isShared() &&
55.1468 + s.thread != null;
55.1469 + }
55.1470 +
55.1471 + /**
55.1472 + * Queries whether any threads have been waiting to acquire longer
55.1473 + * than the current thread.
55.1474 + *
55.1475 + * <p>An invocation of this method is equivalent to (but may be
55.1476 + * more efficient than):
55.1477 + * <pre> {@code
55.1478 + * getFirstQueuedThread() != Thread.currentThread() &&
55.1479 + * hasQueuedThreads()}</pre>
55.1480 + *
55.1481 + * <p>Note that because cancellations due to interrupts and
55.1482 + * timeouts may occur at any time, a {@code true} return does not
55.1483 + * guarantee that some other thread will acquire before the current
55.1484 + * thread. Likewise, it is possible for another thread to win a
55.1485 + * race to enqueue after this method has returned {@code false},
55.1486 + * due to the queue being empty.
55.1487 + *
55.1488 + * <p>This method is designed to be used by a fair synchronizer to
55.1489 + * avoid <a href="AbstractQueuedSynchronizer#barging">barging</a>.
55.1490 + * Such a synchronizer's {@link #tryAcquire} method should return
55.1491 + * {@code false}, and its {@link #tryAcquireShared} method should
55.1492 + * return a negative value, if this method returns {@code true}
55.1493 + * (unless this is a reentrant acquire). For example, the {@code
55.1494 + * tryAcquire} method for a fair, reentrant, exclusive mode
55.1495 + * synchronizer might look like this:
55.1496 + *
55.1497 + * <pre> {@code
55.1498 + * protected boolean tryAcquire(int arg) {
55.1499 + * if (isHeldExclusively()) {
55.1500 + * // A reentrant acquire; increment hold count
55.1501 + * return true;
55.1502 + * } else if (hasQueuedPredecessors()) {
55.1503 + * return false;
55.1504 + * } else {
55.1505 + * // try to acquire normally
55.1506 + * }
55.1507 + * }}</pre>
55.1508 + *
55.1509 + * @return {@code true} if there is a queued thread preceding the
55.1510 + * current thread, and {@code false} if the current thread
55.1511 + * is at the head of the queue or the queue is empty
55.1512 + * @since 1.7
55.1513 + */
55.1514 + public final boolean hasQueuedPredecessors() {
55.1515 + // The correctness of this depends on head being initialized
55.1516 + // before tail and on head.next being accurate if the current
55.1517 + // thread is first in queue.
55.1518 + Node t = tail; // Read fields in reverse initialization order
55.1519 + Node h = head;
55.1520 + Node s;
55.1521 + return h != t &&
55.1522 + ((s = h.next) == null || s.thread != Thread.currentThread());
55.1523 + }
55.1524 +
55.1525 +
55.1526 + // Instrumentation and monitoring methods
55.1527 +
55.1528 + /**
55.1529 + * Returns an estimate of the number of threads waiting to
55.1530 + * acquire. The value is only an estimate because the number of
55.1531 + * threads may change dynamically while this method traverses
55.1532 + * internal data structures. This method is designed for use in
55.1533 + * monitoring system state, not for synchronization
55.1534 + * control.
55.1535 + *
55.1536 + * @return the estimated number of threads waiting to acquire
55.1537 + */
55.1538 + public final int getQueueLength() {
55.1539 + int n = 0;
55.1540 + for (Node p = tail; p != null; p = p.prev) {
55.1541 + if (p.thread != null)
55.1542 + ++n;
55.1543 + }
55.1544 + return n;
55.1545 + }
55.1546 +
55.1547 + /**
55.1548 + * Returns a collection containing threads that may be waiting to
55.1549 + * acquire. Because the actual set of threads may change
55.1550 + * dynamically while constructing this result, the returned
55.1551 + * collection is only a best-effort estimate. The elements of the
55.1552 + * returned collection are in no particular order. This method is
55.1553 + * designed to facilitate construction of subclasses that provide
55.1554 + * more extensive monitoring facilities.
55.1555 + *
55.1556 + * @return the collection of threads
55.1557 + */
55.1558 + public final Collection<Thread> getQueuedThreads() {
55.1559 + ArrayList<Thread> list = new ArrayList<Thread>();
55.1560 + for (Node p = tail; p != null; p = p.prev) {
55.1561 + Thread t = p.thread;
55.1562 + if (t != null)
55.1563 + list.add(t);
55.1564 + }
55.1565 + return list;
55.1566 + }
55.1567 +
55.1568 + /**
55.1569 + * Returns a collection containing threads that may be waiting to
55.1570 + * acquire in exclusive mode. This has the same properties
55.1571 + * as {@link #getQueuedThreads} except that it only returns
55.1572 + * those threads waiting due to an exclusive acquire.
55.1573 + *
55.1574 + * @return the collection of threads
55.1575 + */
55.1576 + public final Collection<Thread> getExclusiveQueuedThreads() {
55.1577 + ArrayList<Thread> list = new ArrayList<Thread>();
55.1578 + for (Node p = tail; p != null; p = p.prev) {
55.1579 + if (!p.isShared()) {
55.1580 + Thread t = p.thread;
55.1581 + if (t != null)
55.1582 + list.add(t);
55.1583 + }
55.1584 + }
55.1585 + return list;
55.1586 + }
55.1587 +
55.1588 + /**
55.1589 + * Returns a collection containing threads that may be waiting to
55.1590 + * acquire in shared mode. This has the same properties
55.1591 + * as {@link #getQueuedThreads} except that it only returns
55.1592 + * those threads waiting due to a shared acquire.
55.1593 + *
55.1594 + * @return the collection of threads
55.1595 + */
55.1596 + public final Collection<Thread> getSharedQueuedThreads() {
55.1597 + ArrayList<Thread> list = new ArrayList<Thread>();
55.1598 + for (Node p = tail; p != null; p = p.prev) {
55.1599 + if (p.isShared()) {
55.1600 + Thread t = p.thread;
55.1601 + if (t != null)
55.1602 + list.add(t);
55.1603 + }
55.1604 + }
55.1605 + return list;
55.1606 + }
55.1607 +
55.1608 + /**
55.1609 + * Returns a string identifying this synchronizer, as well as its state.
55.1610 + * The state, in brackets, includes the String {@code "State ="}
55.1611 + * followed by the current value of {@link #getState}, and either
55.1612 + * {@code "nonempty"} or {@code "empty"} depending on whether the
55.1613 + * queue is empty.
55.1614 + *
55.1615 + * @return a string identifying this synchronizer, as well as its state
55.1616 + */
55.1617 + public String toString() {
55.1618 + int s = getState();
55.1619 + String q = hasQueuedThreads() ? "non" : "";
55.1620 + return super.toString() +
55.1621 + "[State = " + s + ", " + q + "empty queue]";
55.1622 + }
55.1623 +
55.1624 +
55.1625 + // Internal support methods for Conditions
55.1626 +
55.1627 + /**
55.1628 + * Returns true if a node, always one that was initially placed on
55.1629 + * a condition queue, is now waiting to reacquire on sync queue.
55.1630 + * @param node the node
55.1631 + * @return true if is reacquiring
55.1632 + */
55.1633 + final boolean isOnSyncQueue(Node node) {
55.1634 + if (node.waitStatus == Node.CONDITION || node.prev == null)
55.1635 + return false;
55.1636 + if (node.next != null) // If has successor, it must be on queue
55.1637 + return true;
55.1638 + /*
55.1639 + * node.prev can be non-null, but not yet on queue because
55.1640 + * the CAS to place it on queue can fail. So we have to
55.1641 + * traverse from tail to make sure it actually made it. It
55.1642 + * will always be near the tail in calls to this method, and
55.1643 + * unless the CAS failed (which is unlikely), it will be
55.1644 + * there, so we hardly ever traverse much.
55.1645 + */
55.1646 + return findNodeFromTail(node);
55.1647 + }
55.1648 +
55.1649 + /**
55.1650 + * Returns true if node is on sync queue by searching backwards from tail.
55.1651 + * Called only when needed by isOnSyncQueue.
55.1652 + * @return true if present
55.1653 + */
55.1654 + private boolean findNodeFromTail(Node node) {
55.1655 + Node t = tail;
55.1656 + for (;;) {
55.1657 + if (t == node)
55.1658 + return true;
55.1659 + if (t == null)
55.1660 + return false;
55.1661 + t = t.prev;
55.1662 + }
55.1663 + }
55.1664 +
55.1665 + /**
55.1666 + * Transfers a node from a condition queue onto sync queue.
55.1667 + * Returns true if successful.
55.1668 + * @param node the node
55.1669 + * @return true if successfully transferred (else the node was
55.1670 + * cancelled before signal).
55.1671 + */
55.1672 + final boolean transferForSignal(Node node) {
55.1673 + /*
55.1674 + * If cannot change waitStatus, the node has been cancelled.
55.1675 + */
55.1676 + if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))
55.1677 + return false;
55.1678 +
55.1679 + /*
55.1680 + * Splice onto queue and try to set waitStatus of predecessor to
55.1681 + * indicate that thread is (probably) waiting. If cancelled or
55.1682 + * attempt to set waitStatus fails, wake up to resync (in which
55.1683 + * case the waitStatus can be transiently and harmlessly wrong).
55.1684 + */
55.1685 + Node p = enq(node);
55.1686 + int ws = p.waitStatus;
55.1687 + if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))
55.1688 + LockSupport.unpark(node.thread);
55.1689 + return true;
55.1690 + }
55.1691 +
55.1692 + /**
55.1693 + * Transfers node, if necessary, to sync queue after a cancelled
55.1694 + * wait. Returns true if thread was cancelled before being
55.1695 + * signalled.
55.1696 + * @param current the waiting thread
55.1697 + * @param node its node
55.1698 + * @return true if cancelled before the node was signalled
55.1699 + */
55.1700 + final boolean transferAfterCancelledWait(Node node) {
55.1701 + if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) {
55.1702 + enq(node);
55.1703 + return true;
55.1704 + }
55.1705 + /*
55.1706 + * If we lost out to a signal(), then we can't proceed
55.1707 + * until it finishes its enq(). Cancelling during an
55.1708 + * incomplete transfer is both rare and transient, so just
55.1709 + * spin.
55.1710 + */
55.1711 + while (!isOnSyncQueue(node))
55.1712 + Thread.yield();
55.1713 + return false;
55.1714 + }
55.1715 +
55.1716 + /**
55.1717 + * Invokes release with current state value; returns saved state.
55.1718 + * Cancels node and throws exception on failure.
55.1719 + * @param node the condition node for this wait
55.1720 + * @return previous sync state
55.1721 + */
55.1722 + final int fullyRelease(Node node) {
55.1723 + boolean failed = true;
55.1724 + try {
55.1725 + int savedState = getState();
55.1726 + if (release(savedState)) {
55.1727 + failed = false;
55.1728 + return savedState;
55.1729 + } else {
55.1730 + throw new IllegalMonitorStateException();
55.1731 + }
55.1732 + } finally {
55.1733 + if (failed)
55.1734 + node.waitStatus = Node.CANCELLED;
55.1735 + }
55.1736 + }
55.1737 +
55.1738 + // Instrumentation methods for conditions
55.1739 +
55.1740 + /**
55.1741 + * Queries whether the given ConditionObject
55.1742 + * uses this synchronizer as its lock.
55.1743 + *
55.1744 + * @param condition the condition
55.1745 + * @return <tt>true</tt> if owned
55.1746 + * @throws NullPointerException if the condition is null
55.1747 + */
55.1748 + public final boolean owns(ConditionObject condition) {
55.1749 + if (condition == null)
55.1750 + throw new NullPointerException();
55.1751 + return condition.isOwnedBy(this);
55.1752 + }
55.1753 +
55.1754 + /**
55.1755 + * Queries whether any threads are waiting on the given condition
55.1756 + * associated with this synchronizer. Note that because timeouts
55.1757 + * and interrupts may occur at any time, a <tt>true</tt> return
55.1758 + * does not guarantee that a future <tt>signal</tt> will awaken
55.1759 + * any threads. This method is designed primarily for use in
55.1760 + * monitoring of the system state.
55.1761 + *
55.1762 + * @param condition the condition
55.1763 + * @return <tt>true</tt> if there are any waiting threads
55.1764 + * @throws IllegalMonitorStateException if exclusive synchronization
55.1765 + * is not held
55.1766 + * @throws IllegalArgumentException if the given condition is
55.1767 + * not associated with this synchronizer
55.1768 + * @throws NullPointerException if the condition is null
55.1769 + */
55.1770 + public final boolean hasWaiters(ConditionObject condition) {
55.1771 + if (!owns(condition))
55.1772 + throw new IllegalArgumentException("Not owner");
55.1773 + return condition.hasWaiters();
55.1774 + }
55.1775 +
55.1776 + /**
55.1777 + * Returns an estimate of the number of threads waiting on the
55.1778 + * given condition associated with this synchronizer. Note that
55.1779 + * because timeouts and interrupts may occur at any time, the
55.1780 + * estimate serves only as an upper bound on the actual number of
55.1781 + * waiters. This method is designed for use in monitoring of the
55.1782 + * system state, not for synchronization control.
55.1783 + *
55.1784 + * @param condition the condition
55.1785 + * @return the estimated number of waiting threads
55.1786 + * @throws IllegalMonitorStateException if exclusive synchronization
55.1787 + * is not held
55.1788 + * @throws IllegalArgumentException if the given condition is
55.1789 + * not associated with this synchronizer
55.1790 + * @throws NullPointerException if the condition is null
55.1791 + */
55.1792 + public final int getWaitQueueLength(ConditionObject condition) {
55.1793 + if (!owns(condition))
55.1794 + throw new IllegalArgumentException("Not owner");
55.1795 + return condition.getWaitQueueLength();
55.1796 + }
55.1797 +
55.1798 + /**
55.1799 + * Returns a collection containing those threads that may be
55.1800 + * waiting on the given condition associated with this
55.1801 + * synchronizer. Because the actual set of threads may change
55.1802 + * dynamically while constructing this result, the returned
55.1803 + * collection is only a best-effort estimate. The elements of the
55.1804 + * returned collection are in no particular order.
55.1805 + *
55.1806 + * @param condition the condition
55.1807 + * @return the collection of threads
55.1808 + * @throws IllegalMonitorStateException if exclusive synchronization
55.1809 + * is not held
55.1810 + * @throws IllegalArgumentException if the given condition is
55.1811 + * not associated with this synchronizer
55.1812 + * @throws NullPointerException if the condition is null
55.1813 + */
55.1814 + public final Collection<Thread> getWaitingThreads(ConditionObject condition) {
55.1815 + if (!owns(condition))
55.1816 + throw new IllegalArgumentException("Not owner");
55.1817 + return condition.getWaitingThreads();
55.1818 + }
55.1819 +
55.1820 + /**
55.1821 + * Condition implementation for a {@link
55.1822 + * AbstractQueuedSynchronizer} serving as the basis of a {@link
55.1823 + * Lock} implementation.
55.1824 + *
55.1825 + * <p>Method documentation for this class describes mechanics,
55.1826 + * not behavioral specifications from the point of view of Lock
55.1827 + * and Condition users. Exported versions of this class will in
55.1828 + * general need to be accompanied by documentation describing
55.1829 + * condition semantics that rely on those of the associated
55.1830 + * <tt>AbstractQueuedSynchronizer</tt>.
55.1831 + *
55.1832 + * <p>This class is Serializable, but all fields are transient,
55.1833 + * so deserialized conditions have no waiters.
55.1834 + */
55.1835 + public class ConditionObject implements Condition, java.io.Serializable {
55.1836 + private static final long serialVersionUID = 1173984872572414699L;
55.1837 + /** First node of condition queue. */
55.1838 + private transient Node firstWaiter;
55.1839 + /** Last node of condition queue. */
55.1840 + private transient Node lastWaiter;
55.1841 +
55.1842 + /**
55.1843 + * Creates a new <tt>ConditionObject</tt> instance.
55.1844 + */
55.1845 + public ConditionObject() { }
55.1846 +
55.1847 + // Internal methods
55.1848 +
55.1849 + /**
55.1850 + * Adds a new waiter to wait queue.
55.1851 + * @return its new wait node
55.1852 + */
55.1853 + private Node addConditionWaiter() {
55.1854 + Node t = lastWaiter;
55.1855 + // If lastWaiter is cancelled, clean out.
55.1856 + if (t != null && t.waitStatus != Node.CONDITION) {
55.1857 + unlinkCancelledWaiters();
55.1858 + t = lastWaiter;
55.1859 + }
55.1860 + Node node = new Node(Thread.currentThread(), Node.CONDITION);
55.1861 + if (t == null)
55.1862 + firstWaiter = node;
55.1863 + else
55.1864 + t.nextWaiter = node;
55.1865 + lastWaiter = node;
55.1866 + return node;
55.1867 + }
55.1868 +
55.1869 + /**
55.1870 + * Removes and transfers nodes until hit non-cancelled one or
55.1871 + * null. Split out from signal in part to encourage compilers
55.1872 + * to inline the case of no waiters.
55.1873 + * @param first (non-null) the first node on condition queue
55.1874 + */
55.1875 + private void doSignal(Node first) {
55.1876 + do {
55.1877 + if ( (firstWaiter = first.nextWaiter) == null)
55.1878 + lastWaiter = null;
55.1879 + first.nextWaiter = null;
55.1880 + } while (!transferForSignal(first) &&
55.1881 + (first = firstWaiter) != null);
55.1882 + }
55.1883 +
55.1884 + /**
55.1885 + * Removes and transfers all nodes.
55.1886 + * @param first (non-null) the first node on condition queue
55.1887 + */
55.1888 + private void doSignalAll(Node first) {
55.1889 + lastWaiter = firstWaiter = null;
55.1890 + do {
55.1891 + Node next = first.nextWaiter;
55.1892 + first.nextWaiter = null;
55.1893 + transferForSignal(first);
55.1894 + first = next;
55.1895 + } while (first != null);
55.1896 + }
55.1897 +
55.1898 + /**
55.1899 + * Unlinks cancelled waiter nodes from condition queue.
55.1900 + * Called only while holding lock. This is called when
55.1901 + * cancellation occurred during condition wait, and upon
55.1902 + * insertion of a new waiter when lastWaiter is seen to have
55.1903 + * been cancelled. This method is needed to avoid garbage
55.1904 + * retention in the absence of signals. So even though it may
55.1905 + * require a full traversal, it comes into play only when
55.1906 + * timeouts or cancellations occur in the absence of
55.1907 + * signals. It traverses all nodes rather than stopping at a
55.1908 + * particular target to unlink all pointers to garbage nodes
55.1909 + * without requiring many re-traversals during cancellation
55.1910 + * storms.
55.1911 + */
55.1912 + private void unlinkCancelledWaiters() {
55.1913 + Node t = firstWaiter;
55.1914 + Node trail = null;
55.1915 + while (t != null) {
55.1916 + Node next = t.nextWaiter;
55.1917 + if (t.waitStatus != Node.CONDITION) {
55.1918 + t.nextWaiter = null;
55.1919 + if (trail == null)
55.1920 + firstWaiter = next;
55.1921 + else
55.1922 + trail.nextWaiter = next;
55.1923 + if (next == null)
55.1924 + lastWaiter = trail;
55.1925 + }
55.1926 + else
55.1927 + trail = t;
55.1928 + t = next;
55.1929 + }
55.1930 + }
55.1931 +
55.1932 + // public methods
55.1933 +
55.1934 + /**
55.1935 + * Moves the longest-waiting thread, if one exists, from the
55.1936 + * wait queue for this condition to the wait queue for the
55.1937 + * owning lock.
55.1938 + *
55.1939 + * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
55.1940 + * returns {@code false}
55.1941 + */
55.1942 + public final void signal() {
55.1943 + if (!isHeldExclusively())
55.1944 + throw new IllegalMonitorStateException();
55.1945 + Node first = firstWaiter;
55.1946 + if (first != null)
55.1947 + doSignal(first);
55.1948 + }
55.1949 +
55.1950 + /**
55.1951 + * Moves all threads from the wait queue for this condition to
55.1952 + * the wait queue for the owning lock.
55.1953 + *
55.1954 + * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
55.1955 + * returns {@code false}
55.1956 + */
55.1957 + public final void signalAll() {
55.1958 + if (!isHeldExclusively())
55.1959 + throw new IllegalMonitorStateException();
55.1960 + Node first = firstWaiter;
55.1961 + if (first != null)
55.1962 + doSignalAll(first);
55.1963 + }
55.1964 +
55.1965 + /**
55.1966 + * Implements uninterruptible condition wait.
55.1967 + * <ol>
55.1968 + * <li> Save lock state returned by {@link #getState}.
55.1969 + * <li> Invoke {@link #release} with
55.1970 + * saved state as argument, throwing
55.1971 + * IllegalMonitorStateException if it fails.
55.1972 + * <li> Block until signalled.
55.1973 + * <li> Reacquire by invoking specialized version of
55.1974 + * {@link #acquire} with saved state as argument.
55.1975 + * </ol>
55.1976 + */
55.1977 + public final void awaitUninterruptibly() {
55.1978 + Node node = addConditionWaiter();
55.1979 + int savedState = fullyRelease(node);
55.1980 + boolean interrupted = false;
55.1981 + while (!isOnSyncQueue(node)) {
55.1982 + LockSupport.park(this);
55.1983 + if (Thread.interrupted())
55.1984 + interrupted = true;
55.1985 + }
55.1986 + if (acquireQueued(node, savedState) || interrupted)
55.1987 + selfInterrupt();
55.1988 + }
55.1989 +
55.1990 + /*
55.1991 + * For interruptible waits, we need to track whether to throw
55.1992 + * InterruptedException, if interrupted while blocked on
55.1993 + * condition, versus reinterrupt current thread, if
55.1994 + * interrupted while blocked waiting to re-acquire.
55.1995 + */
55.1996 +
55.1997 + /** Mode meaning to reinterrupt on exit from wait */
55.1998 + private static final int REINTERRUPT = 1;
55.1999 + /** Mode meaning to throw InterruptedException on exit from wait */
55.2000 + private static final int THROW_IE = -1;
55.2001 +
55.2002 + /**
55.2003 + * Checks for interrupt, returning THROW_IE if interrupted
55.2004 + * before signalled, REINTERRUPT if after signalled, or
55.2005 + * 0 if not interrupted.
55.2006 + */
55.2007 + private int checkInterruptWhileWaiting(Node node) {
55.2008 + return Thread.interrupted() ?
55.2009 + (transferAfterCancelledWait(node) ? THROW_IE : REINTERRUPT) :
55.2010 + 0;
55.2011 + }
55.2012 +
55.2013 + /**
55.2014 + * Throws InterruptedException, reinterrupts current thread, or
55.2015 + * does nothing, depending on mode.
55.2016 + */
55.2017 + private void reportInterruptAfterWait(int interruptMode)
55.2018 + throws InterruptedException {
55.2019 + if (interruptMode == THROW_IE)
55.2020 + throw new InterruptedException();
55.2021 + else if (interruptMode == REINTERRUPT)
55.2022 + selfInterrupt();
55.2023 + }
55.2024 +
55.2025 + /**
55.2026 + * Implements interruptible condition wait.
55.2027 + * <ol>
55.2028 + * <li> If current thread is interrupted, throw InterruptedException.
55.2029 + * <li> Save lock state returned by {@link #getState}.
55.2030 + * <li> Invoke {@link #release} with
55.2031 + * saved state as argument, throwing
55.2032 + * IllegalMonitorStateException if it fails.
55.2033 + * <li> Block until signalled or interrupted.
55.2034 + * <li> Reacquire by invoking specialized version of
55.2035 + * {@link #acquire} with saved state as argument.
55.2036 + * <li> If interrupted while blocked in step 4, throw InterruptedException.
55.2037 + * </ol>
55.2038 + */
55.2039 + public final void await() throws InterruptedException {
55.2040 + if (Thread.interrupted())
55.2041 + throw new InterruptedException();
55.2042 + Node node = addConditionWaiter();
55.2043 + int savedState = fullyRelease(node);
55.2044 + int interruptMode = 0;
55.2045 + while (!isOnSyncQueue(node)) {
55.2046 + LockSupport.park(this);
55.2047 + if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
55.2048 + break;
55.2049 + }
55.2050 + if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
55.2051 + interruptMode = REINTERRUPT;
55.2052 + if (node.nextWaiter != null) // clean up if cancelled
55.2053 + unlinkCancelledWaiters();
55.2054 + if (interruptMode != 0)
55.2055 + reportInterruptAfterWait(interruptMode);
55.2056 + }
55.2057 +
55.2058 + /**
55.2059 + * Implements timed condition wait.
55.2060 + * <ol>
55.2061 + * <li> If current thread is interrupted, throw InterruptedException.
55.2062 + * <li> Save lock state returned by {@link #getState}.
55.2063 + * <li> Invoke {@link #release} with
55.2064 + * saved state as argument, throwing
55.2065 + * IllegalMonitorStateException if it fails.
55.2066 + * <li> Block until signalled, interrupted, or timed out.
55.2067 + * <li> Reacquire by invoking specialized version of
55.2068 + * {@link #acquire} with saved state as argument.
55.2069 + * <li> If interrupted while blocked in step 4, throw InterruptedException.
55.2070 + * </ol>
55.2071 + */
55.2072 + public final long awaitNanos(long nanosTimeout)
55.2073 + throws InterruptedException {
55.2074 + if (Thread.interrupted())
55.2075 + throw new InterruptedException();
55.2076 + Node node = addConditionWaiter();
55.2077 + int savedState = fullyRelease(node);
55.2078 + long lastTime = System.nanoTime();
55.2079 + int interruptMode = 0;
55.2080 + while (!isOnSyncQueue(node)) {
55.2081 + if (nanosTimeout <= 0L) {
55.2082 + transferAfterCancelledWait(node);
55.2083 + break;
55.2084 + }
55.2085 + LockSupport.parkNanos(this, nanosTimeout);
55.2086 + if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
55.2087 + break;
55.2088 +
55.2089 + long now = System.nanoTime();
55.2090 + nanosTimeout -= now - lastTime;
55.2091 + lastTime = now;
55.2092 + }
55.2093 + if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
55.2094 + interruptMode = REINTERRUPT;
55.2095 + if (node.nextWaiter != null)
55.2096 + unlinkCancelledWaiters();
55.2097 + if (interruptMode != 0)
55.2098 + reportInterruptAfterWait(interruptMode);
55.2099 + return nanosTimeout - (System.nanoTime() - lastTime);
55.2100 + }
55.2101 +
55.2102 + /**
55.2103 + * Implements absolute timed condition wait.
55.2104 + * <ol>
55.2105 + * <li> If current thread is interrupted, throw InterruptedException.
55.2106 + * <li> Save lock state returned by {@link #getState}.
55.2107 + * <li> Invoke {@link #release} with
55.2108 + * saved state as argument, throwing
55.2109 + * IllegalMonitorStateException if it fails.
55.2110 + * <li> Block until signalled, interrupted, or timed out.
55.2111 + * <li> Reacquire by invoking specialized version of
55.2112 + * {@link #acquire} with saved state as argument.
55.2113 + * <li> If interrupted while blocked in step 4, throw InterruptedException.
55.2114 + * <li> If timed out while blocked in step 4, return false, else true.
55.2115 + * </ol>
55.2116 + */
55.2117 + public final boolean awaitUntil(Date deadline)
55.2118 + throws InterruptedException {
55.2119 + if (deadline == null)
55.2120 + throw new NullPointerException();
55.2121 + long abstime = deadline.getTime();
55.2122 + if (Thread.interrupted())
55.2123 + throw new InterruptedException();
55.2124 + Node node = addConditionWaiter();
55.2125 + int savedState = fullyRelease(node);
55.2126 + boolean timedout = false;
55.2127 + int interruptMode = 0;
55.2128 + while (!isOnSyncQueue(node)) {
55.2129 + if (System.currentTimeMillis() > abstime) {
55.2130 + timedout = transferAfterCancelledWait(node);
55.2131 + break;
55.2132 + }
55.2133 + LockSupport.parkUntil(this, abstime);
55.2134 + if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
55.2135 + break;
55.2136 + }
55.2137 + if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
55.2138 + interruptMode = REINTERRUPT;
55.2139 + if (node.nextWaiter != null)
55.2140 + unlinkCancelledWaiters();
55.2141 + if (interruptMode != 0)
55.2142 + reportInterruptAfterWait(interruptMode);
55.2143 + return !timedout;
55.2144 + }
55.2145 +
55.2146 + /**
55.2147 + * Implements timed condition wait.
55.2148 + * <ol>
55.2149 + * <li> If current thread is interrupted, throw InterruptedException.
55.2150 + * <li> Save lock state returned by {@link #getState}.
55.2151 + * <li> Invoke {@link #release} with
55.2152 + * saved state as argument, throwing
55.2153 + * IllegalMonitorStateException if it fails.
55.2154 + * <li> Block until signalled, interrupted, or timed out.
55.2155 + * <li> Reacquire by invoking specialized version of
55.2156 + * {@link #acquire} with saved state as argument.
55.2157 + * <li> If interrupted while blocked in step 4, throw InterruptedException.
55.2158 + * <li> If timed out while blocked in step 4, return false, else true.
55.2159 + * </ol>
55.2160 + */
55.2161 + public final boolean await(long time, TimeUnit unit)
55.2162 + throws InterruptedException {
55.2163 + if (unit == null)
55.2164 + throw new NullPointerException();
55.2165 + long nanosTimeout = unit.toNanos(time);
55.2166 + if (Thread.interrupted())
55.2167 + throw new InterruptedException();
55.2168 + Node node = addConditionWaiter();
55.2169 + int savedState = fullyRelease(node);
55.2170 + long lastTime = System.nanoTime();
55.2171 + boolean timedout = false;
55.2172 + int interruptMode = 0;
55.2173 + while (!isOnSyncQueue(node)) {
55.2174 + if (nanosTimeout <= 0L) {
55.2175 + timedout = transferAfterCancelledWait(node);
55.2176 + break;
55.2177 + }
55.2178 + if (nanosTimeout >= spinForTimeoutThreshold)
55.2179 + LockSupport.parkNanos(this, nanosTimeout);
55.2180 + if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
55.2181 + break;
55.2182 + long now = System.nanoTime();
55.2183 + nanosTimeout -= now - lastTime;
55.2184 + lastTime = now;
55.2185 + }
55.2186 + if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
55.2187 + interruptMode = REINTERRUPT;
55.2188 + if (node.nextWaiter != null)
55.2189 + unlinkCancelledWaiters();
55.2190 + if (interruptMode != 0)
55.2191 + reportInterruptAfterWait(interruptMode);
55.2192 + return !timedout;
55.2193 + }
55.2194 +
55.2195 + // support for instrumentation
55.2196 +
55.2197 + /**
55.2198 + * Returns true if this condition was created by the given
55.2199 + * synchronization object.
55.2200 + *
55.2201 + * @return {@code true} if owned
55.2202 + */
55.2203 + final boolean isOwnedBy(AbstractQueuedSynchronizer sync) {
55.2204 + return sync == AbstractQueuedSynchronizer.this;
55.2205 + }
55.2206 +
55.2207 + /**
55.2208 + * Queries whether any threads are waiting on this condition.
55.2209 + * Implements {@link AbstractQueuedSynchronizer#hasWaiters}.
55.2210 + *
55.2211 + * @return {@code true} if there are any waiting threads
55.2212 + * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
55.2213 + * returns {@code false}
55.2214 + */
55.2215 + protected final boolean hasWaiters() {
55.2216 + if (!isHeldExclusively())
55.2217 + throw new IllegalMonitorStateException();
55.2218 + for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
55.2219 + if (w.waitStatus == Node.CONDITION)
55.2220 + return true;
55.2221 + }
55.2222 + return false;
55.2223 + }
55.2224 +
55.2225 + /**
55.2226 + * Returns an estimate of the number of threads waiting on
55.2227 + * this condition.
55.2228 + * Implements {@link AbstractQueuedSynchronizer#getWaitQueueLength}.
55.2229 + *
55.2230 + * @return the estimated number of waiting threads
55.2231 + * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
55.2232 + * returns {@code false}
55.2233 + */
55.2234 + protected final int getWaitQueueLength() {
55.2235 + if (!isHeldExclusively())
55.2236 + throw new IllegalMonitorStateException();
55.2237 + int n = 0;
55.2238 + for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
55.2239 + if (w.waitStatus == Node.CONDITION)
55.2240 + ++n;
55.2241 + }
55.2242 + return n;
55.2243 + }
55.2244 +
55.2245 + /**
55.2246 + * Returns a collection containing those threads that may be
55.2247 + * waiting on this Condition.
55.2248 + * Implements {@link AbstractQueuedSynchronizer#getWaitingThreads}.
55.2249 + *
55.2250 + * @return the collection of threads
55.2251 + * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
55.2252 + * returns {@code false}
55.2253 + */
55.2254 + protected final Collection<Thread> getWaitingThreads() {
55.2255 + if (!isHeldExclusively())
55.2256 + throw new IllegalMonitorStateException();
55.2257 + ArrayList<Thread> list = new ArrayList<Thread>();
55.2258 + for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
55.2259 + if (w.waitStatus == Node.CONDITION) {
55.2260 + Thread t = w.thread;
55.2261 + if (t != null)
55.2262 + list.add(t);
55.2263 + }
55.2264 + }
55.2265 + return list;
55.2266 + }
55.2267 + }
55.2268 +
55.2269 + /**
55.2270 + * Setup to support compareAndSet. We need to natively implement
55.2271 + * this here: For the sake of permitting future enhancements, we
55.2272 + * cannot explicitly subclass AtomicInteger, which would be
55.2273 + * efficient and useful otherwise. So, as the lesser of evils, we
55.2274 + * natively implement using hotspot intrinsics API. And while we
55.2275 + * are at it, we do the same for other CASable fields (which could
55.2276 + * otherwise be done with atomic field updaters).
55.2277 + */
55.2278 + private static final Unsafe unsafe = Unsafe.getUnsafe();
55.2279 + private static final long stateOffset;
55.2280 + private static final long headOffset;
55.2281 + private static final long tailOffset;
55.2282 + private static final long waitStatusOffset;
55.2283 + private static final long nextOffset;
55.2284 +
55.2285 + static {
55.2286 + try {
55.2287 + stateOffset = unsafe.objectFieldOffset
55.2288 + (AbstractQueuedSynchronizer.class.getDeclaredField("state"));
55.2289 + headOffset = unsafe.objectFieldOffset
55.2290 + (AbstractQueuedSynchronizer.class.getDeclaredField("head"));
55.2291 + tailOffset = unsafe.objectFieldOffset
55.2292 + (AbstractQueuedSynchronizer.class.getDeclaredField("tail"));
55.2293 + waitStatusOffset = unsafe.objectFieldOffset
55.2294 + (Node.class.getDeclaredField("waitStatus"));
55.2295 + nextOffset = unsafe.objectFieldOffset
55.2296 + (Node.class.getDeclaredField("next"));
55.2297 +
55.2298 + } catch (Exception ex) { throw new Error(ex); }
55.2299 + }
55.2300 +
55.2301 + /**
55.2302 + * CAS head field. Used only by enq.
55.2303 + */
55.2304 + private final boolean compareAndSetHead(Node update) {
55.2305 + return unsafe.compareAndSwapObject(this, headOffset, null, update);
55.2306 + }
55.2307 +
55.2308 + /**
55.2309 + * CAS tail field. Used only by enq.
55.2310 + */
55.2311 + private final boolean compareAndSetTail(Node expect, Node update) {
55.2312 + return unsafe.compareAndSwapObject(this, tailOffset, expect, update);
55.2313 + }
55.2314 +
55.2315 + /**
55.2316 + * CAS waitStatus field of a node.
55.2317 + */
55.2318 + private static final boolean compareAndSetWaitStatus(Node node,
55.2319 + int expect,
55.2320 + int update) {
55.2321 + return unsafe.compareAndSwapInt(node, waitStatusOffset,
55.2322 + expect, update);
55.2323 + }
55.2324 +
55.2325 + /**
55.2326 + * CAS next field of a node.
55.2327 + */
55.2328 + private static final boolean compareAndSetNext(Node node,
55.2329 + Node expect,
55.2330 + Node update) {
55.2331 + return unsafe.compareAndSwapObject(node, nextOffset, expect, update);
55.2332 + }
55.2333 +}
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/Condition.java Sat Mar 19 10:46:31 2016 +0100
56.3 @@ -0,0 +1,488 @@
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 java.util.Date;
56.42 +
56.43 +/**
56.44 + * {@code Condition} factors out the {@code Object} monitor
56.45 + * methods ({@link Object#wait() wait}, {@link Object#notify notify}
56.46 + * and {@link Object#notifyAll notifyAll}) into distinct objects to
56.47 + * give the effect of having multiple wait-sets per object, by
56.48 + * combining them with the use of arbitrary {@link Lock} implementations.
56.49 + * Where a {@code Lock} replaces the use of {@code synchronized} methods
56.50 + * and statements, a {@code Condition} replaces the use of the Object
56.51 + * monitor methods.
56.52 + *
56.53 + * <p>Conditions (also known as <em>condition queues</em> or
56.54 + * <em>condition variables</em>) provide a means for one thread to
56.55 + * suspend execution (to "wait") until notified by another
56.56 + * thread that some state condition may now be true. Because access
56.57 + * to this shared state information occurs in different threads, it
56.58 + * must be protected, so a lock of some form is associated with the
56.59 + * condition. The key property that waiting for a condition provides
56.60 + * is that it <em>atomically</em> releases the associated lock and
56.61 + * suspends the current thread, just like {@code Object.wait}.
56.62 + *
56.63 + * <p>A {@code Condition} instance is intrinsically bound to a lock.
56.64 + * To obtain a {@code Condition} instance for a particular {@link Lock}
56.65 + * instance use its {@link Lock#newCondition newCondition()} method.
56.66 + *
56.67 + * <p>As an example, suppose we have a bounded buffer which supports
56.68 + * {@code put} and {@code take} methods. If a
56.69 + * {@code take} is attempted on an empty buffer, then the thread will block
56.70 + * until an item becomes available; if a {@code put} is attempted on a
56.71 + * full buffer, then the thread will block until a space becomes available.
56.72 + * We would like to keep waiting {@code put} threads and {@code take}
56.73 + * threads in separate wait-sets so that we can use the optimization of
56.74 + * only notifying a single thread at a time when items or spaces become
56.75 + * available in the buffer. This can be achieved using two
56.76 + * {@link Condition} instances.
56.77 + * <pre>
56.78 + * class BoundedBuffer {
56.79 + * <b>final Lock lock = new ReentrantLock();</b>
56.80 + * final Condition notFull = <b>lock.newCondition(); </b>
56.81 + * final Condition notEmpty = <b>lock.newCondition(); </b>
56.82 + *
56.83 + * final Object[] items = new Object[100];
56.84 + * int putptr, takeptr, count;
56.85 + *
56.86 + * public void put(Object x) throws InterruptedException {
56.87 + * <b>lock.lock();
56.88 + * try {</b>
56.89 + * while (count == items.length)
56.90 + * <b>notFull.await();</b>
56.91 + * items[putptr] = x;
56.92 + * if (++putptr == items.length) putptr = 0;
56.93 + * ++count;
56.94 + * <b>notEmpty.signal();</b>
56.95 + * <b>} finally {
56.96 + * lock.unlock();
56.97 + * }</b>
56.98 + * }
56.99 + *
56.100 + * public Object take() throws InterruptedException {
56.101 + * <b>lock.lock();
56.102 + * try {</b>
56.103 + * while (count == 0)
56.104 + * <b>notEmpty.await();</b>
56.105 + * Object x = items[takeptr];
56.106 + * if (++takeptr == items.length) takeptr = 0;
56.107 + * --count;
56.108 + * <b>notFull.signal();</b>
56.109 + * return x;
56.110 + * <b>} finally {
56.111 + * lock.unlock();
56.112 + * }</b>
56.113 + * }
56.114 + * }
56.115 + * </pre>
56.116 + *
56.117 + * (The {@link java.util.concurrent.ArrayBlockingQueue} class provides
56.118 + * this functionality, so there is no reason to implement this
56.119 + * sample usage class.)
56.120 + *
56.121 + * <p>A {@code Condition} implementation can provide behavior and semantics
56.122 + * that is
56.123 + * different from that of the {@code Object} monitor methods, such as
56.124 + * guaranteed ordering for notifications, or not requiring a lock to be held
56.125 + * when performing notifications.
56.126 + * If an implementation provides such specialized semantics then the
56.127 + * implementation must document those semantics.
56.128 + *
56.129 + * <p>Note that {@code Condition} instances are just normal objects and can
56.130 + * themselves be used as the target in a {@code synchronized} statement,
56.131 + * and can have their own monitor {@link Object#wait wait} and
56.132 + * {@link Object#notify notification} methods invoked.
56.133 + * Acquiring the monitor lock of a {@code Condition} instance, or using its
56.134 + * monitor methods, has no specified relationship with acquiring the
56.135 + * {@link Lock} associated with that {@code Condition} or the use of its
56.136 + * {@linkplain #await waiting} and {@linkplain #signal signalling} methods.
56.137 + * It is recommended that to avoid confusion you never use {@code Condition}
56.138 + * instances in this way, except perhaps within their own implementation.
56.139 + *
56.140 + * <p>Except where noted, passing a {@code null} value for any parameter
56.141 + * will result in a {@link NullPointerException} being thrown.
56.142 + *
56.143 + * <h3>Implementation Considerations</h3>
56.144 + *
56.145 + * <p>When waiting upon a {@code Condition}, a "<em>spurious
56.146 + * wakeup</em>" is permitted to occur, in
56.147 + * general, as a concession to the underlying platform semantics.
56.148 + * This has little practical impact on most application programs as a
56.149 + * {@code Condition} should always be waited upon in a loop, testing
56.150 + * the state predicate that is being waited for. An implementation is
56.151 + * free to remove the possibility of spurious wakeups but it is
56.152 + * recommended that applications programmers always assume that they can
56.153 + * occur and so always wait in a loop.
56.154 + *
56.155 + * <p>The three forms of condition waiting
56.156 + * (interruptible, non-interruptible, and timed) may differ in their ease of
56.157 + * implementation on some platforms and in their performance characteristics.
56.158 + * In particular, it may be difficult to provide these features and maintain
56.159 + * specific semantics such as ordering guarantees.
56.160 + * Further, the ability to interrupt the actual suspension of the thread may
56.161 + * not always be feasible to implement on all platforms.
56.162 + *
56.163 + * <p>Consequently, an implementation is not required to define exactly the
56.164 + * same guarantees or semantics for all three forms of waiting, nor is it
56.165 + * required to support interruption of the actual suspension of the thread.
56.166 + *
56.167 + * <p>An implementation is required to
56.168 + * clearly document the semantics and guarantees provided by each of the
56.169 + * waiting methods, and when an implementation does support interruption of
56.170 + * thread suspension then it must obey the interruption semantics as defined
56.171 + * in this interface.
56.172 + *
56.173 + * <p>As interruption generally implies cancellation, and checks for
56.174 + * interruption are often infrequent, an implementation can favor responding
56.175 + * to an interrupt over normal method return. This is true even if it can be
56.176 + * shown that the interrupt occurred after another action that may have
56.177 + * unblocked the thread. An implementation should document this behavior.
56.178 + *
56.179 + * @since 1.5
56.180 + * @author Doug Lea
56.181 + */
56.182 +public interface Condition {
56.183 +
56.184 + /**
56.185 + * Causes the current thread to wait until it is signalled or
56.186 + * {@linkplain Thread#interrupt interrupted}.
56.187 + *
56.188 + * <p>The lock associated with this {@code Condition} is atomically
56.189 + * released and the current thread becomes disabled for thread scheduling
56.190 + * purposes and lies dormant until <em>one</em> of four things happens:
56.191 + * <ul>
56.192 + * <li>Some other thread invokes the {@link #signal} method for this
56.193 + * {@code Condition} and the current thread happens to be chosen as the
56.194 + * thread to be awakened; or
56.195 + * <li>Some other thread invokes the {@link #signalAll} method for this
56.196 + * {@code Condition}; or
56.197 + * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
56.198 + * current thread, and interruption of thread suspension is supported; or
56.199 + * <li>A "<em>spurious wakeup</em>" occurs.
56.200 + * </ul>
56.201 + *
56.202 + * <p>In all cases, before this method can return the current thread must
56.203 + * re-acquire the lock associated with this condition. When the
56.204 + * thread returns it is <em>guaranteed</em> to hold this lock.
56.205 + *
56.206 + * <p>If the current thread:
56.207 + * <ul>
56.208 + * <li>has its interrupted status set on entry to this method; or
56.209 + * <li>is {@linkplain Thread#interrupt interrupted} while waiting
56.210 + * and interruption of thread suspension is supported,
56.211 + * </ul>
56.212 + * then {@link InterruptedException} is thrown and the current thread's
56.213 + * interrupted status is cleared. It is not specified, in the first
56.214 + * case, whether or not the test for interruption occurs before the lock
56.215 + * is released.
56.216 + *
56.217 + * <p><b>Implementation Considerations</b>
56.218 + *
56.219 + * <p>The current thread is assumed to hold the lock associated with this
56.220 + * {@code Condition} when this method is called.
56.221 + * It is up to the implementation to determine if this is
56.222 + * the case and if not, how to respond. Typically, an exception will be
56.223 + * thrown (such as {@link IllegalMonitorStateException}) and the
56.224 + * implementation must document that fact.
56.225 + *
56.226 + * <p>An implementation can favor responding to an interrupt over normal
56.227 + * method return in response to a signal. In that case the implementation
56.228 + * must ensure that the signal is redirected to another waiting thread, if
56.229 + * there is one.
56.230 + *
56.231 + * @throws InterruptedException if the current thread is interrupted
56.232 + * (and interruption of thread suspension is supported)
56.233 + */
56.234 + void await() throws InterruptedException;
56.235 +
56.236 + /**
56.237 + * Causes the current thread to wait until it is signalled.
56.238 + *
56.239 + * <p>The lock associated with this condition is atomically
56.240 + * released and the current thread becomes disabled for thread scheduling
56.241 + * purposes and lies dormant until <em>one</em> of three things happens:
56.242 + * <ul>
56.243 + * <li>Some other thread invokes the {@link #signal} method for this
56.244 + * {@code Condition} and the current thread happens to be chosen as the
56.245 + * thread to be awakened; or
56.246 + * <li>Some other thread invokes the {@link #signalAll} method for this
56.247 + * {@code Condition}; or
56.248 + * <li>A "<em>spurious wakeup</em>" occurs.
56.249 + * </ul>
56.250 + *
56.251 + * <p>In all cases, before this method can return the current thread must
56.252 + * re-acquire the lock associated with this condition. When the
56.253 + * thread returns it is <em>guaranteed</em> to hold this lock.
56.254 + *
56.255 + * <p>If the current thread's interrupted status is set when it enters
56.256 + * this method, or it is {@linkplain Thread#interrupt interrupted}
56.257 + * while waiting, it will continue to wait until signalled. When it finally
56.258 + * returns from this method its interrupted status will still
56.259 + * be set.
56.260 + *
56.261 + * <p><b>Implementation Considerations</b>
56.262 + *
56.263 + * <p>The current thread is assumed to hold the lock associated with this
56.264 + * {@code Condition} when this method is called.
56.265 + * It is up to the implementation to determine if this is
56.266 + * the case and if not, how to respond. Typically, an exception will be
56.267 + * thrown (such as {@link IllegalMonitorStateException}) and the
56.268 + * implementation must document that fact.
56.269 + */
56.270 + void awaitUninterruptibly();
56.271 +
56.272 + /**
56.273 + * Causes the current thread to wait until it is signalled or interrupted,
56.274 + * or the specified waiting time elapses.
56.275 + *
56.276 + * <p>The lock associated with this condition is atomically
56.277 + * released and the current thread becomes disabled for thread scheduling
56.278 + * purposes and lies dormant until <em>one</em> of five things happens:
56.279 + * <ul>
56.280 + * <li>Some other thread invokes the {@link #signal} method for this
56.281 + * {@code Condition} and the current thread happens to be chosen as the
56.282 + * thread to be awakened; or
56.283 + * <li>Some other thread invokes the {@link #signalAll} method for this
56.284 + * {@code Condition}; or
56.285 + * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
56.286 + * current thread, and interruption of thread suspension is supported; or
56.287 + * <li>The specified waiting time elapses; or
56.288 + * <li>A "<em>spurious wakeup</em>" occurs.
56.289 + * </ul>
56.290 + *
56.291 + * <p>In all cases, before this method can return the current thread must
56.292 + * re-acquire the lock associated with this condition. When the
56.293 + * thread returns it is <em>guaranteed</em> to hold this lock.
56.294 + *
56.295 + * <p>If the current thread:
56.296 + * <ul>
56.297 + * <li>has its interrupted status set on entry to this method; or
56.298 + * <li>is {@linkplain Thread#interrupt interrupted} while waiting
56.299 + * and interruption of thread suspension is supported,
56.300 + * </ul>
56.301 + * then {@link InterruptedException} is thrown and the current thread's
56.302 + * interrupted status is cleared. It is not specified, in the first
56.303 + * case, whether or not the test for interruption occurs before the lock
56.304 + * is released.
56.305 + *
56.306 + * <p>The method returns an estimate of the number of nanoseconds
56.307 + * remaining to wait given the supplied {@code nanosTimeout}
56.308 + * value upon return, or a value less than or equal to zero if it
56.309 + * timed out. This value can be used to determine whether and how
56.310 + * long to re-wait in cases where the wait returns but an awaited
56.311 + * condition still does not hold. Typical uses of this method take
56.312 + * the following form:
56.313 + *
56.314 + * <pre> {@code
56.315 + * boolean aMethod(long timeout, TimeUnit unit) {
56.316 + * long nanos = unit.toNanos(timeout);
56.317 + * lock.lock();
56.318 + * try {
56.319 + * while (!conditionBeingWaitedFor()) {
56.320 + * if (nanos <= 0L)
56.321 + * return false;
56.322 + * nanos = theCondition.awaitNanos(nanos);
56.323 + * }
56.324 + * // ...
56.325 + * } finally {
56.326 + * lock.unlock();
56.327 + * }
56.328 + * }}</pre>
56.329 + *
56.330 + * <p> Design note: This method requires a nanosecond argument so
56.331 + * as to avoid truncation errors in reporting remaining times.
56.332 + * Such precision loss would make it difficult for programmers to
56.333 + * ensure that total waiting times are not systematically shorter
56.334 + * than specified when re-waits occur.
56.335 + *
56.336 + * <p><b>Implementation Considerations</b>
56.337 + *
56.338 + * <p>The current thread is assumed to hold the lock associated with this
56.339 + * {@code Condition} when this method is called.
56.340 + * It is up to the implementation to determine if this is
56.341 + * the case and if not, how to respond. Typically, an exception will be
56.342 + * thrown (such as {@link IllegalMonitorStateException}) and the
56.343 + * implementation must document that fact.
56.344 + *
56.345 + * <p>An implementation can favor responding to an interrupt over normal
56.346 + * method return in response to a signal, or over indicating the elapse
56.347 + * of the specified waiting time. In either case the implementation
56.348 + * must ensure that the signal is redirected to another waiting thread, if
56.349 + * there is one.
56.350 + *
56.351 + * @param nanosTimeout the maximum time to wait, in nanoseconds
56.352 + * @return an estimate of the {@code nanosTimeout} value minus
56.353 + * the time spent waiting upon return from this method.
56.354 + * A positive value may be used as the argument to a
56.355 + * subsequent call to this method to finish waiting out
56.356 + * the desired time. A value less than or equal to zero
56.357 + * indicates that no time remains.
56.358 + * @throws InterruptedException if the current thread is interrupted
56.359 + * (and interruption of thread suspension is supported)
56.360 + */
56.361 + long awaitNanos(long nanosTimeout) throws InterruptedException;
56.362 +
56.363 + /**
56.364 + * Causes the current thread to wait until it is signalled or interrupted,
56.365 + * or the specified waiting time elapses. This method is behaviorally
56.366 + * equivalent to:<br>
56.367 + * <pre>
56.368 + * awaitNanos(unit.toNanos(time)) > 0
56.369 + * </pre>
56.370 + * @param time the maximum time to wait
56.371 + * @param unit the time unit of the {@code time} argument
56.372 + * @return {@code false} if the waiting time detectably elapsed
56.373 + * before return from the method, else {@code true}
56.374 + * @throws InterruptedException if the current thread is interrupted
56.375 + * (and interruption of thread suspension is supported)
56.376 + */
56.377 + boolean await(long time, TimeUnit unit) throws InterruptedException;
56.378 +
56.379 + /**
56.380 + * Causes the current thread to wait until it is signalled or interrupted,
56.381 + * or the specified deadline elapses.
56.382 + *
56.383 + * <p>The lock associated with this condition is atomically
56.384 + * released and the current thread becomes disabled for thread scheduling
56.385 + * purposes and lies dormant until <em>one</em> of five things happens:
56.386 + * <ul>
56.387 + * <li>Some other thread invokes the {@link #signal} method for this
56.388 + * {@code Condition} and the current thread happens to be chosen as the
56.389 + * thread to be awakened; or
56.390 + * <li>Some other thread invokes the {@link #signalAll} method for this
56.391 + * {@code Condition}; or
56.392 + * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
56.393 + * current thread, and interruption of thread suspension is supported; or
56.394 + * <li>The specified deadline elapses; or
56.395 + * <li>A "<em>spurious wakeup</em>" occurs.
56.396 + * </ul>
56.397 + *
56.398 + * <p>In all cases, before this method can return the current thread must
56.399 + * re-acquire the lock associated with this condition. When the
56.400 + * thread returns it is <em>guaranteed</em> to hold this lock.
56.401 + *
56.402 + *
56.403 + * <p>If the current thread:
56.404 + * <ul>
56.405 + * <li>has its interrupted status set on entry to this method; or
56.406 + * <li>is {@linkplain Thread#interrupt interrupted} while waiting
56.407 + * and interruption of thread suspension is supported,
56.408 + * </ul>
56.409 + * then {@link InterruptedException} is thrown and the current thread's
56.410 + * interrupted status is cleared. It is not specified, in the first
56.411 + * case, whether or not the test for interruption occurs before the lock
56.412 + * is released.
56.413 + *
56.414 + *
56.415 + * <p>The return value indicates whether the deadline has elapsed,
56.416 + * which can be used as follows:
56.417 + * <pre> {@code
56.418 + * boolean aMethod(Date deadline) {
56.419 + * boolean stillWaiting = true;
56.420 + * lock.lock();
56.421 + * try {
56.422 + * while (!conditionBeingWaitedFor()) {
56.423 + * if (!stillWaiting)
56.424 + * return false;
56.425 + * stillWaiting = theCondition.awaitUntil(deadline);
56.426 + * }
56.427 + * // ...
56.428 + * } finally {
56.429 + * lock.unlock();
56.430 + * }
56.431 + * }}</pre>
56.432 + *
56.433 + * <p><b>Implementation Considerations</b>
56.434 + *
56.435 + * <p>The current thread is assumed to hold the lock associated with this
56.436 + * {@code Condition} when this method is called.
56.437 + * It is up to the implementation to determine if this is
56.438 + * the case and if not, how to respond. Typically, an exception will be
56.439 + * thrown (such as {@link IllegalMonitorStateException}) and the
56.440 + * implementation must document that fact.
56.441 + *
56.442 + * <p>An implementation can favor responding to an interrupt over normal
56.443 + * method return in response to a signal, or over indicating the passing
56.444 + * of the specified deadline. In either case the implementation
56.445 + * must ensure that the signal is redirected to another waiting thread, if
56.446 + * there is one.
56.447 + *
56.448 + * @param deadline the absolute time to wait until
56.449 + * @return {@code false} if the deadline has elapsed upon return, else
56.450 + * {@code true}
56.451 + * @throws InterruptedException if the current thread is interrupted
56.452 + * (and interruption of thread suspension is supported)
56.453 + */
56.454 + boolean awaitUntil(Date deadline) throws InterruptedException;
56.455 +
56.456 + /**
56.457 + * Wakes up one waiting thread.
56.458 + *
56.459 + * <p>If any threads are waiting on this condition then one
56.460 + * is selected for waking up. That thread must then re-acquire the
56.461 + * lock before returning from {@code await}.
56.462 + *
56.463 + * <p><b>Implementation Considerations</b>
56.464 + *
56.465 + * <p>An implementation may (and typically does) require that the
56.466 + * current thread hold the lock associated with this {@code
56.467 + * Condition} when this method is called. Implementations must
56.468 + * document this precondition and any actions taken if the lock is
56.469 + * not held. Typically, an exception such as {@link
56.470 + * IllegalMonitorStateException} will be thrown.
56.471 + */
56.472 + void signal();
56.473 +
56.474 + /**
56.475 + * Wakes up all waiting threads.
56.476 + *
56.477 + * <p>If any threads are waiting on this condition then they are
56.478 + * all woken up. Each thread must re-acquire the lock before it can
56.479 + * return from {@code await}.
56.480 + *
56.481 + * <p><b>Implementation Considerations</b>
56.482 + *
56.483 + * <p>An implementation may (and typically does) require that the
56.484 + * current thread hold the lock associated with this {@code
56.485 + * Condition} when this method is called. Implementations must
56.486 + * document this precondition and any actions taken if the lock is
56.487 + * not held. Typically, an exception such as {@link
56.488 + * IllegalMonitorStateException} will be thrown.
56.489 + */
56.490 + void signalAll();
56.491 +}
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/Lock.java Sat Mar 19 10:46:31 2016 +0100
57.3 @@ -0,0 +1,356 @@
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 +import java.util.concurrent.TimeUnit;
57.41 +
57.42 +/**
57.43 + * {@code Lock} implementations provide more extensive locking
57.44 + * operations than can be obtained using {@code synchronized} methods
57.45 + * and statements. They allow more flexible structuring, may have
57.46 + * quite different properties, and may support multiple associated
57.47 + * {@link Condition} objects.
57.48 + *
57.49 + * <p>A lock is a tool for controlling access to a shared resource by
57.50 + * multiple threads. Commonly, a lock provides exclusive access to a
57.51 + * shared resource: only one thread at a time can acquire the lock and
57.52 + * all access to the shared resource requires that the lock be
57.53 + * acquired first. However, some locks may allow concurrent access to
57.54 + * a shared resource, such as the read lock of a {@link ReadWriteLock}.
57.55 + *
57.56 + * <p>The use of {@code synchronized} methods or statements provides
57.57 + * access to the implicit monitor lock associated with every object, but
57.58 + * forces all lock acquisition and release to occur in a block-structured way:
57.59 + * when multiple locks are acquired they must be released in the opposite
57.60 + * order, and all locks must be released in the same lexical scope in which
57.61 + * they were acquired.
57.62 + *
57.63 + * <p>While the scoping mechanism for {@code synchronized} methods
57.64 + * and statements makes it much easier to program with monitor locks,
57.65 + * and helps avoid many common programming errors involving locks,
57.66 + * there are occasions where you need to work with locks in a more
57.67 + * flexible way. For example, some algorithms for traversing
57.68 + * concurrently accessed data structures require the use of
57.69 + * "hand-over-hand" or "chain locking": you
57.70 + * acquire the lock of node A, then node B, then release A and acquire
57.71 + * C, then release B and acquire D and so on. Implementations of the
57.72 + * {@code Lock} interface enable the use of such techniques by
57.73 + * allowing a lock to be acquired and released in different scopes,
57.74 + * and allowing multiple locks to be acquired and released in any
57.75 + * order.
57.76 + *
57.77 + * <p>With this increased flexibility comes additional
57.78 + * responsibility. The absence of block-structured locking removes the
57.79 + * automatic release of locks that occurs with {@code synchronized}
57.80 + * methods and statements. In most cases, the following idiom
57.81 + * should be used:
57.82 + *
57.83 + * <pre><tt> Lock l = ...;
57.84 + * l.lock();
57.85 + * try {
57.86 + * // access the resource protected by this lock
57.87 + * } finally {
57.88 + * l.unlock();
57.89 + * }
57.90 + * </tt></pre>
57.91 + *
57.92 + * When locking and unlocking occur in different scopes, care must be
57.93 + * taken to ensure that all code that is executed while the lock is
57.94 + * held is protected by try-finally or try-catch to ensure that the
57.95 + * lock is released when necessary.
57.96 + *
57.97 + * <p>{@code Lock} implementations provide additional functionality
57.98 + * over the use of {@code synchronized} methods and statements by
57.99 + * providing a non-blocking attempt to acquire a lock ({@link
57.100 + * #tryLock()}), an attempt to acquire the lock that can be
57.101 + * interrupted ({@link #lockInterruptibly}, and an attempt to acquire
57.102 + * the lock that can timeout ({@link #tryLock(long, TimeUnit)}).
57.103 + *
57.104 + * <p>A {@code Lock} class can also provide behavior and semantics
57.105 + * that is quite different from that of the implicit monitor lock,
57.106 + * such as guaranteed ordering, non-reentrant usage, or deadlock
57.107 + * detection. If an implementation provides such specialized semantics
57.108 + * then the implementation must document those semantics.
57.109 + *
57.110 + * <p>Note that {@code Lock} instances are just normal objects and can
57.111 + * themselves be used as the target in a {@code synchronized} statement.
57.112 + * Acquiring the
57.113 + * monitor lock of a {@code Lock} instance has no specified relationship
57.114 + * with invoking any of the {@link #lock} methods of that instance.
57.115 + * It is recommended that to avoid confusion you never use {@code Lock}
57.116 + * instances in this way, except within their own implementation.
57.117 + *
57.118 + * <p>Except where noted, passing a {@code null} value for any
57.119 + * parameter will result in a {@link NullPointerException} being
57.120 + * thrown.
57.121 + *
57.122 + * <h3>Memory Synchronization</h3>
57.123 + *
57.124 + * <p>All {@code Lock} implementations <em>must</em> enforce the same
57.125 + * memory synchronization semantics as provided by the built-in monitor
57.126 + * lock, as described in section 17.4 of
57.127 + * <cite>The Java™ Language Specification</cite>:
57.128 + * <ul>
57.129 + * <li>A successful {@code lock} operation has the same memory
57.130 + * synchronization effects as a successful <em>Lock</em> action.
57.131 + * <li>A successful {@code unlock} operation has the same
57.132 + * memory synchronization effects as a successful <em>Unlock</em> action.
57.133 + * </ul>
57.134 + *
57.135 + * Unsuccessful locking and unlocking operations, and reentrant
57.136 + * locking/unlocking operations, do not require any memory
57.137 + * synchronization effects.
57.138 + *
57.139 + * <h3>Implementation Considerations</h3>
57.140 + *
57.141 + * <p> The three forms of lock acquisition (interruptible,
57.142 + * non-interruptible, and timed) may differ in their performance
57.143 + * characteristics, ordering guarantees, or other implementation
57.144 + * qualities. Further, the ability to interrupt the <em>ongoing</em>
57.145 + * acquisition of a lock may not be available in a given {@code Lock}
57.146 + * class. Consequently, an implementation is not required to define
57.147 + * exactly the same guarantees or semantics for all three forms of
57.148 + * lock acquisition, nor is it required to support interruption of an
57.149 + * ongoing lock acquisition. An implementation is required to clearly
57.150 + * document the semantics and guarantees provided by each of the
57.151 + * locking methods. It must also obey the interruption semantics as
57.152 + * defined in this interface, to the extent that interruption of lock
57.153 + * acquisition is supported: which is either totally, or only on
57.154 + * method entry.
57.155 + *
57.156 + * <p>As interruption generally implies cancellation, and checks for
57.157 + * interruption are often infrequent, an implementation can favor responding
57.158 + * to an interrupt over normal method return. This is true even if it can be
57.159 + * shown that the interrupt occurred after another action may have unblocked
57.160 + * the thread. An implementation should document this behavior.
57.161 + *
57.162 + * @see ReentrantLock
57.163 + * @see Condition
57.164 + * @see ReadWriteLock
57.165 + *
57.166 + * @since 1.5
57.167 + * @author Doug Lea
57.168 + */
57.169 +public interface Lock {
57.170 +
57.171 + /**
57.172 + * Acquires the lock.
57.173 + *
57.174 + * <p>If the lock is not available then the current thread becomes
57.175 + * disabled for thread scheduling purposes and lies dormant until the
57.176 + * lock has been acquired.
57.177 + *
57.178 + * <p><b>Implementation Considerations</b>
57.179 + *
57.180 + * <p>A {@code Lock} implementation may be able to detect erroneous use
57.181 + * of the lock, such as an invocation that would cause deadlock, and
57.182 + * may throw an (unchecked) exception in such circumstances. The
57.183 + * circumstances and the exception type must be documented by that
57.184 + * {@code Lock} implementation.
57.185 + */
57.186 + void lock();
57.187 +
57.188 + /**
57.189 + * Acquires the lock unless the current thread is
57.190 + * {@linkplain Thread#interrupt interrupted}.
57.191 + *
57.192 + * <p>Acquires the lock if it is available and returns immediately.
57.193 + *
57.194 + * <p>If the lock is not available then the current thread becomes
57.195 + * disabled for thread scheduling purposes and lies dormant until
57.196 + * one of two things happens:
57.197 + *
57.198 + * <ul>
57.199 + * <li>The lock is acquired by the current thread; or
57.200 + * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
57.201 + * current thread, and interruption of lock acquisition is supported.
57.202 + * </ul>
57.203 + *
57.204 + * <p>If the current thread:
57.205 + * <ul>
57.206 + * <li>has its interrupted status set on entry to this method; or
57.207 + * <li>is {@linkplain Thread#interrupt interrupted} while acquiring the
57.208 + * lock, and interruption of lock acquisition is supported,
57.209 + * </ul>
57.210 + * then {@link InterruptedException} is thrown and the current thread's
57.211 + * interrupted status is cleared.
57.212 + *
57.213 + * <p><b>Implementation Considerations</b>
57.214 + *
57.215 + * <p>The ability to interrupt a lock acquisition in some
57.216 + * implementations may not be possible, and if possible may be an
57.217 + * expensive operation. The programmer should be aware that this
57.218 + * may be the case. An implementation should document when this is
57.219 + * the case.
57.220 + *
57.221 + * <p>An implementation can favor responding to an interrupt over
57.222 + * normal method return.
57.223 + *
57.224 + * <p>A {@code Lock} implementation may be able to detect
57.225 + * erroneous use of the lock, such as an invocation that would
57.226 + * cause deadlock, and may throw an (unchecked) exception in such
57.227 + * circumstances. The circumstances and the exception type must
57.228 + * be documented by that {@code Lock} implementation.
57.229 + *
57.230 + * @throws InterruptedException if the current thread is
57.231 + * interrupted while acquiring the lock (and interruption
57.232 + * of lock acquisition is supported).
57.233 + */
57.234 + void lockInterruptibly() throws InterruptedException;
57.235 +
57.236 + /**
57.237 + * Acquires the lock only if it is free at the time of invocation.
57.238 + *
57.239 + * <p>Acquires the lock if it is available and returns immediately
57.240 + * with the value {@code true}.
57.241 + * If the lock is not available then this method will return
57.242 + * immediately with the value {@code false}.
57.243 + *
57.244 + * <p>A typical usage idiom for this method would be:
57.245 + * <pre>
57.246 + * Lock lock = ...;
57.247 + * if (lock.tryLock()) {
57.248 + * try {
57.249 + * // manipulate protected state
57.250 + * } finally {
57.251 + * lock.unlock();
57.252 + * }
57.253 + * } else {
57.254 + * // perform alternative actions
57.255 + * }
57.256 + * </pre>
57.257 + * This usage ensures that the lock is unlocked if it was acquired, and
57.258 + * doesn't try to unlock if the lock was not acquired.
57.259 + *
57.260 + * @return {@code true} if the lock was acquired and
57.261 + * {@code false} otherwise
57.262 + */
57.263 + boolean tryLock();
57.264 +
57.265 + /**
57.266 + * Acquires the lock if it is free within the given waiting time and the
57.267 + * current thread has not been {@linkplain Thread#interrupt interrupted}.
57.268 + *
57.269 + * <p>If the lock is available this method returns immediately
57.270 + * with the value {@code true}.
57.271 + * If the lock is not available then
57.272 + * the current thread becomes disabled for thread scheduling
57.273 + * purposes and lies dormant until one of three things happens:
57.274 + * <ul>
57.275 + * <li>The lock is acquired by the current thread; or
57.276 + * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
57.277 + * current thread, and interruption of lock acquisition is supported; or
57.278 + * <li>The specified waiting time elapses
57.279 + * </ul>
57.280 + *
57.281 + * <p>If the lock is acquired then the value {@code true} is returned.
57.282 + *
57.283 + * <p>If the current thread:
57.284 + * <ul>
57.285 + * <li>has its interrupted status set on entry to this method; or
57.286 + * <li>is {@linkplain Thread#interrupt interrupted} while acquiring
57.287 + * the lock, and interruption of lock acquisition is supported,
57.288 + * </ul>
57.289 + * then {@link InterruptedException} is thrown and the current thread's
57.290 + * interrupted status is cleared.
57.291 + *
57.292 + * <p>If the specified waiting time elapses then the value {@code false}
57.293 + * is returned.
57.294 + * If the time is
57.295 + * less than or equal to zero, the method will not wait at all.
57.296 + *
57.297 + * <p><b>Implementation Considerations</b>
57.298 + *
57.299 + * <p>The ability to interrupt a lock acquisition in some implementations
57.300 + * may not be possible, and if possible may
57.301 + * be an expensive operation.
57.302 + * The programmer should be aware that this may be the case. An
57.303 + * implementation should document when this is the case.
57.304 + *
57.305 + * <p>An implementation can favor responding to an interrupt over normal
57.306 + * method return, or reporting a timeout.
57.307 + *
57.308 + * <p>A {@code Lock} implementation may be able to detect
57.309 + * erroneous use of the lock, such as an invocation that would cause
57.310 + * deadlock, and may throw an (unchecked) exception in such circumstances.
57.311 + * The circumstances and the exception type must be documented by that
57.312 + * {@code Lock} implementation.
57.313 + *
57.314 + * @param time the maximum time to wait for the lock
57.315 + * @param unit the time unit of the {@code time} argument
57.316 + * @return {@code true} if the lock was acquired and {@code false}
57.317 + * if the waiting time elapsed before the lock was acquired
57.318 + *
57.319 + * @throws InterruptedException if the current thread is interrupted
57.320 + * while acquiring the lock (and interruption of lock
57.321 + * acquisition is supported)
57.322 + */
57.323 + boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
57.324 +
57.325 + /**
57.326 + * Releases the lock.
57.327 + *
57.328 + * <p><b>Implementation Considerations</b>
57.329 + *
57.330 + * <p>A {@code Lock} implementation will usually impose
57.331 + * restrictions on which thread can release a lock (typically only the
57.332 + * holder of the lock can release it) and may throw
57.333 + * an (unchecked) exception if the restriction is violated.
57.334 + * Any restrictions and the exception
57.335 + * type must be documented by that {@code Lock} implementation.
57.336 + */
57.337 + void unlock();
57.338 +
57.339 + /**
57.340 + * Returns a new {@link Condition} instance that is bound to this
57.341 + * {@code Lock} instance.
57.342 + *
57.343 + * <p>Before waiting on the condition the lock must be held by the
57.344 + * current thread.
57.345 + * A call to {@link Condition#await()} will atomically release the lock
57.346 + * before waiting and re-acquire the lock before the wait returns.
57.347 + *
57.348 + * <p><b>Implementation Considerations</b>
57.349 + *
57.350 + * <p>The exact operation of the {@link Condition} instance depends on
57.351 + * the {@code Lock} implementation and must be documented by that
57.352 + * implementation.
57.353 + *
57.354 + * @return A new {@link Condition} instance for this {@code Lock} instance
57.355 + * @throws UnsupportedOperationException if this {@code Lock}
57.356 + * implementation does not support conditions
57.357 + */
57.358 + Condition newCondition();
57.359 +}
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/LockSupport.java Sat Mar 19 10:46:31 2016 +0100
58.3 @@ -0,0 +1,385 @@
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.concurrent.*;
58.41 +import sun.misc.Unsafe;
58.42 +
58.43 +
58.44 +/**
58.45 + * Basic thread blocking primitives for creating locks and other
58.46 + * synchronization classes.
58.47 + *
58.48 + * <p>This class associates, with each thread that uses it, a permit
58.49 + * (in the sense of the {@link java.util.concurrent.Semaphore
58.50 + * Semaphore} class). A call to {@code park} will return immediately
58.51 + * if the permit is available, consuming it in the process; otherwise
58.52 + * it <em>may</em> block. A call to {@code unpark} makes the permit
58.53 + * available, if it was not already available. (Unlike with Semaphores
58.54 + * though, permits do not accumulate. There is at most one.)
58.55 + *
58.56 + * <p>Methods {@code park} and {@code unpark} provide efficient
58.57 + * means of blocking and unblocking threads that do not encounter the
58.58 + * problems that cause the deprecated methods {@code Thread.suspend}
58.59 + * and {@code Thread.resume} to be unusable for such purposes: Races
58.60 + * between one thread invoking {@code park} and another thread trying
58.61 + * to {@code unpark} it will preserve liveness, due to the
58.62 + * permit. Additionally, {@code park} will return if the caller's
58.63 + * thread was interrupted, and timeout versions are supported. The
58.64 + * {@code park} method may also return at any other time, for "no
58.65 + * reason", so in general must be invoked within a loop that rechecks
58.66 + * conditions upon return. In this sense {@code park} serves as an
58.67 + * optimization of a "busy wait" that does not waste as much time
58.68 + * spinning, but must be paired with an {@code unpark} to be
58.69 + * effective.
58.70 + *
58.71 + * <p>The three forms of {@code park} each also support a
58.72 + * {@code blocker} object parameter. This object is recorded while
58.73 + * the thread is blocked to permit monitoring and diagnostic tools to
58.74 + * identify the reasons that threads are blocked. (Such tools may
58.75 + * access blockers using method {@link #getBlocker}.) The use of these
58.76 + * forms rather than the original forms without this parameter is
58.77 + * strongly encouraged. The normal argument to supply as a
58.78 + * {@code blocker} within a lock implementation is {@code this}.
58.79 + *
58.80 + * <p>These methods are designed to be used as tools for creating
58.81 + * higher-level synchronization utilities, and are not in themselves
58.82 + * useful for most concurrency control applications. The {@code park}
58.83 + * method is designed for use only in constructions of the form:
58.84 + * <pre>while (!canProceed()) { ... LockSupport.park(this); }</pre>
58.85 + * where neither {@code canProceed} nor any other actions prior to the
58.86 + * call to {@code park} entail locking or blocking. Because only one
58.87 + * permit is associated with each thread, any intermediary uses of
58.88 + * {@code park} could interfere with its intended effects.
58.89 + *
58.90 + * <p><b>Sample Usage.</b> Here is a sketch of a first-in-first-out
58.91 + * non-reentrant lock class:
58.92 + * <pre>{@code
58.93 + * class FIFOMutex {
58.94 + * private final AtomicBoolean locked = new AtomicBoolean(false);
58.95 + * private final Queue<Thread> waiters
58.96 + * = new ConcurrentLinkedQueue<Thread>();
58.97 + *
58.98 + * public void lock() {
58.99 + * boolean wasInterrupted = false;
58.100 + * Thread current = Thread.currentThread();
58.101 + * waiters.add(current);
58.102 + *
58.103 + * // Block while not first in queue or cannot acquire lock
58.104 + * while (waiters.peek() != current ||
58.105 + * !locked.compareAndSet(false, true)) {
58.106 + * LockSupport.park(this);
58.107 + * if (Thread.interrupted()) // ignore interrupts while waiting
58.108 + * wasInterrupted = true;
58.109 + * }
58.110 + *
58.111 + * waiters.remove();
58.112 + * if (wasInterrupted) // reassert interrupt status on exit
58.113 + * current.interrupt();
58.114 + * }
58.115 + *
58.116 + * public void unlock() {
58.117 + * locked.set(false);
58.118 + * LockSupport.unpark(waiters.peek());
58.119 + * }
58.120 + * }}</pre>
58.121 + */
58.122 +
58.123 +public class LockSupport {
58.124 + private LockSupport() {} // Cannot be instantiated.
58.125 +
58.126 + // Hotspot implementation via intrinsics API
58.127 + private static final Unsafe unsafe = Unsafe.getUnsafe();
58.128 + private static final long parkBlockerOffset;
58.129 +
58.130 + static {
58.131 + try {
58.132 + parkBlockerOffset = unsafe.objectFieldOffset
58.133 + (java.lang.Thread.class.getDeclaredField("parkBlocker"));
58.134 + } catch (Exception ex) { throw new Error(ex); }
58.135 + }
58.136 +
58.137 + private static void setBlocker(Thread t, Object arg) {
58.138 + // Even though volatile, hotspot doesn't need a write barrier here.
58.139 + unsafe.putObject(t, parkBlockerOffset, arg);
58.140 + }
58.141 +
58.142 + /**
58.143 + * Makes available the permit for the given thread, if it
58.144 + * was not already available. If the thread was blocked on
58.145 + * {@code park} then it will unblock. Otherwise, its next call
58.146 + * to {@code park} is guaranteed not to block. This operation
58.147 + * is not guaranteed to have any effect at all if the given
58.148 + * thread has not been started.
58.149 + *
58.150 + * @param thread the thread to unpark, or {@code null}, in which case
58.151 + * this operation has no effect
58.152 + */
58.153 + public static void unpark(Thread thread) {
58.154 + if (thread != null)
58.155 + unsafe.unpark(thread);
58.156 + }
58.157 +
58.158 + /**
58.159 + * Disables the current thread for thread scheduling purposes unless the
58.160 + * permit is available.
58.161 + *
58.162 + * <p>If the permit is available then it is consumed and the call returns
58.163 + * immediately; otherwise
58.164 + * the current thread becomes disabled for thread scheduling
58.165 + * purposes and lies dormant until one of three things happens:
58.166 + *
58.167 + * <ul>
58.168 + * <li>Some other thread invokes {@link #unpark unpark} with the
58.169 + * current thread as the target; or
58.170 + *
58.171 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
58.172 + * the current thread; or
58.173 + *
58.174 + * <li>The call spuriously (that is, for no reason) returns.
58.175 + * </ul>
58.176 + *
58.177 + * <p>This method does <em>not</em> report which of these caused the
58.178 + * method to return. Callers should re-check the conditions which caused
58.179 + * the thread to park in the first place. Callers may also determine,
58.180 + * for example, the interrupt status of the thread upon return.
58.181 + *
58.182 + * @param blocker the synchronization object responsible for this
58.183 + * thread parking
58.184 + * @since 1.6
58.185 + */
58.186 + public static void park(Object blocker) {
58.187 + Thread t = Thread.currentThread();
58.188 + setBlocker(t, blocker);
58.189 + unsafe.park(false, 0L);
58.190 + setBlocker(t, null);
58.191 + }
58.192 +
58.193 + /**
58.194 + * Disables the current thread for thread scheduling purposes, for up to
58.195 + * the specified waiting time, unless the permit is available.
58.196 + *
58.197 + * <p>If the permit is available then it is consumed and the call
58.198 + * returns immediately; otherwise the current thread becomes disabled
58.199 + * for thread scheduling purposes and lies dormant until one of four
58.200 + * things happens:
58.201 + *
58.202 + * <ul>
58.203 + * <li>Some other thread invokes {@link #unpark unpark} with the
58.204 + * current thread as the target; or
58.205 + *
58.206 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
58.207 + * the current thread; or
58.208 + *
58.209 + * <li>The specified waiting time elapses; or
58.210 + *
58.211 + * <li>The call spuriously (that is, for no reason) returns.
58.212 + * </ul>
58.213 + *
58.214 + * <p>This method does <em>not</em> report which of these caused the
58.215 + * method to return. Callers should re-check the conditions which caused
58.216 + * the thread to park in the first place. Callers may also determine,
58.217 + * for example, the interrupt status of the thread, or the elapsed time
58.218 + * upon return.
58.219 + *
58.220 + * @param blocker the synchronization object responsible for this
58.221 + * thread parking
58.222 + * @param nanos the maximum number of nanoseconds to wait
58.223 + * @since 1.6
58.224 + */
58.225 + public static void parkNanos(Object blocker, long nanos) {
58.226 + if (nanos > 0) {
58.227 + Thread t = Thread.currentThread();
58.228 + setBlocker(t, blocker);
58.229 + unsafe.park(false, nanos);
58.230 + setBlocker(t, null);
58.231 + }
58.232 + }
58.233 +
58.234 + /**
58.235 + * Disables the current thread for thread scheduling purposes, until
58.236 + * the specified deadline, unless the permit is available.
58.237 + *
58.238 + * <p>If the permit is available then it is consumed and the call
58.239 + * returns immediately; otherwise the current thread becomes disabled
58.240 + * for thread scheduling purposes and lies dormant until one of four
58.241 + * things happens:
58.242 + *
58.243 + * <ul>
58.244 + * <li>Some other thread invokes {@link #unpark unpark} with the
58.245 + * current thread as the target; or
58.246 + *
58.247 + * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
58.248 + * current thread; or
58.249 + *
58.250 + * <li>The specified deadline passes; or
58.251 + *
58.252 + * <li>The call spuriously (that is, for no reason) returns.
58.253 + * </ul>
58.254 + *
58.255 + * <p>This method does <em>not</em> report which of these caused the
58.256 + * method to return. Callers should re-check the conditions which caused
58.257 + * the thread to park in the first place. Callers may also determine,
58.258 + * for example, the interrupt status of the thread, or the current time
58.259 + * upon return.
58.260 + *
58.261 + * @param blocker the synchronization object responsible for this
58.262 + * thread parking
58.263 + * @param deadline the absolute time, in milliseconds from the Epoch,
58.264 + * to wait until
58.265 + * @since 1.6
58.266 + */
58.267 + public static void parkUntil(Object blocker, long deadline) {
58.268 + Thread t = Thread.currentThread();
58.269 + setBlocker(t, blocker);
58.270 + unsafe.park(true, deadline);
58.271 + setBlocker(t, null);
58.272 + }
58.273 +
58.274 + /**
58.275 + * Returns the blocker object supplied to the most recent
58.276 + * invocation of a park method that has not yet unblocked, or null
58.277 + * if not blocked. The value returned is just a momentary
58.278 + * snapshot -- the thread may have since unblocked or blocked on a
58.279 + * different blocker object.
58.280 + *
58.281 + * @param t the thread
58.282 + * @return the blocker
58.283 + * @throws NullPointerException if argument is null
58.284 + * @since 1.6
58.285 + */
58.286 + public static Object getBlocker(Thread t) {
58.287 + if (t == null)
58.288 + throw new NullPointerException();
58.289 + return unsafe.getObjectVolatile(t, parkBlockerOffset);
58.290 + }
58.291 +
58.292 + /**
58.293 + * Disables the current thread for thread scheduling purposes unless the
58.294 + * permit is available.
58.295 + *
58.296 + * <p>If the permit is available then it is consumed and the call
58.297 + * returns immediately; otherwise the current thread becomes disabled
58.298 + * for thread scheduling purposes and lies dormant until one of three
58.299 + * things happens:
58.300 + *
58.301 + * <ul>
58.302 + *
58.303 + * <li>Some other thread invokes {@link #unpark unpark} with the
58.304 + * current thread as the target; or
58.305 + *
58.306 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
58.307 + * the current thread; or
58.308 + *
58.309 + * <li>The call spuriously (that is, for no reason) returns.
58.310 + * </ul>
58.311 + *
58.312 + * <p>This method does <em>not</em> report which of these caused the
58.313 + * method to return. Callers should re-check the conditions which caused
58.314 + * the thread to park in the first place. Callers may also determine,
58.315 + * for example, the interrupt status of the thread upon return.
58.316 + */
58.317 + public static void park() {
58.318 + unsafe.park(false, 0L);
58.319 + }
58.320 +
58.321 + /**
58.322 + * Disables the current thread for thread scheduling purposes, for up to
58.323 + * the specified waiting time, unless the permit is available.
58.324 + *
58.325 + * <p>If the permit is available then it is consumed and the call
58.326 + * returns immediately; otherwise the current thread becomes disabled
58.327 + * for thread scheduling purposes and lies dormant until one of four
58.328 + * things happens:
58.329 + *
58.330 + * <ul>
58.331 + * <li>Some other thread invokes {@link #unpark unpark} with the
58.332 + * current thread as the target; or
58.333 + *
58.334 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
58.335 + * the current thread; or
58.336 + *
58.337 + * <li>The specified waiting time elapses; or
58.338 + *
58.339 + * <li>The call spuriously (that is, for no reason) returns.
58.340 + * </ul>
58.341 + *
58.342 + * <p>This method does <em>not</em> report which of these caused the
58.343 + * method to return. Callers should re-check the conditions which caused
58.344 + * the thread to park in the first place. Callers may also determine,
58.345 + * for example, the interrupt status of the thread, or the elapsed time
58.346 + * upon return.
58.347 + *
58.348 + * @param nanos the maximum number of nanoseconds to wait
58.349 + */
58.350 + public static void parkNanos(long nanos) {
58.351 + if (nanos > 0)
58.352 + unsafe.park(false, nanos);
58.353 + }
58.354 +
58.355 + /**
58.356 + * Disables the current thread for thread scheduling purposes, until
58.357 + * the specified deadline, unless the permit is available.
58.358 + *
58.359 + * <p>If the permit is available then it is consumed and the call
58.360 + * returns immediately; otherwise the current thread becomes disabled
58.361 + * for thread scheduling purposes and lies dormant until one of four
58.362 + * things happens:
58.363 + *
58.364 + * <ul>
58.365 + * <li>Some other thread invokes {@link #unpark unpark} with the
58.366 + * current thread as the target; or
58.367 + *
58.368 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
58.369 + * the current thread; or
58.370 + *
58.371 + * <li>The specified deadline passes; or
58.372 + *
58.373 + * <li>The call spuriously (that is, for no reason) returns.
58.374 + * </ul>
58.375 + *
58.376 + * <p>This method does <em>not</em> report which of these caused the
58.377 + * method to return. Callers should re-check the conditions which caused
58.378 + * the thread to park in the first place. Callers may also determine,
58.379 + * for example, the interrupt status of the thread, or the current time
58.380 + * upon return.
58.381 + *
58.382 + * @param deadline the absolute time, in milliseconds from the Epoch,
58.383 + * to wait until
58.384 + */
58.385 + public static void parkUntil(long deadline) {
58.386 + unsafe.park(true, deadline);
58.387 + }
58.388 +}
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/ReadWriteLock.java Sat Mar 19 10:46:31 2016 +0100
59.3 @@ -0,0 +1,133 @@
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 +
59.41 +/**
59.42 + * A <tt>ReadWriteLock</tt> maintains a pair of associated {@link
59.43 + * Lock locks}, one for read-only operations and one for writing.
59.44 + * The {@link #readLock read lock} may be held simultaneously by
59.45 + * multiple reader threads, so long as there are no writers. The
59.46 + * {@link #writeLock write lock} is exclusive.
59.47 + *
59.48 + * <p>All <tt>ReadWriteLock</tt> implementations must guarantee that
59.49 + * the memory synchronization effects of <tt>writeLock</tt> operations
59.50 + * (as specified in the {@link Lock} interface) also hold with respect
59.51 + * to the associated <tt>readLock</tt>. That is, a thread successfully
59.52 + * acquiring the read lock will see all updates made upon previous
59.53 + * release of the write lock.
59.54 + *
59.55 + * <p>A read-write lock allows for a greater level of concurrency in
59.56 + * accessing shared data than that permitted by a mutual exclusion lock.
59.57 + * It exploits the fact that while only a single thread at a time (a
59.58 + * <em>writer</em> thread) can modify the shared data, in many cases any
59.59 + * number of threads can concurrently read the data (hence <em>reader</em>
59.60 + * threads).
59.61 + * In theory, the increase in concurrency permitted by the use of a read-write
59.62 + * lock will lead to performance improvements over the use of a mutual
59.63 + * exclusion lock. In practice this increase in concurrency will only be fully
59.64 + * realized on a multi-processor, and then only if the access patterns for
59.65 + * the shared data are suitable.
59.66 + *
59.67 + * <p>Whether or not a read-write lock will improve performance over the use
59.68 + * of a mutual exclusion lock depends on the frequency that the data is
59.69 + * read compared to being modified, the duration of the read and write
59.70 + * operations, and the contention for the data - that is, the number of
59.71 + * threads that will try to read or write the data at the same time.
59.72 + * For example, a collection that is initially populated with data and
59.73 + * thereafter infrequently modified, while being frequently searched
59.74 + * (such as a directory of some kind) is an ideal candidate for the use of
59.75 + * a read-write lock. However, if updates become frequent then the data
59.76 + * spends most of its time being exclusively locked and there is little, if any
59.77 + * increase in concurrency. Further, if the read operations are too short
59.78 + * the overhead of the read-write lock implementation (which is inherently
59.79 + * more complex than a mutual exclusion lock) can dominate the execution
59.80 + * cost, particularly as many read-write lock implementations still serialize
59.81 + * all threads through a small section of code. Ultimately, only profiling
59.82 + * and measurement will establish whether the use of a read-write lock is
59.83 + * suitable for your application.
59.84 + *
59.85 + *
59.86 + * <p>Although the basic operation of a read-write lock is straight-forward,
59.87 + * there are many policy decisions that an implementation must make, which
59.88 + * may affect the effectiveness of the read-write lock in a given application.
59.89 + * Examples of these policies include:
59.90 + * <ul>
59.91 + * <li>Determining whether to grant the read lock or the write lock, when
59.92 + * both readers and writers are waiting, at the time that a writer releases
59.93 + * the write lock. Writer preference is common, as writes are expected to be
59.94 + * short and infrequent. Reader preference is less common as it can lead to
59.95 + * lengthy delays for a write if the readers are frequent and long-lived as
59.96 + * expected. Fair, or "in-order" implementations are also possible.
59.97 + *
59.98 + * <li>Determining whether readers that request the read lock while a
59.99 + * reader is active and a writer is waiting, are granted the read lock.
59.100 + * Preference to the reader can delay the writer indefinitely, while
59.101 + * preference to the writer can reduce the potential for concurrency.
59.102 + *
59.103 + * <li>Determining whether the locks are reentrant: can a thread with the
59.104 + * write lock reacquire it? Can it acquire a read lock while holding the
59.105 + * write lock? Is the read lock itself reentrant?
59.106 + *
59.107 + * <li>Can the write lock be downgraded to a read lock without allowing
59.108 + * an intervening writer? Can a read lock be upgraded to a write lock,
59.109 + * in preference to other waiting readers or writers?
59.110 + *
59.111 + * </ul>
59.112 + * You should consider all of these things when evaluating the suitability
59.113 + * of a given implementation for your application.
59.114 + *
59.115 + * @see ReentrantReadWriteLock
59.116 + * @see Lock
59.117 + * @see ReentrantLock
59.118 + *
59.119 + * @since 1.5
59.120 + * @author Doug Lea
59.121 + */
59.122 +public interface ReadWriteLock {
59.123 + /**
59.124 + * Returns the lock used for reading.
59.125 + *
59.126 + * @return the lock used for reading.
59.127 + */
59.128 + Lock readLock();
59.129 +
59.130 + /**
59.131 + * Returns the lock used for writing.
59.132 + *
59.133 + * @return the lock used for writing.
59.134 + */
59.135 + Lock writeLock();
59.136 +}
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/ReentrantLock.java Sat Mar 19 10:46:31 2016 +0100
60.3 @@ -0,0 +1,770 @@
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 +package java.util.concurrent.locks;
60.40 +import java.util.*;
60.41 +import java.util.concurrent.*;
60.42 +import java.util.concurrent.atomic.*;
60.43 +
60.44 +/**
60.45 + * A reentrant mutual exclusion {@link Lock} with the same basic
60.46 + * behavior and semantics as the implicit monitor lock accessed using
60.47 + * {@code synchronized} methods and statements, but with extended
60.48 + * capabilities.
60.49 + *
60.50 + * <p>A {@code ReentrantLock} is <em>owned</em> by the thread last
60.51 + * successfully locking, but not yet unlocking it. A thread invoking
60.52 + * {@code lock} will return, successfully acquiring the lock, when
60.53 + * the lock is not owned by another thread. The method will return
60.54 + * immediately if the current thread already owns the lock. This can
60.55 + * be checked using methods {@link #isHeldByCurrentThread}, and {@link
60.56 + * #getHoldCount}.
60.57 + *
60.58 + * <p>The constructor for this class accepts an optional
60.59 + * <em>fairness</em> parameter. When set {@code true}, under
60.60 + * contention, locks favor granting access to the longest-waiting
60.61 + * thread. Otherwise this lock does not guarantee any particular
60.62 + * access order. Programs using fair locks accessed by many threads
60.63 + * may display lower overall throughput (i.e., are slower; often much
60.64 + * slower) than those using the default setting, but have smaller
60.65 + * variances in times to obtain locks and guarantee lack of
60.66 + * starvation. Note however, that fairness of locks does not guarantee
60.67 + * fairness of thread scheduling. Thus, one of many threads using a
60.68 + * fair lock may obtain it multiple times in succession while other
60.69 + * active threads are not progressing and not currently holding the
60.70 + * lock.
60.71 + * Also note that the untimed {@link #tryLock() tryLock} method does not
60.72 + * honor the fairness setting. It will succeed if the lock
60.73 + * is available even if other threads are waiting.
60.74 + *
60.75 + * <p>It is recommended practice to <em>always</em> immediately
60.76 + * follow a call to {@code lock} with a {@code try} block, most
60.77 + * typically in a before/after construction such as:
60.78 + *
60.79 + * <pre>
60.80 + * class X {
60.81 + * private final ReentrantLock lock = new ReentrantLock();
60.82 + * // ...
60.83 + *
60.84 + * public void m() {
60.85 + * lock.lock(); // block until condition holds
60.86 + * try {
60.87 + * // ... method body
60.88 + * } finally {
60.89 + * lock.unlock()
60.90 + * }
60.91 + * }
60.92 + * }
60.93 + * </pre>
60.94 + *
60.95 + * <p>In addition to implementing the {@link Lock} interface, this
60.96 + * class defines methods {@code isLocked} and
60.97 + * {@code getLockQueueLength}, as well as some associated
60.98 + * {@code protected} access methods that may be useful for
60.99 + * instrumentation and monitoring.
60.100 + *
60.101 + * <p>Serialization of this class behaves in the same way as built-in
60.102 + * locks: a deserialized lock is in the unlocked state, regardless of
60.103 + * its state when serialized.
60.104 + *
60.105 + * <p>This lock supports a maximum of 2147483647 recursive locks by
60.106 + * the same thread. Attempts to exceed this limit result in
60.107 + * {@link Error} throws from locking methods.
60.108 + *
60.109 + * @since 1.5
60.110 + * @author Doug Lea
60.111 + */
60.112 +public class ReentrantLock implements Lock, java.io.Serializable {
60.113 + private static final long serialVersionUID = 7373984872572414699L;
60.114 + /** Synchronizer providing all implementation mechanics */
60.115 + private final Sync sync;
60.116 +
60.117 + /**
60.118 + * Base of synchronization control for this lock. Subclassed
60.119 + * into fair and nonfair versions below. Uses AQS state to
60.120 + * represent the number of holds on the lock.
60.121 + */
60.122 + abstract static class Sync extends AbstractQueuedSynchronizer {
60.123 + private static final long serialVersionUID = -5179523762034025860L;
60.124 +
60.125 + /**
60.126 + * Performs {@link Lock#lock}. The main reason for subclassing
60.127 + * is to allow fast path for nonfair version.
60.128 + */
60.129 + abstract void lock();
60.130 +
60.131 + /**
60.132 + * Performs non-fair tryLock. tryAcquire is
60.133 + * implemented in subclasses, but both need nonfair
60.134 + * try for trylock method.
60.135 + */
60.136 + final boolean nonfairTryAcquire(int acquires) {
60.137 + final Thread current = Thread.currentThread();
60.138 + int c = getState();
60.139 + if (c == 0) {
60.140 + if (compareAndSetState(0, acquires)) {
60.141 + setExclusiveOwnerThread(current);
60.142 + return true;
60.143 + }
60.144 + }
60.145 + else if (current == getExclusiveOwnerThread()) {
60.146 + int nextc = c + acquires;
60.147 + if (nextc < 0) // overflow
60.148 + throw new Error("Maximum lock count exceeded");
60.149 + setState(nextc);
60.150 + return true;
60.151 + }
60.152 + return false;
60.153 + }
60.154 +
60.155 + protected final boolean tryRelease(int releases) {
60.156 + int c = getState() - releases;
60.157 + if (Thread.currentThread() != getExclusiveOwnerThread())
60.158 + throw new IllegalMonitorStateException();
60.159 + boolean free = false;
60.160 + if (c == 0) {
60.161 + free = true;
60.162 + setExclusiveOwnerThread(null);
60.163 + }
60.164 + setState(c);
60.165 + return free;
60.166 + }
60.167 +
60.168 + protected final boolean isHeldExclusively() {
60.169 + // While we must in general read state before owner,
60.170 + // we don't need to do so to check if current thread is owner
60.171 + return getExclusiveOwnerThread() == Thread.currentThread();
60.172 + }
60.173 +
60.174 + final ConditionObject newCondition() {
60.175 + return new ConditionObject();
60.176 + }
60.177 +
60.178 + // Methods relayed from outer class
60.179 +
60.180 + final Thread getOwner() {
60.181 + return getState() == 0 ? null : getExclusiveOwnerThread();
60.182 + }
60.183 +
60.184 + final int getHoldCount() {
60.185 + return isHeldExclusively() ? getState() : 0;
60.186 + }
60.187 +
60.188 + final boolean isLocked() {
60.189 + return getState() != 0;
60.190 + }
60.191 +
60.192 + /**
60.193 + * Reconstitutes this lock instance from a stream.
60.194 + * @param s the stream
60.195 + */
60.196 + private void readObject(java.io.ObjectInputStream s)
60.197 + throws java.io.IOException, ClassNotFoundException {
60.198 + s.defaultReadObject();
60.199 + setState(0); // reset to unlocked state
60.200 + }
60.201 + }
60.202 +
60.203 + /**
60.204 + * Sync object for non-fair locks
60.205 + */
60.206 + static final class NonfairSync extends Sync {
60.207 + private static final long serialVersionUID = 7316153563782823691L;
60.208 +
60.209 + /**
60.210 + * Performs lock. Try immediate barge, backing up to normal
60.211 + * acquire on failure.
60.212 + */
60.213 + final void lock() {
60.214 + if (compareAndSetState(0, 1))
60.215 + setExclusiveOwnerThread(Thread.currentThread());
60.216 + else
60.217 + acquire(1);
60.218 + }
60.219 +
60.220 + protected final boolean tryAcquire(int acquires) {
60.221 + return nonfairTryAcquire(acquires);
60.222 + }
60.223 + }
60.224 +
60.225 + /**
60.226 + * Sync object for fair locks
60.227 + */
60.228 + static final class FairSync extends Sync {
60.229 + private static final long serialVersionUID = -3000897897090466540L;
60.230 +
60.231 + final void lock() {
60.232 + acquire(1);
60.233 + }
60.234 +
60.235 + /**
60.236 + * Fair version of tryAcquire. Don't grant access unless
60.237 + * recursive call or no waiters or is first.
60.238 + */
60.239 + protected final boolean tryAcquire(int acquires) {
60.240 + final Thread current = Thread.currentThread();
60.241 + int c = getState();
60.242 + if (c == 0) {
60.243 + if (!hasQueuedPredecessors() &&
60.244 + compareAndSetState(0, acquires)) {
60.245 + setExclusiveOwnerThread(current);
60.246 + return true;
60.247 + }
60.248 + }
60.249 + else if (current == getExclusiveOwnerThread()) {
60.250 + int nextc = c + acquires;
60.251 + if (nextc < 0)
60.252 + throw new Error("Maximum lock count exceeded");
60.253 + setState(nextc);
60.254 + return true;
60.255 + }
60.256 + return false;
60.257 + }
60.258 + }
60.259 +
60.260 + /**
60.261 + * Creates an instance of {@code ReentrantLock}.
60.262 + * This is equivalent to using {@code ReentrantLock(false)}.
60.263 + */
60.264 + public ReentrantLock() {
60.265 + sync = new NonfairSync();
60.266 + }
60.267 +
60.268 + /**
60.269 + * Creates an instance of {@code ReentrantLock} with the
60.270 + * given fairness policy.
60.271 + *
60.272 + * @param fair {@code true} if this lock should use a fair ordering policy
60.273 + */
60.274 + public ReentrantLock(boolean fair) {
60.275 + sync = fair ? new FairSync() : new NonfairSync();
60.276 + }
60.277 +
60.278 + /**
60.279 + * Acquires the lock.
60.280 + *
60.281 + * <p>Acquires the lock if it is not held by another thread and returns
60.282 + * immediately, setting the lock hold count to one.
60.283 + *
60.284 + * <p>If the current thread already holds the lock then the hold
60.285 + * count is incremented by one and the method returns immediately.
60.286 + *
60.287 + * <p>If the lock is held by another thread then the
60.288 + * current thread becomes disabled for thread scheduling
60.289 + * purposes and lies dormant until the lock has been acquired,
60.290 + * at which time the lock hold count is set to one.
60.291 + */
60.292 + public void lock() {
60.293 + sync.lock();
60.294 + }
60.295 +
60.296 + /**
60.297 + * Acquires the lock unless the current thread is
60.298 + * {@linkplain Thread#interrupt interrupted}.
60.299 + *
60.300 + * <p>Acquires the lock if it is not held by another thread and returns
60.301 + * immediately, setting the lock hold count to one.
60.302 + *
60.303 + * <p>If the current thread already holds this lock then the hold count
60.304 + * is incremented by one and the method returns immediately.
60.305 + *
60.306 + * <p>If the lock is held by another thread then the
60.307 + * current thread becomes disabled for thread scheduling
60.308 + * purposes and lies dormant until one of two things happens:
60.309 + *
60.310 + * <ul>
60.311 + *
60.312 + * <li>The lock is acquired by the current thread; or
60.313 + *
60.314 + * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
60.315 + * current thread.
60.316 + *
60.317 + * </ul>
60.318 + *
60.319 + * <p>If the lock is acquired by the current thread then the lock hold
60.320 + * count is set to one.
60.321 + *
60.322 + * <p>If the current thread:
60.323 + *
60.324 + * <ul>
60.325 + *
60.326 + * <li>has its interrupted status set on entry to this method; or
60.327 + *
60.328 + * <li>is {@linkplain Thread#interrupt interrupted} while acquiring
60.329 + * the lock,
60.330 + *
60.331 + * </ul>
60.332 + *
60.333 + * then {@link InterruptedException} is thrown and the current thread's
60.334 + * interrupted status is cleared.
60.335 + *
60.336 + * <p>In this implementation, as this method is an explicit
60.337 + * interruption point, preference is given to responding to the
60.338 + * interrupt over normal or reentrant acquisition of the lock.
60.339 + *
60.340 + * @throws InterruptedException if the current thread is interrupted
60.341 + */
60.342 + public void lockInterruptibly() throws InterruptedException {
60.343 + sync.acquireInterruptibly(1);
60.344 + }
60.345 +
60.346 + /**
60.347 + * Acquires the lock only if it is not held by another thread at the time
60.348 + * of invocation.
60.349 + *
60.350 + * <p>Acquires the lock if it is not held by another thread and
60.351 + * returns immediately with the value {@code true}, setting the
60.352 + * lock hold count to one. Even when this lock has been set to use a
60.353 + * fair ordering policy, a call to {@code tryLock()} <em>will</em>
60.354 + * immediately acquire the lock if it is available, whether or not
60.355 + * other threads are currently waiting for the lock.
60.356 + * This "barging" behavior can be useful in certain
60.357 + * circumstances, even though it breaks fairness. If you want to honor
60.358 + * the fairness setting for this lock, then use
60.359 + * {@link #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) }
60.360 + * which is almost equivalent (it also detects interruption).
60.361 + *
60.362 + * <p> If the current thread already holds this lock then the hold
60.363 + * count is incremented by one and the method returns {@code true}.
60.364 + *
60.365 + * <p>If the lock is held by another thread then this method will return
60.366 + * immediately with the value {@code false}.
60.367 + *
60.368 + * @return {@code true} if the lock was free and was acquired by the
60.369 + * current thread, or the lock was already held by the current
60.370 + * thread; and {@code false} otherwise
60.371 + */
60.372 + public boolean tryLock() {
60.373 + return sync.nonfairTryAcquire(1);
60.374 + }
60.375 +
60.376 + /**
60.377 + * Acquires the lock if it is not held by another thread within the given
60.378 + * waiting time and the current thread has not been
60.379 + * {@linkplain Thread#interrupt interrupted}.
60.380 + *
60.381 + * <p>Acquires the lock if it is not held by another thread and returns
60.382 + * immediately with the value {@code true}, setting the lock hold count
60.383 + * to one. If this lock has been set to use a fair ordering policy then
60.384 + * an available lock <em>will not</em> be acquired if any other threads
60.385 + * are waiting for the lock. This is in contrast to the {@link #tryLock()}
60.386 + * method. If you want a timed {@code tryLock} that does permit barging on
60.387 + * a fair lock then combine the timed and un-timed forms together:
60.388 + *
60.389 + * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
60.390 + * </pre>
60.391 + *
60.392 + * <p>If the current thread
60.393 + * already holds this lock then the hold count is incremented by one and
60.394 + * the method returns {@code true}.
60.395 + *
60.396 + * <p>If the lock is held by another thread then the
60.397 + * current thread becomes disabled for thread scheduling
60.398 + * purposes and lies dormant until one of three things happens:
60.399 + *
60.400 + * <ul>
60.401 + *
60.402 + * <li>The lock is acquired by the current thread; or
60.403 + *
60.404 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
60.405 + * the current thread; or
60.406 + *
60.407 + * <li>The specified waiting time elapses
60.408 + *
60.409 + * </ul>
60.410 + *
60.411 + * <p>If the lock is acquired then the value {@code true} is returned and
60.412 + * the lock hold count is set to one.
60.413 + *
60.414 + * <p>If the current thread:
60.415 + *
60.416 + * <ul>
60.417 + *
60.418 + * <li>has its interrupted status set on entry to this method; or
60.419 + *
60.420 + * <li>is {@linkplain Thread#interrupt interrupted} while
60.421 + * acquiring the lock,
60.422 + *
60.423 + * </ul>
60.424 + * then {@link InterruptedException} is thrown and the current thread's
60.425 + * interrupted status is cleared.
60.426 + *
60.427 + * <p>If the specified waiting time elapses then the value {@code false}
60.428 + * is returned. If the time is less than or equal to zero, the method
60.429 + * will not wait at all.
60.430 + *
60.431 + * <p>In this implementation, as this method is an explicit
60.432 + * interruption point, preference is given to responding to the
60.433 + * interrupt over normal or reentrant acquisition of the lock, and
60.434 + * over reporting the elapse of the waiting time.
60.435 + *
60.436 + * @param timeout the time to wait for the lock
60.437 + * @param unit the time unit of the timeout argument
60.438 + * @return {@code true} if the lock was free and was acquired by the
60.439 + * current thread, or the lock was already held by the current
60.440 + * thread; and {@code false} if the waiting time elapsed before
60.441 + * the lock could be acquired
60.442 + * @throws InterruptedException if the current thread is interrupted
60.443 + * @throws NullPointerException if the time unit is null
60.444 + *
60.445 + */
60.446 + public boolean tryLock(long timeout, TimeUnit unit)
60.447 + throws InterruptedException {
60.448 + return sync.tryAcquireNanos(1, unit.toNanos(timeout));
60.449 + }
60.450 +
60.451 + /**
60.452 + * Attempts to release this lock.
60.453 + *
60.454 + * <p>If the current thread is the holder of this lock then the hold
60.455 + * count is decremented. If the hold count is now zero then the lock
60.456 + * is released. If the current thread is not the holder of this
60.457 + * lock then {@link IllegalMonitorStateException} is thrown.
60.458 + *
60.459 + * @throws IllegalMonitorStateException if the current thread does not
60.460 + * hold this lock
60.461 + */
60.462 + public void unlock() {
60.463 + sync.release(1);
60.464 + }
60.465 +
60.466 + /**
60.467 + * Returns a {@link Condition} instance for use with this
60.468 + * {@link Lock} instance.
60.469 + *
60.470 + * <p>The returned {@link Condition} instance supports the same
60.471 + * usages as do the {@link Object} monitor methods ({@link
60.472 + * Object#wait() wait}, {@link Object#notify notify}, and {@link
60.473 + * Object#notifyAll notifyAll}) when used with the built-in
60.474 + * monitor lock.
60.475 + *
60.476 + * <ul>
60.477 + *
60.478 + * <li>If this lock is not held when any of the {@link Condition}
60.479 + * {@linkplain Condition#await() waiting} or {@linkplain
60.480 + * Condition#signal signalling} methods are called, then an {@link
60.481 + * IllegalMonitorStateException} is thrown.
60.482 + *
60.483 + * <li>When the condition {@linkplain Condition#await() waiting}
60.484 + * methods are called the lock is released and, before they
60.485 + * return, the lock is reacquired and the lock hold count restored
60.486 + * to what it was when the method was called.
60.487 + *
60.488 + * <li>If a thread is {@linkplain Thread#interrupt interrupted}
60.489 + * while waiting then the wait will terminate, an {@link
60.490 + * InterruptedException} will be thrown, and the thread's
60.491 + * interrupted status will be cleared.
60.492 + *
60.493 + * <li> Waiting threads are signalled in FIFO order.
60.494 + *
60.495 + * <li>The ordering of lock reacquisition for threads returning
60.496 + * from waiting methods is the same as for threads initially
60.497 + * acquiring the lock, which is in the default case not specified,
60.498 + * but for <em>fair</em> locks favors those threads that have been
60.499 + * waiting the longest.
60.500 + *
60.501 + * </ul>
60.502 + *
60.503 + * @return the Condition object
60.504 + */
60.505 + public Condition newCondition() {
60.506 + return sync.newCondition();
60.507 + }
60.508 +
60.509 + /**
60.510 + * Queries the number of holds on this lock by the current thread.
60.511 + *
60.512 + * <p>A thread has a hold on a lock for each lock action that is not
60.513 + * matched by an unlock action.
60.514 + *
60.515 + * <p>The hold count information is typically only used for testing and
60.516 + * debugging purposes. For example, if a certain section of code should
60.517 + * not be entered with the lock already held then we can assert that
60.518 + * fact:
60.519 + *
60.520 + * <pre>
60.521 + * class X {
60.522 + * ReentrantLock lock = new ReentrantLock();
60.523 + * // ...
60.524 + * public void m() {
60.525 + * assert lock.getHoldCount() == 0;
60.526 + * lock.lock();
60.527 + * try {
60.528 + * // ... method body
60.529 + * } finally {
60.530 + * lock.unlock();
60.531 + * }
60.532 + * }
60.533 + * }
60.534 + * </pre>
60.535 + *
60.536 + * @return the number of holds on this lock by the current thread,
60.537 + * or zero if this lock is not held by the current thread
60.538 + */
60.539 + public int getHoldCount() {
60.540 + return sync.getHoldCount();
60.541 + }
60.542 +
60.543 + /**
60.544 + * Queries if this lock is held by the current thread.
60.545 + *
60.546 + * <p>Analogous to the {@link Thread#holdsLock} method for built-in
60.547 + * monitor locks, this method is typically used for debugging and
60.548 + * testing. For example, a method that should only be called while
60.549 + * a lock is held can assert that this is the case:
60.550 + *
60.551 + * <pre>
60.552 + * class X {
60.553 + * ReentrantLock lock = new ReentrantLock();
60.554 + * // ...
60.555 + *
60.556 + * public void m() {
60.557 + * assert lock.isHeldByCurrentThread();
60.558 + * // ... method body
60.559 + * }
60.560 + * }
60.561 + * </pre>
60.562 + *
60.563 + * <p>It can also be used to ensure that a reentrant lock is used
60.564 + * in a non-reentrant manner, for example:
60.565 + *
60.566 + * <pre>
60.567 + * class X {
60.568 + * ReentrantLock lock = new ReentrantLock();
60.569 + * // ...
60.570 + *
60.571 + * public void m() {
60.572 + * assert !lock.isHeldByCurrentThread();
60.573 + * lock.lock();
60.574 + * try {
60.575 + * // ... method body
60.576 + * } finally {
60.577 + * lock.unlock();
60.578 + * }
60.579 + * }
60.580 + * }
60.581 + * </pre>
60.582 + *
60.583 + * @return {@code true} if current thread holds this lock and
60.584 + * {@code false} otherwise
60.585 + */
60.586 + public boolean isHeldByCurrentThread() {
60.587 + return sync.isHeldExclusively();
60.588 + }
60.589 +
60.590 + /**
60.591 + * Queries if this lock is held by any thread. This method is
60.592 + * designed for use in monitoring of the system state,
60.593 + * not for synchronization control.
60.594 + *
60.595 + * @return {@code true} if any thread holds this lock and
60.596 + * {@code false} otherwise
60.597 + */
60.598 + public boolean isLocked() {
60.599 + return sync.isLocked();
60.600 + }
60.601 +
60.602 + /**
60.603 + * Returns {@code true} if this lock has fairness set true.
60.604 + *
60.605 + * @return {@code true} if this lock has fairness set true
60.606 + */
60.607 + public final boolean isFair() {
60.608 + return sync instanceof FairSync;
60.609 + }
60.610 +
60.611 + /**
60.612 + * Returns the thread that currently owns this lock, or
60.613 + * {@code null} if not owned. When this method is called by a
60.614 + * thread that is not the owner, the return value reflects a
60.615 + * best-effort approximation of current lock status. For example,
60.616 + * the owner may be momentarily {@code null} even if there are
60.617 + * threads trying to acquire the lock but have not yet done so.
60.618 + * This method is designed to facilitate construction of
60.619 + * subclasses that provide more extensive lock monitoring
60.620 + * facilities.
60.621 + *
60.622 + * @return the owner, or {@code null} if not owned
60.623 + */
60.624 + protected Thread getOwner() {
60.625 + return sync.getOwner();
60.626 + }
60.627 +
60.628 + /**
60.629 + * Queries whether any threads are waiting to acquire this lock. Note that
60.630 + * because cancellations may occur at any time, a {@code true}
60.631 + * return does not guarantee that any other thread will ever
60.632 + * acquire this lock. This method is designed primarily for use in
60.633 + * monitoring of the system state.
60.634 + *
60.635 + * @return {@code true} if there may be other threads waiting to
60.636 + * acquire the lock
60.637 + */
60.638 + public final boolean hasQueuedThreads() {
60.639 + return sync.hasQueuedThreads();
60.640 + }
60.641 +
60.642 +
60.643 + /**
60.644 + * Queries whether the given thread is waiting to acquire this
60.645 + * lock. Note that because cancellations may occur at any time, a
60.646 + * {@code true} return does not guarantee that this thread
60.647 + * will ever acquire this lock. This method is designed primarily for use
60.648 + * in monitoring of the system state.
60.649 + *
60.650 + * @param thread the thread
60.651 + * @return {@code true} if the given thread is queued waiting for this lock
60.652 + * @throws NullPointerException if the thread is null
60.653 + */
60.654 + public final boolean hasQueuedThread(Thread thread) {
60.655 + return sync.isQueued(thread);
60.656 + }
60.657 +
60.658 +
60.659 + /**
60.660 + * Returns an estimate of the number of threads waiting to
60.661 + * acquire this lock. The value is only an estimate because the number of
60.662 + * threads may change dynamically while this method traverses
60.663 + * internal data structures. This method is designed for use in
60.664 + * monitoring of the system state, not for synchronization
60.665 + * control.
60.666 + *
60.667 + * @return the estimated number of threads waiting for this lock
60.668 + */
60.669 + public final int getQueueLength() {
60.670 + return sync.getQueueLength();
60.671 + }
60.672 +
60.673 + /**
60.674 + * Returns a collection containing threads that may be waiting to
60.675 + * acquire this lock. Because the actual set of threads may change
60.676 + * dynamically while constructing this result, the returned
60.677 + * collection is only a best-effort estimate. The elements of the
60.678 + * returned collection are in no particular order. This method is
60.679 + * designed to facilitate construction of subclasses that provide
60.680 + * more extensive monitoring facilities.
60.681 + *
60.682 + * @return the collection of threads
60.683 + */
60.684 + protected Collection<Thread> getQueuedThreads() {
60.685 + return sync.getQueuedThreads();
60.686 + }
60.687 +
60.688 + /**
60.689 + * Queries whether any threads are waiting on the given condition
60.690 + * associated with this lock. Note that because timeouts and
60.691 + * interrupts may occur at any time, a {@code true} return does
60.692 + * not guarantee that a future {@code signal} will awaken any
60.693 + * threads. This method is designed primarily for use in
60.694 + * monitoring of the system state.
60.695 + *
60.696 + * @param condition the condition
60.697 + * @return {@code true} if there are any waiting threads
60.698 + * @throws IllegalMonitorStateException if this lock is not held
60.699 + * @throws IllegalArgumentException if the given condition is
60.700 + * not associated with this lock
60.701 + * @throws NullPointerException if the condition is null
60.702 + */
60.703 + public boolean hasWaiters(Condition condition) {
60.704 + if (condition == null)
60.705 + throw new NullPointerException();
60.706 + if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
60.707 + throw new IllegalArgumentException("not owner");
60.708 + return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
60.709 + }
60.710 +
60.711 + /**
60.712 + * Returns an estimate of the number of threads waiting on the
60.713 + * given condition associated with this lock. Note that because
60.714 + * timeouts and interrupts may occur at any time, the estimate
60.715 + * serves only as an upper bound on the actual number of waiters.
60.716 + * This method is designed for use in monitoring of the system
60.717 + * state, not for synchronization control.
60.718 + *
60.719 + * @param condition the condition
60.720 + * @return the estimated number of waiting threads
60.721 + * @throws IllegalMonitorStateException if this lock is not held
60.722 + * @throws IllegalArgumentException if the given condition is
60.723 + * not associated with this lock
60.724 + * @throws NullPointerException if the condition is null
60.725 + */
60.726 + public int getWaitQueueLength(Condition condition) {
60.727 + if (condition == null)
60.728 + throw new NullPointerException();
60.729 + if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
60.730 + throw new IllegalArgumentException("not owner");
60.731 + return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
60.732 + }
60.733 +
60.734 + /**
60.735 + * Returns a collection containing those threads that may be
60.736 + * waiting on the given condition associated with this lock.
60.737 + * Because the actual set of threads may change dynamically while
60.738 + * constructing this result, the returned collection is only a
60.739 + * best-effort estimate. The elements of the returned collection
60.740 + * are in no particular order. This method is designed to
60.741 + * facilitate construction of subclasses that provide more
60.742 + * extensive condition monitoring facilities.
60.743 + *
60.744 + * @param condition the condition
60.745 + * @return the collection of threads
60.746 + * @throws IllegalMonitorStateException if this lock is not held
60.747 + * @throws IllegalArgumentException if the given condition is
60.748 + * not associated with this lock
60.749 + * @throws NullPointerException if the condition is null
60.750 + */
60.751 + protected Collection<Thread> getWaitingThreads(Condition condition) {
60.752 + if (condition == null)
60.753 + throw new NullPointerException();
60.754 + if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
60.755 + throw new IllegalArgumentException("not owner");
60.756 + return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
60.757 + }
60.758 +
60.759 + /**
60.760 + * Returns a string identifying this lock, as well as its lock state.
60.761 + * The state, in brackets, includes either the String {@code "Unlocked"}
60.762 + * or the String {@code "Locked by"} followed by the
60.763 + * {@linkplain Thread#getName name} of the owning thread.
60.764 + *
60.765 + * @return a string identifying this lock, as well as its lock state
60.766 + */
60.767 + public String toString() {
60.768 + Thread o = sync.getOwner();
60.769 + return super.toString() + ((o == null) ?
60.770 + "[Unlocked]" :
60.771 + "[Locked by thread " + o.getName() + "]");
60.772 + }
60.773 +}
61.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
61.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java Sat Mar 19 10:46:31 2016 +0100
61.3 @@ -0,0 +1,1486 @@
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 +package java.util.concurrent.locks;
61.40 +import java.util.concurrent.*;
61.41 +import java.util.concurrent.atomic.*;
61.42 +import java.util.*;
61.43 +
61.44 +/**
61.45 + * An implementation of {@link ReadWriteLock} supporting similar
61.46 + * semantics to {@link ReentrantLock}.
61.47 + * <p>This class has the following properties:
61.48 + *
61.49 + * <ul>
61.50 + * <li><b>Acquisition order</b>
61.51 + *
61.52 + * <p> This class does not impose a reader or writer preference
61.53 + * ordering for lock access. However, it does support an optional
61.54 + * <em>fairness</em> policy.
61.55 + *
61.56 + * <dl>
61.57 + * <dt><b><i>Non-fair mode (default)</i></b>
61.58 + * <dd>When constructed as non-fair (the default), the order of entry
61.59 + * to the read and write lock is unspecified, subject to reentrancy
61.60 + * constraints. A nonfair lock that is continuously contended may
61.61 + * indefinitely postpone one or more reader or writer threads, but
61.62 + * will normally have higher throughput than a fair lock.
61.63 + * <p>
61.64 + *
61.65 + * <dt><b><i>Fair mode</i></b>
61.66 + * <dd> When constructed as fair, threads contend for entry using an
61.67 + * approximately arrival-order policy. When the currently held lock
61.68 + * is released either the longest-waiting single writer thread will
61.69 + * be assigned the write lock, or if there is a group of reader threads
61.70 + * waiting longer than all waiting writer threads, that group will be
61.71 + * assigned the read lock.
61.72 + *
61.73 + * <p>A thread that tries to acquire a fair read lock (non-reentrantly)
61.74 + * will block if either the write lock is held, or there is a waiting
61.75 + * writer thread. The thread will not acquire the read lock until
61.76 + * after the oldest currently waiting writer thread has acquired and
61.77 + * released the write lock. Of course, if a waiting writer abandons
61.78 + * its wait, leaving one or more reader threads as the longest waiters
61.79 + * in the queue with the write lock free, then those readers will be
61.80 + * assigned the read lock.
61.81 + *
61.82 + * <p>A thread that tries to acquire a fair write lock (non-reentrantly)
61.83 + * will block unless both the read lock and write lock are free (which
61.84 + * implies there are no waiting threads). (Note that the non-blocking
61.85 + * {@link ReadLock#tryLock()} and {@link WriteLock#tryLock()} methods
61.86 + * do not honor this fair setting and will acquire the lock if it is
61.87 + * possible, regardless of waiting threads.)
61.88 + * <p>
61.89 + * </dl>
61.90 + *
61.91 + * <li><b>Reentrancy</b>
61.92 + *
61.93 + * <p>This lock allows both readers and writers to reacquire read or
61.94 + * write locks in the style of a {@link ReentrantLock}. Non-reentrant
61.95 + * readers are not allowed until all write locks held by the writing
61.96 + * thread have been released.
61.97 + *
61.98 + * <p>Additionally, a writer can acquire the read lock, but not
61.99 + * vice-versa. Among other applications, reentrancy can be useful
61.100 + * when write locks are held during calls or callbacks to methods that
61.101 + * perform reads under read locks. If a reader tries to acquire the
61.102 + * write lock it will never succeed.
61.103 + *
61.104 + * <li><b>Lock downgrading</b>
61.105 + * <p>Reentrancy also allows downgrading from the write lock to a read lock,
61.106 + * by acquiring the write lock, then the read lock and then releasing the
61.107 + * write lock. However, upgrading from a read lock to the write lock is
61.108 + * <b>not</b> possible.
61.109 + *
61.110 + * <li><b>Interruption of lock acquisition</b>
61.111 + * <p>The read lock and write lock both support interruption during lock
61.112 + * acquisition.
61.113 + *
61.114 + * <li><b>{@link Condition} support</b>
61.115 + * <p>The write lock provides a {@link Condition} implementation that
61.116 + * behaves in the same way, with respect to the write lock, as the
61.117 + * {@link Condition} implementation provided by
61.118 + * {@link ReentrantLock#newCondition} does for {@link ReentrantLock}.
61.119 + * This {@link Condition} can, of course, only be used with the write lock.
61.120 + *
61.121 + * <p>The read lock does not support a {@link Condition} and
61.122 + * {@code readLock().newCondition()} throws
61.123 + * {@code UnsupportedOperationException}.
61.124 + *
61.125 + * <li><b>Instrumentation</b>
61.126 + * <p>This class supports methods to determine whether locks
61.127 + * are held or contended. These methods are designed for monitoring
61.128 + * system state, not for synchronization control.
61.129 + * </ul>
61.130 + *
61.131 + * <p>Serialization of this class behaves in the same way as built-in
61.132 + * locks: a deserialized lock is in the unlocked state, regardless of
61.133 + * its state when serialized.
61.134 + *
61.135 + * <p><b>Sample usages</b>. Here is a code sketch showing how to perform
61.136 + * lock downgrading after updating a cache (exception handling is
61.137 + * particularly tricky when handling multiple locks in a non-nested
61.138 + * fashion):
61.139 + *
61.140 + * <pre> {@code
61.141 + * class CachedData {
61.142 + * Object data;
61.143 + * volatile boolean cacheValid;
61.144 + * final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
61.145 + *
61.146 + * void processCachedData() {
61.147 + * rwl.readLock().lock();
61.148 + * if (!cacheValid) {
61.149 + * // Must release read lock before acquiring write lock
61.150 + * rwl.readLock().unlock();
61.151 + * rwl.writeLock().lock();
61.152 + * try {
61.153 + * // Recheck state because another thread might have
61.154 + * // acquired write lock and changed state before we did.
61.155 + * if (!cacheValid) {
61.156 + * data = ...
61.157 + * cacheValid = true;
61.158 + * }
61.159 + * // Downgrade by acquiring read lock before releasing write lock
61.160 + * rwl.readLock().lock();
61.161 + * } finally {
61.162 + * rwl.writeLock().unlock(); // Unlock write, still hold read
61.163 + * }
61.164 + * }
61.165 + *
61.166 + * try {
61.167 + * use(data);
61.168 + * } finally {
61.169 + * rwl.readLock().unlock();
61.170 + * }
61.171 + * }
61.172 + * }}</pre>
61.173 + *
61.174 + * ReentrantReadWriteLocks can be used to improve concurrency in some
61.175 + * uses of some kinds of Collections. This is typically worthwhile
61.176 + * only when the collections are expected to be large, accessed by
61.177 + * more reader threads than writer threads, and entail operations with
61.178 + * overhead that outweighs synchronization overhead. For example, here
61.179 + * is a class using a TreeMap that is expected to be large and
61.180 + * concurrently accessed.
61.181 + *
61.182 + * <pre>{@code
61.183 + * class RWDictionary {
61.184 + * private final Map<String, Data> m = new TreeMap<String, Data>();
61.185 + * private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
61.186 + * private final Lock r = rwl.readLock();
61.187 + * private final Lock w = rwl.writeLock();
61.188 + *
61.189 + * public Data get(String key) {
61.190 + * r.lock();
61.191 + * try { return m.get(key); }
61.192 + * finally { r.unlock(); }
61.193 + * }
61.194 + * public String[] allKeys() {
61.195 + * r.lock();
61.196 + * try { return m.keySet().toArray(); }
61.197 + * finally { r.unlock(); }
61.198 + * }
61.199 + * public Data put(String key, Data value) {
61.200 + * w.lock();
61.201 + * try { return m.put(key, value); }
61.202 + * finally { w.unlock(); }
61.203 + * }
61.204 + * public void clear() {
61.205 + * w.lock();
61.206 + * try { m.clear(); }
61.207 + * finally { w.unlock(); }
61.208 + * }
61.209 + * }}</pre>
61.210 + *
61.211 + * <h3>Implementation Notes</h3>
61.212 + *
61.213 + * <p>This lock supports a maximum of 65535 recursive write locks
61.214 + * and 65535 read locks. Attempts to exceed these limits result in
61.215 + * {@link Error} throws from locking methods.
61.216 + *
61.217 + * @since 1.5
61.218 + * @author Doug Lea
61.219 + *
61.220 + */
61.221 +public class ReentrantReadWriteLock
61.222 + implements ReadWriteLock, java.io.Serializable {
61.223 + private static final long serialVersionUID = -6992448646407690164L;
61.224 + /** Inner class providing readlock */
61.225 + private final ReentrantReadWriteLock.ReadLock readerLock;
61.226 + /** Inner class providing writelock */
61.227 + private final ReentrantReadWriteLock.WriteLock writerLock;
61.228 + /** Performs all synchronization mechanics */
61.229 + final Sync sync;
61.230 +
61.231 + /**
61.232 + * Creates a new {@code ReentrantReadWriteLock} with
61.233 + * default (nonfair) ordering properties.
61.234 + */
61.235 + public ReentrantReadWriteLock() {
61.236 + this(false);
61.237 + }
61.238 +
61.239 + /**
61.240 + * Creates a new {@code ReentrantReadWriteLock} with
61.241 + * the given fairness policy.
61.242 + *
61.243 + * @param fair {@code true} if this lock should use a fair ordering policy
61.244 + */
61.245 + public ReentrantReadWriteLock(boolean fair) {
61.246 + sync = fair ? new FairSync() : new NonfairSync();
61.247 + readerLock = new ReadLock(this);
61.248 + writerLock = new WriteLock(this);
61.249 + }
61.250 +
61.251 + public ReentrantReadWriteLock.WriteLock writeLock() { return writerLock; }
61.252 + public ReentrantReadWriteLock.ReadLock readLock() { return readerLock; }
61.253 +
61.254 + /**
61.255 + * Synchronization implementation for ReentrantReadWriteLock.
61.256 + * Subclassed into fair and nonfair versions.
61.257 + */
61.258 + abstract static class Sync extends AbstractQueuedSynchronizer {
61.259 + private static final long serialVersionUID = 6317671515068378041L;
61.260 +
61.261 + /*
61.262 + * Read vs write count extraction constants and functions.
61.263 + * Lock state is logically divided into two unsigned shorts:
61.264 + * The lower one representing the exclusive (writer) lock hold count,
61.265 + * and the upper the shared (reader) hold count.
61.266 + */
61.267 +
61.268 + static final int SHARED_SHIFT = 16;
61.269 + static final int SHARED_UNIT = (1 << SHARED_SHIFT);
61.270 + static final int MAX_COUNT = (1 << SHARED_SHIFT) - 1;
61.271 + static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1;
61.272 +
61.273 + /** Returns the number of shared holds represented in count */
61.274 + static int sharedCount(int c) { return c >>> SHARED_SHIFT; }
61.275 + /** Returns the number of exclusive holds represented in count */
61.276 + static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; }
61.277 +
61.278 + /**
61.279 + * A counter for per-thread read hold counts.
61.280 + * Maintained as a ThreadLocal; cached in cachedHoldCounter
61.281 + */
61.282 + static final class HoldCounter {
61.283 + int count = 0;
61.284 + // Use id, not reference, to avoid garbage retention
61.285 + final long tid = Thread.currentThread().getId();
61.286 + }
61.287 +
61.288 + /**
61.289 + * ThreadLocal subclass. Easiest to explicitly define for sake
61.290 + * of deserialization mechanics.
61.291 + */
61.292 + static final class ThreadLocalHoldCounter
61.293 + extends ThreadLocal<HoldCounter> {
61.294 + public HoldCounter initialValue() {
61.295 + return new HoldCounter();
61.296 + }
61.297 + }
61.298 +
61.299 + /**
61.300 + * The number of reentrant read locks held by current thread.
61.301 + * Initialized only in constructor and readObject.
61.302 + * Removed whenever a thread's read hold count drops to 0.
61.303 + */
61.304 + private transient ThreadLocalHoldCounter readHolds;
61.305 +
61.306 + /**
61.307 + * The hold count of the last thread to successfully acquire
61.308 + * readLock. This saves ThreadLocal lookup in the common case
61.309 + * where the next thread to release is the last one to
61.310 + * acquire. This is non-volatile since it is just used
61.311 + * as a heuristic, and would be great for threads to cache.
61.312 + *
61.313 + * <p>Can outlive the Thread for which it is caching the read
61.314 + * hold count, but avoids garbage retention by not retaining a
61.315 + * reference to the Thread.
61.316 + *
61.317 + * <p>Accessed via a benign data race; relies on the memory
61.318 + * model's final field and out-of-thin-air guarantees.
61.319 + */
61.320 + private transient HoldCounter cachedHoldCounter;
61.321 +
61.322 + /**
61.323 + * firstReader is the first thread to have acquired the read lock.
61.324 + * firstReaderHoldCount is firstReader's hold count.
61.325 + *
61.326 + * <p>More precisely, firstReader is the unique thread that last
61.327 + * changed the shared count from 0 to 1, and has not released the
61.328 + * read lock since then; null if there is no such thread.
61.329 + *
61.330 + * <p>Cannot cause garbage retention unless the thread terminated
61.331 + * without relinquishing its read locks, since tryReleaseShared
61.332 + * sets it to null.
61.333 + *
61.334 + * <p>Accessed via a benign data race; relies on the memory
61.335 + * model's out-of-thin-air guarantees for references.
61.336 + *
61.337 + * <p>This allows tracking of read holds for uncontended read
61.338 + * locks to be very cheap.
61.339 + */
61.340 + private transient Thread firstReader = null;
61.341 + private transient int firstReaderHoldCount;
61.342 +
61.343 + Sync() {
61.344 + readHolds = new ThreadLocalHoldCounter();
61.345 + setState(getState()); // ensures visibility of readHolds
61.346 + }
61.347 +
61.348 + /*
61.349 + * Acquires and releases use the same code for fair and
61.350 + * nonfair locks, but differ in whether/how they allow barging
61.351 + * when queues are non-empty.
61.352 + */
61.353 +
61.354 + /**
61.355 + * Returns true if the current thread, when trying to acquire
61.356 + * the read lock, and otherwise eligible to do so, should block
61.357 + * because of policy for overtaking other waiting threads.
61.358 + */
61.359 + abstract boolean readerShouldBlock();
61.360 +
61.361 + /**
61.362 + * Returns true if the current thread, when trying to acquire
61.363 + * the write lock, and otherwise eligible to do so, should block
61.364 + * because of policy for overtaking other waiting threads.
61.365 + */
61.366 + abstract boolean writerShouldBlock();
61.367 +
61.368 + /*
61.369 + * Note that tryRelease and tryAcquire can be called by
61.370 + * Conditions. So it is possible that their arguments contain
61.371 + * both read and write holds that are all released during a
61.372 + * condition wait and re-established in tryAcquire.
61.373 + */
61.374 +
61.375 + protected final boolean tryRelease(int releases) {
61.376 + if (!isHeldExclusively())
61.377 + throw new IllegalMonitorStateException();
61.378 + int nextc = getState() - releases;
61.379 + boolean free = exclusiveCount(nextc) == 0;
61.380 + if (free)
61.381 + setExclusiveOwnerThread(null);
61.382 + setState(nextc);
61.383 + return free;
61.384 + }
61.385 +
61.386 + protected final boolean tryAcquire(int acquires) {
61.387 + /*
61.388 + * Walkthrough:
61.389 + * 1. If read count nonzero or write count nonzero
61.390 + * and owner is a different thread, fail.
61.391 + * 2. If count would saturate, fail. (This can only
61.392 + * happen if count is already nonzero.)
61.393 + * 3. Otherwise, this thread is eligible for lock if
61.394 + * it is either a reentrant acquire or
61.395 + * queue policy allows it. If so, update state
61.396 + * and set owner.
61.397 + */
61.398 + Thread current = Thread.currentThread();
61.399 + int c = getState();
61.400 + int w = exclusiveCount(c);
61.401 + if (c != 0) {
61.402 + // (Note: if c != 0 and w == 0 then shared count != 0)
61.403 + if (w == 0 || current != getExclusiveOwnerThread())
61.404 + return false;
61.405 + if (w + exclusiveCount(acquires) > MAX_COUNT)
61.406 + throw new Error("Maximum lock count exceeded");
61.407 + // Reentrant acquire
61.408 + setState(c + acquires);
61.409 + return true;
61.410 + }
61.411 + if (writerShouldBlock() ||
61.412 + !compareAndSetState(c, c + acquires))
61.413 + return false;
61.414 + setExclusiveOwnerThread(current);
61.415 + return true;
61.416 + }
61.417 +
61.418 + protected final boolean tryReleaseShared(int unused) {
61.419 + Thread current = Thread.currentThread();
61.420 + if (firstReader == current) {
61.421 + // assert firstReaderHoldCount > 0;
61.422 + if (firstReaderHoldCount == 1)
61.423 + firstReader = null;
61.424 + else
61.425 + firstReaderHoldCount--;
61.426 + } else {
61.427 + HoldCounter rh = cachedHoldCounter;
61.428 + if (rh == null || rh.tid != current.getId())
61.429 + rh = readHolds.get();
61.430 + int count = rh.count;
61.431 + if (count <= 1) {
61.432 + readHolds.remove();
61.433 + if (count <= 0)
61.434 + throw unmatchedUnlockException();
61.435 + }
61.436 + --rh.count;
61.437 + }
61.438 + for (;;) {
61.439 + int c = getState();
61.440 + int nextc = c - SHARED_UNIT;
61.441 + if (compareAndSetState(c, nextc))
61.442 + // Releasing the read lock has no effect on readers,
61.443 + // but it may allow waiting writers to proceed if
61.444 + // both read and write locks are now free.
61.445 + return nextc == 0;
61.446 + }
61.447 + }
61.448 +
61.449 + private IllegalMonitorStateException unmatchedUnlockException() {
61.450 + return new IllegalMonitorStateException(
61.451 + "attempt to unlock read lock, not locked by current thread");
61.452 + }
61.453 +
61.454 + protected final int tryAcquireShared(int unused) {
61.455 + /*
61.456 + * Walkthrough:
61.457 + * 1. If write lock held by another thread, fail.
61.458 + * 2. Otherwise, this thread is eligible for
61.459 + * lock wrt state, so ask if it should block
61.460 + * because of queue policy. If not, try
61.461 + * to grant by CASing state and updating count.
61.462 + * Note that step does not check for reentrant
61.463 + * acquires, which is postponed to full version
61.464 + * to avoid having to check hold count in
61.465 + * the more typical non-reentrant case.
61.466 + * 3. If step 2 fails either because thread
61.467 + * apparently not eligible or CAS fails or count
61.468 + * saturated, chain to version with full retry loop.
61.469 + */
61.470 + Thread current = Thread.currentThread();
61.471 + int c = getState();
61.472 + if (exclusiveCount(c) != 0 &&
61.473 + getExclusiveOwnerThread() != current)
61.474 + return -1;
61.475 + int r = sharedCount(c);
61.476 + if (!readerShouldBlock() &&
61.477 + r < MAX_COUNT &&
61.478 + compareAndSetState(c, c + SHARED_UNIT)) {
61.479 + if (r == 0) {
61.480 + firstReader = current;
61.481 + firstReaderHoldCount = 1;
61.482 + } else if (firstReader == current) {
61.483 + firstReaderHoldCount++;
61.484 + } else {
61.485 + HoldCounter rh = cachedHoldCounter;
61.486 + if (rh == null || rh.tid != current.getId())
61.487 + cachedHoldCounter = rh = readHolds.get();
61.488 + else if (rh.count == 0)
61.489 + readHolds.set(rh);
61.490 + rh.count++;
61.491 + }
61.492 + return 1;
61.493 + }
61.494 + return fullTryAcquireShared(current);
61.495 + }
61.496 +
61.497 + /**
61.498 + * Full version of acquire for reads, that handles CAS misses
61.499 + * and reentrant reads not dealt with in tryAcquireShared.
61.500 + */
61.501 + final int fullTryAcquireShared(Thread current) {
61.502 + /*
61.503 + * This code is in part redundant with that in
61.504 + * tryAcquireShared but is simpler overall by not
61.505 + * complicating tryAcquireShared with interactions between
61.506 + * retries and lazily reading hold counts.
61.507 + */
61.508 + HoldCounter rh = null;
61.509 + for (;;) {
61.510 + int c = getState();
61.511 + if (exclusiveCount(c) != 0) {
61.512 + if (getExclusiveOwnerThread() != current)
61.513 + return -1;
61.514 + // else we hold the exclusive lock; blocking here
61.515 + // would cause deadlock.
61.516 + } else if (readerShouldBlock()) {
61.517 + // Make sure we're not acquiring read lock reentrantly
61.518 + if (firstReader == current) {
61.519 + // assert firstReaderHoldCount > 0;
61.520 + } else {
61.521 + if (rh == null) {
61.522 + rh = cachedHoldCounter;
61.523 + if (rh == null || rh.tid != current.getId()) {
61.524 + rh = readHolds.get();
61.525 + if (rh.count == 0)
61.526 + readHolds.remove();
61.527 + }
61.528 + }
61.529 + if (rh.count == 0)
61.530 + return -1;
61.531 + }
61.532 + }
61.533 + if (sharedCount(c) == MAX_COUNT)
61.534 + throw new Error("Maximum lock count exceeded");
61.535 + if (compareAndSetState(c, c + SHARED_UNIT)) {
61.536 + if (sharedCount(c) == 0) {
61.537 + firstReader = current;
61.538 + firstReaderHoldCount = 1;
61.539 + } else if (firstReader == current) {
61.540 + firstReaderHoldCount++;
61.541 + } else {
61.542 + if (rh == null)
61.543 + rh = cachedHoldCounter;
61.544 + if (rh == null || rh.tid != current.getId())
61.545 + rh = readHolds.get();
61.546 + else if (rh.count == 0)
61.547 + readHolds.set(rh);
61.548 + rh.count++;
61.549 + cachedHoldCounter = rh; // cache for release
61.550 + }
61.551 + return 1;
61.552 + }
61.553 + }
61.554 + }
61.555 +
61.556 + /**
61.557 + * Performs tryLock for write, enabling barging in both modes.
61.558 + * This is identical in effect to tryAcquire except for lack
61.559 + * of calls to writerShouldBlock.
61.560 + */
61.561 + final boolean tryWriteLock() {
61.562 + Thread current = Thread.currentThread();
61.563 + int c = getState();
61.564 + if (c != 0) {
61.565 + int w = exclusiveCount(c);
61.566 + if (w == 0 || current != getExclusiveOwnerThread())
61.567 + return false;
61.568 + if (w == MAX_COUNT)
61.569 + throw new Error("Maximum lock count exceeded");
61.570 + }
61.571 + if (!compareAndSetState(c, c + 1))
61.572 + return false;
61.573 + setExclusiveOwnerThread(current);
61.574 + return true;
61.575 + }
61.576 +
61.577 + /**
61.578 + * Performs tryLock for read, enabling barging in both modes.
61.579 + * This is identical in effect to tryAcquireShared except for
61.580 + * lack of calls to readerShouldBlock.
61.581 + */
61.582 + final boolean tryReadLock() {
61.583 + Thread current = Thread.currentThread();
61.584 + for (;;) {
61.585 + int c = getState();
61.586 + if (exclusiveCount(c) != 0 &&
61.587 + getExclusiveOwnerThread() != current)
61.588 + return false;
61.589 + int r = sharedCount(c);
61.590 + if (r == MAX_COUNT)
61.591 + throw new Error("Maximum lock count exceeded");
61.592 + if (compareAndSetState(c, c + SHARED_UNIT)) {
61.593 + if (r == 0) {
61.594 + firstReader = current;
61.595 + firstReaderHoldCount = 1;
61.596 + } else if (firstReader == current) {
61.597 + firstReaderHoldCount++;
61.598 + } else {
61.599 + HoldCounter rh = cachedHoldCounter;
61.600 + if (rh == null || rh.tid != current.getId())
61.601 + cachedHoldCounter = rh = readHolds.get();
61.602 + else if (rh.count == 0)
61.603 + readHolds.set(rh);
61.604 + rh.count++;
61.605 + }
61.606 + return true;
61.607 + }
61.608 + }
61.609 + }
61.610 +
61.611 + protected final boolean isHeldExclusively() {
61.612 + // While we must in general read state before owner,
61.613 + // we don't need to do so to check if current thread is owner
61.614 + return getExclusiveOwnerThread() == Thread.currentThread();
61.615 + }
61.616 +
61.617 + // Methods relayed to outer class
61.618 +
61.619 + final ConditionObject newCondition() {
61.620 + return new ConditionObject();
61.621 + }
61.622 +
61.623 + final Thread getOwner() {
61.624 + // Must read state before owner to ensure memory consistency
61.625 + return ((exclusiveCount(getState()) == 0) ?
61.626 + null :
61.627 + getExclusiveOwnerThread());
61.628 + }
61.629 +
61.630 + final int getReadLockCount() {
61.631 + return sharedCount(getState());
61.632 + }
61.633 +
61.634 + final boolean isWriteLocked() {
61.635 + return exclusiveCount(getState()) != 0;
61.636 + }
61.637 +
61.638 + final int getWriteHoldCount() {
61.639 + return isHeldExclusively() ? exclusiveCount(getState()) : 0;
61.640 + }
61.641 +
61.642 + final int getReadHoldCount() {
61.643 + if (getReadLockCount() == 0)
61.644 + return 0;
61.645 +
61.646 + Thread current = Thread.currentThread();
61.647 + if (firstReader == current)
61.648 + return firstReaderHoldCount;
61.649 +
61.650 + HoldCounter rh = cachedHoldCounter;
61.651 + if (rh != null && rh.tid == current.getId())
61.652 + return rh.count;
61.653 +
61.654 + int count = readHolds.get().count;
61.655 + if (count == 0) readHolds.remove();
61.656 + return count;
61.657 + }
61.658 +
61.659 + /**
61.660 + * Reconstitute this lock instance from a stream
61.661 + * @param s the stream
61.662 + */
61.663 + private void readObject(java.io.ObjectInputStream s)
61.664 + throws java.io.IOException, ClassNotFoundException {
61.665 + s.defaultReadObject();
61.666 + readHolds = new ThreadLocalHoldCounter();
61.667 + setState(0); // reset to unlocked state
61.668 + }
61.669 +
61.670 + final int getCount() { return getState(); }
61.671 + }
61.672 +
61.673 + /**
61.674 + * Nonfair version of Sync
61.675 + */
61.676 + static final class NonfairSync extends Sync {
61.677 + private static final long serialVersionUID = -8159625535654395037L;
61.678 + final boolean writerShouldBlock() {
61.679 + return false; // writers can always barge
61.680 + }
61.681 + final boolean readerShouldBlock() {
61.682 + /* As a heuristic to avoid indefinite writer starvation,
61.683 + * block if the thread that momentarily appears to be head
61.684 + * of queue, if one exists, is a waiting writer. This is
61.685 + * only a probabilistic effect since a new reader will not
61.686 + * block if there is a waiting writer behind other enabled
61.687 + * readers that have not yet drained from the queue.
61.688 + */
61.689 + return apparentlyFirstQueuedIsExclusive();
61.690 + }
61.691 + }
61.692 +
61.693 + /**
61.694 + * Fair version of Sync
61.695 + */
61.696 + static final class FairSync extends Sync {
61.697 + private static final long serialVersionUID = -2274990926593161451L;
61.698 + final boolean writerShouldBlock() {
61.699 + return hasQueuedPredecessors();
61.700 + }
61.701 + final boolean readerShouldBlock() {
61.702 + return hasQueuedPredecessors();
61.703 + }
61.704 + }
61.705 +
61.706 + /**
61.707 + * The lock returned by method {@link ReentrantReadWriteLock#readLock}.
61.708 + */
61.709 + public static class ReadLock implements Lock, java.io.Serializable {
61.710 + private static final long serialVersionUID = -5992448646407690164L;
61.711 + private final Sync sync;
61.712 +
61.713 + /**
61.714 + * Constructor for use by subclasses
61.715 + *
61.716 + * @param lock the outer lock object
61.717 + * @throws NullPointerException if the lock is null
61.718 + */
61.719 + protected ReadLock(ReentrantReadWriteLock lock) {
61.720 + sync = lock.sync;
61.721 + }
61.722 +
61.723 + /**
61.724 + * Acquires the read lock.
61.725 + *
61.726 + * <p>Acquires the read lock if the write lock is not held by
61.727 + * another thread and returns immediately.
61.728 + *
61.729 + * <p>If the write lock is held by another thread then
61.730 + * the current thread becomes disabled for thread scheduling
61.731 + * purposes and lies dormant until the read lock has been acquired.
61.732 + */
61.733 + public void lock() {
61.734 + sync.acquireShared(1);
61.735 + }
61.736 +
61.737 + /**
61.738 + * Acquires the read lock unless the current thread is
61.739 + * {@linkplain Thread#interrupt interrupted}.
61.740 + *
61.741 + * <p>Acquires the read lock if the write lock is not held
61.742 + * by another thread and returns immediately.
61.743 + *
61.744 + * <p>If the write lock is held by another thread then the
61.745 + * current thread becomes disabled for thread scheduling
61.746 + * purposes and lies dormant until one of two things happens:
61.747 + *
61.748 + * <ul>
61.749 + *
61.750 + * <li>The read lock is acquired by the current thread; or
61.751 + *
61.752 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
61.753 + * the current thread.
61.754 + *
61.755 + * </ul>
61.756 + *
61.757 + * <p>If the current thread:
61.758 + *
61.759 + * <ul>
61.760 + *
61.761 + * <li>has its interrupted status set on entry to this method; or
61.762 + *
61.763 + * <li>is {@linkplain Thread#interrupt interrupted} while
61.764 + * acquiring the read lock,
61.765 + *
61.766 + * </ul>
61.767 + *
61.768 + * then {@link InterruptedException} is thrown and the current
61.769 + * thread's interrupted status is cleared.
61.770 + *
61.771 + * <p>In this implementation, as this method is an explicit
61.772 + * interruption point, preference is given to responding to
61.773 + * the interrupt over normal or reentrant acquisition of the
61.774 + * lock.
61.775 + *
61.776 + * @throws InterruptedException if the current thread is interrupted
61.777 + */
61.778 + public void lockInterruptibly() throws InterruptedException {
61.779 + sync.acquireSharedInterruptibly(1);
61.780 + }
61.781 +
61.782 + /**
61.783 + * Acquires the read lock only if the write lock is not held by
61.784 + * another thread at the time of invocation.
61.785 + *
61.786 + * <p>Acquires the read lock if the write lock is not held by
61.787 + * another thread and returns immediately with the value
61.788 + * {@code true}. Even when this lock has been set to use a
61.789 + * fair ordering policy, a call to {@code tryLock()}
61.790 + * <em>will</em> immediately acquire the read lock if it is
61.791 + * available, whether or not other threads are currently
61.792 + * waiting for the read lock. This "barging" behavior
61.793 + * can be useful in certain circumstances, even though it
61.794 + * breaks fairness. If you want to honor the fairness setting
61.795 + * for this lock, then use {@link #tryLock(long, TimeUnit)
61.796 + * tryLock(0, TimeUnit.SECONDS) } which is almost equivalent
61.797 + * (it also detects interruption).
61.798 + *
61.799 + * <p>If the write lock is held by another thread then
61.800 + * this method will return immediately with the value
61.801 + * {@code false}.
61.802 + *
61.803 + * @return {@code true} if the read lock was acquired
61.804 + */
61.805 + public boolean tryLock() {
61.806 + return sync.tryReadLock();
61.807 + }
61.808 +
61.809 + /**
61.810 + * Acquires the read lock if the write lock is not held by
61.811 + * another thread within the given waiting time and the
61.812 + * current thread has not been {@linkplain Thread#interrupt
61.813 + * interrupted}.
61.814 + *
61.815 + * <p>Acquires the read lock if the write lock is not held by
61.816 + * another thread and returns immediately with the value
61.817 + * {@code true}. If this lock has been set to use a fair
61.818 + * ordering policy then an available lock <em>will not</em> be
61.819 + * acquired if any other threads are waiting for the
61.820 + * lock. This is in contrast to the {@link #tryLock()}
61.821 + * method. If you want a timed {@code tryLock} that does
61.822 + * permit barging on a fair lock then combine the timed and
61.823 + * un-timed forms together:
61.824 + *
61.825 + * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
61.826 + * </pre>
61.827 + *
61.828 + * <p>If the write lock is held by another thread then the
61.829 + * current thread becomes disabled for thread scheduling
61.830 + * purposes and lies dormant until one of three things happens:
61.831 + *
61.832 + * <ul>
61.833 + *
61.834 + * <li>The read lock is acquired by the current thread; or
61.835 + *
61.836 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
61.837 + * the current thread; or
61.838 + *
61.839 + * <li>The specified waiting time elapses.
61.840 + *
61.841 + * </ul>
61.842 + *
61.843 + * <p>If the read lock is acquired then the value {@code true} is
61.844 + * returned.
61.845 + *
61.846 + * <p>If the current thread:
61.847 + *
61.848 + * <ul>
61.849 + *
61.850 + * <li>has its interrupted status set on entry to this method; or
61.851 + *
61.852 + * <li>is {@linkplain Thread#interrupt interrupted} while
61.853 + * acquiring the read lock,
61.854 + *
61.855 + * </ul> then {@link InterruptedException} is thrown and the
61.856 + * current thread's interrupted status is cleared.
61.857 + *
61.858 + * <p>If the specified waiting time elapses then the value
61.859 + * {@code false} is returned. If the time is less than or
61.860 + * equal to zero, the method will not wait at all.
61.861 + *
61.862 + * <p>In this implementation, as this method is an explicit
61.863 + * interruption point, preference is given to responding to
61.864 + * the interrupt over normal or reentrant acquisition of the
61.865 + * lock, and over reporting the elapse of the waiting time.
61.866 + *
61.867 + * @param timeout the time to wait for the read lock
61.868 + * @param unit the time unit of the timeout argument
61.869 + * @return {@code true} if the read lock was acquired
61.870 + * @throws InterruptedException if the current thread is interrupted
61.871 + * @throws NullPointerException if the time unit is null
61.872 + *
61.873 + */
61.874 + public boolean tryLock(long timeout, TimeUnit unit)
61.875 + throws InterruptedException {
61.876 + return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
61.877 + }
61.878 +
61.879 + /**
61.880 + * Attempts to release this lock.
61.881 + *
61.882 + * <p> If the number of readers is now zero then the lock
61.883 + * is made available for write lock attempts.
61.884 + */
61.885 + public void unlock() {
61.886 + sync.releaseShared(1);
61.887 + }
61.888 +
61.889 + /**
61.890 + * Throws {@code UnsupportedOperationException} because
61.891 + * {@code ReadLocks} do not support conditions.
61.892 + *
61.893 + * @throws UnsupportedOperationException always
61.894 + */
61.895 + public Condition newCondition() {
61.896 + throw new UnsupportedOperationException();
61.897 + }
61.898 +
61.899 + /**
61.900 + * Returns a string identifying this lock, as well as its lock state.
61.901 + * The state, in brackets, includes the String {@code "Read locks ="}
61.902 + * followed by the number of held read locks.
61.903 + *
61.904 + * @return a string identifying this lock, as well as its lock state
61.905 + */
61.906 + public String toString() {
61.907 + int r = sync.getReadLockCount();
61.908 + return super.toString() +
61.909 + "[Read locks = " + r + "]";
61.910 + }
61.911 + }
61.912 +
61.913 + /**
61.914 + * The lock returned by method {@link ReentrantReadWriteLock#writeLock}.
61.915 + */
61.916 + public static class WriteLock implements Lock, java.io.Serializable {
61.917 + private static final long serialVersionUID = -4992448646407690164L;
61.918 + private final Sync sync;
61.919 +
61.920 + /**
61.921 + * Constructor for use by subclasses
61.922 + *
61.923 + * @param lock the outer lock object
61.924 + * @throws NullPointerException if the lock is null
61.925 + */
61.926 + protected WriteLock(ReentrantReadWriteLock lock) {
61.927 + sync = lock.sync;
61.928 + }
61.929 +
61.930 + /**
61.931 + * Acquires the write lock.
61.932 + *
61.933 + * <p>Acquires the write lock if neither the read nor write lock
61.934 + * are held by another thread
61.935 + * and returns immediately, setting the write lock hold count to
61.936 + * one.
61.937 + *
61.938 + * <p>If the current thread already holds the write lock then the
61.939 + * hold count is incremented by one and the method returns
61.940 + * immediately.
61.941 + *
61.942 + * <p>If the lock is held by another thread then the current
61.943 + * thread becomes disabled for thread scheduling purposes and
61.944 + * lies dormant until the write lock has been acquired, at which
61.945 + * time the write lock hold count is set to one.
61.946 + */
61.947 + public void lock() {
61.948 + sync.acquire(1);
61.949 + }
61.950 +
61.951 + /**
61.952 + * Acquires the write lock unless the current thread is
61.953 + * {@linkplain Thread#interrupt interrupted}.
61.954 + *
61.955 + * <p>Acquires the write lock if neither the read nor write lock
61.956 + * are held by another thread
61.957 + * and returns immediately, setting the write lock hold count to
61.958 + * one.
61.959 + *
61.960 + * <p>If the current thread already holds this lock then the
61.961 + * hold count is incremented by one and the method returns
61.962 + * immediately.
61.963 + *
61.964 + * <p>If the lock is held by another thread then the current
61.965 + * thread becomes disabled for thread scheduling purposes and
61.966 + * lies dormant until one of two things happens:
61.967 + *
61.968 + * <ul>
61.969 + *
61.970 + * <li>The write lock is acquired by the current thread; or
61.971 + *
61.972 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
61.973 + * the current thread.
61.974 + *
61.975 + * </ul>
61.976 + *
61.977 + * <p>If the write lock is acquired by the current thread then the
61.978 + * lock hold count is set to one.
61.979 + *
61.980 + * <p>If the current thread:
61.981 + *
61.982 + * <ul>
61.983 + *
61.984 + * <li>has its interrupted status set on entry to this method;
61.985 + * or
61.986 + *
61.987 + * <li>is {@linkplain Thread#interrupt interrupted} while
61.988 + * acquiring the write lock,
61.989 + *
61.990 + * </ul>
61.991 + *
61.992 + * then {@link InterruptedException} is thrown and the current
61.993 + * thread's interrupted status is cleared.
61.994 + *
61.995 + * <p>In this implementation, as this method is an explicit
61.996 + * interruption point, preference is given to responding to
61.997 + * the interrupt over normal or reentrant acquisition of the
61.998 + * lock.
61.999 + *
61.1000 + * @throws InterruptedException if the current thread is interrupted
61.1001 + */
61.1002 + public void lockInterruptibly() throws InterruptedException {
61.1003 + sync.acquireInterruptibly(1);
61.1004 + }
61.1005 +
61.1006 + /**
61.1007 + * Acquires the write lock only if it is not held by another thread
61.1008 + * at the time of invocation.
61.1009 + *
61.1010 + * <p>Acquires the write lock if neither the read nor write lock
61.1011 + * are held by another thread
61.1012 + * and returns immediately with the value {@code true},
61.1013 + * setting the write lock hold count to one. Even when this lock has
61.1014 + * been set to use a fair ordering policy, a call to
61.1015 + * {@code tryLock()} <em>will</em> immediately acquire the
61.1016 + * lock if it is available, whether or not other threads are
61.1017 + * currently waiting for the write lock. This "barging"
61.1018 + * behavior can be useful in certain circumstances, even
61.1019 + * though it breaks fairness. If you want to honor the
61.1020 + * fairness setting for this lock, then use {@link
61.1021 + * #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) }
61.1022 + * which is almost equivalent (it also detects interruption).
61.1023 + *
61.1024 + * <p> If the current thread already holds this lock then the
61.1025 + * hold count is incremented by one and the method returns
61.1026 + * {@code true}.
61.1027 + *
61.1028 + * <p>If the lock is held by another thread then this method
61.1029 + * will return immediately with the value {@code false}.
61.1030 + *
61.1031 + * @return {@code true} if the lock was free and was acquired
61.1032 + * by the current thread, or the write lock was already held
61.1033 + * by the current thread; and {@code false} otherwise.
61.1034 + */
61.1035 + public boolean tryLock( ) {
61.1036 + return sync.tryWriteLock();
61.1037 + }
61.1038 +
61.1039 + /**
61.1040 + * Acquires the write lock if it is not held by another thread
61.1041 + * within the given waiting time and the current thread has
61.1042 + * not been {@linkplain Thread#interrupt interrupted}.
61.1043 + *
61.1044 + * <p>Acquires the write lock if neither the read nor write lock
61.1045 + * are held by another thread
61.1046 + * and returns immediately with the value {@code true},
61.1047 + * setting the write lock hold count to one. If this lock has been
61.1048 + * set to use a fair ordering policy then an available lock
61.1049 + * <em>will not</em> be acquired if any other threads are
61.1050 + * waiting for the write lock. This is in contrast to the {@link
61.1051 + * #tryLock()} method. If you want a timed {@code tryLock}
61.1052 + * that does permit barging on a fair lock then combine the
61.1053 + * timed and un-timed forms together:
61.1054 + *
61.1055 + * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
61.1056 + * </pre>
61.1057 + *
61.1058 + * <p>If the current thread already holds this lock then the
61.1059 + * hold count is incremented by one and the method returns
61.1060 + * {@code true}.
61.1061 + *
61.1062 + * <p>If the lock is held by another thread then the current
61.1063 + * thread becomes disabled for thread scheduling purposes and
61.1064 + * lies dormant until one of three things happens:
61.1065 + *
61.1066 + * <ul>
61.1067 + *
61.1068 + * <li>The write lock is acquired by the current thread; or
61.1069 + *
61.1070 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
61.1071 + * the current thread; or
61.1072 + *
61.1073 + * <li>The specified waiting time elapses
61.1074 + *
61.1075 + * </ul>
61.1076 + *
61.1077 + * <p>If the write lock is acquired then the value {@code true} is
61.1078 + * returned and the write lock hold count is set to one.
61.1079 + *
61.1080 + * <p>If the current thread:
61.1081 + *
61.1082 + * <ul>
61.1083 + *
61.1084 + * <li>has its interrupted status set on entry to this method;
61.1085 + * or
61.1086 + *
61.1087 + * <li>is {@linkplain Thread#interrupt interrupted} while
61.1088 + * acquiring the write lock,
61.1089 + *
61.1090 + * </ul>
61.1091 + *
61.1092 + * then {@link InterruptedException} is thrown and the current
61.1093 + * thread's interrupted status is cleared.
61.1094 + *
61.1095 + * <p>If the specified waiting time elapses then the value
61.1096 + * {@code false} is returned. If the time is less than or
61.1097 + * equal to zero, the method will not wait at all.
61.1098 + *
61.1099 + * <p>In this implementation, as this method is an explicit
61.1100 + * interruption point, preference is given to responding to
61.1101 + * the interrupt over normal or reentrant acquisition of the
61.1102 + * lock, and over reporting the elapse of the waiting time.
61.1103 + *
61.1104 + * @param timeout the time to wait for the write lock
61.1105 + * @param unit the time unit of the timeout argument
61.1106 + *
61.1107 + * @return {@code true} if the lock was free and was acquired
61.1108 + * by the current thread, or the write lock was already held by the
61.1109 + * current thread; and {@code false} if the waiting time
61.1110 + * elapsed before the lock could be acquired.
61.1111 + *
61.1112 + * @throws InterruptedException if the current thread is interrupted
61.1113 + * @throws NullPointerException if the time unit is null
61.1114 + *
61.1115 + */
61.1116 + public boolean tryLock(long timeout, TimeUnit unit)
61.1117 + throws InterruptedException {
61.1118 + return sync.tryAcquireNanos(1, unit.toNanos(timeout));
61.1119 + }
61.1120 +
61.1121 + /**
61.1122 + * Attempts to release this lock.
61.1123 + *
61.1124 + * <p>If the current thread is the holder of this lock then
61.1125 + * the hold count is decremented. If the hold count is now
61.1126 + * zero then the lock is released. If the current thread is
61.1127 + * not the holder of this lock then {@link
61.1128 + * IllegalMonitorStateException} is thrown.
61.1129 + *
61.1130 + * @throws IllegalMonitorStateException if the current thread does not
61.1131 + * hold this lock.
61.1132 + */
61.1133 + public void unlock() {
61.1134 + sync.release(1);
61.1135 + }
61.1136 +
61.1137 + /**
61.1138 + * Returns a {@link Condition} instance for use with this
61.1139 + * {@link Lock} instance.
61.1140 + * <p>The returned {@link Condition} instance supports the same
61.1141 + * usages as do the {@link Object} monitor methods ({@link
61.1142 + * Object#wait() wait}, {@link Object#notify notify}, and {@link
61.1143 + * Object#notifyAll notifyAll}) when used with the built-in
61.1144 + * monitor lock.
61.1145 + *
61.1146 + * <ul>
61.1147 + *
61.1148 + * <li>If this write lock is not held when any {@link
61.1149 + * Condition} method is called then an {@link
61.1150 + * IllegalMonitorStateException} is thrown. (Read locks are
61.1151 + * held independently of write locks, so are not checked or
61.1152 + * affected. However it is essentially always an error to
61.1153 + * invoke a condition waiting method when the current thread
61.1154 + * has also acquired read locks, since other threads that
61.1155 + * could unblock it will not be able to acquire the write
61.1156 + * lock.)
61.1157 + *
61.1158 + * <li>When the condition {@linkplain Condition#await() waiting}
61.1159 + * methods are called the write lock is released and, before
61.1160 + * they return, the write lock is reacquired and the lock hold
61.1161 + * count restored to what it was when the method was called.
61.1162 + *
61.1163 + * <li>If a thread is {@linkplain Thread#interrupt interrupted} while
61.1164 + * waiting then the wait will terminate, an {@link
61.1165 + * InterruptedException} will be thrown, and the thread's
61.1166 + * interrupted status will be cleared.
61.1167 + *
61.1168 + * <li> Waiting threads are signalled in FIFO order.
61.1169 + *
61.1170 + * <li>The ordering of lock reacquisition for threads returning
61.1171 + * from waiting methods is the same as for threads initially
61.1172 + * acquiring the lock, which is in the default case not specified,
61.1173 + * but for <em>fair</em> locks favors those threads that have been
61.1174 + * waiting the longest.
61.1175 + *
61.1176 + * </ul>
61.1177 + *
61.1178 + * @return the Condition object
61.1179 + */
61.1180 + public Condition newCondition() {
61.1181 + return sync.newCondition();
61.1182 + }
61.1183 +
61.1184 + /**
61.1185 + * Returns a string identifying this lock, as well as its lock
61.1186 + * state. The state, in brackets includes either the String
61.1187 + * {@code "Unlocked"} or the String {@code "Locked by"}
61.1188 + * followed by the {@linkplain Thread#getName name} of the owning thread.
61.1189 + *
61.1190 + * @return a string identifying this lock, as well as its lock state
61.1191 + */
61.1192 + public String toString() {
61.1193 + Thread o = sync.getOwner();
61.1194 + return super.toString() + ((o == null) ?
61.1195 + "[Unlocked]" :
61.1196 + "[Locked by thread " + o.getName() + "]");
61.1197 + }
61.1198 +
61.1199 + /**
61.1200 + * Queries if this write lock is held by the current thread.
61.1201 + * Identical in effect to {@link
61.1202 + * ReentrantReadWriteLock#isWriteLockedByCurrentThread}.
61.1203 + *
61.1204 + * @return {@code true} if the current thread holds this lock and
61.1205 + * {@code false} otherwise
61.1206 + * @since 1.6
61.1207 + */
61.1208 + public boolean isHeldByCurrentThread() {
61.1209 + return sync.isHeldExclusively();
61.1210 + }
61.1211 +
61.1212 + /**
61.1213 + * Queries the number of holds on this write lock by the current
61.1214 + * thread. A thread has a hold on a lock for each lock action
61.1215 + * that is not matched by an unlock action. Identical in effect
61.1216 + * to {@link ReentrantReadWriteLock#getWriteHoldCount}.
61.1217 + *
61.1218 + * @return the number of holds on this lock by the current thread,
61.1219 + * or zero if this lock is not held by the current thread
61.1220 + * @since 1.6
61.1221 + */
61.1222 + public int getHoldCount() {
61.1223 + return sync.getWriteHoldCount();
61.1224 + }
61.1225 + }
61.1226 +
61.1227 + // Instrumentation and status
61.1228 +
61.1229 + /**
61.1230 + * Returns {@code true} if this lock has fairness set true.
61.1231 + *
61.1232 + * @return {@code true} if this lock has fairness set true
61.1233 + */
61.1234 + public final boolean isFair() {
61.1235 + return sync instanceof FairSync;
61.1236 + }
61.1237 +
61.1238 + /**
61.1239 + * Returns the thread that currently owns the write lock, or
61.1240 + * {@code null} if not owned. When this method is called by a
61.1241 + * thread that is not the owner, the return value reflects a
61.1242 + * best-effort approximation of current lock status. For example,
61.1243 + * the owner may be momentarily {@code null} even if there are
61.1244 + * threads trying to acquire the lock but have not yet done so.
61.1245 + * This method is designed to facilitate construction of
61.1246 + * subclasses that provide more extensive lock monitoring
61.1247 + * facilities.
61.1248 + *
61.1249 + * @return the owner, or {@code null} if not owned
61.1250 + */
61.1251 + protected Thread getOwner() {
61.1252 + return sync.getOwner();
61.1253 + }
61.1254 +
61.1255 + /**
61.1256 + * Queries the number of read locks held for this lock. This
61.1257 + * method is designed for use in monitoring system state, not for
61.1258 + * synchronization control.
61.1259 + * @return the number of read locks held.
61.1260 + */
61.1261 + public int getReadLockCount() {
61.1262 + return sync.getReadLockCount();
61.1263 + }
61.1264 +
61.1265 + /**
61.1266 + * Queries if the write lock is held by any thread. This method is
61.1267 + * designed for use in monitoring system state, not for
61.1268 + * synchronization control.
61.1269 + *
61.1270 + * @return {@code true} if any thread holds the write lock and
61.1271 + * {@code false} otherwise
61.1272 + */
61.1273 + public boolean isWriteLocked() {
61.1274 + return sync.isWriteLocked();
61.1275 + }
61.1276 +
61.1277 + /**
61.1278 + * Queries if the write lock is held by the current thread.
61.1279 + *
61.1280 + * @return {@code true} if the current thread holds the write lock and
61.1281 + * {@code false} otherwise
61.1282 + */
61.1283 + public boolean isWriteLockedByCurrentThread() {
61.1284 + return sync.isHeldExclusively();
61.1285 + }
61.1286 +
61.1287 + /**
61.1288 + * Queries the number of reentrant write holds on this lock by the
61.1289 + * current thread. A writer thread has a hold on a lock for
61.1290 + * each lock action that is not matched by an unlock action.
61.1291 + *
61.1292 + * @return the number of holds on the write lock by the current thread,
61.1293 + * or zero if the write lock is not held by the current thread
61.1294 + */
61.1295 + public int getWriteHoldCount() {
61.1296 + return sync.getWriteHoldCount();
61.1297 + }
61.1298 +
61.1299 + /**
61.1300 + * Queries the number of reentrant read holds on this lock by the
61.1301 + * current thread. A reader thread has a hold on a lock for
61.1302 + * each lock action that is not matched by an unlock action.
61.1303 + *
61.1304 + * @return the number of holds on the read lock by the current thread,
61.1305 + * or zero if the read lock is not held by the current thread
61.1306 + * @since 1.6
61.1307 + */
61.1308 + public int getReadHoldCount() {
61.1309 + return sync.getReadHoldCount();
61.1310 + }
61.1311 +
61.1312 + /**
61.1313 + * Returns a collection containing threads that may be waiting to
61.1314 + * acquire the write lock. Because the actual set of threads may
61.1315 + * change dynamically while constructing this result, the returned
61.1316 + * collection is only a best-effort estimate. The elements of the
61.1317 + * returned collection are in no particular order. This method is
61.1318 + * designed to facilitate construction of subclasses that provide
61.1319 + * more extensive lock monitoring facilities.
61.1320 + *
61.1321 + * @return the collection of threads
61.1322 + */
61.1323 + protected Collection<Thread> getQueuedWriterThreads() {
61.1324 + return sync.getExclusiveQueuedThreads();
61.1325 + }
61.1326 +
61.1327 + /**
61.1328 + * Returns a collection containing threads that may be waiting to
61.1329 + * acquire the read lock. Because the actual set of threads may
61.1330 + * change dynamically while constructing this result, the returned
61.1331 + * collection is only a best-effort estimate. The elements of the
61.1332 + * returned collection are in no particular order. This method is
61.1333 + * designed to facilitate construction of subclasses that provide
61.1334 + * more extensive lock monitoring facilities.
61.1335 + *
61.1336 + * @return the collection of threads
61.1337 + */
61.1338 + protected Collection<Thread> getQueuedReaderThreads() {
61.1339 + return sync.getSharedQueuedThreads();
61.1340 + }
61.1341 +
61.1342 + /**
61.1343 + * Queries whether any threads are waiting to acquire the read or
61.1344 + * write lock. Note that because cancellations may occur at any
61.1345 + * time, a {@code true} return does not guarantee that any other
61.1346 + * thread will ever acquire a lock. This method is designed
61.1347 + * primarily for use in monitoring of the system state.
61.1348 + *
61.1349 + * @return {@code true} if there may be other threads waiting to
61.1350 + * acquire the lock
61.1351 + */
61.1352 + public final boolean hasQueuedThreads() {
61.1353 + return sync.hasQueuedThreads();
61.1354 + }
61.1355 +
61.1356 + /**
61.1357 + * Queries whether the given thread is waiting to acquire either
61.1358 + * the read or write lock. Note that because cancellations may
61.1359 + * occur at any time, a {@code true} return does not guarantee
61.1360 + * that this thread will ever acquire a lock. This method is
61.1361 + * designed primarily for use in monitoring of the system state.
61.1362 + *
61.1363 + * @param thread the thread
61.1364 + * @return {@code true} if the given thread is queued waiting for this lock
61.1365 + * @throws NullPointerException if the thread is null
61.1366 + */
61.1367 + public final boolean hasQueuedThread(Thread thread) {
61.1368 + return sync.isQueued(thread);
61.1369 + }
61.1370 +
61.1371 + /**
61.1372 + * Returns an estimate of the number of threads waiting to acquire
61.1373 + * either the read or write lock. The value is only an estimate
61.1374 + * because the number of threads may change dynamically while this
61.1375 + * method traverses internal data structures. This method is
61.1376 + * designed for use in monitoring of the system state, not for
61.1377 + * synchronization control.
61.1378 + *
61.1379 + * @return the estimated number of threads waiting for this lock
61.1380 + */
61.1381 + public final int getQueueLength() {
61.1382 + return sync.getQueueLength();
61.1383 + }
61.1384 +
61.1385 + /**
61.1386 + * Returns a collection containing threads that may be waiting to
61.1387 + * acquire either the read or write lock. Because the actual set
61.1388 + * of threads may change dynamically while constructing this
61.1389 + * result, the returned collection is only a best-effort estimate.
61.1390 + * The elements of the returned collection are in no particular
61.1391 + * order. This method is designed to facilitate construction of
61.1392 + * subclasses that provide more extensive monitoring facilities.
61.1393 + *
61.1394 + * @return the collection of threads
61.1395 + */
61.1396 + protected Collection<Thread> getQueuedThreads() {
61.1397 + return sync.getQueuedThreads();
61.1398 + }
61.1399 +
61.1400 + /**
61.1401 + * Queries whether any threads are waiting on the given condition
61.1402 + * associated with the write lock. Note that because timeouts and
61.1403 + * interrupts may occur at any time, a {@code true} return does
61.1404 + * not guarantee that a future {@code signal} will awaken any
61.1405 + * threads. This method is designed primarily for use in
61.1406 + * monitoring of the system state.
61.1407 + *
61.1408 + * @param condition the condition
61.1409 + * @return {@code true} if there are any waiting threads
61.1410 + * @throws IllegalMonitorStateException if this lock is not held
61.1411 + * @throws IllegalArgumentException if the given condition is
61.1412 + * not associated with this lock
61.1413 + * @throws NullPointerException if the condition is null
61.1414 + */
61.1415 + public boolean hasWaiters(Condition condition) {
61.1416 + if (condition == null)
61.1417 + throw new NullPointerException();
61.1418 + if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
61.1419 + throw new IllegalArgumentException("not owner");
61.1420 + return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
61.1421 + }
61.1422 +
61.1423 + /**
61.1424 + * Returns an estimate of the number of threads waiting on the
61.1425 + * given condition associated with the write lock. Note that because
61.1426 + * timeouts and interrupts may occur at any time, the estimate
61.1427 + * serves only as an upper bound on the actual number of waiters.
61.1428 + * This method is designed for use in monitoring of the system
61.1429 + * state, not for synchronization control.
61.1430 + *
61.1431 + * @param condition the condition
61.1432 + * @return the estimated number of waiting threads
61.1433 + * @throws IllegalMonitorStateException if this lock is not held
61.1434 + * @throws IllegalArgumentException if the given condition is
61.1435 + * not associated with this lock
61.1436 + * @throws NullPointerException if the condition is null
61.1437 + */
61.1438 + public int getWaitQueueLength(Condition condition) {
61.1439 + if (condition == null)
61.1440 + throw new NullPointerException();
61.1441 + if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
61.1442 + throw new IllegalArgumentException("not owner");
61.1443 + return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
61.1444 + }
61.1445 +
61.1446 + /**
61.1447 + * Returns a collection containing those threads that may be
61.1448 + * waiting on the given condition associated with the write lock.
61.1449 + * Because the actual set of threads may change dynamically while
61.1450 + * constructing this result, the returned collection is only a
61.1451 + * best-effort estimate. The elements of the returned collection
61.1452 + * are in no particular order. This method is designed to
61.1453 + * facilitate construction of subclasses that provide more
61.1454 + * extensive condition monitoring facilities.
61.1455 + *
61.1456 + * @param condition the condition
61.1457 + * @return the collection of threads
61.1458 + * @throws IllegalMonitorStateException if this lock is not held
61.1459 + * @throws IllegalArgumentException if the given condition is
61.1460 + * not associated with this lock
61.1461 + * @throws NullPointerException if the condition is null
61.1462 + */
61.1463 + protected Collection<Thread> getWaitingThreads(Condition condition) {
61.1464 + if (condition == null)
61.1465 + throw new NullPointerException();
61.1466 + if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
61.1467 + throw new IllegalArgumentException("not owner");
61.1468 + return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
61.1469 + }
61.1470 +
61.1471 + /**
61.1472 + * Returns a string identifying this lock, as well as its lock state.
61.1473 + * The state, in brackets, includes the String {@code "Write locks ="}
61.1474 + * followed by the number of reentrantly held write locks, and the
61.1475 + * String {@code "Read locks ="} followed by the number of held
61.1476 + * read locks.
61.1477 + *
61.1478 + * @return a string identifying this lock, as well as its lock state
61.1479 + */
61.1480 + public String toString() {
61.1481 + int c = sync.getCount();
61.1482 + int w = Sync.exclusiveCount(c);
61.1483 + int r = Sync.sharedCount(c);
61.1484 +
61.1485 + return super.toString() +
61.1486 + "[Write locks = " + w + ", Read locks = " + r + "]";
61.1487 + }
61.1488 +
61.1489 +}
62.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
62.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/locks/package-info.java Sat Mar 19 10:46:31 2016 +0100
62.3 @@ -0,0 +1,79 @@
62.4 +/*
62.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
62.6 + *
62.7 + * This code is free software; you can redistribute it and/or modify it
62.8 + * under the terms of the GNU General Public License version 2 only, as
62.9 + * published by the Free Software Foundation. Oracle designates this
62.10 + * particular file as subject to the "Classpath" exception as provided
62.11 + * by Oracle in the LICENSE file that accompanied this code.
62.12 + *
62.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
62.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
62.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
62.16 + * version 2 for more details (a copy is included in the LICENSE file that
62.17 + * accompanied this code).
62.18 + *
62.19 + * You should have received a copy of the GNU General Public License version
62.20 + * 2 along with this work; if not, write to the Free Software Foundation,
62.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
62.22 + *
62.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
62.24 + * or visit www.oracle.com if you need additional information or have any
62.25 + * questions.
62.26 + */
62.27 +
62.28 +/*
62.29 + * This file is available under and governed by the GNU General Public
62.30 + * License version 2 only, as published by the Free Software Foundation.
62.31 + * However, the following notice accompanied the original version of this
62.32 + * file:
62.33 + *
62.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
62.35 + * Expert Group and released to the public domain, as explained at
62.36 + * http://creativecommons.org/publicdomain/zero/1.0/
62.37 + */
62.38 +
62.39 +/**
62.40 + * Interfaces and classes providing a framework for locking and waiting
62.41 + * for conditions that is distinct from built-in synchronization and
62.42 + * monitors. The framework permits much greater flexibility in the use of
62.43 + * locks and conditions, at the expense of more awkward syntax.
62.44 + *
62.45 + * <p>The {@link java.util.concurrent.locks.Lock} interface supports
62.46 + * locking disciplines that differ in semantics (reentrant, fair, etc),
62.47 + * and that can be used in non-block-structured contexts including
62.48 + * hand-over-hand and lock reordering algorithms. The main implementation
62.49 + * is {@link java.util.concurrent.locks.ReentrantLock}.
62.50 + *
62.51 + * <p>The {@link java.util.concurrent.locks.ReadWriteLock} interface
62.52 + * similarly defines locks that may be shared among readers but are
62.53 + * exclusive to writers. Only a single implementation, {@link
62.54 + * java.util.concurrent.locks.ReentrantReadWriteLock}, is provided, since
62.55 + * it covers most standard usage contexts. But programmers may create
62.56 + * their own implementations to cover nonstandard requirements.
62.57 + *
62.58 + * <p>The {@link java.util.concurrent.locks.Condition} interface
62.59 + * describes condition variables that may be associated with Locks.
62.60 + * These are similar in usage to the implicit monitors accessed using
62.61 + * {@code Object.wait}, but offer extended capabilities.
62.62 + * In particular, multiple {@code Condition} objects may be associated
62.63 + * with a single {@code Lock}. To avoid compatibility issues, the
62.64 + * names of {@code Condition} methods are different from the
62.65 + * corresponding {@code Object} versions.
62.66 + *
62.67 + * <p>The {@link java.util.concurrent.locks.AbstractQueuedSynchronizer}
62.68 + * class serves as a useful superclass for defining locks and other
62.69 + * synchronizers that rely on queuing blocked threads. The {@link
62.70 + * java.util.concurrent.locks.AbstractQueuedLongSynchronizer} class
62.71 + * provides the same functionality but extends support to 64 bits of
62.72 + * synchronization state. Both extend class {@link
62.73 + * java.util.concurrent.locks.AbstractOwnableSynchronizer}, a simple
62.74 + * class that helps record the thread currently holding exclusive
62.75 + * synchronization. The {@link java.util.concurrent.locks.LockSupport}
62.76 + * class provides lower-level blocking and unblocking support that is
62.77 + * useful for those developers implementing their own customized lock
62.78 + * classes.
62.79 + *
62.80 + * @since 1.5
62.81 + */
62.82 +package java.util.concurrent.locks;
63.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
63.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/package-info.java Sat Mar 19 10:46:31 2016 +0100
63.3 @@ -0,0 +1,300 @@
63.4 +/*
63.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
63.6 + *
63.7 + * This code is free software; you can redistribute it and/or modify it
63.8 + * under the terms of the GNU General Public License version 2 only, as
63.9 + * published by the Free Software Foundation. Oracle designates this
63.10 + * particular file as subject to the "Classpath" exception as provided
63.11 + * by Oracle in the LICENSE file that accompanied this code.
63.12 + *
63.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
63.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
63.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
63.16 + * version 2 for more details (a copy is included in the LICENSE file that
63.17 + * accompanied this code).
63.18 + *
63.19 + * You should have received a copy of the GNU General Public License version
63.20 + * 2 along with this work; if not, write to the Free Software Foundation,
63.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
63.22 + *
63.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
63.24 + * or visit www.oracle.com if you need additional information or have any
63.25 + * questions.
63.26 + */
63.27 +
63.28 +/*
63.29 + * This file is available under and governed by the GNU General Public
63.30 + * License version 2 only, as published by the Free Software Foundation.
63.31 + * However, the following notice accompanied the original version of this
63.32 + * file:
63.33 + *
63.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
63.35 + * Expert Group and released to the public domain, as explained at
63.36 + * http://creativecommons.org/publicdomain/zero/1.0/
63.37 + */
63.38 +
63.39 +/**
63.40 + * Utility classes commonly useful in concurrent programming. This
63.41 + * package includes a few small standardized extensible frameworks, as
63.42 + * well as some classes that provide useful functionality and are
63.43 + * otherwise tedious or difficult to implement. Here are brief
63.44 + * descriptions of the main components. See also the
63.45 + * {@link java.util.concurrent.locks} and
63.46 + * {@link java.util.concurrent.atomic} packages.
63.47 + *
63.48 + * <h2>Executors</h2>
63.49 + *
63.50 + * <b>Interfaces.</b>
63.51 + *
63.52 + * {@link java.util.concurrent.Executor} is a simple standardized
63.53 + * interface for defining custom thread-like subsystems, including
63.54 + * thread pools, asynchronous IO, and lightweight task frameworks.
63.55 + * Depending on which concrete Executor class is being used, tasks may
63.56 + * execute in a newly created thread, an existing task-execution thread,
63.57 + * or the thread calling {@link java.util.concurrent.Executor#execute
63.58 + * execute}, and may execute sequentially or concurrently.
63.59 + *
63.60 + * {@link java.util.concurrent.ExecutorService} provides a more
63.61 + * complete asynchronous task execution framework. An
63.62 + * ExecutorService manages queuing and scheduling of tasks,
63.63 + * and allows controlled shutdown.
63.64 + *
63.65 + * The {@link java.util.concurrent.ScheduledExecutorService}
63.66 + * subinterface and associated interfaces add support for
63.67 + * delayed and periodic task execution. ExecutorServices
63.68 + * provide methods arranging asynchronous execution of any
63.69 + * function expressed as {@link java.util.concurrent.Callable},
63.70 + * the result-bearing analog of {@link java.lang.Runnable}.
63.71 + *
63.72 + * A {@link java.util.concurrent.Future} returns the results of
63.73 + * a function, allows determination of whether execution has
63.74 + * completed, and provides a means to cancel execution.
63.75 + *
63.76 + * A {@link java.util.concurrent.RunnableFuture} is a {@code Future}
63.77 + * that possesses a {@code run} method that upon execution,
63.78 + * sets its results.
63.79 + *
63.80 + * <p>
63.81 + *
63.82 + * <b>Implementations.</b>
63.83 + *
63.84 + * Classes {@link java.util.concurrent.ThreadPoolExecutor} and
63.85 + * {@link java.util.concurrent.ScheduledThreadPoolExecutor}
63.86 + * provide tunable, flexible thread pools.
63.87 + *
63.88 + * The {@link java.util.concurrent.Executors} class provides
63.89 + * factory methods for the most common kinds and configurations
63.90 + * of Executors, as well as a few utility methods for using
63.91 + * them. Other utilities based on {@code Executors} include the
63.92 + * concrete class {@link java.util.concurrent.FutureTask}
63.93 + * providing a common extensible implementation of Futures, and
63.94 + * {@link java.util.concurrent.ExecutorCompletionService}, that
63.95 + * assists in coordinating the processing of groups of
63.96 + * asynchronous tasks.
63.97 + *
63.98 + * <p>Class {@link java.util.concurrent.ForkJoinPool} provides an
63.99 + * Executor primarily designed for processing instances of {@link
63.100 + * java.util.concurrent.ForkJoinTask} and its subclasses. These
63.101 + * classes employ a work-stealing scheduler that attains high
63.102 + * throughput for tasks conforming to restrictions that often hold in
63.103 + * computation-intensive parallel processing.
63.104 + *
63.105 + * <h2>Queues</h2>
63.106 + *
63.107 + * The {@link java.util.concurrent.ConcurrentLinkedQueue} class
63.108 + * supplies an efficient scalable thread-safe non-blocking FIFO
63.109 + * queue.
63.110 + *
63.111 + * <p>Five implementations in {@code java.util.concurrent} support
63.112 + * the extended {@link java.util.concurrent.BlockingQueue}
63.113 + * interface, that defines blocking versions of put and take:
63.114 + * {@link java.util.concurrent.LinkedBlockingQueue},
63.115 + * {@link java.util.concurrent.ArrayBlockingQueue},
63.116 + * {@link java.util.concurrent.SynchronousQueue},
63.117 + * {@link java.util.concurrent.PriorityBlockingQueue}, and
63.118 + * {@link java.util.concurrent.DelayQueue}.
63.119 + * The different classes cover the most common usage contexts
63.120 + * for producer-consumer, messaging, parallel tasking, and
63.121 + * related concurrent designs.
63.122 + *
63.123 + * <p> Extended interface {@link java.util.concurrent.TransferQueue},
63.124 + * and implementation {@link java.util.concurrent.LinkedTransferQueue}
63.125 + * introduce a synchronous {@code transfer} method (along with related
63.126 + * features) in which a producer may optionally block awaiting its
63.127 + * consumer.
63.128 + *
63.129 + * <p>The {@link java.util.concurrent.BlockingDeque} interface
63.130 + * extends {@code BlockingQueue} to support both FIFO and LIFO
63.131 + * (stack-based) operations.
63.132 + * Class {@link java.util.concurrent.LinkedBlockingDeque}
63.133 + * provides an implementation.
63.134 + *
63.135 + * <h2>Timing</h2>
63.136 + *
63.137 + * The {@link java.util.concurrent.TimeUnit} class provides
63.138 + * multiple granularities (including nanoseconds) for
63.139 + * specifying and controlling time-out based operations. Most
63.140 + * classes in the package contain operations based on time-outs
63.141 + * in addition to indefinite waits. In all cases that
63.142 + * time-outs are used, the time-out specifies the minimum time
63.143 + * that the method should wait before indicating that it
63.144 + * timed-out. Implementations make a "best effort"
63.145 + * to detect time-outs as soon as possible after they occur.
63.146 + * However, an indefinite amount of time may elapse between a
63.147 + * time-out being detected and a thread actually executing
63.148 + * again after that time-out. All methods that accept timeout
63.149 + * parameters treat values less than or equal to zero to mean
63.150 + * not to wait at all. To wait "forever", you can use a value
63.151 + * of {@code Long.MAX_VALUE}.
63.152 + *
63.153 + * <h2>Synchronizers</h2>
63.154 + *
63.155 + * Five classes aid common special-purpose synchronization idioms.
63.156 + * <ul>
63.157 + *
63.158 + * <li>{@link java.util.concurrent.Semaphore} is a classic concurrency tool.
63.159 + *
63.160 + * <li>{@link java.util.concurrent.CountDownLatch} is a very simple yet
63.161 + * very common utility for blocking until a given number of signals,
63.162 + * events, or conditions hold.
63.163 + *
63.164 + * <li>A {@link java.util.concurrent.CyclicBarrier} is a resettable
63.165 + * multiway synchronization point useful in some styles of parallel
63.166 + * programming.
63.167 + *
63.168 + * <li>A {@link java.util.concurrent.Phaser} provides
63.169 + * a more flexible form of barrier that may be used to control phased
63.170 + * computation among multiple threads.
63.171 + *
63.172 + * <li>An {@link java.util.concurrent.Exchanger} allows two threads to
63.173 + * exchange objects at a rendezvous point, and is useful in several
63.174 + * pipeline designs.
63.175 + *
63.176 + * </ul>
63.177 + *
63.178 + * <h2>Concurrent Collections</h2>
63.179 + *
63.180 + * Besides Queues, this package supplies Collection implementations
63.181 + * designed for use in multithreaded contexts:
63.182 + * {@link java.util.concurrent.ConcurrentHashMap},
63.183 + * {@link java.util.concurrent.ConcurrentSkipListMap},
63.184 + * {@link java.util.concurrent.ConcurrentSkipListSet},
63.185 + * {@link java.util.concurrent.CopyOnWriteArrayList}, and
63.186 + * {@link java.util.concurrent.CopyOnWriteArraySet}.
63.187 + * When many threads are expected to access a given collection, a
63.188 + * {@code ConcurrentHashMap} is normally preferable to a synchronized
63.189 + * {@code HashMap}, and a {@code ConcurrentSkipListMap} is normally
63.190 + * preferable to a synchronized {@code TreeMap}.
63.191 + * A {@code CopyOnWriteArrayList} is preferable to a synchronized
63.192 + * {@code ArrayList} when the expected number of reads and traversals
63.193 + * greatly outnumber the number of updates to a list.
63.194 +
63.195 + * <p>The "Concurrent" prefix used with some classes in this package
63.196 + * is a shorthand indicating several differences from similar
63.197 + * "synchronized" classes. For example {@code java.util.Hashtable} and
63.198 + * {@code Collections.synchronizedMap(new HashMap())} are
63.199 + * synchronized. But {@link
63.200 + * java.util.concurrent.ConcurrentHashMap} is "concurrent". A
63.201 + * concurrent collection is thread-safe, but not governed by a
63.202 + * single exclusion lock. In the particular case of
63.203 + * ConcurrentHashMap, it safely permits any number of
63.204 + * concurrent reads as well as a tunable number of concurrent
63.205 + * writes. "Synchronized" classes can be useful when you need
63.206 + * to prevent all access to a collection via a single lock, at
63.207 + * the expense of poorer scalability. In other cases in which
63.208 + * multiple threads are expected to access a common collection,
63.209 + * "concurrent" versions are normally preferable. And
63.210 + * unsynchronized collections are preferable when either
63.211 + * collections are unshared, or are accessible only when
63.212 + * holding other locks.
63.213 + *
63.214 + * <p>Most concurrent Collection implementations (including most
63.215 + * Queues) also differ from the usual java.util conventions in that
63.216 + * their Iterators provide <em>weakly consistent</em> rather than
63.217 + * fast-fail traversal. A weakly consistent iterator is thread-safe,
63.218 + * but does not necessarily freeze the collection while iterating, so
63.219 + * it may (or may not) reflect any updates since the iterator was
63.220 + * created.
63.221 + *
63.222 + * <h2><a name="MemoryVisibility">Memory Consistency Properties</a></h2>
63.223 + *
63.224 + * Chapter 17 of
63.225 + * <cite>The Java™ Language Specification</cite>
63.226 + * defines the
63.227 + * <i>happens-before</i> relation on memory operations such as reads and
63.228 + * writes of shared variables. The results of a write by one thread are
63.229 + * guaranteed to be visible to a read by another thread only if the write
63.230 + * operation <i>happens-before</i> the read operation. The
63.231 + * {@code synchronized} and {@code volatile} constructs, as well as the
63.232 + * {@code Thread.start()} and {@code Thread.join()} methods, can form
63.233 + * <i>happens-before</i> relationships. In particular:
63.234 + *
63.235 + * <ul>
63.236 + * <li>Each action in a thread <i>happens-before</i> every action in that
63.237 + * thread that comes later in the program's order.
63.238 + *
63.239 + * <li>An unlock ({@code synchronized} block or method exit) of a
63.240 + * monitor <i>happens-before</i> every subsequent lock ({@code synchronized}
63.241 + * block or method entry) of that same monitor. And because
63.242 + * the <i>happens-before</i> relation is transitive, all actions
63.243 + * of a thread prior to unlocking <i>happen-before</i> all actions
63.244 + * subsequent to any thread locking that monitor.
63.245 + *
63.246 + * <li>A write to a {@code volatile} field <i>happens-before</i> every
63.247 + * subsequent read of that same field. Writes and reads of
63.248 + * {@code volatile} fields have similar memory consistency effects
63.249 + * as entering and exiting monitors, but do <em>not</em> entail
63.250 + * mutual exclusion locking.
63.251 + *
63.252 + * <li>A call to {@code start} on a thread <i>happens-before</i> any
63.253 + * action in the started thread.
63.254 + *
63.255 + * <li>All actions in a thread <i>happen-before</i> any other thread
63.256 + * successfully returns from a {@code join} on that thread.
63.257 + *
63.258 + * </ul>
63.259 + *
63.260 + *
63.261 + * The methods of all classes in {@code java.util.concurrent} and its
63.262 + * subpackages extend these guarantees to higher-level
63.263 + * synchronization. In particular:
63.264 + *
63.265 + * <ul>
63.266 + *
63.267 + * <li>Actions in a thread prior to placing an object into any concurrent
63.268 + * collection <i>happen-before</i> actions subsequent to the access or
63.269 + * removal of that element from the collection in another thread.
63.270 + *
63.271 + * <li>Actions in a thread prior to the submission of a {@code Runnable}
63.272 + * to an {@code Executor} <i>happen-before</i> its execution begins.
63.273 + * Similarly for {@code Callables} submitted to an {@code ExecutorService}.
63.274 + *
63.275 + * <li>Actions taken by the asynchronous computation represented by a
63.276 + * {@code Future} <i>happen-before</i> actions subsequent to the
63.277 + * retrieval of the result via {@code Future.get()} in another thread.
63.278 + *
63.279 + * <li>Actions prior to "releasing" synchronizer methods such as
63.280 + * {@code Lock.unlock}, {@code Semaphore.release}, and
63.281 + * {@code CountDownLatch.countDown} <i>happen-before</i> actions
63.282 + * subsequent to a successful "acquiring" method such as
63.283 + * {@code Lock.lock}, {@code Semaphore.acquire},
63.284 + * {@code Condition.await}, and {@code CountDownLatch.await} on the
63.285 + * same synchronizer object in another thread.
63.286 + *
63.287 + * <li>For each pair of threads that successfully exchange objects via
63.288 + * an {@code Exchanger}, actions prior to the {@code exchange()}
63.289 + * in each thread <i>happen-before</i> those subsequent to the
63.290 + * corresponding {@code exchange()} in another thread.
63.291 + *
63.292 + * <li>Actions prior to calling {@code CyclicBarrier.await} and
63.293 + * {@code Phaser.awaitAdvance} (as well as its variants)
63.294 + * <i>happen-before</i> actions performed by the barrier action, and
63.295 + * actions performed by the barrier action <i>happen-before</i> actions
63.296 + * subsequent to a successful return from the corresponding {@code await}
63.297 + * in other threads.
63.298 + *
63.299 + * </ul>
63.300 + *
63.301 + * @since 1.5
63.302 + */
63.303 +package java.util.concurrent;