Showing the changes to java/pkg/java/util/concurrent (282 of 18352 files). Show all
Unified · Split
Binary file not shown.
| @@ -0,0 +1,309 @@ | |||
| 1 | /* | ||
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 3 | * | ||
| 4 | * This code is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License version 2 only, as | ||
| 6 | * published by the Free Software Foundation. Oracle designates this | ||
| 7 | * particular file as subject to the "Classpath" exception as provided | ||
| 8 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 9 | * | ||
| 10 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 13 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 14 | * accompanied this code). | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License version | ||
| 17 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | * | ||
| 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 21 | * or visit www.oracle.com if you need additional information or have any | ||
| 22 | * questions. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * This file is available under and governed by the GNU General Public | ||
| 27 | * License version 2 only, as published by the Free Software Foundation. | ||
| 28 | * However, the following notice accompanied the original version of this | ||
| 29 | * file: | ||
| 30 | * | ||
| 31 | * Written by Doug Lea with assistance from members of JCP JSR-166 | ||
| 32 | * Expert Group and released to the public domain, as explained at | ||
| 33 | * http://creativecommons.org/publicdomain/zero/1.0/ | ||
| 34 | */ | ||
| 35 | |||
| 36 | package java.util.concurrent; | ||
| 37 | import java.util.*; | ||
| 38 | |||
| 39 | /** | ||
| 40 | * Provides default implementations of {@link ExecutorService} | ||
| 41 | * execution methods. This class implements the <tt>submit</tt>, | ||
| 42 | * <tt>invokeAny</tt> and <tt>invokeAll</tt> methods using a | ||
| 43 | * {@link RunnableFuture} returned by <tt>newTaskFor</tt>, which defaults | ||
| 44 | * to the {@link FutureTask} class provided in this package. For example, | ||
| 45 | * the implementation of <tt>submit(Runnable)</tt> creates an | ||
| 46 | * associated <tt>RunnableFuture</tt> that is executed and | ||
| 47 | * returned. Subclasses may override the <tt>newTaskFor</tt> methods | ||
| 48 | * to return <tt>RunnableFuture</tt> implementations other than | ||
| 49 | * <tt>FutureTask</tt>. | ||
| 50 | * | ||
| 51 | * <p> <b>Extension example</b>. Here is a sketch of a class | ||
| 52 | * that customizes {@link ThreadPoolExecutor} to use | ||
| 53 | * a <tt>CustomTask</tt> class instead of the default <tt>FutureTask</tt>: | ||
| 54 | * <pre> {@code | ||
| 55 | * public class CustomThreadPoolExecutor extends ThreadPoolExecutor { | ||
| 56 | * | ||
| 57 | * static class CustomTask<V> implements RunnableFuture<V> {...} | ||
| 58 | * | ||
| 59 | * protected <V> RunnableFuture<V> newTaskFor(Callable<V> c) { | ||
| 60 | * return new CustomTask<V>(c); | ||
| 61 | * } | ||
| 62 | * protected <V> RunnableFuture<V> newTaskFor(Runnable r, V v) { | ||
| 63 | * return new CustomTask<V>(r, v); | ||
| 64 | * } | ||
| 65 | * // ... add constructors, etc. | ||
| 66 | * }}</pre> | ||
| 67 | * | ||
| 68 | * @since 1.5 | ||
| 69 | * @author Doug Lea | ||
| 70 | */ | ||
| 71 | public abstract class AbstractExecutorService implements ExecutorService { | ||
| 72 | |||
| 73 | /** | ||
| 74 | * Returns a <tt>RunnableFuture</tt> for the given runnable and default | ||
| 75 | * value. | ||
| 76 | * | ||
| 77 | * @param runnable the runnable task being wrapped | ||
| 78 | * @param value the default value for the returned future | ||
| 79 | * @return a <tt>RunnableFuture</tt> which when run will run the | ||
| 80 | * underlying runnable and which, as a <tt>Future</tt>, will yield | ||
| 81 | * the given value as its result and provide for cancellation of | ||
| 82 | * the underlying task. | ||
| 83 | * @since 1.6 | ||
| 84 | */ | ||
| 85 | protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) { | ||
| 86 | return new FutureTask<T>(runnable, value); | ||
| 87 | } | ||
| 88 | |||
| 89 | /** | ||
| 90 | * Returns a <tt>RunnableFuture</tt> for the given callable task. | ||
| 91 | * | ||
| 92 | * @param callable the callable task being wrapped | ||
| 93 | * @return a <tt>RunnableFuture</tt> which when run will call the | ||
| 94 | * underlying callable and which, as a <tt>Future</tt>, will yield | ||
| 95 | * the callable's result as its result and provide for | ||
| 96 | * cancellation of the underlying task. | ||
| 97 | * @since 1.6 | ||
| 98 | */ | ||
| 99 | protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) { | ||
| 100 | return new FutureTask<T>(callable); | ||
| 101 | } | ||
| 102 | |||
| 103 | /** | ||
| 104 | * @throws RejectedExecutionException {@inheritDoc} | ||
| 105 | * @throws NullPointerException {@inheritDoc} | ||
| 106 | */ | ||
| 107 | public Future<?> submit(Runnable task) { | ||
| 108 | if (task == null) throw new NullPointerException(); | ||
| 109 | RunnableFuture<Void> ftask = newTaskFor(task, null); | ||
| 110 | execute(ftask); | ||
| 111 | return ftask; | ||
| 112 | } | ||
| 113 | |||
| 114 | /** | ||
| 115 | * @throws RejectedExecutionException {@inheritDoc} | ||
| 116 | * @throws NullPointerException {@inheritDoc} | ||
| 117 | */ | ||
| 118 | public <T> Future<T> submit(Runnable task, T result) { | ||
| 119 | if (task == null) throw new NullPointerException(); | ||
| 120 | RunnableFuture<T> ftask = newTaskFor(task, result); | ||
| 121 | execute(ftask); | ||
| 122 | return ftask; | ||
| 123 | } | ||
| 124 | |||
| 125 | /** | ||
| 126 | * @throws RejectedExecutionException {@inheritDoc} | ||
| 127 | * @throws NullPointerException {@inheritDoc} | ||
| 128 | */ | ||
| 129 | public <T> Future<T> submit(Callable<T> task) { | ||
| 130 | if (task == null) throw new NullPointerException(); | ||
| 131 | RunnableFuture<T> ftask = newTaskFor(task); | ||
| 132 | execute(ftask); | ||
| 133 | return ftask; | ||
| 134 | } | ||
| 135 | |||
| 136 | /** | ||
| 137 | * the main mechanics of invokeAny. | ||
| 138 | */ | ||
| 139 | private <T> T doInvokeAny(Collection<? extends Callable<T>> tasks, | ||
| 140 | boolean timed, long nanos) | ||
| 141 | throws InterruptedException, ExecutionException, TimeoutException { | ||
| 142 | if (tasks == null) | ||
| 143 | throw new NullPointerException(); | ||
| 144 | int ntasks = tasks.size(); | ||
| 145 | if (ntasks == 0) | ||
| 146 | throw new IllegalArgumentException(); | ||
| 147 | List<Future<T>> futures= new ArrayList<Future<T>>(ntasks); | ||
| 148 | ExecutorCompletionService<T> ecs = | ||
| 149 | new ExecutorCompletionService<T>(this); | ||
| 150 | |||
| 151 | // For efficiency, especially in executors with limited | ||
| 152 | // parallelism, check to see if previously submitted tasks are | ||
| 153 | // done before submitting more of them. This interleaving | ||
| 154 | // plus the exception mechanics account for messiness of main | ||
| 155 | // loop. | ||
| 156 | |||
| 157 | try { | ||
| 158 | // Record exceptions so that if we fail to obtain any | ||
| 159 | // result, we can throw the last exception we got. | ||
| 160 | ExecutionException ee = null; | ||
| 161 | long lastTime = timed ? System.nanoTime() : 0; | ||
| 162 | Iterator<? extends Callable<T>> it = tasks.iterator(); | ||
| 163 | |||
| 164 | // Start one task for sure; the rest incrementally | ||
| 165 | futures.add(ecs.submit(it.next())); | ||
| 166 | --ntasks; | ||
| 167 | int active = 1; | ||
| 168 | |||
| 169 | for (;;) { | ||
| 170 | Future<T> f = ecs.poll(); | ||
| 171 | if (f == null) { | ||
| 172 | if (ntasks > 0) { | ||
| 173 | --ntasks; | ||
| 174 | futures.add(ecs.submit(it.next())); | ||
| 175 | ++active; | ||
| 176 | } | ||
| 177 | else if (active == 0) | ||
| 178 | break; | ||
| 179 | else if (timed) { | ||
| 180 | f = ecs.poll(nanos, TimeUnit.NANOSECONDS); | ||
| 181 | if (f == null) | ||
| 182 | throw new TimeoutException(); | ||
| 183 | long now = System.nanoTime(); | ||
| 184 | nanos -= now - lastTime; | ||
| 185 | lastTime = now; | ||
| 186 | } | ||
| 187 | else | ||
| 188 | f = ecs.take(); | ||
| 189 | } | ||
| 190 | if (f != null) { | ||
| 191 | --active; | ||
| 192 | try { | ||
| 193 | return f.get(); | ||
| 194 | } catch (ExecutionException eex) { | ||
| 195 | ee = eex; | ||
| 196 | } catch (RuntimeException rex) { | ||
| 197 | ee = new ExecutionException(rex); | ||
| 198 | } | ||
| 199 | } | ||
| 200 | } | ||
| 201 | |||
| 202 | if (ee == null) | ||
| 203 | ee = new ExecutionException(); | ||
| 204 | throw ee; | ||
| 205 | |||
| 206 | } finally { | ||
| 207 | for (Future<T> f : futures) | ||
| 208 | f.cancel(true); | ||
| 209 | } | ||
| 210 | } | ||
| 211 | |||
| 212 | public <T> T invokeAny(Collection<? extends Callable<T>> tasks) | ||
| 213 | throws InterruptedException, ExecutionException { | ||
| 214 | try { | ||
| 215 | return doInvokeAny(tasks, false, 0); | ||
| 216 | } catch (TimeoutException cannotHappen) { | ||
| 217 | assert false; | ||
| 218 | return null; | ||
| 219 | } | ||
| 220 | } | ||
| 221 | |||
| 222 | public <T> T invokeAny(Collection<? extends Callable<T>> tasks, | ||
| 223 | long timeout, TimeUnit unit) | ||
| 224 | throws InterruptedException, ExecutionException, TimeoutException { | ||
| 225 | return doInvokeAny(tasks, true, unit.toNanos(timeout)); | ||
| 226 | } | ||
| 227 | |||
| 228 | public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) | ||
| 229 | throws InterruptedException { | ||
| 230 | if (tasks == null) | ||
| 231 | throw new NullPointerException(); | ||
| 232 | List<Future<T>> futures = new ArrayList<Future<T>>(tasks.size()); | ||
| 233 | boolean done = false; | ||
| 234 | try { | ||
| 235 | for (Callable<T> t : tasks) { | ||
| 236 | RunnableFuture<T> f = newTaskFor(t); | ||
| 237 | futures.add(f); | ||
| 238 | execute(f); | ||
| 239 | } | ||
| 240 | for (Future<T> f : futures) { | ||
| 241 | if (!f.isDone()) { | ||
| 242 | try { | ||
| 243 | f.get(); | ||
| 244 | } catch (CancellationException ignore) { | ||
| 245 | } catch (ExecutionException ignore) { | ||
| 246 | } | ||
| 247 | } | ||
| 248 | } | ||
| 249 | done = true; | ||
| 250 | return futures; | ||
| 251 | } finally { | ||
| 252 | if (!done) | ||
| 253 | for (Future<T> f : futures) | ||
| 254 | f.cancel(true); | ||
| 255 | } | ||
| 256 | } | ||
| 257 | |||
| 258 | public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, | ||
| 259 | long timeout, TimeUnit unit) | ||
| 260 | throws InterruptedException { | ||
| 261 | if (tasks == null || unit == null) | ||
| 262 | throw new NullPointerException(); | ||
| 263 | long nanos = unit.toNanos(timeout); | ||
| 264 | List<Future<T>> futures = new ArrayList<Future<T>>(tasks.size()); | ||
| 265 | boolean done = false; | ||
| 266 | try { | ||
| 267 | for (Callable<T> t : tasks) | ||
| 268 | futures.add(newTaskFor(t)); | ||
| 269 | |||
| 270 | long lastTime = System.nanoTime(); | ||
| 271 | |||
| 272 | // Interleave time checks and calls to execute in case | ||
| 273 | // executor doesn't have any/much parallelism. | ||
| 274 | Iterator<Future<T>> it = futures.iterator(); | ||
| 275 | while (it.hasNext()) { | ||
| 276 | execute((Runnable)(it.next())); | ||
| 277 | long now = System.nanoTime(); | ||
| 278 | nanos -= now - lastTime; | ||
| 279 | lastTime = now; | ||
| 280 | if (nanos <= 0) | ||
| 281 | return futures; | ||
| 282 | } | ||
| 283 | |||
| 284 | for (Future<T> f : futures) { | ||
| 285 | if (!f.isDone()) { | ||
| 286 | if (nanos <= 0) | ||
| 287 | return futures; | ||
| 288 | try { | ||
| 289 | f.get(nanos, TimeUnit.NANOSECONDS); | ||
| 290 | } catch (CancellationException ignore) { | ||
| 291 | } catch (ExecutionException ignore) { | ||
| 292 | } catch (TimeoutException toe) { | ||
| 293 | return futures; | ||
| 294 | } | ||
| 295 | long now = System.nanoTime(); | ||
| 296 | nanos -= now - lastTime; | ||
| 297 | lastTime = now; | ||
| 298 | } | ||
| 299 | } | ||
| 300 | done = true; | ||
| 301 | return futures; | ||
| 302 | } finally { | ||
| 303 | if (!done) | ||
| 304 | for (Future<T> f : futures) | ||
| 305 | f.cancel(true); | ||
| 306 | } | ||
| 307 | } | ||
| 308 | |||
| 309 | } | ||
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,805 @@ | |||
| 1 | /* | ||
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 3 | * | ||
| 4 | * This code is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License version 2 only, as | ||
| 6 | * published by the Free Software Foundation. Oracle designates this | ||
| 7 | * particular file as subject to the "Classpath" exception as provided | ||
| 8 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 9 | * | ||
| 10 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 13 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 14 | * accompanied this code). | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License version | ||
| 17 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | * | ||
| 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 21 | * or visit www.oracle.com if you need additional information or have any | ||
| 22 | * questions. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * This file is available under and governed by the GNU General Public | ||
| 27 | * License version 2 only, as published by the Free Software Foundation. | ||
| 28 | * However, the following notice accompanied the original version of this | ||
| 29 | * file: | ||
| 30 | * | ||
| 31 | * Written by Doug Lea with assistance from members of JCP JSR-166 | ||
| 32 | * Expert Group and released to the public domain, as explained at | ||
| 33 | * http://creativecommons.org/publicdomain/zero/1.0/ | ||
| 34 | */ | ||
| 35 | |||
| 36 | package java.util.concurrent; | ||
| 37 | import java.util.concurrent.locks.*; | ||
| 38 | import java.util.*; | ||
| 39 | |||
| 40 | /** | ||
| 41 | * A bounded {@linkplain BlockingQueue blocking queue} backed by an | ||
| 42 | * array. This queue orders elements FIFO (first-in-first-out). The | ||
| 43 | * <em>head</em> of the queue is that element that has been on the | ||
| 44 | * queue the longest time. The <em>tail</em> of the queue is that | ||
| 45 | * element that has been on the queue the shortest time. New elements | ||
| 46 | * are inserted at the tail of the queue, and the queue retrieval | ||
| 47 | * operations obtain elements at the head of the queue. | ||
| 48 | * | ||
| 49 | * <p>This is a classic "bounded buffer", in which a | ||
| 50 | * fixed-sized array holds elements inserted by producers and | ||
| 51 | * extracted by consumers. Once created, the capacity cannot be | ||
| 52 | * changed. Attempts to {@code put} an element into a full queue | ||
| 53 | * will result in the operation blocking; attempts to {@code take} an | ||
| 54 | * element from an empty queue will similarly block. | ||
| 55 | * | ||
| 56 | * <p>This class supports an optional fairness policy for ordering | ||
| 57 | * waiting producer and consumer threads. By default, this ordering | ||
| 58 | * is not guaranteed. However, a queue constructed with fairness set | ||
| 59 | * to {@code true} grants threads access in FIFO order. Fairness | ||
| 60 | * generally decreases throughput but reduces variability and avoids | ||
| 61 | * starvation. | ||
| 62 | * | ||
| 63 | * <p>This class and its iterator implement all of the | ||
| 64 | * <em>optional</em> methods of the {@link Collection} and {@link | ||
| 65 | * Iterator} interfaces. | ||
| 66 | * | ||
| 67 | * <p>This class is a member of the | ||
| 68 | * <a href="{@docRoot}/../technotes/guides/collections/index.html"> | ||
| 69 | * Java Collections Framework</a>. | ||
| 70 | * | ||
| 71 | * @since 1.5 | ||
| 72 | * @author Doug Lea | ||
| 73 | * @param <E> the type of elements held in this collection | ||
| 74 | */ | ||
| 75 | public class ArrayBlockingQueue<E> extends AbstractQueue<E> | ||
| 76 | implements BlockingQueue<E>, java.io.Serializable { | ||
| 77 | |||
| 78 | /** | ||
| 79 | * Serialization ID. This class relies on default serialization | ||
| 80 | * even for the items array, which is default-serialized, even if | ||
| 81 | * it is empty. Otherwise it could not be declared final, which is | ||
| 82 | * necessary here. | ||
| 83 | */ | ||
| 84 | private static final long serialVersionUID = -817911632652898426L; | ||
| 85 | |||
| 86 | /** The queued items */ | ||
| 87 | final Object[] items; | ||
| 88 | |||
| 89 | /** items index for next take, poll, peek or remove */ | ||
| 90 | int takeIndex; | ||
| 91 | |||
| 92 | /** items index for next put, offer, or add */ | ||
| 93 | int putIndex; | ||
| 94 | |||
| 95 | /** Number of elements in the queue */ | ||
| 96 | int count; | ||
| 97 | |||
| 98 | /* | ||
| 99 | * Concurrency control uses the classic two-condition algorithm | ||
| 100 | * found in any textbook. | ||
| 101 | */ | ||
| 102 | |||
| 103 | /** Main lock guarding all access */ | ||
| 104 | final ReentrantLock lock; | ||
| 105 | /** Condition for waiting takes */ | ||
| 106 | private final Condition notEmpty; | ||
| 107 | /** Condition for waiting puts */ | ||
| 108 | private final Condition notFull; | ||
| 109 | |||
| 110 | // Internal helper methods | ||
| 111 | |||
| 112 | /** | ||
| 113 | * Circularly increment i. | ||
| 114 | */ | ||
| 115 | final int inc(int i) { | ||
| 116 | return (++i == items.length) ? 0 : i; | ||
| 117 | } | ||
| 118 | |||
| 119 | /** | ||
| 120 | * Circularly decrement i. | ||
| 121 | */ | ||
| 122 | final int dec(int i) { | ||
| 123 | return ((i == 0) ? items.length : i) - 1; | ||
| 124 | } | ||
| 125 | |||
| 126 | @SuppressWarnings("unchecked") | ||
| 127 | static <E> E cast(Object item) { | ||
| 128 | return (E) item; | ||
| 129 | } | ||
| 130 | |||
| 131 | /** | ||
| 132 | * Returns item at index i. | ||
| 133 | */ | ||
| 134 | final E itemAt(int i) { | ||
| 135 | return this.<E>cast(items[i]); | ||
| 136 | } | ||
| 137 | |||
| 138 | /** | ||
| 139 | * Throws NullPointerException if argument is null. | ||
| 140 | * | ||
| 141 | * @param v the element | ||
| 142 | */ | ||
| 143 | private static void checkNotNull(Object v) { | ||
| 144 | if (v == null) | ||
| 145 | throw new NullPointerException(); | ||
| 146 | } | ||
| 147 | |||
| 148 | /** | ||
| 149 | * Inserts element at current put position, advances, and signals. | ||
| 150 | * Call only when holding lock. | ||
| 151 | */ | ||
| 152 | private void insert(E x) { | ||
| 153 | items[putIndex] = x; | ||
| 154 | putIndex = inc(putIndex); | ||
| 155 | ++count; | ||
| 156 | notEmpty.signal(); | ||
| 157 | } | ||
| 158 | |||
| 159 | /** | ||
| 160 | * Extracts element at current take position, advances, and signals. | ||
| 161 | * Call only when holding lock. | ||
| 162 | */ | ||
| 163 | private E extract() { | ||
| 164 | final Object[] items = this.items; | ||
| 165 | E x = this.<E>cast(items[takeIndex]); | ||
| 166 | items[takeIndex] = null; | ||
| 167 | takeIndex = inc(takeIndex); | ||
| 168 | --count; | ||
| 169 | notFull.signal(); | ||
| 170 | return x; | ||
| 171 | } | ||
| 172 | |||
| 173 | /** | ||
| 174 | * Deletes item at position i. | ||
| 175 | * Utility for remove and iterator.remove. | ||
| 176 | * Call only when holding lock. | ||
| 177 | */ | ||
| 178 | void removeAt(int i) { | ||
| 179 | final Object[] items = this.items; | ||
| 180 | // if removing front item, just advance | ||
| 181 | if (i == takeIndex) { | ||
| 182 | items[takeIndex] = null; | ||
| 183 | takeIndex = inc(takeIndex); | ||
| 184 | } else { | ||
| 185 | // slide over all others up through putIndex. | ||
| 186 | for (;;) { | ||
| 187 | int nexti = inc(i); | ||
| 188 | if (nexti != putIndex) { | ||
| 189 | items[i] = items[nexti]; | ||
| 190 | i = nexti; | ||
| 191 | } else { | ||
| 192 | items[i] = null; | ||
| 193 | putIndex = i; | ||
| 194 | break; | ||
| 195 | } | ||
| 196 | } | ||
| 197 | } | ||
| 198 | --count; | ||
| 199 | notFull.signal(); | ||
| 200 | } | ||
| 201 | |||
| 202 | /** | ||
| 203 | * Creates an {@code ArrayBlockingQueue} with the given (fixed) | ||
| 204 | * capacity and default access policy. | ||
| 205 | * | ||
| 206 | * @param capacity the capacity of this queue | ||
| 207 | * @throws IllegalArgumentException if {@code capacity < 1} | ||
| 208 | */ | ||
| 209 | public ArrayBlockingQueue(int capacity) { | ||
| 210 | this(capacity, false); | ||
| 211 | } | ||
| 212 | |||
| 213 | /** | ||
| 214 | * Creates an {@code ArrayBlockingQueue} with the given (fixed) | ||
| 215 | * capacity and the specified access policy. | ||
| 216 | * | ||
| 217 | * @param capacity the capacity of this queue | ||
| 218 | * @param fair if {@code true} then queue accesses for threads blocked | ||
| 219 | * on insertion or removal, are processed in FIFO order; | ||
| 220 | * if {@code false} the access order is unspecified. | ||
| 221 | * @throws IllegalArgumentException if {@code capacity < 1} | ||
| 222 | */ | ||
| 223 | public ArrayBlockingQueue(int capacity, boolean fair) { | ||
| 224 | if (capacity <= 0) | ||
| 225 | throw new IllegalArgumentException(); | ||
| 226 | this.items = new Object[capacity]; | ||
| 227 | lock = new ReentrantLock(fair); | ||
| 228 | notEmpty = lock.newCondition(); | ||
| 229 | notFull = lock.newCondition(); | ||
| 230 | } | ||
| 231 | |||
| 232 | /** | ||
| 233 | * Creates an {@code ArrayBlockingQueue} with the given (fixed) | ||
| 234 | * capacity, the specified access policy and initially containing the | ||
| 235 | * elements of the given collection, | ||
| 236 | * added in traversal order of the collection's iterator. | ||
| 237 | * | ||
| 238 | * @param capacity the capacity of this queue | ||
| 239 | * @param fair if {@code true} then queue accesses for threads blocked | ||
| 240 | * on insertion or removal, are processed in FIFO order; | ||
| 241 | * if {@code false} the access order is unspecified. | ||
| 242 | * @param c the collection of elements to initially contain | ||
| 243 | * @throws IllegalArgumentException if {@code capacity} is less than | ||
| 244 | * {@code c.size()}, or less than 1. | ||
| 245 | * @throws NullPointerException if the specified collection or any | ||
| 246 | * of its elements are null | ||
| 247 | */ | ||
| 248 | public ArrayBlockingQueue(int capacity, boolean fair, | ||
| 249 | Collection<? extends E> c) { | ||
| 250 | this(capacity, fair); | ||
| 251 | |||
| 252 | final ReentrantLock lock = this.lock; | ||
| 253 | lock.lock(); // Lock only for visibility, not mutual exclusion | ||
| 254 | try { | ||
| 255 | int i = 0; | ||
| 256 | try { | ||
| 257 | for (E e : c) { | ||
| 258 | checkNotNull(e); | ||
| 259 | items[i++] = e; | ||
| 260 | } | ||
| 261 | } catch (ArrayIndexOutOfBoundsException ex) { | ||
| 262 | throw new IllegalArgumentException(); | ||
| 263 | } | ||
| 264 | count = i; | ||
| 265 | putIndex = (i == capacity) ? 0 : i; | ||
| 266 | } finally { | ||
| 267 | lock.unlock(); | ||
| 268 | } | ||
| 269 | } | ||
| 270 | |||
| 271 | /** | ||
| 272 | * Inserts the specified element at the tail of this queue if it is | ||
| 273 | * possible to do so immediately without exceeding the queue's capacity, | ||
| 274 | * returning {@code true} upon success and throwing an | ||
| 275 | * {@code IllegalStateException} if this queue is full. | ||
| 276 | * | ||
| 277 | * @param e the element to add | ||
| 278 | * @return {@code true} (as specified by {@link Collection#add}) | ||
| 279 | * @throws IllegalStateException if this queue is full | ||
| 280 | * @throws NullPointerException if the specified element is null | ||
| 281 | */ | ||
| 282 | public boolean add(E e) { | ||
| 283 | return super.add(e); | ||
| 284 | } | ||
| 285 | |||
| 286 | /** | ||
| 287 | * Inserts the specified element at the tail of this queue if it is | ||
| 288 | * possible to do so immediately without exceeding the queue's capacity, | ||
| 289 | * returning {@code true} upon success and {@code false} if this queue | ||
| 290 | * is full. This method is generally preferable to method {@link #add}, | ||
| 291 | * which can fail to insert an element only by throwing an exception. | ||
| 292 | * | ||
| 293 | * @throws NullPointerException if the specified element is null | ||
| 294 | */ | ||
| 295 | public boolean offer(E e) { | ||
| 296 | checkNotNull(e); | ||
| 297 | final ReentrantLock lock = this.lock; | ||
| 298 | lock.lock(); | ||
| 299 | try { | ||
| 300 | if (count == items.length) | ||
| 301 | return false; | ||
| 302 | else { | ||
| 303 | insert(e); | ||
| 304 | return true; | ||
| 305 | } | ||
| 306 | } finally { | ||
| 307 | lock.unlock(); | ||
| 308 | } | ||
| 309 | } | ||
| 310 | |||
| 311 | /** | ||
| 312 | * Inserts the specified element at the tail of this queue, waiting | ||
| 313 | * for space to become available if the queue is full. | ||
| 314 | * | ||
| 315 | * @throws InterruptedException {@inheritDoc} | ||
| 316 | * @throws NullPointerException {@inheritDoc} | ||
| 317 | */ | ||
| 318 | public void put(E e) throws InterruptedException { | ||
| 319 | checkNotNull(e); | ||
| 320 | final ReentrantLock lock = this.lock; | ||
| 321 | lock.lockInterruptibly(); | ||
| 322 | try { | ||
| 323 | while (count == items.length) | ||
| 324 | notFull.await(); | ||
| 325 | insert(e); | ||
| 326 | } finally { | ||
| 327 | lock.unlock(); | ||
| 328 | } | ||
| 329 | } | ||
| 330 | |||
| 331 | /** | ||
| 332 | * Inserts the specified element at the tail of this queue, waiting | ||
| 333 | * up to the specified wait time for space to become available if | ||
| 334 | * the queue is full. | ||
| 335 | * | ||
| 336 | * @throws InterruptedException {@inheritDoc} | ||
| 337 | * @throws NullPointerException {@inheritDoc} | ||
| 338 | */ | ||
| 339 | public boolean offer(E e, long timeout, TimeUnit unit) | ||
| 340 | throws InterruptedException { | ||
| 341 | |||
| 342 | checkNotNull(e); | ||
| 343 | long nanos = unit.toNanos(timeout); | ||
| 344 | final ReentrantLock lock = this.lock; | ||
| 345 | lock.lockInterruptibly(); | ||
| 346 | try { | ||
| 347 | while (count == items.length) { | ||
| 348 | if (nanos <= 0) | ||
| 349 | return false; | ||
| 350 | nanos = notFull.awaitNanos(nanos); | ||
| 351 | } | ||
| 352 | insert(e); | ||
| 353 | return true; | ||
| 354 | } finally { | ||
| 355 | lock.unlock(); | ||
| 356 | } | ||
| 357 | } | ||
| 358 | |||
| 359 | public E poll() { | ||
| 360 | final ReentrantLock lock = this.lock; | ||
| 361 | lock.lock(); | ||
| 362 | try { | ||
| 363 | return (count == 0) ? null : extract(); | ||
| 364 | } finally { | ||
| 365 | lock.unlock(); | ||
| 366 | } | ||
| 367 | } | ||
| 368 | |||
| 369 | public E take() throws InterruptedException { | ||
| 370 | final ReentrantLock lock = this.lock; | ||
| 371 | lock.lockInterruptibly(); | ||
| 372 | try { | ||
| 373 | while (count == 0) | ||
| 374 | notEmpty.await(); | ||
| 375 | return extract(); | ||
| 376 | } finally { | ||
| 377 | lock.unlock(); | ||
| 378 | } | ||
| 379 | } | ||
| 380 | |||
| 381 | public E poll(long timeout, TimeUnit unit) throws InterruptedException { | ||
| 382 | long nanos = unit.toNanos(timeout); | ||
| 383 | final ReentrantLock lock = this.lock; | ||
| 384 | lock.lockInterruptibly(); | ||
| 385 | try { | ||
| 386 | while (count == 0) { | ||
| 387 | if (nanos <= 0) | ||
| 388 | return null; | ||
| 389 | nanos = notEmpty.awaitNanos(nanos); | ||
| 390 | } | ||
| 391 | return extract(); | ||
| 392 | } finally { | ||
| 393 | lock.unlock(); | ||
| 394 | } | ||
| 395 | } | ||
| 396 | |||
| 397 | public E peek() { | ||
| 398 | final ReentrantLock lock = this.lock; | ||
| 399 | lock.lock(); | ||
| 400 | try { | ||
| 401 | return (count == 0) ? null : itemAt(takeIndex); | ||
| 402 | } finally { | ||
| 403 | lock.unlock(); | ||
| 404 | } | ||
| 405 | } | ||
| 406 | |||
| 407 | // this doc comment is overridden to remove the reference to collections | ||
| 408 | // greater in size than Integer.MAX_VALUE | ||
| 409 | /** | ||
| 410 | * Returns the number of elements in this queue. | ||
| 411 | * | ||
| 412 | * @return the number of elements in this queue | ||
| 413 | */ | ||
| 414 | public int size() { | ||
| 415 | final ReentrantLock lock = this.lock; | ||
| 416 | lock.lock(); | ||
| 417 | try { | ||
| 418 | return count; | ||
| 419 | } finally { | ||
| 420 | lock.unlock(); | ||
| 421 | } | ||
| 422 | } | ||
| 423 | |||
| 424 | // this doc comment is a modified copy of the inherited doc comment, | ||
| 425 | // without the reference to unlimited queues. | ||
| 426 | /** | ||
| 427 | * Returns the number of additional elements that this queue can ideally | ||
| 428 | * (in the absence of memory or resource constraints) accept without | ||
| 429 | * blocking. This is always equal to the initial capacity of this queue | ||
| 430 | * less the current {@code size} of this queue. | ||
| 431 | * | ||
| 432 | * <p>Note that you <em>cannot</em> always tell if an attempt to insert | ||
| 433 | * an element will succeed by inspecting {@code remainingCapacity} | ||
| 434 | * because it may be the case that another thread is about to | ||
| 435 | * insert or remove an element. | ||
| 436 | */ | ||
| 437 | public int remainingCapacity() { | ||
| 438 | final ReentrantLock lock = this.lock; | ||
| 439 | lock.lock(); | ||
| 440 | try { | ||
| 441 | return items.length - count; | ||
| 442 | } finally { | ||
| 443 | lock.unlock(); | ||
| 444 | } | ||
| 445 | } | ||
| 446 | |||
| 447 | /** | ||
| 448 | * Removes a single instance of the specified element from this queue, | ||
| 449 | * if it is present. More formally, removes an element {@code e} such | ||
| 450 | * that {@code o.equals(e)}, if this queue contains one or more such | ||
| 451 | * elements. | ||
| 452 | * Returns {@code true} if this queue contained the specified element | ||
| 453 | * (or equivalently, if this queue changed as a result of the call). | ||
| 454 | * | ||
| 455 | * <p>Removal of interior elements in circular array based queues | ||
| 456 | * is an intrinsically slow and disruptive operation, so should | ||
| 457 | * be undertaken only in exceptional circumstances, ideally | ||
| 458 | * only when the queue is known not to be accessible by other | ||
| 459 | * threads. | ||
| 460 | * | ||
| 461 | * @param o element to be removed from this queue, if present | ||
| 462 | * @return {@code true} if this queue changed as a result of the call | ||
| 463 | */ | ||
| 464 | public boolean remove(Object o) { | ||
| 465 | if (o == null) return false; | ||
| 466 | final Object[] items = this.items; | ||
| 467 | final ReentrantLock lock = this.lock; | ||
| 468 | lock.lock(); | ||
| 469 | try { | ||
| 470 | for (int i = takeIndex, k = count; k > 0; i = inc(i), k--) { | ||
| 471 | if (o.equals(items[i])) { | ||
| 472 | removeAt(i); | ||
| 473 | return true; | ||
| 474 | } | ||
| 475 | } | ||
| 476 | return false; | ||
| 477 | } finally { | ||
| 478 | lock.unlock(); | ||
| 479 | } | ||
| 480 | } | ||
| 481 | |||
| 482 | /** | ||
| 483 | * Returns {@code true} if this queue contains the specified element. | ||
| 484 | * More formally, returns {@code true} if and only if this queue contains | ||
| 485 | * at least one element {@code e} such that {@code o.equals(e)}. | ||
| 486 | * | ||
| 487 | * @param o object to be checked for containment in this queue | ||
| 488 | * @return {@code true} if this queue contains the specified element | ||
| 489 | */ | ||
| 490 | public boolean contains(Object o) { | ||
| 491 | if (o == null) return false; | ||
| 492 | final Object[] items = this.items; | ||
| 493 | final ReentrantLock lock = this.lock; | ||
| 494 | lock.lock(); | ||
| 495 | try { | ||
| 496 | for (int i = takeIndex, k = count; k > 0; i = inc(i), k--) | ||
| 497 | if (o.equals(items[i])) | ||
| 498 | return true; | ||
| 499 | return false; | ||
| 500 | } finally { | ||
| 501 | lock.unlock(); | ||
| 502 | } | ||
| 503 | } | ||
| 504 | |||
| 505 | /** | ||
| 506 | * Returns an array containing all of the elements in this queue, in | ||
| 507 | * proper sequence. | ||
| 508 | * | ||
| 509 | * <p>The returned array will be "safe" in that no references to it are | ||
| 510 | * maintained by this queue. (In other words, this method must allocate | ||
| 511 | * a new array). The caller is thus free to modify the returned array. | ||
| 512 | * | ||
| 513 | * <p>This method acts as bridge between array-based and collection-based | ||
| 514 | * APIs. | ||
| 515 | * | ||
| 516 | * @return an array containing all of the elements in this queue | ||
| 517 | */ | ||
| 518 | public Object[] toArray() { | ||
| 519 | final Object[] items = this.items; | ||
| 520 | final ReentrantLock lock = this.lock; | ||
| 521 | lock.lock(); | ||
| 522 | try { | ||
| 523 | final int count = this.count; | ||
| 524 | Object[] a = new Object[count]; | ||
| 525 | for (int i = takeIndex, k = 0; k < count; i = inc(i), k++) | ||
| 526 | a[k] = items[i]; | ||
| 527 | return a; | ||
| 528 | } finally { | ||
| 529 | lock.unlock(); | ||
| 530 | } | ||
| 531 | } | ||
| 532 | |||
| 533 | /** | ||
| 534 | * Returns an array containing all of the elements in this queue, in | ||
| 535 | * proper sequence; the runtime type of the returned array is that of | ||
| 536 | * the specified array. If the queue fits in the specified array, it | ||
| 537 | * is returned therein. Otherwise, a new array is allocated with the | ||
| 538 | * runtime type of the specified array and the size of this queue. | ||
| 539 | * | ||
| 540 | * <p>If this queue fits in the specified array with room to spare | ||
| 541 | * (i.e., the array has more elements than this queue), the element in | ||
| 542 | * the array immediately following the end of the queue is set to | ||
| 543 | * {@code null}. | ||
| 544 | * | ||
| 545 | * <p>Like the {@link #toArray()} method, this method acts as bridge between | ||
| 546 | * array-based and collection-based APIs. Further, this method allows | ||
| 547 | * precise control over the runtime type of the output array, and may, | ||
| 548 | * under certain circumstances, be used to save allocation costs. | ||
| 549 | * | ||
| 550 | * <p>Suppose {@code x} is a queue known to contain only strings. | ||
| 551 | * The following code can be used to dump the queue into a newly | ||
| 552 | * allocated array of {@code String}: | ||
| 553 | * | ||
| 554 | * <pre> | ||
| 555 | * String[] y = x.toArray(new String[0]);</pre> | ||
| 556 | * | ||
| 557 | * Note that {@code toArray(new Object[0])} is identical in function to | ||
| 558 | * {@code toArray()}. | ||
| 559 | * | ||
| 560 | * @param a the array into which the elements of the queue are to | ||
| 561 | * be stored, if it is big enough; otherwise, a new array of the | ||
| 562 | * same runtime type is allocated for this purpose | ||
| 563 | * @return an array containing all of the elements in this queue | ||
| 564 | * @throws ArrayStoreException if the runtime type of the specified array | ||
| 565 | * is not a supertype of the runtime type of every element in | ||
| 566 | * this queue | ||
| 567 | * @throws NullPointerException if the specified array is null | ||
| 568 | */ | ||
| 569 | @SuppressWarnings("unchecked") | ||
| 570 | public <T> T[] toArray(T[] a) { | ||
| 571 | final Object[] items = this.items; | ||
| 572 | final ReentrantLock lock = this.lock; | ||
| 573 | lock.lock(); | ||
| 574 | try { | ||
| 575 | final int count = this.count; | ||
| 576 | final int len = a.length; | ||
| 577 | if (len < count) | ||
| 578 | a = (T[])java.lang.reflect.Array.newInstance( | ||
| 579 | a.getClass().getComponentType(), count); | ||
| 580 | for (int i = takeIndex, k = 0; k < count; i = inc(i), k++) | ||
| 581 | a[k] = (T) items[i]; | ||
| 582 | if (len > count) | ||
| 583 | a[count] = null; | ||
| 584 | return a; | ||
| 585 | } finally { | ||
| 586 | lock.unlock(); | ||
| 587 | } | ||
| 588 | } | ||
| 589 | |||
| 590 | public String toString() { | ||
| 591 | final ReentrantLock lock = this.lock; | ||
| 592 | lock.lock(); | ||
| 593 | try { | ||
| 594 | int k = count; | ||
| 595 | if (k == 0) | ||
| 596 | return "[]"; | ||
| 597 | |||
| 598 | StringBuilder sb = new StringBuilder(); | ||
| 599 | sb.append('['); | ||
| 600 | for (int i = takeIndex; ; i = inc(i)) { | ||
| 601 | Object e = items[i]; | ||
| 602 | sb.append(e == this ? "(this Collection)" : e); | ||
| 603 | if (--k == 0) | ||
| 604 | return sb.append(']').toString(); | ||
| 605 | sb.append(',').append(' '); | ||
| 606 | } | ||
| 607 | } finally { | ||
| 608 | lock.unlock(); | ||
| 609 | } | ||
| 610 | } | ||
| 611 | |||
| 612 | /** | ||
| 613 | * Atomically removes all of the elements from this queue. | ||
| 614 | * The queue will be empty after this call returns. | ||
| 615 | */ | ||
| 616 | public void clear() { | ||
| 617 | final Object[] items = this.items; | ||
| 618 | final ReentrantLock lock = this.lock; | ||
| 619 | lock.lock(); | ||
| 620 | try { | ||
| 621 | for (int i = takeIndex, k = count; k > 0; i = inc(i), k--) | ||
| 622 | items[i] = null; | ||
| 623 | count = 0; | ||
| 624 | putIndex = 0; | ||
| 625 | takeIndex = 0; | ||
| 626 | notFull.signalAll(); | ||
| 627 | } finally { | ||
| 628 | lock.unlock(); | ||
| 629 | } | ||
| 630 | } | ||
| 631 | |||
| 632 | /** | ||
| 633 | * @throws UnsupportedOperationException {@inheritDoc} | ||
| 634 | * @throws ClassCastException {@inheritDoc} | ||
| 635 | * @throws NullPointerException {@inheritDoc} | ||
| 636 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 637 | */ | ||
| 638 | public int drainTo(Collection<? super E> c) { | ||
| 639 | checkNotNull(c); | ||
| 640 | if (c == this) | ||
| 641 | throw new IllegalArgumentException(); | ||
| 642 | final Object[] items = this.items; | ||
| 643 | final ReentrantLock lock = this.lock; | ||
| 644 | lock.lock(); | ||
| 645 | try { | ||
| 646 | int i = takeIndex; | ||
| 647 | int n = 0; | ||
| 648 | int max = count; | ||
| 649 | while (n < max) { | ||
| 650 | c.add(this.<E>cast(items[i])); | ||
| 651 | items[i] = null; | ||
| 652 | i = inc(i); | ||
| 653 | ++n; | ||
| 654 | } | ||
| 655 | if (n > 0) { | ||
| 656 | count = 0; | ||
| 657 | putIndex = 0; | ||
| 658 | takeIndex = 0; | ||
| 659 | notFull.signalAll(); | ||
| 660 | } | ||
| 661 | return n; | ||
| 662 | } finally { | ||
| 663 | lock.unlock(); | ||
| 664 | } | ||
| 665 | } | ||
| 666 | |||
| 667 | /** | ||
| 668 | * @throws UnsupportedOperationException {@inheritDoc} | ||
| 669 | * @throws ClassCastException {@inheritDoc} | ||
| 670 | * @throws NullPointerException {@inheritDoc} | ||
| 671 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 672 | */ | ||
| 673 | public int drainTo(Collection<? super E> c, int maxElements) { | ||
| 674 | checkNotNull(c); | ||
| 675 | if (c == this) | ||
| 676 | throw new IllegalArgumentException(); | ||
| 677 | if (maxElements <= 0) | ||
| 678 | return 0; | ||
| 679 | final Object[] items = this.items; | ||
| 680 | final ReentrantLock lock = this.lock; | ||
| 681 | lock.lock(); | ||
| 682 | try { | ||
| 683 | int i = takeIndex; | ||
| 684 | int n = 0; | ||
| 685 | int max = (maxElements < count) ? maxElements : count; | ||
| 686 | while (n < max) { | ||
| 687 | c.add(this.<E>cast(items[i])); | ||
| 688 | items[i] = null; | ||
| 689 | i = inc(i); | ||
| 690 | ++n; | ||
| 691 | } | ||
| 692 | if (n > 0) { | ||
| 693 | count -= n; | ||
| 694 | takeIndex = i; | ||
| 695 | notFull.signalAll(); | ||
| 696 | } | ||
| 697 | return n; | ||
| 698 | } finally { | ||
| 699 | lock.unlock(); | ||
| 700 | } | ||
| 701 | } | ||
| 702 | |||
| 703 | /** | ||
| 704 | * Returns an iterator over the elements in this queue in proper sequence. | ||
| 705 | * The elements will be returned in order from first (head) to last (tail). | ||
| 706 | * | ||
| 707 | * <p>The returned {@code Iterator} is a "weakly consistent" iterator that | ||
| 708 | * will never throw {@link java.util.ConcurrentModificationException | ||
| 709 | * ConcurrentModificationException}, | ||
| 710 | * and guarantees to traverse elements as they existed upon | ||
| 711 | * construction of the iterator, and may (but is not guaranteed to) | ||
| 712 | * reflect any modifications subsequent to construction. | ||
| 713 | * | ||
| 714 | * @return an iterator over the elements in this queue in proper sequence | ||
| 715 | */ | ||
| 716 | public Iterator<E> iterator() { | ||
| 717 | return new Itr(); | ||
| 718 | } | ||
| 719 | |||
| 720 | /** | ||
| 721 | * Iterator for ArrayBlockingQueue. To maintain weak consistency | ||
| 722 | * with respect to puts and takes, we (1) read ahead one slot, so | ||
| 723 | * as to not report hasNext true but then not have an element to | ||
| 724 | * return -- however we later recheck this slot to use the most | ||
| 725 | * current value; (2) ensure that each array slot is traversed at | ||
| 726 | * most once (by tracking "remaining" elements); (3) skip over | ||
| 727 | * null slots, which can occur if takes race ahead of iterators. | ||
| 728 | * However, for circular array-based queues, we cannot rely on any | ||
| 729 | * well established definition of what it means to be weakly | ||
| 730 | * consistent with respect to interior removes since these may | ||
| 731 | * require slot overwrites in the process of sliding elements to | ||
| 732 | * cover gaps. So we settle for resiliency, operating on | ||
| 733 | * established apparent nexts, which may miss some elements that | ||
| 734 | * have moved between calls to next. | ||
| 735 | */ | ||
| 736 | private class Itr implements Iterator<E> { | ||
| 737 | private int remaining; // Number of elements yet to be returned | ||
| 738 | private int nextIndex; // Index of element to be returned by next | ||
| 739 | private E nextItem; // Element to be returned by next call to next | ||
| 740 | private E lastItem; // Element returned by last call to next | ||
| 741 | private int lastRet; // Index of last element returned, or -1 if none | ||
| 742 | |||
| 743 | Itr() { | ||
| 744 | final ReentrantLock lock = ArrayBlockingQueue.this.lock; | ||
| 745 | lock.lock(); | ||
| 746 | try { | ||
| 747 | lastRet = -1; | ||
| 748 | if ((remaining = count) > 0) | ||
| 749 | nextItem = itemAt(nextIndex = takeIndex); | ||
| 750 | } finally { | ||
| 751 | lock.unlock(); | ||
| 752 | } | ||
| 753 | } | ||
| 754 | |||
| 755 | public boolean hasNext() { | ||
| 756 | return remaining > 0; | ||
| 757 | } | ||
| 758 | |||
| 759 | public E next() { | ||
| 760 | final ReentrantLock lock = ArrayBlockingQueue.this.lock; | ||
| 761 | lock.lock(); | ||
| 762 | try { | ||
| 763 | if (remaining <= 0) | ||
| 764 | throw new NoSuchElementException(); | ||
| 765 | lastRet = nextIndex; | ||
| 766 | E x = itemAt(nextIndex); // check for fresher value | ||
| 767 | if (x == null) { | ||
| 768 | x = nextItem; // we are forced to report old value | ||
| 769 | lastItem = null; // but ensure remove fails | ||
| 770 | } | ||
| 771 | else | ||
| 772 | lastItem = x; | ||
| 773 | while (--remaining > 0 && // skip over nulls | ||
| 774 | (nextItem = itemAt(nextIndex = inc(nextIndex))) == null) | ||
| 775 | ; | ||
| 776 | return x; | ||
| 777 | } finally { | ||
| 778 | lock.unlock(); | ||
| 779 | } | ||
| 780 | } | ||
| 781 | |||
| 782 | public void remove() { | ||
| 783 | final ReentrantLock lock = ArrayBlockingQueue.this.lock; | ||
| 784 | lock.lock(); | ||
| 785 | try { | ||
| 786 | int i = lastRet; | ||
| 787 | if (i == -1) | ||
| 788 | throw new IllegalStateException(); | ||
| 789 | lastRet = -1; | ||
| 790 | E x = lastItem; | ||
| 791 | lastItem = null; | ||
| 792 | // only remove if item still at index | ||
| 793 | if (x != null && x == items[i]) { | ||
| 794 | boolean removingHead = (i == takeIndex); | ||
| 795 | removeAt(i); | ||
| 796 | if (!removingHead) | ||
| 797 | nextIndex = dec(nextIndex); | ||
| 798 | } | ||
| 799 | } finally { | ||
| 800 | lock.unlock(); | ||
| 801 | } | ||
| 802 | } | ||
| 803 | } | ||
| 804 | |||
| 805 | } | ||
Binary file not shown.
| @@ -0,0 +1,650 @@ | |||
| 1 | /* | ||
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 3 | * | ||
| 4 | * This code is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License version 2 only, as | ||
| 6 | * published by the Free Software Foundation. Oracle designates this | ||
| 7 | * particular file as subject to the "Classpath" exception as provided | ||
| 8 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 9 | * | ||
| 10 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 13 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 14 | * accompanied this code). | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License version | ||
| 17 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | * | ||
| 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 21 | * or visit www.oracle.com if you need additional information or have any | ||
| 22 | * questions. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * This file is available under and governed by the GNU General Public | ||
| 27 | * License version 2 only, as published by the Free Software Foundation. | ||
| 28 | * However, the following notice accompanied the original version of this | ||
| 29 | * file: | ||
| 30 | * | ||
| 31 | * Written by Doug Lea with assistance from members of JCP JSR-166 | ||
| 32 | * Expert Group and released to the public domain, as explained at | ||
| 33 | * http://creativecommons.org/publicdomain/zero/1.0/ | ||
| 34 | */ | ||
| 35 | |||
| 36 | package java.util.concurrent; | ||
| 37 | import java.util.*; | ||
| 38 | |||
| 39 | /** | ||
| 40 | * A {@link Deque} that additionally supports blocking operations that wait | ||
| 41 | * for the deque to become non-empty when retrieving an element, and wait for | ||
| 42 | * space to become available in the deque when storing an element. | ||
| 43 | * | ||
| 44 | * <p><tt>BlockingDeque</tt> methods come in four forms, with different ways | ||
| 45 | * of handling operations that cannot be satisfied immediately, but may be | ||
| 46 | * satisfied at some point in the future: | ||
| 47 | * one throws an exception, the second returns a special value (either | ||
| 48 | * <tt>null</tt> or <tt>false</tt>, depending on the operation), the third | ||
| 49 | * blocks the current thread indefinitely until the operation can succeed, | ||
| 50 | * and the fourth blocks for only a given maximum time limit before giving | ||
| 51 | * up. These methods are summarized in the following table: | ||
| 52 | * | ||
| 53 | * <p> | ||
| 54 | * <table BORDER CELLPADDING=3 CELLSPACING=1> | ||
| 55 | * <tr> | ||
| 56 | * <td ALIGN=CENTER COLSPAN = 5> <b>First Element (Head)</b></td> | ||
| 57 | * </tr> | ||
| 58 | * <tr> | ||
| 59 | * <td></td> | ||
| 60 | * <td ALIGN=CENTER><em>Throws exception</em></td> | ||
| 61 | * <td ALIGN=CENTER><em>Special value</em></td> | ||
| 62 | * <td ALIGN=CENTER><em>Blocks</em></td> | ||
| 63 | * <td ALIGN=CENTER><em>Times out</em></td> | ||
| 64 | * </tr> | ||
| 65 | * <tr> | ||
| 66 | * <td><b>Insert</b></td> | ||
| 67 | * <td>{@link #addFirst addFirst(e)}</td> | ||
| 68 | * <td>{@link #offerFirst(Object) offerFirst(e)}</td> | ||
| 69 | * <td>{@link #putFirst putFirst(e)}</td> | ||
| 70 | * <td>{@link #offerFirst(Object, long, TimeUnit) offerFirst(e, time, unit)}</td> | ||
| 71 | * </tr> | ||
| 72 | * <tr> | ||
| 73 | * <td><b>Remove</b></td> | ||
| 74 | * <td>{@link #removeFirst removeFirst()}</td> | ||
| 75 | * <td>{@link #pollFirst pollFirst()}</td> | ||
| 76 | * <td>{@link #takeFirst takeFirst()}</td> | ||
| 77 | * <td>{@link #pollFirst(long, TimeUnit) pollFirst(time, unit)}</td> | ||
| 78 | * </tr> | ||
| 79 | * <tr> | ||
| 80 | * <td><b>Examine</b></td> | ||
| 81 | * <td>{@link #getFirst getFirst()}</td> | ||
| 82 | * <td>{@link #peekFirst peekFirst()}</td> | ||
| 83 | * <td><em>not applicable</em></td> | ||
| 84 | * <td><em>not applicable</em></td> | ||
| 85 | * </tr> | ||
| 86 | * <tr> | ||
| 87 | * <td ALIGN=CENTER COLSPAN = 5> <b>Last Element (Tail)</b></td> | ||
| 88 | * </tr> | ||
| 89 | * <tr> | ||
| 90 | * <td></td> | ||
| 91 | * <td ALIGN=CENTER><em>Throws exception</em></td> | ||
| 92 | * <td ALIGN=CENTER><em>Special value</em></td> | ||
| 93 | * <td ALIGN=CENTER><em>Blocks</em></td> | ||
| 94 | * <td ALIGN=CENTER><em>Times out</em></td> | ||
| 95 | * </tr> | ||
| 96 | * <tr> | ||
| 97 | * <td><b>Insert</b></td> | ||
| 98 | * <td>{@link #addLast addLast(e)}</td> | ||
| 99 | * <td>{@link #offerLast(Object) offerLast(e)}</td> | ||
| 100 | * <td>{@link #putLast putLast(e)}</td> | ||
| 101 | * <td>{@link #offerLast(Object, long, TimeUnit) offerLast(e, time, unit)}</td> | ||
| 102 | * </tr> | ||
| 103 | * <tr> | ||
| 104 | * <td><b>Remove</b></td> | ||
| 105 | * <td>{@link #removeLast() removeLast()}</td> | ||
| 106 | * <td>{@link #pollLast() pollLast()}</td> | ||
| 107 | * <td>{@link #takeLast takeLast()}</td> | ||
| 108 | * <td>{@link #pollLast(long, TimeUnit) pollLast(time, unit)}</td> | ||
| 109 | * </tr> | ||
| 110 | * <tr> | ||
| 111 | * <td><b>Examine</b></td> | ||
| 112 | * <td>{@link #getLast getLast()}</td> | ||
| 113 | * <td>{@link #peekLast peekLast()}</td> | ||
| 114 | * <td><em>not applicable</em></td> | ||
| 115 | * <td><em>not applicable</em></td> | ||
| 116 | * </tr> | ||
| 117 | * </table> | ||
| 118 | * | ||
| 119 | * <p>Like any {@link BlockingQueue}, a <tt>BlockingDeque</tt> is thread safe, | ||
| 120 | * does not permit null elements, and may (or may not) be | ||
| 121 | * capacity-constrained. | ||
| 122 | * | ||
| 123 | * <p>A <tt>BlockingDeque</tt> implementation may be used directly as a FIFO | ||
| 124 | * <tt>BlockingQueue</tt>. The methods inherited from the | ||
| 125 | * <tt>BlockingQueue</tt> interface are precisely equivalent to | ||
| 126 | * <tt>BlockingDeque</tt> methods as indicated in the following table: | ||
| 127 | * | ||
| 128 | * <p> | ||
| 129 | * <table BORDER CELLPADDING=3 CELLSPACING=1> | ||
| 130 | * <tr> | ||
| 131 | * <td ALIGN=CENTER> <b><tt>BlockingQueue</tt> Method</b></td> | ||
| 132 | * <td ALIGN=CENTER> <b>Equivalent <tt>BlockingDeque</tt> Method</b></td> | ||
| 133 | * </tr> | ||
| 134 | * <tr> | ||
| 135 | * <td ALIGN=CENTER COLSPAN = 2> <b>Insert</b></td> | ||
| 136 | * </tr> | ||
| 137 | * <tr> | ||
| 138 | * <td>{@link #add(Object) add(e)}</td> | ||
| 139 | * <td>{@link #addLast(Object) addLast(e)}</td> | ||
| 140 | * </tr> | ||
| 141 | * <tr> | ||
| 142 | * <td>{@link #offer(Object) offer(e)}</td> | ||
| 143 | * <td>{@link #offerLast(Object) offerLast(e)}</td> | ||
| 144 | * </tr> | ||
| 145 | * <tr> | ||
| 146 | * <td>{@link #put(Object) put(e)}</td> | ||
| 147 | * <td>{@link #putLast(Object) putLast(e)}</td> | ||
| 148 | * </tr> | ||
| 149 | * <tr> | ||
| 150 | * <td>{@link #offer(Object, long, TimeUnit) offer(e, time, unit)}</td> | ||
| 151 | * <td>{@link #offerLast(Object, long, TimeUnit) offerLast(e, time, unit)}</td> | ||
| 152 | * </tr> | ||
| 153 | * <tr> | ||
| 154 | * <td ALIGN=CENTER COLSPAN = 2> <b>Remove</b></td> | ||
| 155 | * </tr> | ||
| 156 | * <tr> | ||
| 157 | * <td>{@link #remove() remove()}</td> | ||
| 158 | * <td>{@link #removeFirst() removeFirst()}</td> | ||
| 159 | * </tr> | ||
| 160 | * <tr> | ||
| 161 | * <td>{@link #poll() poll()}</td> | ||
| 162 | * <td>{@link #pollFirst() pollFirst()}</td> | ||
| 163 | * </tr> | ||
| 164 | * <tr> | ||
| 165 | * <td>{@link #take() take()}</td> | ||
| 166 | * <td>{@link #takeFirst() takeFirst()}</td> | ||
| 167 | * </tr> | ||
| 168 | * <tr> | ||
| 169 | * <td>{@link #poll(long, TimeUnit) poll(time, unit)}</td> | ||
| 170 | * <td>{@link #pollFirst(long, TimeUnit) pollFirst(time, unit)}</td> | ||
| 171 | * </tr> | ||
| 172 | * <tr> | ||
| 173 | * <td ALIGN=CENTER COLSPAN = 2> <b>Examine</b></td> | ||
| 174 | * </tr> | ||
| 175 | * <tr> | ||
| 176 | * <td>{@link #element() element()}</td> | ||
| 177 | * <td>{@link #getFirst() getFirst()}</td> | ||
| 178 | * </tr> | ||
| 179 | * <tr> | ||
| 180 | * <td>{@link #peek() peek()}</td> | ||
| 181 | * <td>{@link #peekFirst() peekFirst()}</td> | ||
| 182 | * </tr> | ||
| 183 | * </table> | ||
| 184 | * | ||
| 185 | * <p>Memory consistency effects: As with other concurrent | ||
| 186 | * collections, actions in a thread prior to placing an object into a | ||
| 187 | * {@code BlockingDeque} | ||
| 188 | * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> | ||
| 189 | * actions subsequent to the access or removal of that element from | ||
| 190 | * the {@code BlockingDeque} in another thread. | ||
| 191 | * | ||
| 192 | * <p>This interface is a member of the | ||
| 193 | * <a href="{@docRoot}/../technotes/guides/collections/index.html"> | ||
| 194 | * Java Collections Framework</a>. | ||
| 195 | * | ||
| 196 | * @since 1.6 | ||
| 197 | * @author Doug Lea | ||
| 198 | * @param <E> the type of elements held in this collection | ||
| 199 | */ | ||
| 200 | public interface BlockingDeque<E> extends BlockingQueue<E>, Deque<E> { | ||
| 201 | /* | ||
| 202 | * We have "diamond" multiple interface inheritance here, and that | ||
| 203 | * introduces ambiguities. Methods might end up with different | ||
| 204 | * specs depending on the branch chosen by javadoc. Thus a lot of | ||
| 205 | * methods specs here are copied from superinterfaces. | ||
| 206 | */ | ||
| 207 | |||
| 208 | /** | ||
| 209 | * Inserts the specified element at the front of this deque if it is | ||
| 210 | * possible to do so immediately without violating capacity restrictions, | ||
| 211 | * throwing an <tt>IllegalStateException</tt> if no space is currently | ||
| 212 | * available. When using a capacity-restricted deque, it is generally | ||
| 213 | * preferable to use {@link #offerFirst(Object) offerFirst}. | ||
| 214 | * | ||
| 215 | * @param e the element to add | ||
| 216 | * @throws IllegalStateException {@inheritDoc} | ||
| 217 | * @throws ClassCastException {@inheritDoc} | ||
| 218 | * @throws NullPointerException if the specified element is null | ||
| 219 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 220 | */ | ||
| 221 | void addFirst(E e); | ||
| 222 | |||
| 223 | /** | ||
| 224 | * Inserts the specified element at the end of this deque if it is | ||
| 225 | * possible to do so immediately without violating capacity restrictions, | ||
| 226 | * throwing an <tt>IllegalStateException</tt> if no space is currently | ||
| 227 | * available. When using a capacity-restricted deque, it is generally | ||
| 228 | * preferable to use {@link #offerLast(Object) offerLast}. | ||
| 229 | * | ||
| 230 | * @param e the element to add | ||
| 231 | * @throws IllegalStateException {@inheritDoc} | ||
| 232 | * @throws ClassCastException {@inheritDoc} | ||
| 233 | * @throws NullPointerException if the specified element is null | ||
| 234 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 235 | */ | ||
| 236 | void addLast(E e); | ||
| 237 | |||
| 238 | /** | ||
| 239 | * Inserts the specified element at the front of this deque if it is | ||
| 240 | * possible to do so immediately without violating capacity restrictions, | ||
| 241 | * returning <tt>true</tt> upon success and <tt>false</tt> if no space is | ||
| 242 | * currently available. | ||
| 243 | * When using a capacity-restricted deque, this method is generally | ||
| 244 | * preferable to the {@link #addFirst(Object) addFirst} method, which can | ||
| 245 | * fail to insert an element only by throwing an exception. | ||
| 246 | * | ||
| 247 | * @param e the element to add | ||
| 248 | * @throws ClassCastException {@inheritDoc} | ||
| 249 | * @throws NullPointerException if the specified element is null | ||
| 250 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 251 | */ | ||
| 252 | boolean offerFirst(E e); | ||
| 253 | |||
| 254 | /** | ||
| 255 | * Inserts the specified element at the end of this deque if it is | ||
| 256 | * possible to do so immediately without violating capacity restrictions, | ||
| 257 | * returning <tt>true</tt> upon success and <tt>false</tt> if no space is | ||
| 258 | * currently available. | ||
| 259 | * When using a capacity-restricted deque, this method is generally | ||
| 260 | * preferable to the {@link #addLast(Object) addLast} method, which can | ||
| 261 | * fail to insert an element only by throwing an exception. | ||
| 262 | * | ||
| 263 | * @param e the element to add | ||
| 264 | * @throws ClassCastException {@inheritDoc} | ||
| 265 | * @throws NullPointerException if the specified element is null | ||
| 266 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 267 | */ | ||
| 268 | boolean offerLast(E e); | ||
| 269 | |||
| 270 | /** | ||
| 271 | * Inserts the specified element at the front of this deque, | ||
| 272 | * waiting if necessary for space to become available. | ||
| 273 | * | ||
| 274 | * @param e the element to add | ||
| 275 | * @throws InterruptedException if interrupted while waiting | ||
| 276 | * @throws ClassCastException if the class of the specified element | ||
| 277 | * prevents it from being added to this deque | ||
| 278 | * @throws NullPointerException if the specified element is null | ||
| 279 | * @throws IllegalArgumentException if some property of the specified | ||
| 280 | * element prevents it from being added to this deque | ||
| 281 | */ | ||
| 282 | void putFirst(E e) throws InterruptedException; | ||
| 283 | |||
| 284 | /** | ||
| 285 | * Inserts the specified element at the end of this deque, | ||
| 286 | * waiting if necessary for space to become available. | ||
| 287 | * | ||
| 288 | * @param e the element to add | ||
| 289 | * @throws InterruptedException if interrupted while waiting | ||
| 290 | * @throws ClassCastException if the class of the specified element | ||
| 291 | * prevents it from being added to this deque | ||
| 292 | * @throws NullPointerException if the specified element is null | ||
| 293 | * @throws IllegalArgumentException if some property of the specified | ||
| 294 | * element prevents it from being added to this deque | ||
| 295 | */ | ||
| 296 | void putLast(E e) throws InterruptedException; | ||
| 297 | |||
| 298 | /** | ||
| 299 | * Inserts the specified element at the front of this deque, | ||
| 300 | * waiting up to the specified wait time if necessary for space to | ||
| 301 | * become available. | ||
| 302 | * | ||
| 303 | * @param e the element to add | ||
| 304 | * @param timeout how long to wait before giving up, in units of | ||
| 305 | * <tt>unit</tt> | ||
| 306 | * @param unit a <tt>TimeUnit</tt> determining how to interpret the | ||
| 307 | * <tt>timeout</tt> parameter | ||
| 308 | * @return <tt>true</tt> if successful, or <tt>false</tt> if | ||
| 309 | * the specified waiting time elapses before space is available | ||
| 310 | * @throws InterruptedException if interrupted while waiting | ||
| 311 | * @throws ClassCastException if the class of the specified element | ||
| 312 | * prevents it from being added to this deque | ||
| 313 | * @throws NullPointerException if the specified element is null | ||
| 314 | * @throws IllegalArgumentException if some property of the specified | ||
| 315 | * element prevents it from being added to this deque | ||
| 316 | */ | ||
| 317 | boolean offerFirst(E e, long timeout, TimeUnit unit) | ||
| 318 | throws InterruptedException; | ||
| 319 | |||
| 320 | /** | ||
| 321 | * Inserts the specified element at the end of this deque, | ||
| 322 | * waiting up to the specified wait time if necessary for space to | ||
| 323 | * become available. | ||
| 324 | * | ||
| 325 | * @param e the element to add | ||
| 326 | * @param timeout how long to wait before giving up, in units of | ||
| 327 | * <tt>unit</tt> | ||
| 328 | * @param unit a <tt>TimeUnit</tt> determining how to interpret the | ||
| 329 | * <tt>timeout</tt> parameter | ||
| 330 | * @return <tt>true</tt> if successful, or <tt>false</tt> if | ||
| 331 | * the specified waiting time elapses before space is available | ||
| 332 | * @throws InterruptedException if interrupted while waiting | ||
| 333 | * @throws ClassCastException if the class of the specified element | ||
| 334 | * prevents it from being added to this deque | ||
| 335 | * @throws NullPointerException if the specified element is null | ||
| 336 | * @throws IllegalArgumentException if some property of the specified | ||
| 337 | * element prevents it from being added to this deque | ||
| 338 | */ | ||
| 339 | boolean offerLast(E e, long timeout, TimeUnit unit) | ||
| 340 | throws InterruptedException; | ||
| 341 | |||
| 342 | /** | ||
| 343 | * Retrieves and removes the first element of this deque, waiting | ||
| 344 | * if necessary until an element becomes available. | ||
| 345 | * | ||
| 346 | * @return the head of this deque | ||
| 347 | * @throws InterruptedException if interrupted while waiting | ||
| 348 | */ | ||
| 349 | E takeFirst() throws InterruptedException; | ||
| 350 | |||
| 351 | /** | ||
| 352 | * Retrieves and removes the last element of this deque, waiting | ||
| 353 | * if necessary until an element becomes available. | ||
| 354 | * | ||
| 355 | * @return the tail of this deque | ||
| 356 | * @throws InterruptedException if interrupted while waiting | ||
| 357 | */ | ||
| 358 | E takeLast() throws InterruptedException; | ||
| 359 | |||
| 360 | /** | ||
| 361 | * Retrieves and removes the first element of this deque, waiting | ||
| 362 | * up to the specified wait time if necessary for an element to | ||
| 363 | * become available. | ||
| 364 | * | ||
| 365 | * @param timeout how long to wait before giving up, in units of | ||
| 366 | * <tt>unit</tt> | ||
| 367 | * @param unit a <tt>TimeUnit</tt> determining how to interpret the | ||
| 368 | * <tt>timeout</tt> parameter | ||
| 369 | * @return the head of this deque, or <tt>null</tt> if the specified | ||
| 370 | * waiting time elapses before an element is available | ||
| 371 | * @throws InterruptedException if interrupted while waiting | ||
| 372 | */ | ||
| 373 | E pollFirst(long timeout, TimeUnit unit) | ||
| 374 | throws InterruptedException; | ||
| 375 | |||
| 376 | /** | ||
| 377 | * Retrieves and removes the last element of this deque, waiting | ||
| 378 | * up to the specified wait time if necessary for an element to | ||
| 379 | * become available. | ||
| 380 | * | ||
| 381 | * @param timeout how long to wait before giving up, in units of | ||
| 382 | * <tt>unit</tt> | ||
| 383 | * @param unit a <tt>TimeUnit</tt> determining how to interpret the | ||
| 384 | * <tt>timeout</tt> parameter | ||
| 385 | * @return the tail of this deque, or <tt>null</tt> if the specified | ||
| 386 | * waiting time elapses before an element is available | ||
| 387 | * @throws InterruptedException if interrupted while waiting | ||
| 388 | */ | ||
| 389 | E pollLast(long timeout, TimeUnit unit) | ||
| 390 | throws InterruptedException; | ||
| 391 | |||
| 392 | /** | ||
| 393 | * Removes the first occurrence of the specified element from this deque. | ||
| 394 | * If the deque does not contain the element, it is unchanged. | ||
| 395 | * More formally, removes the first element <tt>e</tt> such that | ||
| 396 | * <tt>o.equals(e)</tt> (if such an element exists). | ||
| 397 | * Returns <tt>true</tt> if this deque contained the specified element | ||
| 398 | * (or equivalently, if this deque changed as a result of the call). | ||
| 399 | * | ||
| 400 | * @param o element to be removed from this deque, if present | ||
| 401 | * @return <tt>true</tt> if an element was removed as a result of this call | ||
| 402 | * @throws ClassCastException if the class of the specified element | ||
| 403 | * is incompatible with this deque | ||
| 404 | * (<a href="../Collection.html#optional-restrictions">optional</a>) | ||
| 405 | * @throws NullPointerException if the specified element is null | ||
| 406 | * (<a href="../Collection.html#optional-restrictions">optional</a>) | ||
| 407 | */ | ||
| 408 | boolean removeFirstOccurrence(Object o); | ||
| 409 | |||
| 410 | /** | ||
| 411 | * Removes the last occurrence of the specified element from this deque. | ||
| 412 | * If the deque does not contain the element, it is unchanged. | ||
| 413 | * More formally, removes the last element <tt>e</tt> such that | ||
| 414 | * <tt>o.equals(e)</tt> (if such an element exists). | ||
| 415 | * Returns <tt>true</tt> if this deque contained the specified element | ||
| 416 | * (or equivalently, if this deque changed as a result of the call). | ||
| 417 | * | ||
| 418 | * @param o element to be removed from this deque, if present | ||
| 419 | * @return <tt>true</tt> if an element was removed as a result of this call | ||
| 420 | * @throws ClassCastException if the class of the specified element | ||
| 421 | * is incompatible with this deque | ||
| 422 | * (<a href="../Collection.html#optional-restrictions">optional</a>) | ||
| 423 | * @throws NullPointerException if the specified element is null | ||
| 424 | * (<a href="../Collection.html#optional-restrictions">optional</a>) | ||
| 425 | */ | ||
| 426 | boolean removeLastOccurrence(Object o); | ||
| 427 | |||
| 428 | // *** BlockingQueue methods *** | ||
| 429 | |||
| 430 | /** | ||
| 431 | * Inserts the specified element into the queue represented by this deque | ||
| 432 | * (in other words, at the tail of this deque) if it is possible to do so | ||
| 433 | * immediately without violating capacity restrictions, returning | ||
| 434 | * <tt>true</tt> upon success and throwing an | ||
| 435 | * <tt>IllegalStateException</tt> if no space is currently available. | ||
| 436 | * When using a capacity-restricted deque, it is generally preferable to | ||
| 437 | * use {@link #offer(Object) offer}. | ||
| 438 | * | ||
| 439 | * <p>This method is equivalent to {@link #addLast(Object) addLast}. | ||
| 440 | * | ||
| 441 | * @param e the element to add | ||
| 442 | * @throws IllegalStateException {@inheritDoc} | ||
| 443 | * @throws ClassCastException if the class of the specified element | ||
| 444 | * prevents it from being added to this deque | ||
| 445 | * @throws NullPointerException if the specified element is null | ||
| 446 | * @throws IllegalArgumentException if some property of the specified | ||
| 447 | * element prevents it from being added to this deque | ||
| 448 | */ | ||
| 449 | boolean add(E e); | ||
| 450 | |||
| 451 | /** | ||
| 452 | * Inserts the specified element into the queue represented by this deque | ||
| 453 | * (in other words, at the tail of this deque) if it is possible to do so | ||
| 454 | * immediately without violating capacity restrictions, returning | ||
| 455 | * <tt>true</tt> upon success and <tt>false</tt> if no space is currently | ||
| 456 | * available. When using a capacity-restricted deque, this method is | ||
| 457 | * generally preferable to the {@link #add} method, which can fail to | ||
| 458 | * insert an element only by throwing an exception. | ||
| 459 | * | ||
| 460 | * <p>This method is equivalent to {@link #offerLast(Object) offerLast}. | ||
| 461 | * | ||
| 462 | * @param e the element to add | ||
| 463 | * @throws ClassCastException if the class of the specified element | ||
| 464 | * prevents it from being added to this deque | ||
| 465 | * @throws NullPointerException if the specified element is null | ||
| 466 | * @throws IllegalArgumentException if some property of the specified | ||
| 467 | * element prevents it from being added to this deque | ||
| 468 | */ | ||
| 469 | boolean offer(E e); | ||
| 470 | |||
| 471 | /** | ||
| 472 | * Inserts the specified element into the queue represented by this deque | ||
| 473 | * (in other words, at the tail of this deque), waiting if necessary for | ||
| 474 | * space to become available. | ||
| 475 | * | ||
| 476 | * <p>This method is equivalent to {@link #putLast(Object) putLast}. | ||
| 477 | * | ||
| 478 | * @param e the element to add | ||
| 479 | * @throws InterruptedException {@inheritDoc} | ||
| 480 | * @throws ClassCastException if the class of the specified element | ||
| 481 | * prevents it from being added to this deque | ||
| 482 | * @throws NullPointerException if the specified element is null | ||
| 483 | * @throws IllegalArgumentException if some property of the specified | ||
| 484 | * element prevents it from being added to this deque | ||
| 485 | */ | ||
| 486 | void put(E e) throws InterruptedException; | ||
| 487 | |||
| 488 | /** | ||
| 489 | * Inserts the specified element into the queue represented by this deque | ||
| 490 | * (in other words, at the tail of this deque), waiting up to the | ||
| 491 | * specified wait time if necessary for space to become available. | ||
| 492 | * | ||
| 493 | * <p>This method is equivalent to | ||
| 494 | * {@link #offerLast(Object,long,TimeUnit) offerLast}. | ||
| 495 | * | ||
| 496 | * @param e the element to add | ||
| 497 | * @return <tt>true</tt> if the element was added to this deque, else | ||
| 498 | * <tt>false</tt> | ||
| 499 | * @throws InterruptedException {@inheritDoc} | ||
| 500 | * @throws ClassCastException if the class of the specified element | ||
| 501 | * prevents it from being added to this deque | ||
| 502 | * @throws NullPointerException if the specified element is null | ||
| 503 | * @throws IllegalArgumentException if some property of the specified | ||
| 504 | * element prevents it from being added to this deque | ||
| 505 | */ | ||
| 506 | boolean offer(E e, long timeout, TimeUnit unit) | ||
| 507 | throws InterruptedException; | ||
| 508 | |||
| 509 | /** | ||
| 510 | * Retrieves and removes the head of the queue represented by this deque | ||
| 511 | * (in other words, the first element of this deque). | ||
| 512 | * This method differs from {@link #poll poll} only in that it | ||
| 513 | * throws an exception if this deque is empty. | ||
| 514 | * | ||
| 515 | * <p>This method is equivalent to {@link #removeFirst() removeFirst}. | ||
| 516 | * | ||
| 517 | * @return the head of the queue represented by this deque | ||
| 518 | * @throws NoSuchElementException if this deque is empty | ||
| 519 | */ | ||
| 520 | E remove(); | ||
| 521 | |||
| 522 | /** | ||
| 523 | * Retrieves and removes the head of the queue represented by this deque | ||
| 524 | * (in other words, the first element of this deque), or returns | ||
| 525 | * <tt>null</tt> if this deque is empty. | ||
| 526 | * | ||
| 527 | * <p>This method is equivalent to {@link #pollFirst()}. | ||
| 528 | * | ||
| 529 | * @return the head of this deque, or <tt>null</tt> if this deque is empty | ||
| 530 | */ | ||
| 531 | E poll(); | ||
| 532 | |||
| 533 | /** | ||
| 534 | * Retrieves and removes the head of the queue represented by this deque | ||
| 535 | * (in other words, the first element of this deque), waiting if | ||
| 536 | * necessary until an element becomes available. | ||
| 537 | * | ||
| 538 | * <p>This method is equivalent to {@link #takeFirst() takeFirst}. | ||
| 539 | * | ||
| 540 | * @return the head of this deque | ||
| 541 | * @throws InterruptedException if interrupted while waiting | ||
| 542 | */ | ||
| 543 | E take() throws InterruptedException; | ||
| 544 | |||
| 545 | /** | ||
| 546 | * Retrieves and removes the head of the queue represented by this deque | ||
| 547 | * (in other words, the first element of this deque), waiting up to the | ||
| 548 | * specified wait time if necessary for an element to become available. | ||
| 549 | * | ||
| 550 | * <p>This method is equivalent to | ||
| 551 | * {@link #pollFirst(long,TimeUnit) pollFirst}. | ||
| 552 | * | ||
| 553 | * @return the head of this deque, or <tt>null</tt> if the | ||
| 554 | * specified waiting time elapses before an element is available | ||
| 555 | * @throws InterruptedException if interrupted while waiting | ||
| 556 | */ | ||
| 557 | E poll(long timeout, TimeUnit unit) | ||
| 558 | throws InterruptedException; | ||
| 559 | |||
| 560 | /** | ||
| 561 | * Retrieves, but does not remove, the head of the queue represented by | ||
| 562 | * this deque (in other words, the first element of this deque). | ||
| 563 | * This method differs from {@link #peek peek} only in that it throws an | ||
| 564 | * exception if this deque is empty. | ||
| 565 | * | ||
| 566 | * <p>This method is equivalent to {@link #getFirst() getFirst}. | ||
| 567 | * | ||
| 568 | * @return the head of this deque | ||
| 569 | * @throws NoSuchElementException if this deque is empty | ||
| 570 | */ | ||
| 571 | E element(); | ||
| 572 | |||
| 573 | /** | ||
| 574 | * Retrieves, but does not remove, the head of the queue represented by | ||
| 575 | * this deque (in other words, the first element of this deque), or | ||
| 576 | * returns <tt>null</tt> if this deque is empty. | ||
| 577 | * | ||
| 578 | * <p>This method is equivalent to {@link #peekFirst() peekFirst}. | ||
| 579 | * | ||
| 580 | * @return the head of this deque, or <tt>null</tt> if this deque is empty | ||
| 581 | */ | ||
| 582 | E peek(); | ||
| 583 | |||
| 584 | /** | ||
| 585 | * Removes the first occurrence of the specified element from this deque. | ||
| 586 | * If the deque does not contain the element, it is unchanged. | ||
| 587 | * More formally, removes the first element <tt>e</tt> such that | ||
| 588 | * <tt>o.equals(e)</tt> (if such an element exists). | ||
| 589 | * Returns <tt>true</tt> if this deque contained the specified element | ||
| 590 | * (or equivalently, if this deque changed as a result of the call). | ||
| 591 | * | ||
| 592 | * <p>This method is equivalent to | ||
| 593 | * {@link #removeFirstOccurrence(Object) removeFirstOccurrence}. | ||
| 594 | * | ||
| 595 | * @param o element to be removed from this deque, if present | ||
| 596 | * @return <tt>true</tt> if this deque changed as a result of the call | ||
| 597 | * @throws ClassCastException if the class of the specified element | ||
| 598 | * is incompatible with this deque | ||
| 599 | * (<a href="../Collection.html#optional-restrictions">optional</a>) | ||
| 600 | * @throws NullPointerException if the specified element is null | ||
| 601 | * (<a href="../Collection.html#optional-restrictions">optional</a>) | ||
| 602 | */ | ||
| 603 | boolean remove(Object o); | ||
| 604 | |||
| 605 | /** | ||
| 606 | * Returns <tt>true</tt> if this deque contains the specified element. | ||
| 607 | * More formally, returns <tt>true</tt> if and only if this deque contains | ||
| 608 | * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>. | ||
| 609 | * | ||
| 610 | * @param o object to be checked for containment in this deque | ||
| 611 | * @return <tt>true</tt> if this deque contains the specified element | ||
| 612 | * @throws ClassCastException if the class of the specified element | ||
| 613 | * is incompatible with this deque | ||
| 614 | * (<a href="../Collection.html#optional-restrictions">optional</a>) | ||
| 615 | * @throws NullPointerException if the specified element is null | ||
| 616 | * (<a href="../Collection.html#optional-restrictions">optional</a>) | ||
| 617 | */ | ||
| 618 | public boolean contains(Object o); | ||
| 619 | |||
| 620 | /** | ||
| 621 | * Returns the number of elements in this deque. | ||
| 622 | * | ||
| 623 | * @return the number of elements in this deque | ||
| 624 | */ | ||
| 625 | public int size(); | ||
| 626 | |||
| 627 | /** | ||
| 628 | * Returns an iterator over the elements in this deque in proper sequence. | ||
| 629 | * The elements will be returned in order from first (head) to last (tail). | ||
| 630 | * | ||
| 631 | * @return an iterator over the elements in this deque in proper sequence | ||
| 632 | */ | ||
| 633 | Iterator<E> iterator(); | ||
| 634 | |||
| 635 | // *** Stack methods *** | ||
| 636 | |||
| 637 | /** | ||
| 638 | * Pushes an element onto the stack represented by this deque. In other | ||
| 639 | * words, inserts the element at the front of this deque unless it would | ||
| 640 | * violate capacity restrictions. | ||
| 641 | * | ||
| 642 | * <p>This method is equivalent to {@link #addFirst(Object) addFirst}. | ||
| 643 | * | ||
| 644 | * @throws IllegalStateException {@inheritDoc} | ||
| 645 | * @throws ClassCastException {@inheritDoc} | ||
| 646 | * @throws NullPointerException if the specified element is null | ||
| 647 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 648 | */ | ||
| 649 | void push(E e); | ||
| 650 | } | ||
Binary file not shown.
| @@ -0,0 +1,377 @@ | |||
| 1 | /* | ||
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 3 | * | ||
| 4 | * This code is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License version 2 only, as | ||
| 6 | * published by the Free Software Foundation. Oracle designates this | ||
| 7 | * particular file as subject to the "Classpath" exception as provided | ||
| 8 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 9 | * | ||
| 10 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 13 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 14 | * accompanied this code). | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License version | ||
| 17 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | * | ||
| 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 21 | * or visit www.oracle.com if you need additional information or have any | ||
| 22 | * questions. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * This file is available under and governed by the GNU General Public | ||
| 27 | * License version 2 only, as published by the Free Software Foundation. | ||
| 28 | * However, the following notice accompanied the original version of this | ||
| 29 | * file: | ||
| 30 | * | ||
| 31 | * Written by Doug Lea with assistance from members of JCP JSR-166 | ||
| 32 | * Expert Group and released to the public domain, as explained at | ||
| 33 | * http://creativecommons.org/publicdomain/zero/1.0/ | ||
| 34 | */ | ||
| 35 | |||
| 36 | package java.util.concurrent; | ||
| 37 | |||
| 38 | import java.util.Collection; | ||
| 39 | import java.util.Queue; | ||
| 40 | |||
| 41 | /** | ||
| 42 | * A {@link java.util.Queue} that additionally supports operations | ||
| 43 | * that wait for the queue to become non-empty when retrieving an | ||
| 44 | * element, and wait for space to become available in the queue when | ||
| 45 | * storing an element. | ||
| 46 | * | ||
| 47 | * <p><tt>BlockingQueue</tt> methods come in four forms, with different ways | ||
| 48 | * of handling operations that cannot be satisfied immediately, but may be | ||
| 49 | * satisfied at some point in the future: | ||
| 50 | * one throws an exception, the second returns a special value (either | ||
| 51 | * <tt>null</tt> or <tt>false</tt>, depending on the operation), the third | ||
| 52 | * blocks the current thread indefinitely until the operation can succeed, | ||
| 53 | * and the fourth blocks for only a given maximum time limit before giving | ||
| 54 | * up. These methods are summarized in the following table: | ||
| 55 | * | ||
| 56 | * <p> | ||
| 57 | * <table BORDER CELLPADDING=3 CELLSPACING=1> | ||
| 58 | * <tr> | ||
| 59 | * <td></td> | ||
| 60 | * <td ALIGN=CENTER><em>Throws exception</em></td> | ||
| 61 | * <td ALIGN=CENTER><em>Special value</em></td> | ||
| 62 | * <td ALIGN=CENTER><em>Blocks</em></td> | ||
| 63 | * <td ALIGN=CENTER><em>Times out</em></td> | ||
| 64 | * </tr> | ||
| 65 | * <tr> | ||
| 66 | * <td><b>Insert</b></td> | ||
| 67 | * <td>{@link #add add(e)}</td> | ||
| 68 | * <td>{@link #offer offer(e)}</td> | ||
| 69 | * <td>{@link #put put(e)}</td> | ||
| 70 | * <td>{@link #offer(Object, long, TimeUnit) offer(e, time, unit)}</td> | ||
| 71 | * </tr> | ||
| 72 | * <tr> | ||
| 73 | * <td><b>Remove</b></td> | ||
| 74 | * <td>{@link #remove remove()}</td> | ||
| 75 | * <td>{@link #poll poll()}</td> | ||
| 76 | * <td>{@link #take take()}</td> | ||
| 77 | * <td>{@link #poll(long, TimeUnit) poll(time, unit)}</td> | ||
| 78 | * </tr> | ||
| 79 | * <tr> | ||
| 80 | * <td><b>Examine</b></td> | ||
| 81 | * <td>{@link #element element()}</td> | ||
| 82 | * <td>{@link #peek peek()}</td> | ||
| 83 | * <td><em>not applicable</em></td> | ||
| 84 | * <td><em>not applicable</em></td> | ||
| 85 | * </tr> | ||
| 86 | * </table> | ||
| 87 | * | ||
| 88 | * <p>A <tt>BlockingQueue</tt> does not accept <tt>null</tt> elements. | ||
| 89 | * Implementations throw <tt>NullPointerException</tt> on attempts | ||
| 90 | * to <tt>add</tt>, <tt>put</tt> or <tt>offer</tt> a <tt>null</tt>. A | ||
| 91 | * <tt>null</tt> is used as a sentinel value to indicate failure of | ||
| 92 | * <tt>poll</tt> operations. | ||
| 93 | * | ||
| 94 | * <p>A <tt>BlockingQueue</tt> may be capacity bounded. At any given | ||
| 95 | * time it may have a <tt>remainingCapacity</tt> beyond which no | ||
| 96 | * additional elements can be <tt>put</tt> without blocking. | ||
| 97 | * A <tt>BlockingQueue</tt> without any intrinsic capacity constraints always | ||
| 98 | * reports a remaining capacity of <tt>Integer.MAX_VALUE</tt>. | ||
| 99 | * | ||
| 100 | * <p> <tt>BlockingQueue</tt> implementations are designed to be used | ||
| 101 | * primarily for producer-consumer queues, but additionally support | ||
| 102 | * the {@link java.util.Collection} interface. So, for example, it is | ||
| 103 | * possible to remove an arbitrary element from a queue using | ||
| 104 | * <tt>remove(x)</tt>. However, such operations are in general | ||
| 105 | * <em>not</em> performed very efficiently, and are intended for only | ||
| 106 | * occasional use, such as when a queued message is cancelled. | ||
| 107 | * | ||
| 108 | * <p> <tt>BlockingQueue</tt> implementations are thread-safe. All | ||
| 109 | * queuing methods achieve their effects atomically using internal | ||
| 110 | * locks or other forms of concurrency control. However, the | ||
| 111 | * <em>bulk</em> Collection operations <tt>addAll</tt>, | ||
| 112 | * <tt>containsAll</tt>, <tt>retainAll</tt> and <tt>removeAll</tt> are | ||
| 113 | * <em>not</em> necessarily performed atomically unless specified | ||
| 114 | * otherwise in an implementation. So it is possible, for example, for | ||
| 115 | * <tt>addAll(c)</tt> to fail (throwing an exception) after adding | ||
| 116 | * only some of the elements in <tt>c</tt>. | ||
| 117 | * | ||
| 118 | * <p>A <tt>BlockingQueue</tt> does <em>not</em> intrinsically support | ||
| 119 | * any kind of "close" or "shutdown" operation to | ||
| 120 | * indicate that no more items will be added. The needs and usage of | ||
| 121 | * such features tend to be implementation-dependent. For example, a | ||
| 122 | * common tactic is for producers to insert special | ||
| 123 | * <em>end-of-stream</em> or <em>poison</em> objects, that are | ||
| 124 | * interpreted accordingly when taken by consumers. | ||
| 125 | * | ||
| 126 | * <p> | ||
| 127 | * Usage example, based on a typical producer-consumer scenario. | ||
| 128 | * Note that a <tt>BlockingQueue</tt> can safely be used with multiple | ||
| 129 | * producers and multiple consumers. | ||
| 130 | * <pre> | ||
| 131 | * class Producer implements Runnable { | ||
| 132 | * private final BlockingQueue queue; | ||
| 133 | * Producer(BlockingQueue q) { queue = q; } | ||
| 134 | * public void run() { | ||
| 135 | * try { | ||
| 136 | * while (true) { queue.put(produce()); } | ||
| 137 | * } catch (InterruptedException ex) { ... handle ...} | ||
| 138 | * } | ||
| 139 | * Object produce() { ... } | ||
| 140 | * } | ||
| 141 | * | ||
| 142 | * class Consumer implements Runnable { | ||
| 143 | * private final BlockingQueue queue; | ||
| 144 | * Consumer(BlockingQueue q) { queue = q; } | ||
| 145 | * public void run() { | ||
| 146 | * try { | ||
| 147 | * while (true) { consume(queue.take()); } | ||
| 148 | * } catch (InterruptedException ex) { ... handle ...} | ||
| 149 | * } | ||
| 150 | * void consume(Object x) { ... } | ||
| 151 | * } | ||
| 152 | * | ||
| 153 | * class Setup { | ||
| 154 | * void main() { | ||
| 155 | * BlockingQueue q = new SomeQueueImplementation(); | ||
| 156 | * Producer p = new Producer(q); | ||
| 157 | * Consumer c1 = new Consumer(q); | ||
| 158 | * Consumer c2 = new Consumer(q); | ||
| 159 | * new Thread(p).start(); | ||
| 160 | * new Thread(c1).start(); | ||
| 161 | * new Thread(c2).start(); | ||
| 162 | * } | ||
| 163 | * } | ||
| 164 | * </pre> | ||
| 165 | * | ||
| 166 | * <p>Memory consistency effects: As with other concurrent | ||
| 167 | * collections, actions in a thread prior to placing an object into a | ||
| 168 | * {@code BlockingQueue} | ||
| 169 | * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> | ||
| 170 | * actions subsequent to the access or removal of that element from | ||
| 171 | * the {@code BlockingQueue} in another thread. | ||
| 172 | * | ||
| 173 | * <p>This interface is a member of the | ||
| 174 | * <a href="{@docRoot}/../technotes/guides/collections/index.html"> | ||
| 175 | * Java Collections Framework</a>. | ||
| 176 | * | ||
| 177 | * @since 1.5 | ||
| 178 | * @author Doug Lea | ||
| 179 | * @param <E> the type of elements held in this collection | ||
| 180 | */ | ||
| 181 | public interface BlockingQueue<E> extends Queue<E> { | ||
| 182 | /** | ||
| 183 | * Inserts the specified element into this queue if it is possible to do | ||
| 184 | * so immediately without violating capacity restrictions, returning | ||
| 185 | * <tt>true</tt> upon success and throwing an | ||
| 186 | * <tt>IllegalStateException</tt> if no space is currently available. | ||
| 187 | * When using a capacity-restricted queue, it is generally preferable to | ||
| 188 | * use {@link #offer(Object) offer}. | ||
| 189 | * | ||
| 190 | * @param e the element to add | ||
| 191 | * @return <tt>true</tt> (as specified by {@link Collection#add}) | ||
| 192 | * @throws IllegalStateException if the element cannot be added at this | ||
| 193 | * time due to capacity restrictions | ||
| 194 | * @throws ClassCastException if the class of the specified element | ||
| 195 | * prevents it from being added to this queue | ||
| 196 | * @throws NullPointerException if the specified element is null | ||
| 197 | * @throws IllegalArgumentException if some property of the specified | ||
| 198 | * element prevents it from being added to this queue | ||
| 199 | */ | ||
| 200 | boolean add(E e); | ||
| 201 | |||
| 202 | /** | ||
| 203 | * Inserts the specified element into this queue if it is possible to do | ||
| 204 | * so immediately without violating capacity restrictions, returning | ||
| 205 | * <tt>true</tt> upon success and <tt>false</tt> if no space is currently | ||
| 206 | * available. When using a capacity-restricted queue, this method is | ||
| 207 | * generally preferable to {@link #add}, which can fail to insert an | ||
| 208 | * element only by throwing an exception. | ||
| 209 | * | ||
| 210 | * @param e the element to add | ||
| 211 | * @return <tt>true</tt> if the element was added to this queue, else | ||
| 212 | * <tt>false</tt> | ||
| 213 | * @throws ClassCastException if the class of the specified element | ||
| 214 | * prevents it from being added to this queue | ||
| 215 | * @throws NullPointerException if the specified element is null | ||
| 216 | * @throws IllegalArgumentException if some property of the specified | ||
| 217 | * element prevents it from being added to this queue | ||
| 218 | */ | ||
| 219 | boolean offer(E e); | ||
| 220 | |||
| 221 | /** | ||
| 222 | * Inserts the specified element into this queue, waiting if necessary | ||
| 223 | * for space to become available. | ||
| 224 | * | ||
| 225 | * @param e the element to add | ||
| 226 | * @throws InterruptedException if interrupted while waiting | ||
| 227 | * @throws ClassCastException if the class of the specified element | ||
| 228 | * prevents it from being added to this queue | ||
| 229 | * @throws NullPointerException if the specified element is null | ||
| 230 | * @throws IllegalArgumentException if some property of the specified | ||
| 231 | * element prevents it from being added to this queue | ||
| 232 | */ | ||
| 233 | void put(E e) throws InterruptedException; | ||
| 234 | |||
| 235 | /** | ||
| 236 | * Inserts the specified element into this queue, waiting up to the | ||
| 237 | * specified wait time if necessary for space to become available. | ||
| 238 | * | ||
| 239 | * @param e the element to add | ||
| 240 | * @param timeout how long to wait before giving up, in units of | ||
| 241 | * <tt>unit</tt> | ||
| 242 | * @param unit a <tt>TimeUnit</tt> determining how to interpret the | ||
| 243 | * <tt>timeout</tt> parameter | ||
| 244 | * @return <tt>true</tt> if successful, or <tt>false</tt> if | ||
| 245 | * the specified waiting time elapses before space is available | ||
| 246 | * @throws InterruptedException if interrupted while waiting | ||
| 247 | * @throws ClassCastException if the class of the specified element | ||
| 248 | * prevents it from being added to this queue | ||
| 249 | * @throws NullPointerException if the specified element is null | ||
| 250 | * @throws IllegalArgumentException if some property of the specified | ||
| 251 | * element prevents it from being added to this queue | ||
| 252 | */ | ||
| 253 | boolean offer(E e, long timeout, TimeUnit unit) | ||
| 254 | throws InterruptedException; | ||
| 255 | |||
| 256 | /** | ||
| 257 | * Retrieves and removes the head of this queue, waiting if necessary | ||
| 258 | * until an element becomes available. | ||
| 259 | * | ||
| 260 | * @return the head of this queue | ||
| 261 | * @throws InterruptedException if interrupted while waiting | ||
| 262 | */ | ||
| 263 | E take() throws InterruptedException; | ||
| 264 | |||
| 265 | /** | ||
| 266 | * Retrieves and removes the head of this queue, waiting up to the | ||
| 267 | * specified wait time if necessary for an element to become available. | ||
| 268 | * | ||
| 269 | * @param timeout how long to wait before giving up, in units of | ||
| 270 | * <tt>unit</tt> | ||
| 271 | * @param unit a <tt>TimeUnit</tt> determining how to interpret the | ||
| 272 | * <tt>timeout</tt> parameter | ||
| 273 | * @return the head of this queue, or <tt>null</tt> if the | ||
| 274 | * specified waiting time elapses before an element is available | ||
| 275 | * @throws InterruptedException if interrupted while waiting | ||
| 276 | */ | ||
| 277 | E poll(long timeout, TimeUnit unit) | ||
| 278 | throws InterruptedException; | ||
| 279 | |||
| 280 | /** | ||
| 281 | * Returns the number of additional elements that this queue can ideally | ||
| 282 | * (in the absence of memory or resource constraints) accept without | ||
| 283 | * blocking, or <tt>Integer.MAX_VALUE</tt> if there is no intrinsic | ||
| 284 | * limit. | ||
| 285 | * | ||
| 286 | * <p>Note that you <em>cannot</em> always tell if an attempt to insert | ||
| 287 | * an element will succeed by inspecting <tt>remainingCapacity</tt> | ||
| 288 | * because it may be the case that another thread is about to | ||
| 289 | * insert or remove an element. | ||
| 290 | * | ||
| 291 | * @return the remaining capacity | ||
| 292 | */ | ||
| 293 | int remainingCapacity(); | ||
| 294 | |||
| 295 | /** | ||
| 296 | * Removes a single instance of the specified element from this queue, | ||
| 297 | * if it is present. More formally, removes an element <tt>e</tt> such | ||
| 298 | * that <tt>o.equals(e)</tt>, if this queue contains one or more such | ||
| 299 | * elements. | ||
| 300 | * Returns <tt>true</tt> if this queue contained the specified element | ||
| 301 | * (or equivalently, if this queue changed as a result of the call). | ||
| 302 | * | ||
| 303 | * @param o element to be removed from this queue, if present | ||
| 304 | * @return <tt>true</tt> if this queue changed as a result of the call | ||
| 305 | * @throws ClassCastException if the class of the specified element | ||
| 306 | * is incompatible with this queue | ||
| 307 | * (<a href="../Collection.html#optional-restrictions">optional</a>) | ||
| 308 | * @throws NullPointerException if the specified element is null | ||
| 309 | * (<a href="../Collection.html#optional-restrictions">optional</a>) | ||
| 310 | */ | ||
| 311 | boolean remove(Object o); | ||
| 312 | |||
| 313 | /** | ||
| 314 | * Returns <tt>true</tt> if this queue contains the specified element. | ||
| 315 | * More formally, returns <tt>true</tt> if and only if this queue contains | ||
| 316 | * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>. | ||
| 317 | * | ||
| 318 | * @param o object to be checked for containment in this queue | ||
| 319 | * @return <tt>true</tt> if this queue contains the specified element | ||
| 320 | * @throws ClassCastException if the class of the specified element | ||
| 321 | * is incompatible with this queue | ||
| 322 | * (<a href="../Collection.html#optional-restrictions">optional</a>) | ||
| 323 | * @throws NullPointerException if the specified element is null | ||
| 324 | * (<a href="../Collection.html#optional-restrictions">optional</a>) | ||
| 325 | */ | ||
| 326 | public boolean contains(Object o); | ||
| 327 | |||
| 328 | /** | ||
| 329 | * Removes all available elements from this queue and adds them | ||
| 330 | * to the given collection. This operation may be more | ||
| 331 | * efficient than repeatedly polling this queue. A failure | ||
| 332 | * encountered while attempting to add elements to | ||
| 333 | * collection <tt>c</tt> may result in elements being in neither, | ||
| 334 | * either or both collections when the associated exception is | ||
| 335 | * thrown. Attempts to drain a queue to itself result in | ||
| 336 | * <tt>IllegalArgumentException</tt>. Further, the behavior of | ||
| 337 | * this operation is undefined if the specified collection is | ||
| 338 | * modified while the operation is in progress. | ||
| 339 | * | ||
| 340 | * @param c the collection to transfer elements into | ||
| 341 | * @return the number of elements transferred | ||
| 342 | * @throws UnsupportedOperationException if addition of elements | ||
| 343 | * is not supported by the specified collection | ||
| 344 | * @throws ClassCastException if the class of an element of this queue | ||
| 345 | * prevents it from being added to the specified collection | ||
| 346 | * @throws NullPointerException if the specified collection is null | ||
| 347 | * @throws IllegalArgumentException if the specified collection is this | ||
| 348 | * queue, or some property of an element of this queue prevents | ||
| 349 | * it from being added to the specified collection | ||
| 350 | */ | ||
| 351 | int drainTo(Collection<? super E> c); | ||
| 352 | |||
| 353 | /** | ||
| 354 | * Removes at most the given number of available elements from | ||
| 355 | * this queue and adds them to the given collection. A failure | ||
| 356 | * encountered while attempting to add elements to | ||
| 357 | * collection <tt>c</tt> may result in elements being in neither, | ||
| 358 | * either or both collections when the associated exception is | ||
| 359 | * thrown. Attempts to drain a queue to itself result in | ||
| 360 | * <tt>IllegalArgumentException</tt>. Further, the behavior of | ||
| 361 | * this operation is undefined if the specified collection is | ||
| 362 | * modified while the operation is in progress. | ||
| 363 | * | ||
| 364 | * @param c the collection to transfer elements into | ||
| 365 | * @param maxElements the maximum number of elements to transfer | ||
| 366 | * @return the number of elements transferred | ||
| 367 | * @throws UnsupportedOperationException if addition of elements | ||
| 368 | * is not supported by the specified collection | ||
| 369 | * @throws ClassCastException if the class of an element of this queue | ||
| 370 | * prevents it from being added to the specified collection | ||
| 371 | * @throws NullPointerException if the specified collection is null | ||
| 372 | * @throws IllegalArgumentException if the specified collection is this | ||
| 373 | * queue, or some property of an element of this queue prevents | ||
| 374 | * it from being added to the specified collection | ||
| 375 | */ | ||
| 376 | int drainTo(Collection<? super E> c, int maxElements); | ||
| 377 | } | ||
Binary file not shown.
| @@ -0,0 +1,67 @@ | |||
| 1 | /* | ||
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 3 | * | ||
| 4 | * This code is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License version 2 only, as | ||
| 6 | * published by the Free Software Foundation. Oracle designates this | ||
| 7 | * particular file as subject to the "Classpath" exception as provided | ||
| 8 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 9 | * | ||
| 10 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 13 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 14 | * accompanied this code). | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License version | ||
| 17 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | * | ||
| 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 21 | * or visit www.oracle.com if you need additional information or have any | ||
| 22 | * questions. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * This file is available under and governed by the GNU General Public | ||
| 27 | * License version 2 only, as published by the Free Software Foundation. | ||
| 28 | * However, the following notice accompanied the original version of this | ||
| 29 | * file: | ||
| 30 | * | ||
| 31 | * Written by Doug Lea with assistance from members of JCP JSR-166 | ||
| 32 | * Expert Group and released to the public domain, as explained at | ||
| 33 | * http://creativecommons.org/publicdomain/zero/1.0/ | ||
| 34 | */ | ||
| 35 | |||
| 36 | package java.util.concurrent; | ||
| 37 | |||
| 38 | /** | ||
| 39 | * Exception thrown when a thread tries to wait upon a barrier that is | ||
| 40 | * in a broken state, or which enters the broken state while the thread | ||
| 41 | * is waiting. | ||
| 42 | * | ||
| 43 | * @see CyclicBarrier | ||
| 44 | * | ||
| 45 | * @since 1.5 | ||
| 46 | * @author Doug Lea | ||
| 47 | * | ||
| 48 | */ | ||
| 49 | public class BrokenBarrierException extends Exception { | ||
| 50 | private static final long serialVersionUID = 7117394618823254244L; | ||
| 51 | |||
| 52 | /** | ||
| 53 | * Constructs a <tt>BrokenBarrierException</tt> with no specified detail | ||
| 54 | * message. | ||
| 55 | */ | ||
| 56 | public BrokenBarrierException() {} | ||
| 57 | |||
| 58 | /** | ||
| 59 | * Constructs a <tt>BrokenBarrierException</tt> with the specified | ||
| 60 | * detail message. | ||
| 61 | * | ||
| 62 | * @param message the detail message | ||
| 63 | */ | ||
| 64 | public BrokenBarrierException(String message) { | ||
| 65 | super(message); | ||
| 66 | } | ||
| 67 | } | ||
Binary file not shown.
| @@ -0,0 +1,65 @@ | |||
| 1 | /* | ||
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 3 | * | ||
| 4 | * This code is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License version 2 only, as | ||
| 6 | * published by the Free Software Foundation. Oracle designates this | ||
| 7 | * particular file as subject to the "Classpath" exception as provided | ||
| 8 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 9 | * | ||
| 10 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 13 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 14 | * accompanied this code). | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License version | ||
| 17 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | * | ||
| 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 21 | * or visit www.oracle.com if you need additional information or have any | ||
| 22 | * questions. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * This file is available under and governed by the GNU General Public | ||
| 27 | * License version 2 only, as published by the Free Software Foundation. | ||
| 28 | * However, the following notice accompanied the original version of this | ||
| 29 | * file: | ||
| 30 | * | ||
| 31 | * Written by Doug Lea with assistance from members of JCP JSR-166 | ||
| 32 | * Expert Group and released to the public domain, as explained at | ||
| 33 | * http://creativecommons.org/publicdomain/zero/1.0/ | ||
| 34 | */ | ||
| 35 | |||
| 36 | package java.util.concurrent; | ||
| 37 | |||
| 38 | /** | ||
| 39 | * A task that returns a result and may throw an exception. | ||
| 40 | * Implementors define a single method with no arguments called | ||
| 41 | * <tt>call</tt>. | ||
| 42 | * | ||
| 43 | * <p>The <tt>Callable</tt> interface is similar to {@link | ||
| 44 | * java.lang.Runnable}, in that both are designed for classes whose | ||
| 45 | * instances are potentially executed by another thread. A | ||
| 46 | * <tt>Runnable</tt>, however, does not return a result and cannot | ||
| 47 | * throw a checked exception. | ||
| 48 | * | ||
| 49 | * <p> The {@link Executors} class contains utility methods to | ||
| 50 | * convert from other common forms to <tt>Callable</tt> classes. | ||
| 51 | * | ||
| 52 | * @see Executor | ||
| 53 | * @since 1.5 | ||
| 54 | * @author Doug Lea | ||
| 55 | * @param <V> the result type of method <tt>call</tt> | ||
| 56 | */ | ||
| 57 | public interface Callable<V> { | ||
| 58 | /** | ||
| 59 | * Computes a result, or throws an exception if unable to do so. | ||
| 60 | * | ||
| 61 | * @return computed result | ||
| 62 | * @throws Exception if unable to compute a result | ||
| 63 | */ | ||
| 64 | V call() throws Exception; | ||
| 65 | } | ||
Binary file not shown.
| @@ -0,0 +1,63 @@ | |||
| 1 | /* | ||
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 3 | * | ||
| 4 | * This code is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License version 2 only, as | ||
| 6 | * published by the Free Software Foundation. Oracle designates this | ||
| 7 | * particular file as subject to the "Classpath" exception as provided | ||
| 8 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 9 | * | ||
| 10 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 13 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 14 | * accompanied this code). | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License version | ||
| 17 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | * | ||
| 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 21 | * or visit www.oracle.com if you need additional information or have any | ||
| 22 | * questions. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * This file is available under and governed by the GNU General Public | ||
| 27 | * License version 2 only, as published by the Free Software Foundation. | ||
| 28 | * However, the following notice accompanied the original version of this | ||
| 29 | * file: | ||
| 30 | * | ||
| 31 | * Written by Doug Lea with assistance from members of JCP JSR-166 | ||
| 32 | * Expert Group and released to the public domain, as explained at | ||
| 33 | * http://creativecommons.org/publicdomain/zero/1.0/ | ||
| 34 | */ | ||
| 35 | |||
| 36 | package java.util.concurrent; | ||
| 37 | |||
| 38 | /** | ||
| 39 | * Exception indicating that the result of a value-producing task, | ||
| 40 | * such as a {@link FutureTask}, cannot be retrieved because the task | ||
| 41 | * was cancelled. | ||
| 42 | * | ||
| 43 | * @since 1.5 | ||
| 44 | * @author Doug Lea | ||
| 45 | */ | ||
| 46 | public class CancellationException extends IllegalStateException { | ||
| 47 | private static final long serialVersionUID = -9202173006928992231L; | ||
| 48 | |||
| 49 | /** | ||
| 50 | * Constructs a <tt>CancellationException</tt> with no detail message. | ||
| 51 | */ | ||
| 52 | public CancellationException() {} | ||
| 53 | |||
| 54 | /** | ||
| 55 | * Constructs a <tt>CancellationException</tt> with the specified detail | ||
| 56 | * message. | ||
| 57 | * | ||
| 58 | * @param message the detail message | ||
| 59 | */ | ||
| 60 | public CancellationException(String message) { | ||
| 61 | super(message); | ||
| 62 | } | ||
| 63 | } | ||
Binary file not shown.
| @@ -0,0 +1,126 @@ | |||
| 1 | /* | ||
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 3 | * | ||
| 4 | * This code is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License version 2 only, as | ||
| 6 | * published by the Free Software Foundation. Oracle designates this | ||
| 7 | * particular file as subject to the "Classpath" exception as provided | ||
| 8 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 9 | * | ||
| 10 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 13 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 14 | * accompanied this code). | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License version | ||
| 17 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | * | ||
| 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 21 | * or visit www.oracle.com if you need additional information or have any | ||
| 22 | * questions. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * This file is available under and governed by the GNU General Public | ||
| 27 | * License version 2 only, as published by the Free Software Foundation. | ||
| 28 | * However, the following notice accompanied the original version of this | ||
| 29 | * file: | ||
| 30 | * | ||
| 31 | * Written by Doug Lea with assistance from members of JCP JSR-166 | ||
| 32 | * Expert Group and released to the public domain, as explained at | ||
| 33 | * http://creativecommons.org/publicdomain/zero/1.0/ | ||
| 34 | */ | ||
| 35 | |||
| 36 | package java.util.concurrent; | ||
| 37 | |||
| 38 | /** | ||
| 39 | * A service that decouples the production of new asynchronous tasks | ||
| 40 | * from the consumption of the results of completed tasks. Producers | ||
| 41 | * <tt>submit</tt> tasks for execution. Consumers <tt>take</tt> | ||
| 42 | * completed tasks and process their results in the order they | ||
| 43 | * complete. A <tt>CompletionService</tt> can for example be used to | ||
| 44 | * manage asynchronous IO, in which tasks that perform reads are | ||
| 45 | * submitted in one part of a program or system, and then acted upon | ||
| 46 | * in a different part of the program when the reads complete, | ||
| 47 | * possibly in a different order than they were requested. | ||
| 48 | * | ||
| 49 | * <p>Typically, a <tt>CompletionService</tt> relies on a separate | ||
| 50 | * {@link Executor} to actually execute the tasks, in which case the | ||
| 51 | * <tt>CompletionService</tt> only manages an internal completion | ||
| 52 | * queue. The {@link ExecutorCompletionService} class provides an | ||
| 53 | * implementation of this approach. | ||
| 54 | * | ||
| 55 | * <p>Memory consistency effects: Actions in a thread prior to | ||
| 56 | * submitting a task to a {@code CompletionService} | ||
| 57 | * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> | ||
| 58 | * actions taken by that task, which in turn <i>happen-before</i> | ||
| 59 | * actions following a successful return from the corresponding {@code take()}. | ||
| 60 | * | ||
| 61 | */ | ||
| 62 | public interface CompletionService<V> { | ||
| 63 | /** | ||
| 64 | * Submits a value-returning task for execution and returns a Future | ||
| 65 | * representing the pending results of the task. Upon completion, | ||
| 66 | * this task may be taken or polled. | ||
| 67 | * | ||
| 68 | * @param task the task to submit | ||
| 69 | * @return a Future representing pending completion of the task | ||
| 70 | * @throws RejectedExecutionException if the task cannot be | ||
| 71 | * scheduled for execution | ||
| 72 | * @throws NullPointerException if the task is null | ||
| 73 | */ | ||
| 74 | Future<V> submit(Callable<V> task); | ||
| 75 | |||
| 76 | /** | ||
| 77 | * Submits a Runnable task for execution and returns a Future | ||
| 78 | * representing that task. Upon completion, this task may be | ||
| 79 | * taken or polled. | ||
| 80 | * | ||
| 81 | * @param task the task to submit | ||
| 82 | * @param result the result to return upon successful completion | ||
| 83 | * @return a Future representing pending completion of the task, | ||
| 84 | * and whose <tt>get()</tt> method will return the given | ||
| 85 | * result value upon completion | ||
| 86 | * @throws RejectedExecutionException if the task cannot be | ||
| 87 | * scheduled for execution | ||
| 88 | * @throws NullPointerException if the task is null | ||
| 89 | */ | ||
| 90 | Future<V> submit(Runnable task, V result); | ||
| 91 | |||
| 92 | /** | ||
| 93 | * Retrieves and removes the Future representing the next | ||
| 94 | * completed task, waiting if none are yet present. | ||
| 95 | * | ||
| 96 | * @return the Future representing the next completed task | ||
| 97 | * @throws InterruptedException if interrupted while waiting | ||
| 98 | */ | ||
| 99 | Future<V> take() throws InterruptedException; | ||
| 100 | |||
| 101 | |||
| 102 | /** | ||
| 103 | * Retrieves and removes the Future representing the next | ||
| 104 | * completed task or <tt>null</tt> if none are present. | ||
| 105 | * | ||
| 106 | * @return the Future representing the next completed task, or | ||
| 107 | * <tt>null</tt> if none are present | ||
| 108 | */ | ||
| 109 | Future<V> poll(); | ||
| 110 | |||
| 111 | /** | ||
| 112 | * Retrieves and removes the Future representing the next | ||
| 113 | * completed task, waiting if necessary up to the specified wait | ||
| 114 | * time if none are yet present. | ||
| 115 | * | ||
| 116 | * @param timeout how long to wait before giving up, in units of | ||
| 117 | * <tt>unit</tt> | ||
| 118 | * @param unit a <tt>TimeUnit</tt> determining how to interpret the | ||
| 119 | * <tt>timeout</tt> parameter | ||
| 120 | * @return the Future representing the next completed task or | ||
| 121 | * <tt>null</tt> if the specified waiting time elapses | ||
| 122 | * before one is present | ||
| 123 | * @throws InterruptedException if interrupted while waiting | ||
| 124 | */ | ||
| 125 | Future<V> poll(long timeout, TimeUnit unit) throws InterruptedException; | ||
| 126 | } | ||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,1522 @@ | |||
| 1 | /* | ||
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 3 | * | ||
| 4 | * This code is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License version 2 only, as | ||
| 6 | * published by the Free Software Foundation. Oracle designates this | ||
| 7 | * particular file as subject to the "Classpath" exception as provided | ||
| 8 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 9 | * | ||
| 10 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 13 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 14 | * accompanied this code). | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License version | ||
| 17 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | * | ||
| 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 21 | * or visit www.oracle.com if you need additional information or have any | ||
| 22 | * questions. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * This file is available under and governed by the GNU General Public | ||
| 27 | * License version 2 only, as published by the Free Software Foundation. | ||
| 28 | * However, the following notice accompanied the original version of this | ||
| 29 | * file: | ||
| 30 | * | ||
| 31 | * Written by Doug Lea with assistance from members of JCP JSR-166 | ||
| 32 | * Expert Group and released to the public domain, as explained at | ||
| 33 | * http://creativecommons.org/publicdomain/zero/1.0/ | ||
| 34 | */ | ||
| 35 | |||
| 36 | package java.util.concurrent; | ||
| 37 | import java.util.concurrent.locks.*; | ||
| 38 | import java.util.*; | ||
| 39 | import java.io.Serializable; | ||
| 40 | import java.io.IOException; | ||
| 41 | import java.io.ObjectInputStream; | ||
| 42 | import java.io.ObjectOutputStream; | ||
| 43 | |||
| 44 | /** | ||
| 45 | * A hash table supporting full concurrency of retrievals and | ||
| 46 | * adjustable expected concurrency for updates. This class obeys the | ||
| 47 | * same functional specification as {@link java.util.Hashtable}, and | ||
| 48 | * includes versions of methods corresponding to each method of | ||
| 49 | * <tt>Hashtable</tt>. However, even though all operations are | ||
| 50 | * thread-safe, retrieval operations do <em>not</em> entail locking, | ||
| 51 | * and there is <em>not</em> any support for locking the entire table | ||
| 52 | * in a way that prevents all access. This class is fully | ||
| 53 | * interoperable with <tt>Hashtable</tt> in programs that rely on its | ||
| 54 | * thread safety but not on its synchronization details. | ||
| 55 | * | ||
| 56 | * <p> Retrieval operations (including <tt>get</tt>) generally do not | ||
| 57 | * block, so may overlap with update operations (including | ||
| 58 | * <tt>put</tt> and <tt>remove</tt>). Retrievals reflect the results | ||
| 59 | * of the most recently <em>completed</em> update operations holding | ||
| 60 | * upon their onset. For aggregate operations such as <tt>putAll</tt> | ||
| 61 | * and <tt>clear</tt>, concurrent retrievals may reflect insertion or | ||
| 62 | * removal of only some entries. Similarly, Iterators and | ||
| 63 | * Enumerations return elements reflecting the state of the hash table | ||
| 64 | * at some point at or since the creation of the iterator/enumeration. | ||
| 65 | * They do <em>not</em> throw {@link ConcurrentModificationException}. | ||
| 66 | * However, iterators are designed to be used by only one thread at a time. | ||
| 67 | * | ||
| 68 | * <p> The allowed concurrency among update operations is guided by | ||
| 69 | * the optional <tt>concurrencyLevel</tt> constructor argument | ||
| 70 | * (default <tt>16</tt>), which is used as a hint for internal sizing. The | ||
| 71 | * table is internally partitioned to try to permit the indicated | ||
| 72 | * number of concurrent updates without contention. Because placement | ||
| 73 | * in hash tables is essentially random, the actual concurrency will | ||
| 74 | * vary. Ideally, you should choose a value to accommodate as many | ||
| 75 | * threads as will ever concurrently modify the table. Using a | ||
| 76 | * significantly higher value than you need can waste space and time, | ||
| 77 | * and a significantly lower value can lead to thread contention. But | ||
| 78 | * overestimates and underestimates within an order of magnitude do | ||
| 79 | * not usually have much noticeable impact. A value of one is | ||
| 80 | * appropriate when it is known that only one thread will modify and | ||
| 81 | * all others will only read. Also, resizing this or any other kind of | ||
| 82 | * hash table is a relatively slow operation, so, when possible, it is | ||
| 83 | * a good idea to provide estimates of expected table sizes in | ||
| 84 | * constructors. | ||
| 85 | * | ||
| 86 | * <p>This class and its views and iterators implement all of the | ||
| 87 | * <em>optional</em> methods of the {@link Map} and {@link Iterator} | ||
| 88 | * interfaces. | ||
| 89 | * | ||
| 90 | * <p> Like {@link Hashtable} but unlike {@link HashMap}, this class | ||
| 91 | * does <em>not</em> allow <tt>null</tt> to be used as a key or value. | ||
| 92 | * | ||
| 93 | * <p>This class is a member of the | ||
| 94 | * <a href="{@docRoot}/../technotes/guides/collections/index.html"> | ||
| 95 | * Java Collections Framework</a>. | ||
| 96 | * | ||
| 97 | * @since 1.5 | ||
| 98 | * @author Doug Lea | ||
| 99 | * @param <K> the type of keys maintained by this map | ||
| 100 | * @param <V> the type of mapped values | ||
| 101 | */ | ||
| 102 | public class ConcurrentHashMap<K, V> extends AbstractMap<K, V> | ||
| 103 | implements ConcurrentMap<K, V>, Serializable { | ||
| 104 | private static final long serialVersionUID = 7249069246763182397L; | ||
| 105 | |||
| 106 | /* | ||
| 107 | * The basic strategy is to subdivide the table among Segments, | ||
| 108 | * each of which itself is a concurrently readable hash table. To | ||
| 109 | * reduce footprint, all but one segments are constructed only | ||
| 110 | * when first needed (see ensureSegment). To maintain visibility | ||
| 111 | * in the presence of lazy construction, accesses to segments as | ||
| 112 | * well as elements of segment's table must use volatile access, | ||
| 113 | * which is done via Unsafe within methods segmentAt etc | ||
| 114 | * below. These provide the functionality of AtomicReferenceArrays | ||
| 115 | * but reduce the levels of indirection. Additionally, | ||
| 116 | * volatile-writes of table elements and entry "next" fields | ||
| 117 | * within locked operations use the cheaper "lazySet" forms of | ||
| 118 | * writes (via putOrderedObject) because these writes are always | ||
| 119 | * followed by lock releases that maintain sequential consistency | ||
| 120 | * of table updates. | ||
| 121 | * | ||
| 122 | * Historical note: The previous version of this class relied | ||
| 123 | * heavily on "final" fields, which avoided some volatile reads at | ||
| 124 | * the expense of a large initial footprint. Some remnants of | ||
| 125 | * that design (including forced construction of segment 0) exist | ||
| 126 | * to ensure serialization compatibility. | ||
| 127 | */ | ||
| 128 | |||
| 129 | /* ---------------- Constants -------------- */ | ||
| 130 | |||
| 131 | /** | ||
| 132 | * The default initial capacity for this table, | ||
| 133 | * used when not otherwise specified in a constructor. | ||
| 134 | */ | ||
| 135 | static final int DEFAULT_INITIAL_CAPACITY = 16; | ||
| 136 | |||
| 137 | /** | ||
| 138 | * The default load factor for this table, used when not | ||
| 139 | * otherwise specified in a constructor. | ||
| 140 | */ | ||
| 141 | static final float DEFAULT_LOAD_FACTOR = 0.75f; | ||
| 142 | |||
| 143 | /** | ||
| 144 | * The default concurrency level for this table, used when not | ||
| 145 | * otherwise specified in a constructor. | ||
| 146 | */ | ||
| 147 | static final int DEFAULT_CONCURRENCY_LEVEL = 16; | ||
| 148 | |||
| 149 | /** | ||
| 150 | * The maximum capacity, used if a higher value is implicitly | ||
| 151 | * specified by either of the constructors with arguments. MUST | ||
| 152 | * be a power of two <= 1<<30 to ensure that entries are indexable | ||
| 153 | * using ints. | ||
| 154 | */ | ||
| 155 | static final int MAXIMUM_CAPACITY = 1 << 30; | ||
| 156 | |||
| 157 | /** | ||
| 158 | * The minimum capacity for per-segment tables. Must be a power | ||
| 159 | * of two, at least two to avoid immediate resizing on next use | ||
| 160 | * after lazy construction. | ||
| 161 | */ | ||
| 162 | static final int MIN_SEGMENT_TABLE_CAPACITY = 2; | ||
| 163 | |||
| 164 | /** | ||
| 165 | * The maximum number of segments to allow; used to bound | ||
| 166 | * constructor arguments. Must be power of two less than 1 << 24. | ||
| 167 | */ | ||
| 168 | static final int MAX_SEGMENTS = 1 << 16; // slightly conservative | ||
| 169 | |||
| 170 | /** | ||
| 171 | * Number of unsynchronized retries in size and containsValue | ||
| 172 | * methods before resorting to locking. This is used to avoid | ||
| 173 | * unbounded retries if tables undergo continuous modification | ||
| 174 | * which would make it impossible to obtain an accurate result. | ||
| 175 | */ | ||
| 176 | static final int RETRIES_BEFORE_LOCK = 2; | ||
| 177 | |||
| 178 | /* ---------------- Fields -------------- */ | ||
| 179 | |||
| 180 | /** | ||
| 181 | * Mask value for indexing into segments. The upper bits of a | ||
| 182 | * key's hash code are used to choose the segment. | ||
| 183 | */ | ||
| 184 | final int segmentMask; | ||
| 185 | |||
| 186 | /** | ||
| 187 | * Shift value for indexing within segments. | ||
| 188 | */ | ||
| 189 | final int segmentShift; | ||
| 190 | |||
| 191 | /** | ||
| 192 | * The segments, each of which is a specialized hash table. | ||
| 193 | */ | ||
| 194 | final Segment<K,V>[] segments; | ||
| 195 | |||
| 196 | transient Set<K> keySet; | ||
| 197 | transient Set<Map.Entry<K,V>> entrySet; | ||
| 198 | transient Collection<V> values; | ||
| 199 | |||
| 200 | /** | ||
| 201 | * ConcurrentHashMap list entry. Note that this is never exported | ||
| 202 | * out as a user-visible Map.Entry. | ||
| 203 | */ | ||
| 204 | static final class HashEntry<K,V> { | ||
| 205 | final int hash; | ||
| 206 | final K key; | ||
| 207 | volatile V value; | ||
| 208 | volatile HashEntry<K,V> next; | ||
| 209 | |||
| 210 | HashEntry(int hash, K key, V value, HashEntry<K,V> next) { | ||
| 211 | this.hash = hash; | ||
| 212 | this.key = key; | ||
| 213 | this.value = value; | ||
| 214 | this.next = next; | ||
| 215 | } | ||
| 216 | |||
| 217 | /** | ||
| 218 | * Sets next field with volatile write semantics. (See above | ||
| 219 | * about use of putOrderedObject.) | ||
| 220 | */ | ||
| 221 | final void setNext(HashEntry<K,V> n) { | ||
| 222 | UNSAFE.putOrderedObject(this, nextOffset, n); | ||
| 223 | } | ||
| 224 | |||
| 225 | // Unsafe mechanics | ||
| 226 | static final sun.misc.Unsafe UNSAFE; | ||
| 227 | static final long nextOffset; | ||
| 228 | static { | ||
| 229 | try { | ||
| 230 | UNSAFE = sun.misc.Unsafe.getUnsafe(); | ||
| 231 | Class k = HashEntry.class; | ||
| 232 | nextOffset = UNSAFE.objectFieldOffset | ||
| 233 | (k.getDeclaredField("next")); | ||
| 234 | } catch (Exception e) { | ||
| 235 | throw new Error(e); | ||
| 236 | } | ||
| 237 | } | ||
| 238 | } | ||
| 239 | |||
| 240 | /** | ||
| 241 | * Gets the ith element of given table (if nonnull) with volatile | ||
| 242 | * read semantics. Note: This is manually integrated into a few | ||
| 243 | * performance-sensitive methods to reduce call overhead. | ||
| 244 | */ | ||
| 245 | @SuppressWarnings("unchecked") | ||
| 246 | static final <K,V> HashEntry<K,V> entryAt(HashEntry<K,V>[] tab, int i) { | ||
| 247 | return (tab == null) ? null : | ||
| 248 | (HashEntry<K,V>) UNSAFE.getObjectVolatile | ||
| 249 | (tab, ((long)i << TSHIFT) + TBASE); | ||
| 250 | } | ||
| 251 | |||
| 252 | /** | ||
| 253 | * Sets the ith element of given table, with volatile write | ||
| 254 | * semantics. (See above about use of putOrderedObject.) | ||
| 255 | */ | ||
| 256 | static final <K,V> void setEntryAt(HashEntry<K,V>[] tab, int i, | ||
| 257 | HashEntry<K,V> e) { | ||
| 258 | UNSAFE.putOrderedObject(tab, ((long)i << TSHIFT) + TBASE, e); | ||
| 259 | } | ||
| 260 | |||
| 261 | /** | ||
| 262 | * Applies a supplemental hash function to a given hashCode, which | ||
| 263 | * defends against poor quality hash functions. This is critical | ||
| 264 | * because ConcurrentHashMap uses power-of-two length hash tables, | ||
| 265 | * that otherwise encounter collisions for hashCodes that do not | ||
| 266 | * differ in lower or upper bits. | ||
| 267 | */ | ||
| 268 | private static int hash(int h) { | ||
| 269 | // Spread bits to regularize both segment and index locations, | ||
| 270 | // using variant of single-word Wang/Jenkins hash. | ||
| 271 | h += (h << 15) ^ 0xffffcd7d; | ||
| 272 | h ^= (h >>> 10); | ||
| 273 | h += (h << 3); | ||
| 274 | h ^= (h >>> 6); | ||
| 275 | h += (h << 2) + (h << 14); | ||
| 276 | return h ^ (h >>> 16); | ||
| 277 | } | ||
| 278 | |||
| 279 | /** | ||
| 280 | * Segments are specialized versions of hash tables. This | ||
| 281 | * subclasses from ReentrantLock opportunistically, just to | ||
| 282 | * simplify some locking and avoid separate construction. | ||
| 283 | */ | ||
| 284 | static final class Segment<K,V> extends ReentrantLock implements Serializable { | ||
| 285 | /* | ||
| 286 | * Segments maintain a table of entry lists that are always | ||
| 287 | * kept in a consistent state, so can be read (via volatile | ||
| 288 | * reads of segments and tables) without locking. This | ||
| 289 | * requires replicating nodes when necessary during table | ||
| 290 | * resizing, so the old lists can be traversed by readers | ||
| 291 | * still using old version of table. | ||
| 292 | * | ||
| 293 | * This class defines only mutative methods requiring locking. | ||
| 294 | * Except as noted, the methods of this class perform the | ||
| 295 | * per-segment versions of ConcurrentHashMap methods. (Other | ||
| 296 | * methods are integrated directly into ConcurrentHashMap | ||
| 297 | * methods.) These mutative methods use a form of controlled | ||
| 298 | * spinning on contention via methods scanAndLock and | ||
| 299 | * scanAndLockForPut. These intersperse tryLocks with | ||
| 300 | * traversals to locate nodes. The main benefit is to absorb | ||
| 301 | * cache misses (which are very common for hash tables) while | ||
| 302 | * obtaining locks so that traversal is faster once | ||
| 303 | * acquired. We do not actually use the found nodes since they | ||
| 304 | * must be re-acquired under lock anyway to ensure sequential | ||
| 305 | * consistency of updates (and in any case may be undetectably | ||
| 306 | * stale), but they will normally be much faster to re-locate. | ||
| 307 | * Also, scanAndLockForPut speculatively creates a fresh node | ||
| 308 | * to use in put if no node is found. | ||
| 309 | */ | ||
| 310 | |||
| 311 | private static final long serialVersionUID = 2249069246763182397L; | ||
| 312 | |||
| 313 | /** | ||
| 314 | * The maximum number of times to tryLock in a prescan before | ||
| 315 | * possibly blocking on acquire in preparation for a locked | ||
| 316 | * segment operation. On multiprocessors, using a bounded | ||
| 317 | * number of retries maintains cache acquired while locating | ||
| 318 | * nodes. | ||
| 319 | */ | ||
| 320 | static final int MAX_SCAN_RETRIES = | ||
| 321 | Runtime.getRuntime().availableProcessors() > 1 ? 64 : 1; | ||
| 322 | |||
| 323 | /** | ||
| 324 | * The per-segment table. Elements are accessed via | ||
| 325 | * entryAt/setEntryAt providing volatile semantics. | ||
| 326 | */ | ||
| 327 | transient volatile HashEntry<K,V>[] table; | ||
| 328 | |||
| 329 | /** | ||
| 330 | * The number of elements. Accessed only either within locks | ||
| 331 | * or among other volatile reads that maintain visibility. | ||
| 332 | */ | ||
| 333 | transient int count; | ||
| 334 | |||
| 335 | /** | ||
| 336 | * The total number of mutative operations in this segment. | ||
| 337 | * Even though this may overflows 32 bits, it provides | ||
| 338 | * sufficient accuracy for stability checks in CHM isEmpty() | ||
| 339 | * and size() methods. Accessed only either within locks or | ||
| 340 | * among other volatile reads that maintain visibility. | ||
| 341 | */ | ||
| 342 | transient int modCount; | ||
| 343 | |||
| 344 | /** | ||
| 345 | * The table is rehashed when its size exceeds this threshold. | ||
| 346 | * (The value of this field is always <tt>(int)(capacity * | ||
| 347 | * loadFactor)</tt>.) | ||
| 348 | */ | ||
| 349 | transient int threshold; | ||
| 350 | |||
| 351 | /** | ||
| 352 | * The load factor for the hash table. Even though this value | ||
| 353 | * is same for all segments, it is replicated to avoid needing | ||
| 354 | * links to outer object. | ||
| 355 | * @serial | ||
| 356 | */ | ||
| 357 | final float loadFactor; | ||
| 358 | |||
| 359 | Segment(float lf, int threshold, HashEntry<K,V>[] tab) { | ||
| 360 | this.loadFactor = lf; | ||
| 361 | this.threshold = threshold; | ||
| 362 | this.table = tab; | ||
| 363 | } | ||
| 364 | |||
| 365 | final V put(K key, int hash, V value, boolean onlyIfAbsent) { | ||
| 366 | HashEntry<K,V> node = tryLock() ? null : | ||
| 367 | scanAndLockForPut(key, hash, value); | ||
| 368 | V oldValue; | ||
| 369 | try { | ||
| 370 | HashEntry<K,V>[] tab = table; | ||
| 371 | int index = (tab.length - 1) & hash; | ||
| 372 | HashEntry<K,V> first = entryAt(tab, index); | ||
| 373 | for (HashEntry<K,V> e = first;;) { | ||
| 374 | if (e != null) { | ||
| 375 | K k; | ||
| 376 | if ((k = e.key) == key || | ||
| 377 | (e.hash == hash && key.equals(k))) { | ||
| 378 | oldValue = e.value; | ||
| 379 | if (!onlyIfAbsent) { | ||
| 380 | e.value = value; | ||
| 381 | ++modCount; | ||
| 382 | } | ||
| 383 | break; | ||
| 384 | } | ||
| 385 | e = e.next; | ||
| 386 | } | ||
| 387 | else { | ||
| 388 | if (node != null) | ||
| 389 | node.setNext(first); | ||
| 390 | else | ||
| 391 | node = new HashEntry<K,V>(hash, key, value, first); | ||
| 392 | int c = count + 1; | ||
| 393 | if (c > threshold && tab.length < MAXIMUM_CAPACITY) | ||
| 394 | rehash(node); | ||
| 395 | else | ||
| 396 | setEntryAt(tab, index, node); | ||
| 397 | ++modCount; | ||
| 398 | count = c; | ||
| 399 | oldValue = null; | ||
| 400 | break; | ||
| 401 | } | ||
| 402 | } | ||
| 403 | } finally { | ||
| 404 | unlock(); | ||
| 405 | } | ||
| 406 | return oldValue; | ||
| 407 | } | ||
| 408 | |||
| 409 | /** | ||
| 410 | * Doubles size of table and repacks entries, also adding the | ||
| 411 | * given node to new table | ||
| 412 | */ | ||
| 413 | @SuppressWarnings("unchecked") | ||
| 414 | private void rehash(HashEntry<K,V> node) { | ||
| 415 | /* | ||
| 416 | * Reclassify nodes in each list to new table. Because we | ||
| 417 | * are using power-of-two expansion, the elements from | ||
| 418 | * each bin must either stay at same index, or move with a | ||
| 419 | * power of two offset. We eliminate unnecessary node | ||
| 420 | * creation by catching cases where old nodes can be | ||
| 421 | * reused because their next fields won't change. | ||
| 422 | * Statistically, at the default threshold, only about | ||
| 423 | * one-sixth of them need cloning when a table | ||
| 424 | * doubles. The nodes they replace will be garbage | ||
| 425 | * collectable as soon as they are no longer referenced by | ||
| 426 | * any reader thread that may be in the midst of | ||
| 427 | * concurrently traversing table. Entry accesses use plain | ||
| 428 | * array indexing because they are followed by volatile | ||
| 429 | * table write. | ||
| 430 | */ | ||
| 431 | HashEntry<K,V>[] oldTable = table; | ||
| 432 | int oldCapacity = oldTable.length; | ||
| 433 | int newCapacity = oldCapacity << 1; | ||
| 434 | threshold = (int)(newCapacity * loadFactor); | ||
| 435 | HashEntry<K,V>[] newTable = | ||
| 436 | (HashEntry<K,V>[]) new HashEntry[newCapacity]; | ||
| 437 | int sizeMask = newCapacity - 1; | ||
| 438 | for (int i = 0; i < oldCapacity ; i++) { | ||
| 439 | HashEntry<K,V> e = oldTable[i]; | ||
| 440 | if (e != null) { | ||
| 441 | HashEntry<K,V> next = e.next; | ||
| 442 | int idx = e.hash & sizeMask; | ||
| 443 | if (next == null) // Single node on list | ||
| 444 | newTable[idx] = e; | ||
| 445 | else { // Reuse consecutive sequence at same slot | ||
| 446 | HashEntry<K,V> lastRun = e; | ||
| 447 | int lastIdx = idx; | ||
| 448 | for (HashEntry<K,V> last = next; | ||
| 449 | last != null; | ||
| 450 | last = last.next) { | ||
| 451 | int k = last.hash & sizeMask; | ||
| 452 | if (k != lastIdx) { | ||
| 453 | lastIdx = k; | ||
| 454 | lastRun = last; | ||
| 455 | } | ||
| 456 | } | ||
| 457 | newTable[lastIdx] = lastRun; | ||
| 458 | // Clone remaining nodes | ||
| 459 | for (HashEntry<K,V> p = e; p != lastRun; p = p.next) { | ||
| 460 | V v = p.value; | ||
| 461 | int h = p.hash; | ||
| 462 | int k = h & sizeMask; | ||
| 463 | HashEntry<K,V> n = newTable[k]; | ||
| 464 | newTable[k] = new HashEntry<K,V>(h, p.key, v, n); | ||
| 465 | } | ||
| 466 | } | ||
| 467 | } | ||
| 468 | } | ||
| 469 | int nodeIndex = node.hash & sizeMask; // add the new node | ||
| 470 | node.setNext(newTable[nodeIndex]); | ||
| 471 | newTable[nodeIndex] = node; | ||
| 472 | table = newTable; | ||
| 473 | } | ||
| 474 | |||
| 475 | /** | ||
| 476 | * Scans for a node containing given key while trying to | ||
| 477 | * acquire lock, creating and returning one if not found. Upon | ||
| 478 | * return, guarantees that lock is held. UNlike in most | ||
| 479 | * methods, calls to method equals are not screened: Since | ||
| 480 | * traversal speed doesn't matter, we might as well help warm | ||
| 481 | * up the associated code and accesses as well. | ||
| 482 | * | ||
| 483 | * @return a new node if key not found, else null | ||
| 484 | */ | ||
| 485 | private HashEntry<K,V> scanAndLockForPut(K key, int hash, V value) { | ||
| 486 | HashEntry<K,V> first = entryForHash(this, hash); | ||
| 487 | HashEntry<K,V> e = first; | ||
| 488 | HashEntry<K,V> node = null; | ||
| 489 | int retries = -1; // negative while locating node | ||
| 490 | while (!tryLock()) { | ||
| 491 | HashEntry<K,V> f; // to recheck first below | ||
| 492 | if (retries < 0) { | ||
| 493 | if (e == null) { | ||
| 494 | if (node == null) // speculatively create node | ||
| 495 | node = new HashEntry<K,V>(hash, key, value, null); | ||
| 496 | retries = 0; | ||
| 497 | } | ||
| 498 | else if (key.equals(e.key)) | ||
| 499 | retries = 0; | ||
| 500 | else | ||
| 501 | e = e.next; | ||
| 502 | } | ||
| 503 | else if (++retries > MAX_SCAN_RETRIES) { | ||
| 504 | lock(); | ||
| 505 | break; | ||
| 506 | } | ||
| 507 | else if ((retries & 1) == 0 && | ||
| 508 | (f = entryForHash(this, hash)) != first) { | ||
| 509 | e = first = f; // re-traverse if entry changed | ||
| 510 | retries = -1; | ||
| 511 | } | ||
| 512 | } | ||
| 513 | return node; | ||
| 514 | } | ||
| 515 | |||
| 516 | /** | ||
| 517 | * Scans for a node containing the given key while trying to | ||
| 518 | * acquire lock for a remove or replace operation. Upon | ||
| 519 | * return, guarantees that lock is held. Note that we must | ||
| 520 | * lock even if the key is not found, to ensure sequential | ||
| 521 | * consistency of updates. | ||
| 522 | */ | ||
| 523 | private void scanAndLock(Object key, int hash) { | ||
| 524 | // similar to but simpler than scanAndLockForPut | ||
| 525 | HashEntry<K,V> first = entryForHash(this, hash); | ||
| 526 | HashEntry<K,V> e = first; | ||
| 527 | int retries = -1; | ||
| 528 | while (!tryLock()) { | ||
| 529 | HashEntry<K,V> f; | ||
| 530 | if (retries < 0) { | ||
| 531 | if (e == null || key.equals(e.key)) | ||
| 532 | retries = 0; | ||
| 533 | else | ||
| 534 | e = e.next; | ||
| 535 | } | ||
| 536 | else if (++retries > MAX_SCAN_RETRIES) { | ||
| 537 | lock(); | ||
| 538 | break; | ||
| 539 | } | ||
| 540 | else if ((retries & 1) == 0 && | ||
| 541 | (f = entryForHash(this, hash)) != first) { | ||
| 542 | e = first = f; | ||
| 543 | retries = -1; | ||
| 544 | } | ||
| 545 | } | ||
| 546 | } | ||
| 547 | |||
| 548 | /** | ||
| 549 | * Remove; match on key only if value null, else match both. | ||
| 550 | */ | ||
| 551 | final V remove(Object key, int hash, Object value) { | ||
| 552 | if (!tryLock()) | ||
| 553 | scanAndLock(key, hash); | ||
| 554 | V oldValue = null; | ||
| 555 | try { | ||
| 556 | HashEntry<K,V>[] tab = table; | ||
| 557 | int index = (tab.length - 1) & hash; | ||
| 558 | HashEntry<K,V> e = entryAt(tab, index); | ||
| 559 | HashEntry<K,V> pred = null; | ||
| 560 | while (e != null) { | ||
| 561 | K k; | ||
| 562 | HashEntry<K,V> next = e.next; | ||
| 563 | if ((k = e.key) == key || | ||
| 564 | (e.hash == hash && key.equals(k))) { | ||
| 565 | V v = e.value; | ||
| 566 | if (value == null || value == v || value.equals(v)) { | ||
| 567 | if (pred == null) | ||
| 568 | setEntryAt(tab, index, next); | ||
| 569 | else | ||
| 570 | pred.setNext(next); | ||
| 571 | ++modCount; | ||
| 572 | --count; | ||
| 573 | oldValue = v; | ||
| 574 | } | ||
| 575 | break; | ||
| 576 | } | ||
| 577 | pred = e; | ||
| 578 | e = next; | ||
| 579 | } | ||
| 580 | } finally { | ||
| 581 | unlock(); | ||
| 582 | } | ||
| 583 | return oldValue; | ||
| 584 | } | ||
| 585 | |||
| 586 | final boolean replace(K key, int hash, V oldValue, V newValue) { | ||
| 587 | if (!tryLock()) | ||
| 588 | scanAndLock(key, hash); | ||
| 589 | boolean replaced = false; | ||
| 590 | try { | ||
| 591 | HashEntry<K,V> e; | ||
| 592 | for (e = entryForHash(this, hash); e != null; e = e.next) { | ||
| 593 | K k; | ||
| 594 | if ((k = e.key) == key || | ||
| 595 | (e.hash == hash && key.equals(k))) { | ||
| 596 | if (oldValue.equals(e.value)) { | ||
| 597 | e.value = newValue; | ||
| 598 | ++modCount; | ||
| 599 | replaced = true; | ||
| 600 | } | ||
| 601 | break; | ||
| 602 | } | ||
| 603 | } | ||
| 604 | } finally { | ||
| 605 | unlock(); | ||
| 606 | } | ||
| 607 | return replaced; | ||
| 608 | } | ||
| 609 | |||
| 610 | final V replace(K key, int hash, V value) { | ||
| 611 | if (!tryLock()) | ||
| 612 | scanAndLock(key, hash); | ||
| 613 | V oldValue = null; | ||
| 614 | try { | ||
| 615 | HashEntry<K,V> e; | ||
| 616 | for (e = entryForHash(this, hash); e != null; e = e.next) { | ||
| 617 | K k; | ||
| 618 | if ((k = e.key) == key || | ||
| 619 | (e.hash == hash && key.equals(k))) { | ||
| 620 | oldValue = e.value; | ||
| 621 | e.value = value; | ||
| 622 | ++modCount; | ||
| 623 | break; | ||
| 624 | } | ||
| 625 | } | ||
| 626 | } finally { | ||
| 627 | unlock(); | ||
| 628 | } | ||
| 629 | return oldValue; | ||
| 630 | } | ||
| 631 | |||
| 632 | final void clear() { | ||
| 633 | lock(); | ||
| 634 | try { | ||
| 635 | HashEntry<K,V>[] tab = table; | ||
| 636 | for (int i = 0; i < tab.length ; i++) | ||
| 637 | setEntryAt(tab, i, null); | ||
| 638 | ++modCount; | ||
| 639 | count = 0; | ||
| 640 | } finally { | ||
| 641 | unlock(); | ||
| 642 | } | ||
| 643 | } | ||
| 644 | } | ||
| 645 | |||
| 646 | // Accessing segments | ||
| 647 | |||
| 648 | /** | ||
| 649 | * Gets the jth element of given segment array (if nonnull) with | ||
| 650 | * volatile element access semantics via Unsafe. (The null check | ||
| 651 | * can trigger harmlessly only during deserialization.) Note: | ||
| 652 | * because each element of segments array is set only once (using | ||
| 653 | * fully ordered writes), some performance-sensitive methods rely | ||
| 654 | * on this method only as a recheck upon null reads. | ||
| 655 | */ | ||
| 656 | @SuppressWarnings("unchecked") | ||
| 657 | static final <K,V> Segment<K,V> segmentAt(Segment<K,V>[] ss, int j) { | ||
| 658 | long u = (j << SSHIFT) + SBASE; | ||
| 659 | return ss == null ? null : | ||
| 660 | (Segment<K,V>) UNSAFE.getObjectVolatile(ss, u); | ||
| 661 | } | ||
| 662 | |||
| 663 | /** | ||
| 664 | * Returns the segment for the given index, creating it and | ||
| 665 | * recording in segment table (via CAS) if not already present. | ||
| 666 | * | ||
| 667 | * @param k the index | ||
| 668 | * @return the segment | ||
| 669 | */ | ||
| 670 | @SuppressWarnings("unchecked") | ||
| 671 | private Segment<K,V> ensureSegment(int k) { | ||
| 672 | final Segment<K,V>[] ss = this.segments; | ||
| 673 | long u = (k << SSHIFT) + SBASE; // raw offset | ||
| 674 | Segment<K,V> seg; | ||
| 675 | if ((seg = (Segment<K,V>)UNSAFE.getObjectVolatile(ss, u)) == null) { | ||
| 676 | Segment<K,V> proto = ss[0]; // use segment 0 as prototype | ||
| 677 | int cap = proto.table.length; | ||
| 678 | float lf = proto.loadFactor; | ||
| 679 | int threshold = (int)(cap * lf); | ||
| 680 | HashEntry<K,V>[] tab = (HashEntry<K,V>[])new HashEntry[cap]; | ||
| 681 | if ((seg = (Segment<K,V>)UNSAFE.getObjectVolatile(ss, u)) | ||
| 682 | == null) { // recheck | ||
| 683 | Segment<K,V> s = new Segment<K,V>(lf, threshold, tab); | ||
| 684 | while ((seg = (Segment<K,V>)UNSAFE.getObjectVolatile(ss, u)) | ||
| 685 | == null) { | ||
| 686 | if (UNSAFE.compareAndSwapObject(ss, u, null, seg = s)) | ||
| 687 | break; | ||
| 688 | } | ||
| 689 | } | ||
| 690 | } | ||
| 691 | return seg; | ||
| 692 | } | ||
| 693 | |||
| 694 | // Hash-based segment and entry accesses | ||
| 695 | |||
| 696 | /** | ||
| 697 | * Get the segment for the given hash | ||
| 698 | */ | ||
| 699 | @SuppressWarnings("unchecked") | ||
| 700 | private Segment<K,V> segmentForHash(int h) { | ||
| 701 | long u = (((h >>> segmentShift) & segmentMask) << SSHIFT) + SBASE; | ||
| 702 | return (Segment<K,V>) UNSAFE.getObjectVolatile(segments, u); | ||
| 703 | } | ||
| 704 | |||
| 705 | /** | ||
| 706 | * Gets the table entry for the given segment and hash | ||
| 707 | */ | ||
| 708 | @SuppressWarnings("unchecked") | ||
| 709 | static final <K,V> HashEntry<K,V> entryForHash(Segment<K,V> seg, int h) { | ||
| 710 | HashEntry<K,V>[] tab; | ||
| 711 | return (seg == null || (tab = seg.table) == null) ? null : | ||
| 712 | (HashEntry<K,V>) UNSAFE.getObjectVolatile | ||
| 713 | (tab, ((long)(((tab.length - 1) & h)) << TSHIFT) + TBASE); | ||
| 714 | } | ||
| 715 | |||
| 716 | /* ---------------- Public operations -------------- */ | ||
| 717 | |||
| 718 | /** | ||
| 719 | * Creates a new, empty map with the specified initial | ||
| 720 | * capacity, load factor and concurrency level. | ||
| 721 | * | ||
| 722 | * @param initialCapacity the initial capacity. The implementation | ||
| 723 | * performs internal sizing to accommodate this many elements. | ||
| 724 | * @param loadFactor the load factor threshold, used to control resizing. | ||
| 725 | * Resizing may be performed when the average number of elements per | ||
| 726 | * bin exceeds this threshold. | ||
| 727 | * @param concurrencyLevel the estimated number of concurrently | ||
| 728 | * updating threads. The implementation performs internal sizing | ||
| 729 | * to try to accommodate this many threads. | ||
| 730 | * @throws IllegalArgumentException if the initial capacity is | ||
| 731 | * negative or the load factor or concurrencyLevel are | ||
| 732 | * nonpositive. | ||
| 733 | */ | ||
| 734 | @SuppressWarnings("unchecked") | ||
| 735 | public ConcurrentHashMap(int initialCapacity, | ||
| 736 | float loadFactor, int concurrencyLevel) { | ||
| 737 | if (!(loadFactor > 0) || initialCapacity < 0 || concurrencyLevel <= 0) | ||
| 738 | throw new IllegalArgumentException(); | ||
| 739 | if (concurrencyLevel > MAX_SEGMENTS) | ||
| 740 | concurrencyLevel = MAX_SEGMENTS; | ||
| 741 | // Find power-of-two sizes best matching arguments | ||
| 742 | int sshift = 0; | ||
| 743 | int ssize = 1; | ||
| 744 | while (ssize < concurrencyLevel) { | ||
| 745 | ++sshift; | ||
| 746 | ssize <<= 1; | ||
| 747 | } | ||
| 748 | this.segmentShift = 32 - sshift; | ||
| 749 | this.segmentMask = ssize - 1; | ||
| 750 | if (initialCapacity > MAXIMUM_CAPACITY) | ||
| 751 | initialCapacity = MAXIMUM_CAPACITY; | ||
| 752 | int c = initialCapacity / ssize; | ||
| 753 | if (c * ssize < initialCapacity) | ||
| 754 | ++c; | ||
| 755 | int cap = MIN_SEGMENT_TABLE_CAPACITY; | ||
| 756 | while (cap < c) | ||
| 757 | cap <<= 1; | ||
| 758 | // create segments and segments[0] | ||
| 759 | Segment<K,V> s0 = | ||
| 760 | new Segment<K,V>(loadFactor, (int)(cap * loadFactor), | ||
| 761 | (HashEntry<K,V>[])new HashEntry[cap]); | ||
| 762 | Segment<K,V>[] ss = (Segment<K,V>[])new Segment[ssize]; | ||
| 763 | UNSAFE.putOrderedObject(ss, SBASE, s0); // ordered write of segments[0] | ||
| 764 | this.segments = ss; | ||
| 765 | } | ||
| 766 | |||
| 767 | /** | ||
| 768 | * Creates a new, empty map with the specified initial capacity | ||
| 769 | * and load factor and with the default concurrencyLevel (16). | ||
| 770 | * | ||
| 771 | * @param initialCapacity The implementation performs internal | ||
| 772 | * sizing to accommodate this many elements. | ||
| 773 | * @param loadFactor the load factor threshold, used to control resizing. | ||
| 774 | * Resizing may be performed when the average number of elements per | ||
| 775 | * bin exceeds this threshold. | ||
| 776 | * @throws IllegalArgumentException if the initial capacity of | ||
| 777 | * elements is negative or the load factor is nonpositive | ||
| 778 | * | ||
| 779 | * @since 1.6 | ||
| 780 | */ | ||
| 781 | public ConcurrentHashMap(int initialCapacity, float loadFactor) { | ||
| 782 | this(initialCapacity, loadFactor, DEFAULT_CONCURRENCY_LEVEL); | ||
| 783 | } | ||
| 784 | |||
| 785 | /** | ||
| 786 | * Creates a new, empty map with the specified initial capacity, | ||
| 787 | * and with default load factor (0.75) and concurrencyLevel (16). | ||
| 788 | * | ||
| 789 | * @param initialCapacity the initial capacity. The implementation | ||
| 790 | * performs internal sizing to accommodate this many elements. | ||
| 791 | * @throws IllegalArgumentException if the initial capacity of | ||
| 792 | * elements is negative. | ||
| 793 | */ | ||
| 794 | public ConcurrentHashMap(int initialCapacity) { | ||
| 795 | this(initialCapacity, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL); | ||
| 796 | } | ||
| 797 | |||
| 798 | /** | ||
| 799 | * Creates a new, empty map with a default initial capacity (16), | ||
| 800 | * load factor (0.75) and concurrencyLevel (16). | ||
| 801 | */ | ||
| 802 | public ConcurrentHashMap() { | ||
| 803 | this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL); | ||
| 804 | } | ||
| 805 | |||
| 806 | /** | ||
| 807 | * Creates a new map with the same mappings as the given map. | ||
| 808 | * The map is created with a capacity of 1.5 times the number | ||
| 809 | * of mappings in the given map or 16 (whichever is greater), | ||
| 810 | * and a default load factor (0.75) and concurrencyLevel (16). | ||
| 811 | * | ||
| 812 | * @param m the map | ||
| 813 | */ | ||
| 814 | public ConcurrentHashMap(Map<? extends K, ? extends V> m) { | ||
| 815 | this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1, | ||
| 816 | DEFAULT_INITIAL_CAPACITY), | ||
| 817 | DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL); | ||
| 818 | putAll(m); | ||
| 819 | } | ||
| 820 | |||
| 821 | /** | ||
| 822 | * Returns <tt>true</tt> if this map contains no key-value mappings. | ||
| 823 | * | ||
| 824 | * @return <tt>true</tt> if this map contains no key-value mappings | ||
| 825 | */ | ||
| 826 | public boolean isEmpty() { | ||
| 827 | /* | ||
| 828 | * Sum per-segment modCounts to avoid mis-reporting when | ||
| 829 | * elements are concurrently added and removed in one segment | ||
| 830 | * while checking another, in which case the table was never | ||
| 831 | * actually empty at any point. (The sum ensures accuracy up | ||
| 832 | * through at least 1<<31 per-segment modifications before | ||
| 833 | * recheck.) Methods size() and containsValue() use similar | ||
| 834 | * constructions for stability checks. | ||
| 835 | */ | ||
| 836 | long sum = 0L; | ||
| 837 | final Segment<K,V>[] segments = this.segments; | ||
| 838 | for (int j = 0; j < segments.length; ++j) { | ||
| 839 | Segment<K,V> seg = segmentAt(segments, j); | ||
| 840 | if (seg != null) { | ||
| 841 | if (seg.count != 0) | ||
| 842 | return false; | ||
| 843 | sum += seg.modCount; | ||
| 844 | } | ||
| 845 | } | ||
| 846 | if (sum != 0L) { // recheck unless no modifications | ||
| 847 | for (int j = 0; j < segments.length; ++j) { | ||
| 848 | Segment<K,V> seg = segmentAt(segments, j); | ||
| 849 | if (seg != null) { | ||
| 850 | if (seg.count != 0) | ||
| 851 | return false; | ||
| 852 | sum -= seg.modCount; | ||
| 853 | } | ||
| 854 | } | ||
| 855 | if (sum != 0L) | ||
| 856 | return false; | ||
| 857 | } | ||
| 858 | return true; | ||
| 859 | } | ||
| 860 | |||
| 861 | /** | ||
| 862 | * Returns the number of key-value mappings in this map. If the | ||
| 863 | * map contains more than <tt>Integer.MAX_VALUE</tt> elements, returns | ||
| 864 | * <tt>Integer.MAX_VALUE</tt>. | ||
| 865 | * | ||
| 866 | * @return the number of key-value mappings in this map | ||
| 867 | */ | ||
| 868 | public int size() { | ||
| 869 | // Try a few times to get accurate count. On failure due to | ||
| 870 | // continuous async changes in table, resort to locking. | ||
| 871 | final Segment<K,V>[] segments = this.segments; | ||
| 872 | int size; | ||
| 873 | boolean overflow; // true if size overflows 32 bits | ||
| 874 | long sum; // sum of modCounts | ||
| 875 | long last = 0L; // previous sum | ||
| 876 | int retries = -1; // first iteration isn't retry | ||
| 877 | try { | ||
| 878 | for (;;) { | ||
| 879 | if (retries++ == RETRIES_BEFORE_LOCK) { | ||
| 880 | for (int j = 0; j < segments.length; ++j) | ||
| 881 | ensureSegment(j).lock(); // force creation | ||
| 882 | } | ||
| 883 | sum = 0L; | ||
| 884 | size = 0; | ||
| 885 | overflow = false; | ||
| 886 | for (int j = 0; j < segments.length; ++j) { | ||
| 887 | Segment<K,V> seg = segmentAt(segments, j); | ||
| 888 | if (seg != null) { | ||
| 889 | sum += seg.modCount; | ||
| 890 | int c = seg.count; | ||
| 891 | if (c < 0 || (size += c) < 0) | ||
| 892 | overflow = true; | ||
| 893 | } | ||
| 894 | } | ||
| 895 | if (sum == last) | ||
| 896 | break; | ||
| 897 | last = sum; | ||
| 898 | } | ||
| 899 | } finally { | ||
| 900 | if (retries > RETRIES_BEFORE_LOCK) { | ||
| 901 | for (int j = 0; j < segments.length; ++j) | ||
| 902 | segmentAt(segments, j).unlock(); | ||
| 903 | } | ||
| 904 | } | ||
| 905 | return overflow ? Integer.MAX_VALUE : size; | ||
| 906 | } | ||
| 907 | |||
| 908 | /** | ||
| 909 | * Returns the value to which the specified key is mapped, | ||
| 910 | * or {@code null} if this map contains no mapping for the key. | ||
| 911 | * | ||
| 912 | * <p>More formally, if this map contains a mapping from a key | ||
| 913 | * {@code k} to a value {@code v} such that {@code key.equals(k)}, | ||
| 914 | * then this method returns {@code v}; otherwise it returns | ||
| 915 | * {@code null}. (There can be at most one such mapping.) | ||
| 916 | * | ||
| 917 | * @throws NullPointerException if the specified key is null | ||
| 918 | */ | ||
| 919 | public V get(Object key) { | ||
| 920 | Segment<K,V> s; // manually integrate access methods to reduce overhead | ||
| 921 | HashEntry<K,V>[] tab; | ||
| 922 | int h = hash(key.hashCode()); | ||
| 923 | long u = (((h >>> segmentShift) & segmentMask) << SSHIFT) + SBASE; | ||
| 924 | if ((s = (Segment<K,V>)UNSAFE.getObjectVolatile(segments, u)) != null && | ||
| 925 | (tab = s.table) != null) { | ||
| 926 | for (HashEntry<K,V> e = (HashEntry<K,V>) UNSAFE.getObjectVolatile | ||
| 927 | (tab, ((long)(((tab.length - 1) & h)) << TSHIFT) + TBASE); | ||
| 928 | e != null; e = e.next) { | ||
| 929 | K k; | ||
| 930 | if ((k = e.key) == key || (e.hash == h && key.equals(k))) | ||
| 931 | return e.value; | ||
| 932 | } | ||
| 933 | } | ||
| 934 | return null; | ||
| 935 | } | ||
| 936 | |||
| 937 | /** | ||
| 938 | * Tests if the specified object is a key in this table. | ||
| 939 | * | ||
| 940 | * @param key possible key | ||
| 941 | * @return <tt>true</tt> if and only if the specified object | ||
| 942 | * is a key in this table, as determined by the | ||
| 943 | * <tt>equals</tt> method; <tt>false</tt> otherwise. | ||
| 944 | * @throws NullPointerException if the specified key is null | ||
| 945 | */ | ||
| 946 | @SuppressWarnings("unchecked") | ||
| 947 | public boolean containsKey(Object key) { | ||
| 948 | Segment<K,V> s; // same as get() except no need for volatile value read | ||
| 949 | HashEntry<K,V>[] tab; | ||
| 950 | int h = hash(key.hashCode()); | ||
| 951 | long u = (((h >>> segmentShift) & segmentMask) << SSHIFT) + SBASE; | ||
| 952 | if ((s = (Segment<K,V>)UNSAFE.getObjectVolatile(segments, u)) != null && | ||
| 953 | (tab = s.table) != null) { | ||
| 954 | for (HashEntry<K,V> e = (HashEntry<K,V>) UNSAFE.getObjectVolatile | ||
| 955 | (tab, ((long)(((tab.length - 1) & h)) << TSHIFT) + TBASE); | ||
| 956 | e != null; e = e.next) { | ||
| 957 | K k; | ||
| 958 | if ((k = e.key) == key || (e.hash == h && key.equals(k))) | ||
| 959 | return true; | ||
| 960 | } | ||
| 961 | } | ||
| 962 | return false; | ||
| 963 | } | ||
| 964 | |||
| 965 | /** | ||
| 966 | * Returns <tt>true</tt> if this map maps one or more keys to the | ||
| 967 | * specified value. Note: This method requires a full internal | ||
| 968 | * traversal of the hash table, and so is much slower than | ||
| 969 | * method <tt>containsKey</tt>. | ||
| 970 | * | ||
| 971 | * @param value value whose presence in this map is to be tested | ||
| 972 | * @return <tt>true</tt> if this map maps one or more keys to the | ||
| 973 | * specified value | ||
| 974 | * @throws NullPointerException if the specified value is null | ||
| 975 | */ | ||
| 976 | public boolean containsValue(Object value) { | ||
| 977 | // Same idea as size() | ||
| 978 | if (value == null) | ||
| 979 | throw new NullPointerException(); | ||
| 980 | final Segment<K,V>[] segments = this.segments; | ||
| 981 | boolean found = false; | ||
| 982 | long last = 0; | ||
| 983 | int retries = -1; | ||
| 984 | try { | ||
| 985 | outer: for (;;) { | ||
| 986 | if (retries++ == RETRIES_BEFORE_LOCK) { | ||
| 987 | for (int j = 0; j < segments.length; ++j) | ||
| 988 | ensureSegment(j).lock(); // force creation | ||
| 989 | } | ||
| 990 | long hashSum = 0L; | ||
| 991 | int sum = 0; | ||
| 992 | for (int j = 0; j < segments.length; ++j) { | ||
| 993 | HashEntry<K,V>[] tab; | ||
| 994 | Segment<K,V> seg = segmentAt(segments, j); | ||
| 995 | if (seg != null && (tab = seg.table) != null) { | ||
| 996 | for (int i = 0 ; i < tab.length; i++) { | ||
| 997 | HashEntry<K,V> e; | ||
| 998 | for (e = entryAt(tab, i); e != null; e = e.next) { | ||
| 999 | V v = e.value; | ||
| 1000 | if (v != null && value.equals(v)) { | ||
| 1001 | found = true; | ||
| 1002 | break outer; | ||
| 1003 | } | ||
| 1004 | } | ||
| 1005 | } | ||
| 1006 | sum += seg.modCount; | ||
| 1007 | } | ||
| 1008 | } | ||
| 1009 | if (retries > 0 && sum == last) | ||
| 1010 | break; | ||
| 1011 | last = sum; | ||
| 1012 | } | ||
| 1013 | } finally { | ||
| 1014 | if (retries > RETRIES_BEFORE_LOCK) { | ||
| 1015 | for (int j = 0; j < segments.length; ++j) | ||
| 1016 | segmentAt(segments, j).unlock(); | ||
| 1017 | } | ||
| 1018 | } | ||
| 1019 | return found; | ||
| 1020 | } | ||
| 1021 | |||
| 1022 | /** | ||
| 1023 | * Legacy method testing if some key maps into the specified value | ||
| 1024 | * in this table. This method is identical in functionality to | ||
| 1025 | * {@link #containsValue}, and exists solely to ensure | ||
| 1026 | * full compatibility with class {@link java.util.Hashtable}, | ||
| 1027 | * which supported this method prior to introduction of the | ||
| 1028 | * Java Collections framework. | ||
| 1029 | |||
| 1030 | * @param value a value to search for | ||
| 1031 | * @return <tt>true</tt> if and only if some key maps to the | ||
| 1032 | * <tt>value</tt> argument in this table as | ||
| 1033 | * determined by the <tt>equals</tt> method; | ||
| 1034 | * <tt>false</tt> otherwise | ||
| 1035 | * @throws NullPointerException if the specified value is null | ||
| 1036 | */ | ||
| 1037 | public boolean contains(Object value) { | ||
| 1038 | return containsValue(value); | ||
| 1039 | } | ||
| 1040 | |||
| 1041 | /** | ||
| 1042 | * Maps the specified key to the specified value in this table. | ||
| 1043 | * Neither the key nor the value can be null. | ||
| 1044 | * | ||
| 1045 | * <p> The value can be retrieved by calling the <tt>get</tt> method | ||
| 1046 | * with a key that is equal to the original key. | ||
| 1047 | * | ||
| 1048 | * @param key key with which the specified value is to be associated | ||
| 1049 | * @param value value to be associated with the specified key | ||
| 1050 | * @return the previous value associated with <tt>key</tt>, or | ||
| 1051 | * <tt>null</tt> if there was no mapping for <tt>key</tt> | ||
| 1052 | * @throws NullPointerException if the specified key or value is null | ||
| 1053 | */ | ||
| 1054 | @SuppressWarnings("unchecked") | ||
| 1055 | public V put(K key, V value) { | ||
| 1056 | Segment<K,V> s; | ||
| 1057 | if (value == null) | ||
| 1058 | throw new NullPointerException(); | ||
| 1059 | int hash = hash(key.hashCode()); | ||
| 1060 | int j = (hash >>> segmentShift) & segmentMask; | ||
| 1061 | if ((s = (Segment<K,V>)UNSAFE.getObject // nonvolatile; recheck | ||
| 1062 | (segments, (j << SSHIFT) + SBASE)) == null) // in ensureSegment | ||
| 1063 | s = ensureSegment(j); | ||
| 1064 | return s.put(key, hash, value, false); | ||
| 1065 | } | ||
| 1066 | |||
| 1067 | /** | ||
| 1068 | * {@inheritDoc} | ||
| 1069 | * | ||
| 1070 | * @return the previous value associated with the specified key, | ||
| 1071 | * or <tt>null</tt> if there was no mapping for the key | ||
| 1072 | * @throws NullPointerException if the specified key or value is null | ||
| 1073 | */ | ||
| 1074 | @SuppressWarnings("unchecked") | ||
| 1075 | public V putIfAbsent(K key, V value) { | ||
| 1076 | Segment<K,V> s; | ||
| 1077 | if (value == null) | ||
| 1078 | throw new NullPointerException(); | ||
| 1079 | int hash = hash(key.hashCode()); | ||
| 1080 | int j = (hash >>> segmentShift) & segmentMask; | ||
| 1081 | if ((s = (Segment<K,V>)UNSAFE.getObject | ||
| 1082 | (segments, (j << SSHIFT) + SBASE)) == null) | ||
| 1083 | s = ensureSegment(j); | ||
| 1084 | return s.put(key, hash, value, true); | ||
| 1085 | } | ||
| 1086 | |||
| 1087 | /** | ||
| 1088 | * Copies all of the mappings from the specified map to this one. | ||
| 1089 | * These mappings replace any mappings that this map had for any of the | ||
| 1090 | * keys currently in the specified map. | ||
| 1091 | * | ||
| 1092 | * @param m mappings to be stored in this map | ||
| 1093 | */ | ||
| 1094 | public void putAll(Map<? extends K, ? extends V> m) { | ||
| 1095 | for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) | ||
| 1096 | put(e.getKey(), e.getValue()); | ||
| 1097 | } | ||
| 1098 | |||
| 1099 | /** | ||
| 1100 | * Removes the key (and its corresponding value) from this map. | ||
| 1101 | * This method does nothing if the key is not in the map. | ||
| 1102 | * | ||
| 1103 | * @param key the key that needs to be removed | ||
| 1104 | * @return the previous value associated with <tt>key</tt>, or | ||
| 1105 | * <tt>null</tt> if there was no mapping for <tt>key</tt> | ||
| 1106 | * @throws NullPointerException if the specified key is null | ||
| 1107 | */ | ||
| 1108 | public V remove(Object key) { | ||
| 1109 | int hash = hash(key.hashCode()); | ||
| 1110 | Segment<K,V> s = segmentForHash(hash); | ||
| 1111 | return s == null ? null : s.remove(key, hash, null); | ||
| 1112 | } | ||
| 1113 | |||
| 1114 | /** | ||
| 1115 | * {@inheritDoc} | ||
| 1116 | * | ||
| 1117 | * @throws NullPointerException if the specified key is null | ||
| 1118 | */ | ||
| 1119 | public boolean remove(Object key, Object value) { | ||
| 1120 | int hash = hash(key.hashCode()); | ||
| 1121 | Segment<K,V> s; | ||
| 1122 | return value != null && (s = segmentForHash(hash)) != null && | ||
| 1123 | s.remove(key, hash, value) != null; | ||
| 1124 | } | ||
| 1125 | |||
| 1126 | /** | ||
| 1127 | * {@inheritDoc} | ||
| 1128 | * | ||
| 1129 | * @throws NullPointerException if any of the arguments are null | ||
| 1130 | */ | ||
| 1131 | public boolean replace(K key, V oldValue, V newValue) { | ||
| 1132 | int hash = hash(key.hashCode()); | ||
| 1133 | if (oldValue == null || newValue == null) | ||
| 1134 | throw new NullPointerException(); | ||
| 1135 | Segment<K,V> s = segmentForHash(hash); | ||
| 1136 | return s != null && s.replace(key, hash, oldValue, newValue); | ||
| 1137 | } | ||
| 1138 | |||
| 1139 | /** | ||
| 1140 | * {@inheritDoc} | ||
| 1141 | * | ||
| 1142 | * @return the previous value associated with the specified key, | ||
| 1143 | * or <tt>null</tt> if there was no mapping for the key | ||
| 1144 | * @throws NullPointerException if the specified key or value is null | ||
| 1145 | */ | ||
| 1146 | public V replace(K key, V value) { | ||
| 1147 | int hash = hash(key.hashCode()); | ||
| 1148 | if (value == null) | ||
| 1149 | throw new NullPointerException(); | ||
| 1150 | Segment<K,V> s = segmentForHash(hash); | ||
| 1151 | return s == null ? null : s.replace(key, hash, value); | ||
| 1152 | } | ||
| 1153 | |||
| 1154 | /** | ||
| 1155 | * Removes all of the mappings from this map. | ||
| 1156 | */ | ||
| 1157 | public void clear() { | ||
| 1158 | final Segment<K,V>[] segments = this.segments; | ||
| 1159 | for (int j = 0; j < segments.length; ++j) { | ||
| 1160 | Segment<K,V> s = segmentAt(segments, j); | ||
| 1161 | if (s != null) | ||
| 1162 | s.clear(); | ||
| 1163 | } | ||
| 1164 | } | ||
| 1165 | |||
| 1166 | /** | ||
| 1167 | * Returns a {@link Set} view of the keys contained in this map. | ||
| 1168 | * The set is backed by the map, so changes to the map are | ||
| 1169 | * reflected in the set, and vice-versa. The set supports element | ||
| 1170 | * removal, which removes the corresponding mapping from this map, | ||
| 1171 | * via the <tt>Iterator.remove</tt>, <tt>Set.remove</tt>, | ||
| 1172 | * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> | ||
| 1173 | * operations. It does not support the <tt>add</tt> or | ||
| 1174 | * <tt>addAll</tt> operations. | ||
| 1175 | * | ||
| 1176 | * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator | ||
| 1177 | * that will never throw {@link ConcurrentModificationException}, | ||
| 1178 | * and guarantees to traverse elements as they existed upon | ||
| 1179 | * construction of the iterator, and may (but is not guaranteed to) | ||
| 1180 | * reflect any modifications subsequent to construction. | ||
| 1181 | */ | ||
| 1182 | public Set<K> keySet() { | ||
| 1183 | Set<K> ks = keySet; | ||
| 1184 | return (ks != null) ? ks : (keySet = new KeySet()); | ||
| 1185 | } | ||
| 1186 | |||
| 1187 | /** | ||
| 1188 | * Returns a {@link Collection} view of the values contained in this map. | ||
| 1189 | * The collection is backed by the map, so changes to the map are | ||
| 1190 | * reflected in the collection, and vice-versa. The collection | ||
| 1191 | * supports element removal, which removes the corresponding | ||
| 1192 | * mapping from this map, via the <tt>Iterator.remove</tt>, | ||
| 1193 | * <tt>Collection.remove</tt>, <tt>removeAll</tt>, | ||
| 1194 | * <tt>retainAll</tt>, and <tt>clear</tt> operations. It does not | ||
| 1195 | * support the <tt>add</tt> or <tt>addAll</tt> operations. | ||
| 1196 | * | ||
| 1197 | * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator | ||
| 1198 | * that will never throw {@link ConcurrentModificationException}, | ||
| 1199 | * and guarantees to traverse elements as they existed upon | ||
| 1200 | * construction of the iterator, and may (but is not guaranteed to) | ||
| 1201 | * reflect any modifications subsequent to construction. | ||
| 1202 | */ | ||
| 1203 | public Collection<V> values() { | ||
| 1204 | Collection<V> vs = values; | ||
| 1205 | return (vs != null) ? vs : (values = new Values()); | ||
| 1206 | } | ||
| 1207 | |||
| 1208 | /** | ||
| 1209 | * Returns a {@link Set} view of the mappings contained in this map. | ||
| 1210 | * The set is backed by the map, so changes to the map are | ||
| 1211 | * reflected in the set, and vice-versa. The set supports element | ||
| 1212 | * removal, which removes the corresponding mapping from the map, | ||
| 1213 | * via the <tt>Iterator.remove</tt>, <tt>Set.remove</tt>, | ||
| 1214 | * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> | ||
| 1215 | * operations. It does not support the <tt>add</tt> or | ||
| 1216 | * <tt>addAll</tt> operations. | ||
| 1217 | * | ||
| 1218 | * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator | ||
| 1219 | * that will never throw {@link ConcurrentModificationException}, | ||
| 1220 | * and guarantees to traverse elements as they existed upon | ||
| 1221 | * construction of the iterator, and may (but is not guaranteed to) | ||
| 1222 | * reflect any modifications subsequent to construction. | ||
| 1223 | */ | ||
| 1224 | public Set<Map.Entry<K,V>> entrySet() { | ||
| 1225 | Set<Map.Entry<K,V>> es = entrySet; | ||
| 1226 | return (es != null) ? es : (entrySet = new EntrySet()); | ||
| 1227 | } | ||
| 1228 | |||
| 1229 | /** | ||
| 1230 | * Returns an enumeration of the keys in this table. | ||
| 1231 | * | ||
| 1232 | * @return an enumeration of the keys in this table | ||
| 1233 | * @see #keySet() | ||
| 1234 | */ | ||
| 1235 | public Enumeration<K> keys() { | ||
| 1236 | return new KeyIterator(); | ||
| 1237 | } | ||
| 1238 | |||
| 1239 | /** | ||
| 1240 | * Returns an enumeration of the values in this table. | ||
| 1241 | * | ||
| 1242 | * @return an enumeration of the values in this table | ||
| 1243 | * @see #values() | ||
| 1244 | */ | ||
| 1245 | public Enumeration<V> elements() { | ||
| 1246 | return new ValueIterator(); | ||
| 1247 | } | ||
| 1248 | |||
| 1249 | /* ---------------- Iterator Support -------------- */ | ||
| 1250 | |||
| 1251 | abstract class HashIterator { | ||
| 1252 | int nextSegmentIndex; | ||
| 1253 | int nextTableIndex; | ||
| 1254 | HashEntry<K,V>[] currentTable; | ||
| 1255 | HashEntry<K, V> nextEntry; | ||
| 1256 | HashEntry<K, V> lastReturned; | ||
| 1257 | |||
| 1258 | HashIterator() { | ||
| 1259 | nextSegmentIndex = segments.length - 1; | ||
| 1260 | nextTableIndex = -1; | ||
| 1261 | advance(); | ||
| 1262 | } | ||
| 1263 | |||
| 1264 | /** | ||
| 1265 | * Set nextEntry to first node of next non-empty table | ||
| 1266 | * (in backwards order, to simplify checks). | ||
| 1267 | */ | ||
| 1268 | final void advance() { | ||
| 1269 | for (;;) { | ||
| 1270 | if (nextTableIndex >= 0) { | ||
| 1271 | if ((nextEntry = entryAt(currentTable, | ||
| 1272 | nextTableIndex--)) != null) | ||
| 1273 | break; | ||
| 1274 | } | ||
| 1275 | else if (nextSegmentIndex >= 0) { | ||
| 1276 | Segment<K,V> seg = segmentAt(segments, nextSegmentIndex--); | ||
| 1277 | if (seg != null && (currentTable = seg.table) != null) | ||
| 1278 | nextTableIndex = currentTable.length - 1; | ||
| 1279 | } | ||
| 1280 | else | ||
| 1281 | break; | ||
| 1282 | } | ||
| 1283 | } | ||
| 1284 | |||
| 1285 | final HashEntry<K,V> nextEntry() { | ||
| 1286 | HashEntry<K,V> e = nextEntry; | ||
| 1287 | if (e == null) | ||
| 1288 | throw new NoSuchElementException(); | ||
| 1289 | lastReturned = e; // cannot assign until after null check | ||
| 1290 | if ((nextEntry = e.next) == null) | ||
| 1291 | advance(); | ||
| 1292 | return e; | ||
| 1293 | } | ||
| 1294 | |||
| 1295 | public final boolean hasNext() { return nextEntry != null; } | ||
| 1296 | public final boolean hasMoreElements() { return nextEntry != null; } | ||
| 1297 | |||
| 1298 | public final void remove() { | ||
| 1299 | if (lastReturned == null) | ||
| 1300 | throw new IllegalStateException(); | ||
| 1301 | ConcurrentHashMap.this.remove(lastReturned.key); | ||
| 1302 | lastReturned = null; | ||
| 1303 | } | ||
| 1304 | } | ||
| 1305 | |||
| 1306 | final class KeyIterator | ||
| 1307 | extends HashIterator | ||
| 1308 | implements Iterator<K>, Enumeration<K> | ||
| 1309 | { | ||
| 1310 | public final K next() { return super.nextEntry().key; } | ||
| 1311 | public final K nextElement() { return super.nextEntry().key; } | ||
| 1312 | } | ||
| 1313 | |||
| 1314 | final class ValueIterator | ||
| 1315 | extends HashIterator | ||
| 1316 | implements Iterator<V>, Enumeration<V> | ||
| 1317 | { | ||
| 1318 | public final V next() { return super.nextEntry().value; } | ||
| 1319 | public final V nextElement() { return super.nextEntry().value; } | ||
| 1320 | } | ||
| 1321 | |||
| 1322 | /** | ||
| 1323 | * Custom Entry class used by EntryIterator.next(), that relays | ||
| 1324 | * setValue changes to the underlying map. | ||
| 1325 | */ | ||
| 1326 | final class WriteThroughEntry | ||
| 1327 | extends AbstractMap.SimpleEntry<K,V> | ||
| 1328 | { | ||
| 1329 | WriteThroughEntry(K k, V v) { | ||
| 1330 | super(k,v); | ||
| 1331 | } | ||
| 1332 | |||
| 1333 | /** | ||
| 1334 | * Set our entry's value and write through to the map. The | ||
| 1335 | * value to return is somewhat arbitrary here. Since a | ||
| 1336 | * WriteThroughEntry does not necessarily track asynchronous | ||
| 1337 | * changes, the most recent "previous" value could be | ||
| 1338 | * different from what we return (or could even have been | ||
| 1339 | * removed in which case the put will re-establish). We do not | ||
| 1340 | * and cannot guarantee more. | ||
| 1341 | */ | ||
| 1342 | public V setValue(V value) { | ||
| 1343 | if (value == null) throw new NullPointerException(); | ||
| 1344 | V v = super.setValue(value); | ||
| 1345 | ConcurrentHashMap.this.put(getKey(), value); | ||
| 1346 | return v; | ||
| 1347 | } | ||
| 1348 | } | ||
| 1349 | |||
| 1350 | final class EntryIterator | ||
| 1351 | extends HashIterator | ||
| 1352 | implements Iterator<Entry<K,V>> | ||
| 1353 | { | ||
| 1354 | public Map.Entry<K,V> next() { | ||
| 1355 | HashEntry<K,V> e = super.nextEntry(); | ||
| 1356 | return new WriteThroughEntry(e.key, e.value); | ||
| 1357 | } | ||
| 1358 | } | ||
| 1359 | |||
| 1360 | final class KeySet extends AbstractSet<K> { | ||
| 1361 | public Iterator<K> iterator() { | ||
| 1362 | return new KeyIterator(); | ||
| 1363 | } | ||
| 1364 | public int size() { | ||
| 1365 | return ConcurrentHashMap.this.size(); | ||
| 1366 | } | ||
| 1367 | public boolean isEmpty() { | ||
| 1368 | return ConcurrentHashMap.this.isEmpty(); | ||
| 1369 | } | ||
| 1370 | public boolean contains(Object o) { | ||
| 1371 | return ConcurrentHashMap.this.containsKey(o); | ||
| 1372 | } | ||
| 1373 | public boolean remove(Object o) { | ||
| 1374 | return ConcurrentHashMap.this.remove(o) != null; | ||
| 1375 | } | ||
| 1376 | public void clear() { | ||
| 1377 | ConcurrentHashMap.this.clear(); | ||
| 1378 | } | ||
| 1379 | } | ||
| 1380 | |||
| 1381 | final class Values extends AbstractCollection<V> { | ||
| 1382 | public Iterator<V> iterator() { | ||
| 1383 | return new ValueIterator(); | ||
| 1384 | } | ||
| 1385 | public int size() { | ||
| 1386 | return ConcurrentHashMap.this.size(); | ||
| 1387 | } | ||
| 1388 | public boolean isEmpty() { | ||
| 1389 | return ConcurrentHashMap.this.isEmpty(); | ||
| 1390 | } | ||
| 1391 | public boolean contains(Object o) { | ||
| 1392 | return ConcurrentHashMap.this.containsValue(o); | ||
| 1393 | } | ||
| 1394 | public void clear() { | ||
| 1395 | ConcurrentHashMap.this.clear(); | ||
| 1396 | } | ||
| 1397 | } | ||
| 1398 | |||
| 1399 | final class EntrySet extends AbstractSet<Map.Entry<K,V>> { | ||
| 1400 | public Iterator<Map.Entry<K,V>> iterator() { | ||
| 1401 | return new EntryIterator(); | ||
| 1402 | } | ||
| 1403 | public boolean contains(Object o) { | ||
| 1404 | if (!(o instanceof Map.Entry)) | ||
| 1405 | return false; | ||
| 1406 | Map.Entry<?,?> e = (Map.Entry<?,?>)o; | ||
| 1407 | V v = ConcurrentHashMap.this.get(e.getKey()); | ||
| 1408 | return v != null && v.equals(e.getValue()); | ||
| 1409 | } | ||
| 1410 | public boolean remove(Object o) { | ||
| 1411 | if (!(o instanceof Map.Entry)) | ||
| 1412 | return false; | ||
| 1413 | Map.Entry<?,?> e = (Map.Entry<?,?>)o; | ||
| 1414 | return ConcurrentHashMap.this.remove(e.getKey(), e.getValue()); | ||
| 1415 | } | ||
| 1416 | public int size() { | ||
| 1417 | return ConcurrentHashMap.this.size(); | ||
| 1418 | } | ||
| 1419 | public boolean isEmpty() { | ||
| 1420 | return ConcurrentHashMap.this.isEmpty(); | ||
| 1421 | } | ||
| 1422 | public void clear() { | ||
| 1423 | ConcurrentHashMap.this.clear(); | ||
| 1424 | } | ||
| 1425 | } | ||
| 1426 | |||
| 1427 | /* ---------------- Serialization Support -------------- */ | ||
| 1428 | |||
| 1429 | /** | ||
| 1430 | * Save the state of the <tt>ConcurrentHashMap</tt> instance to a | ||
| 1431 | * stream (i.e., serialize it). | ||
| 1432 | * @param s the stream | ||
| 1433 | * @serialData | ||
| 1434 | * the key (Object) and value (Object) | ||
| 1435 | * for each key-value mapping, followed by a null pair. | ||
| 1436 | * The key-value mappings are emitted in no particular order. | ||
| 1437 | */ | ||
| 1438 | private void writeObject(java.io.ObjectOutputStream s) throws IOException { | ||
| 1439 | // force all segments for serialization compatibility | ||
| 1440 | for (int k = 0; k < segments.length; ++k) | ||
| 1441 | ensureSegment(k); | ||
| 1442 | s.defaultWriteObject(); | ||
| 1443 | |||
| 1444 | final Segment<K,V>[] segments = this.segments; | ||
| 1445 | for (int k = 0; k < segments.length; ++k) { | ||
| 1446 | Segment<K,V> seg = segmentAt(segments, k); | ||
| 1447 | seg.lock(); | ||
| 1448 | try { | ||
| 1449 | HashEntry<K,V>[] tab = seg.table; | ||
| 1450 | for (int i = 0; i < tab.length; ++i) { | ||
| 1451 | HashEntry<K,V> e; | ||
| 1452 | for (e = entryAt(tab, i); e != null; e = e.next) { | ||
| 1453 | s.writeObject(e.key); | ||
| 1454 | s.writeObject(e.value); | ||
| 1455 | } | ||
| 1456 | } | ||
| 1457 | } finally { | ||
| 1458 | seg.unlock(); | ||
| 1459 | } | ||
| 1460 | } | ||
| 1461 | s.writeObject(null); | ||
| 1462 | s.writeObject(null); | ||
| 1463 | } | ||
| 1464 | |||
| 1465 | /** | ||
| 1466 | * Reconstitute the <tt>ConcurrentHashMap</tt> instance from a | ||
| 1467 | * stream (i.e., deserialize it). | ||
| 1468 | * @param s the stream | ||
| 1469 | */ | ||
| 1470 | @SuppressWarnings("unchecked") | ||
| 1471 | private void readObject(java.io.ObjectInputStream s) | ||
| 1472 | throws IOException, ClassNotFoundException { | ||
| 1473 | s.defaultReadObject(); | ||
| 1474 | |||
| 1475 | // Re-initialize segments to be minimally sized, and let grow. | ||
| 1476 | int cap = MIN_SEGMENT_TABLE_CAPACITY; | ||
| 1477 | final Segment<K,V>[] segments = this.segments; | ||
| 1478 | for (int k = 0; k < segments.length; ++k) { | ||
| 1479 | Segment<K,V> seg = segments[k]; | ||
| 1480 | if (seg != null) { | ||
| 1481 | seg.threshold = (int)(cap * seg.loadFactor); | ||
| 1482 | seg.table = (HashEntry<K,V>[]) new HashEntry[cap]; | ||
| 1483 | } | ||
| 1484 | } | ||
| 1485 | |||
| 1486 | // Read the keys and values, and put the mappings in the table | ||
| 1487 | for (;;) { | ||
| 1488 | K key = (K) s.readObject(); | ||
| 1489 | V value = (V) s.readObject(); | ||
| 1490 | if (key == null) | ||
| 1491 | break; | ||
| 1492 | put(key, value); | ||
| 1493 | } | ||
| 1494 | } | ||
| 1495 | |||
| 1496 | // Unsafe mechanics | ||
| 1497 | private static final sun.misc.Unsafe UNSAFE; | ||
| 1498 | private static final long SBASE; | ||
| 1499 | private static final int SSHIFT; | ||
| 1500 | private static final long TBASE; | ||
| 1501 | private static final int TSHIFT; | ||
| 1502 | |||
| 1503 | static { | ||
| 1504 | int ss, ts; | ||
| 1505 | try { | ||
| 1506 | UNSAFE = sun.misc.Unsafe.getUnsafe(); | ||
| 1507 | Class tc = HashEntry[].class; | ||
| 1508 | Class sc = Segment[].class; | ||
| 1509 | TBASE = UNSAFE.arrayBaseOffset(tc); | ||
| 1510 | SBASE = UNSAFE.arrayBaseOffset(sc); | ||
| 1511 | ts = UNSAFE.arrayIndexScale(tc); | ||
| 1512 | ss = UNSAFE.arrayIndexScale(sc); | ||
| 1513 | } catch (Exception e) { | ||
| 1514 | throw new Error(e); | ||
| 1515 | } | ||
| 1516 | if ((ss & (ss-1)) != 0 || (ts & (ts-1)) != 0) | ||
| 1517 | throw new Error("data type scale not a power of two"); | ||
| 1518 | SSHIFT = 31 - Integer.numberOfLeadingZeros(ss); | ||
| 1519 | TSHIFT = 31 - Integer.numberOfLeadingZeros(ts); | ||
| 1520 | } | ||
| 1521 | |||
| 1522 | } | ||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,1469 @@ | |||
| 1 | /* | ||
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 3 | * | ||
| 4 | * This code is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License version 2 only, as | ||
| 6 | * published by the Free Software Foundation. Oracle designates this | ||
| 7 | * particular file as subject to the "Classpath" exception as provided | ||
| 8 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 9 | * | ||
| 10 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 13 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 14 | * accompanied this code). | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License version | ||
| 17 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | * | ||
| 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 21 | * or visit www.oracle.com if you need additional information or have any | ||
| 22 | * questions. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * This file is available under and governed by the GNU General Public | ||
| 27 | * License version 2 only, as published by the Free Software Foundation. | ||
| 28 | * However, the following notice accompanied the original version of this | ||
| 29 | * file: | ||
| 30 | * | ||
| 31 | * Written by Doug Lea and Martin Buchholz with assistance from members of | ||
| 32 | * JCP JSR-166 Expert Group and released to the public domain, as explained | ||
| 33 | * at http://creativecommons.org/publicdomain/zero/1.0/ | ||
| 34 | */ | ||
| 35 | |||
| 36 | package java.util.concurrent; | ||
| 37 | |||
| 38 | import java.util.AbstractCollection; | ||
| 39 | import java.util.ArrayList; | ||
| 40 | import java.util.Collection; | ||
| 41 | import java.util.Deque; | ||
| 42 | import java.util.Iterator; | ||
| 43 | import java.util.NoSuchElementException; | ||
| 44 | import java.util.Queue; | ||
| 45 | |||
| 46 | /** | ||
| 47 | * An unbounded concurrent {@linkplain Deque deque} based on linked nodes. | ||
| 48 | * Concurrent insertion, removal, and access operations execute safely | ||
| 49 | * across multiple threads. | ||
| 50 | * A {@code ConcurrentLinkedDeque} is an appropriate choice when | ||
| 51 | * many threads will share access to a common collection. | ||
| 52 | * Like most other concurrent collection implementations, this class | ||
| 53 | * does not permit the use of {@code null} elements. | ||
| 54 | * | ||
| 55 | * <p>Iterators are <i>weakly consistent</i>, returning elements | ||
| 56 | * reflecting the state of the deque at some point at or since the | ||
| 57 | * creation of the iterator. They do <em>not</em> throw {@link | ||
| 58 | * java.util.ConcurrentModificationException | ||
| 59 | * ConcurrentModificationException}, and may proceed concurrently with | ||
| 60 | * other operations. | ||
| 61 | * | ||
| 62 | * <p>Beware that, unlike in most collections, the {@code size} method | ||
| 63 | * is <em>NOT</em> a constant-time operation. Because of the | ||
| 64 | * asynchronous nature of these deques, determining the current number | ||
| 65 | * of elements requires a traversal of the elements, and so may report | ||
| 66 | * inaccurate results if this collection is modified during traversal. | ||
| 67 | * Additionally, the bulk operations {@code addAll}, | ||
| 68 | * {@code removeAll}, {@code retainAll}, {@code containsAll}, | ||
| 69 | * {@code equals}, and {@code toArray} are <em>not</em> guaranteed | ||
| 70 | * to be performed atomically. For example, an iterator operating | ||
| 71 | * concurrently with an {@code addAll} operation might view only some | ||
| 72 | * of the added elements. | ||
| 73 | * | ||
| 74 | * <p>This class and its iterator implement all of the <em>optional</em> | ||
| 75 | * methods of the {@link Deque} and {@link Iterator} interfaces. | ||
| 76 | * | ||
| 77 | * <p>Memory consistency effects: As with other concurrent collections, | ||
| 78 | * actions in a thread prior to placing an object into a | ||
| 79 | * {@code ConcurrentLinkedDeque} | ||
| 80 | * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> | ||
| 81 | * actions subsequent to the access or removal of that element from | ||
| 82 | * the {@code ConcurrentLinkedDeque} in another thread. | ||
| 83 | * | ||
| 84 | * <p>This class is a member of the | ||
| 85 | * <a href="{@docRoot}/../technotes/guides/collections/index.html"> | ||
| 86 | * Java Collections Framework</a>. | ||
| 87 | * | ||
| 88 | * @since 1.7 | ||
| 89 | * @author Doug Lea | ||
| 90 | * @author Martin Buchholz | ||
| 91 | * @param <E> the type of elements held in this collection | ||
| 92 | */ | ||
| 93 | |||
| 94 | public class ConcurrentLinkedDeque<E> | ||
| 95 | extends AbstractCollection<E> | ||
| 96 | implements Deque<E>, java.io.Serializable { | ||
| 97 | |||
| 98 | /* | ||
| 99 | * This is an implementation of a concurrent lock-free deque | ||
| 100 | * supporting interior removes but not interior insertions, as | ||
| 101 | * required to support the entire Deque interface. | ||
| 102 | * | ||
| 103 | * We extend the techniques developed for ConcurrentLinkedQueue and | ||
| 104 | * LinkedTransferQueue (see the internal docs for those classes). | ||
| 105 | * Understanding the ConcurrentLinkedQueue implementation is a | ||
| 106 | * prerequisite for understanding the implementation of this class. | ||
| 107 | * | ||
| 108 | * The data structure is a symmetrical doubly-linked "GC-robust" | ||
| 109 | * linked list of nodes. We minimize the number of volatile writes | ||
| 110 | * using two techniques: advancing multiple hops with a single CAS | ||
| 111 | * and mixing volatile and non-volatile writes of the same memory | ||
| 112 | * locations. | ||
| 113 | * | ||
| 114 | * A node contains the expected E ("item") and links to predecessor | ||
| 115 | * ("prev") and successor ("next") nodes: | ||
| 116 | * | ||
| 117 | * class Node<E> { volatile Node<E> prev, next; volatile E item; } | ||
| 118 | * | ||
| 119 | * A node p is considered "live" if it contains a non-null item | ||
| 120 | * (p.item != null). When an item is CASed to null, the item is | ||
| 121 | * atomically logically deleted from the collection. | ||
| 122 | * | ||
| 123 | * At any time, there is precisely one "first" node with a null | ||
| 124 | * prev reference that terminates any chain of prev references | ||
| 125 | * starting at a live node. Similarly there is precisely one | ||
| 126 | * "last" node terminating any chain of next references starting at | ||
| 127 | * a live node. The "first" and "last" nodes may or may not be live. | ||
| 128 | * The "first" and "last" nodes are always mutually reachable. | ||
| 129 | * | ||
| 130 | * A new element is added atomically by CASing the null prev or | ||
| 131 | * next reference in the first or last node to a fresh node | ||
| 132 | * containing the element. The element's node atomically becomes | ||
| 133 | * "live" at that point. | ||
| 134 | * | ||
| 135 | * A node is considered "active" if it is a live node, or the | ||
| 136 | * first or last node. Active nodes cannot be unlinked. | ||
| 137 | * | ||
| 138 | * A "self-link" is a next or prev reference that is the same node: | ||
| 139 | * p.prev == p or p.next == p | ||
| 140 | * Self-links are used in the node unlinking process. Active nodes | ||
| 141 | * never have self-links. | ||
| 142 | * | ||
| 143 | * A node p is active if and only if: | ||
| 144 | * | ||
| 145 | * p.item != null || | ||
| 146 | * (p.prev == null && p.next != p) || | ||
| 147 | * (p.next == null && p.prev != p) | ||
| 148 | * | ||
| 149 | * The deque object has two node references, "head" and "tail". | ||
| 150 | * The head and tail are only approximations to the first and last | ||
| 151 | * nodes of the deque. The first node can always be found by | ||
| 152 | * following prev pointers from head; likewise for tail. However, | ||
| 153 | * it is permissible for head and tail to be referring to deleted | ||
| 154 | * nodes that have been unlinked and so may not be reachable from | ||
| 155 | * any live node. | ||
| 156 | * | ||
| 157 | * There are 3 stages of node deletion; | ||
| 158 | * "logical deletion", "unlinking", and "gc-unlinking". | ||
| 159 | * | ||
| 160 | * 1. "logical deletion" by CASing item to null atomically removes | ||
| 161 | * the element from the collection, and makes the containing node | ||
| 162 | * eligible for unlinking. | ||
| 163 | * | ||
| 164 | * 2. "unlinking" makes a deleted node unreachable from active | ||
| 165 | * nodes, and thus eventually reclaimable by GC. Unlinked nodes | ||
| 166 | * may remain reachable indefinitely from an iterator. | ||
| 167 | * | ||
| 168 | * Physical node unlinking is merely an optimization (albeit a | ||
| 169 | * critical one), and so can be performed at our convenience. At | ||
| 170 | * any time, the set of live nodes maintained by prev and next | ||
| 171 | * links are identical, that is, the live nodes found via next | ||
| 172 | * links from the first node is equal to the elements found via | ||
| 173 | * prev links from the last node. However, this is not true for | ||
| 174 | * nodes that have already been logically deleted - such nodes may | ||
| 175 | * be reachable in one direction only. | ||
| 176 | * | ||
| 177 | * 3. "gc-unlinking" takes unlinking further by making active | ||
| 178 | * nodes unreachable from deleted nodes, making it easier for the | ||
| 179 | * GC to reclaim future deleted nodes. This step makes the data | ||
| 180 | * structure "gc-robust", as first described in detail by Boehm | ||
| 181 | * (http://portal.acm.org/citation.cfm?doid=503272.503282). | ||
| 182 | * | ||
| 183 | * GC-unlinked nodes may remain reachable indefinitely from an | ||
| 184 | * iterator, but unlike unlinked nodes, are never reachable from | ||
| 185 | * head or tail. | ||
| 186 | * | ||
| 187 | * Making the data structure GC-robust will eliminate the risk of | ||
| 188 | * unbounded memory retention with conservative GCs and is likely | ||
| 189 | * to improve performance with generational GCs. | ||
| 190 | * | ||
| 191 | * When a node is dequeued at either end, e.g. via poll(), we would | ||
| 192 | * like to break any references from the node to active nodes. We | ||
| 193 | * develop further the use of self-links that was very effective in | ||
| 194 | * other concurrent collection classes. The idea is to replace | ||
| 195 | * prev and next pointers with special values that are interpreted | ||
| 196 | * to mean off-the-list-at-one-end. These are approximations, but | ||
| 197 | * good enough to preserve the properties we want in our | ||
| 198 | * traversals, e.g. we guarantee that a traversal will never visit | ||
| 199 | * the same element twice, but we don't guarantee whether a | ||
| 200 | * traversal that runs out of elements will be able to see more | ||
| 201 | * elements later after enqueues at that end. Doing gc-unlinking | ||
| 202 | * safely is particularly tricky, since any node can be in use | ||
| 203 | * indefinitely (for example by an iterator). We must ensure that | ||
| 204 | * the nodes pointed at by head/tail never get gc-unlinked, since | ||
| 205 | * head/tail are needed to get "back on track" by other nodes that | ||
| 206 | * are gc-unlinked. gc-unlinking accounts for much of the | ||
| 207 | * implementation complexity. | ||
| 208 | * | ||
| 209 | * Since neither unlinking nor gc-unlinking are necessary for | ||
| 210 | * correctness, there are many implementation choices regarding | ||
| 211 | * frequency (eagerness) of these operations. Since volatile | ||
| 212 | * reads are likely to be much cheaper than CASes, saving CASes by | ||
| 213 | * unlinking multiple adjacent nodes at a time may be a win. | ||
| 214 | * gc-unlinking can be performed rarely and still be effective, | ||
| 215 | * since it is most important that long chains of deleted nodes | ||
| 216 | * are occasionally broken. | ||
| 217 | * | ||
| 218 | * The actual representation we use is that p.next == p means to | ||
| 219 | * goto the first node (which in turn is reached by following prev | ||
| 220 | * pointers from head), and p.next == null && p.prev == p means | ||
| 221 | * that the iteration is at an end and that p is a (static final) | ||
| 222 | * dummy node, NEXT_TERMINATOR, and not the last active node. | ||
| 223 | * Finishing the iteration when encountering such a TERMINATOR is | ||
| 224 | * good enough for read-only traversals, so such traversals can use | ||
| 225 | * p.next == null as the termination condition. When we need to | ||
| 226 | * find the last (active) node, for enqueueing a new node, we need | ||
| 227 | * to check whether we have reached a TERMINATOR node; if so, | ||
| 228 | * restart traversal from tail. | ||
| 229 | * | ||
| 230 | * The implementation is completely directionally symmetrical, | ||
| 231 | * except that most public methods that iterate through the list | ||
| 232 | * follow next pointers ("forward" direction). | ||
| 233 | * | ||
| 234 | * We believe (without full proof) that all single-element deque | ||
| 235 | * operations (e.g., addFirst, peekLast, pollLast) are linearizable | ||
| 236 | * (see Herlihy and Shavit's book). However, some combinations of | ||
| 237 | * operations are known not to be linearizable. In particular, | ||
| 238 | * when an addFirst(A) is racing with pollFirst() removing B, it is | ||
| 239 | * possible for an observer iterating over the elements to observe | ||
| 240 | * A B C and subsequently observe A C, even though no interior | ||
| 241 | * removes are ever performed. Nevertheless, iterators behave | ||
| 242 | * reasonably, providing the "weakly consistent" guarantees. | ||
| 243 | * | ||
| 244 | * Empirically, microbenchmarks suggest that this class adds about | ||
| 245 | * 40% overhead relative to ConcurrentLinkedQueue, which feels as | ||
| 246 | * good as we can hope for. | ||
| 247 | */ | ||
| 248 | |||
| 249 | private static final long serialVersionUID = 876323262645176354L; | ||
| 250 | |||
| 251 | /** | ||
| 252 | * A node from which the first node on list (that is, the unique node p | ||
| 253 | * with p.prev == null && p.next != p) can be reached in O(1) time. | ||
| 254 | * Invariants: | ||
| 255 | * - the first node is always O(1) reachable from head via prev links | ||
| 256 | * - all live nodes are reachable from the first node via succ() | ||
| 257 | * - head != null | ||
| 258 | * - (tmp = head).next != tmp || tmp != head | ||
| 259 | * - head is never gc-unlinked (but may be unlinked) | ||
| 260 | * Non-invariants: | ||
| 261 | * - head.item may or may not be null | ||
| 262 | * - head may not be reachable from the first or last node, or from tail | ||
| 263 | */ | ||
| 264 | private transient volatile Node<E> head; | ||
| 265 | |||
| 266 | /** | ||
| 267 | * A node from which the last node on list (that is, the unique node p | ||
| 268 | * with p.next == null && p.prev != p) can be reached in O(1) time. | ||
| 269 | * Invariants: | ||
| 270 | * - the last node is always O(1) reachable from tail via next links | ||
| 271 | * - all live nodes are reachable from the last node via pred() | ||
| 272 | * - tail != null | ||
| 273 | * - tail is never gc-unlinked (but may be unlinked) | ||
| 274 | * Non-invariants: | ||
| 275 | * - tail.item may or may not be null | ||
| 276 | * - tail may not be reachable from the first or last node, or from head | ||
| 277 | */ | ||
| 278 | private transient volatile Node<E> tail; | ||
| 279 | |||
| 280 | private static final Node<Object> PREV_TERMINATOR, NEXT_TERMINATOR; | ||
| 281 | |||
| 282 | @SuppressWarnings("unchecked") | ||
| 283 | Node<E> prevTerminator() { | ||
| 284 | return (Node<E>) PREV_TERMINATOR; | ||
| 285 | } | ||
| 286 | |||
| 287 | @SuppressWarnings("unchecked") | ||
| 288 | Node<E> nextTerminator() { | ||
| 289 | return (Node<E>) NEXT_TERMINATOR; | ||
| 290 | } | ||
| 291 | |||
| 292 | static final class Node<E> { | ||
| 293 | volatile Node<E> prev; | ||
| 294 | volatile E item; | ||
| 295 | volatile Node<E> next; | ||
| 296 | |||
| 297 | Node() { // default constructor for NEXT_TERMINATOR, PREV_TERMINATOR | ||
| 298 | } | ||
| 299 | |||
| 300 | /** | ||
| 301 | * Constructs a new node. Uses relaxed write because item can | ||
| 302 | * only be seen after publication via casNext or casPrev. | ||
| 303 | */ | ||
| 304 | Node(E item) { | ||
| 305 | UNSAFE.putObject(this, itemOffset, item); | ||
| 306 | } | ||
| 307 | |||
| 308 | boolean casItem(E cmp, E val) { | ||
| 309 | return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val); | ||
| 310 | } | ||
| 311 | |||
| 312 | void lazySetNext(Node<E> val) { | ||
| 313 | UNSAFE.putOrderedObject(this, nextOffset, val); | ||
| 314 | } | ||
| 315 | |||
| 316 | boolean casNext(Node<E> cmp, Node<E> val) { | ||
| 317 | return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val); | ||
| 318 | } | ||
| 319 | |||
| 320 | void lazySetPrev(Node<E> val) { | ||
| 321 | UNSAFE.putOrderedObject(this, prevOffset, val); | ||
| 322 | } | ||
| 323 | |||
| 324 | boolean casPrev(Node<E> cmp, Node<E> val) { | ||
| 325 | return UNSAFE.compareAndSwapObject(this, prevOffset, cmp, val); | ||
| 326 | } | ||
| 327 | |||
| 328 | // Unsafe mechanics | ||
| 329 | |||
| 330 | private static final sun.misc.Unsafe UNSAFE; | ||
| 331 | private static final long prevOffset; | ||
| 332 | private static final long itemOffset; | ||
| 333 | private static final long nextOffset; | ||
| 334 | |||
| 335 | static { | ||
| 336 | try { | ||
| 337 | UNSAFE = sun.misc.Unsafe.getUnsafe(); | ||
| 338 | Class k = Node.class; | ||
| 339 | prevOffset = UNSAFE.objectFieldOffset | ||
| 340 | (k.getDeclaredField("prev")); | ||
| 341 | itemOffset = UNSAFE.objectFieldOffset | ||
| 342 | (k.getDeclaredField("item")); | ||
| 343 | nextOffset = UNSAFE.objectFieldOffset | ||
| 344 | (k.getDeclaredField("next")); | ||
| 345 | } catch (Exception e) { | ||
| 346 | throw new Error(e); | ||
| 347 | } | ||
| 348 | } | ||
| 349 | } | ||
| 350 | |||
| 351 | /** | ||
| 352 | * Links e as first element. | ||
| 353 | */ | ||
| 354 | private void linkFirst(E e) { | ||
| 355 | checkNotNull(e); | ||
| 356 | final Node<E> newNode = new Node<E>(e); | ||
| 357 | |||
| 358 | restartFromHead: | ||
| 359 | for (;;) | ||
| 360 | for (Node<E> h = head, p = h, q;;) { | ||
| 361 | if ((q = p.prev) != null && | ||
| 362 | (q = (p = q).prev) != null) | ||
| 363 | // Check for head updates every other hop. | ||
| 364 | // If p == q, we are sure to follow head instead. | ||
| 365 | p = (h != (h = head)) ? h : q; | ||
| 366 | else if (p.next == p) // PREV_TERMINATOR | ||
| 367 | continue restartFromHead; | ||
| 368 | else { | ||
| 369 | // p is first node | ||
| 370 | newNode.lazySetNext(p); // CAS piggyback | ||
| 371 | if (p.casPrev(null, newNode)) { | ||
| 372 | // Successful CAS is the linearization point | ||
| 373 | // for e to become an element of this deque, | ||
| 374 | // and for newNode to become "live". | ||
| 375 | if (p != h) // hop two nodes at a time | ||
| 376 | casHead(h, newNode); // Failure is OK. | ||
| 377 | return; | ||
| 378 | } | ||
| 379 | // Lost CAS race to another thread; re-read prev | ||
| 380 | } | ||
| 381 | } | ||
| 382 | } | ||
| 383 | |||
| 384 | /** | ||
| 385 | * Links e as last element. | ||
| 386 | */ | ||
| 387 | private void linkLast(E e) { | ||
| 388 | checkNotNull(e); | ||
| 389 | final Node<E> newNode = new Node<E>(e); | ||
| 390 | |||
| 391 | restartFromTail: | ||
| 392 | for (;;) | ||
| 393 | for (Node<E> t = tail, p = t, q;;) { | ||
| 394 | if ((q = p.next) != null && | ||
| 395 | (q = (p = q).next) != null) | ||
| 396 | // Check for tail updates every other hop. | ||
| 397 | // If p == q, we are sure to follow tail instead. | ||
| 398 | p = (t != (t = tail)) ? t : q; | ||
| 399 | else if (p.prev == p) // NEXT_TERMINATOR | ||
| 400 | continue restartFromTail; | ||
| 401 | else { | ||
| 402 | // p is last node | ||
| 403 | newNode.lazySetPrev(p); // CAS piggyback | ||
| 404 | if (p.casNext(null, newNode)) { | ||
| 405 | // Successful CAS is the linearization point | ||
| 406 | // for e to become an element of this deque, | ||
| 407 | // and for newNode to become "live". | ||
| 408 | if (p != t) // hop two nodes at a time | ||
| 409 | casTail(t, newNode); // Failure is OK. | ||
| 410 | return; | ||
| 411 | } | ||
| 412 | // Lost CAS race to another thread; re-read next | ||
| 413 | } | ||
| 414 | } | ||
| 415 | } | ||
| 416 | |||
| 417 | private static final int HOPS = 2; | ||
| 418 | |||
| 419 | /** | ||
| 420 | * Unlinks non-null node x. | ||
| 421 | */ | ||
| 422 | void unlink(Node<E> x) { | ||
| 423 | // assert x != null; | ||
| 424 | // assert x.item == null; | ||
| 425 | // assert x != PREV_TERMINATOR; | ||
| 426 | // assert x != NEXT_TERMINATOR; | ||
| 427 | |||
| 428 | final Node<E> prev = x.prev; | ||
| 429 | final Node<E> next = x.next; | ||
| 430 | if (prev == null) { | ||
| 431 | unlinkFirst(x, next); | ||
| 432 | } else if (next == null) { | ||
| 433 | unlinkLast(x, prev); | ||
| 434 | } else { | ||
| 435 | // Unlink interior node. | ||
| 436 | // | ||
| 437 | // This is the common case, since a series of polls at the | ||
| 438 | // same end will be "interior" removes, except perhaps for | ||
| 439 | // the first one, since end nodes cannot be unlinked. | ||
| 440 | // | ||
| 441 | // At any time, all active nodes are mutually reachable by | ||
| 442 | // following a sequence of either next or prev pointers. | ||
| 443 | // | ||
| 444 | // Our strategy is to find the unique active predecessor | ||
| 445 | // and successor of x. Try to fix up their links so that | ||
| 446 | // they point to each other, leaving x unreachable from | ||
| 447 | // active nodes. If successful, and if x has no live | ||
| 448 | // predecessor/successor, we additionally try to gc-unlink, | ||
| 449 | // leaving active nodes unreachable from x, by rechecking | ||
| 450 | // that the status of predecessor and successor are | ||
| 451 | // unchanged and ensuring that x is not reachable from | ||
| 452 | // tail/head, before setting x's prev/next links to their | ||
| 453 | // logical approximate replacements, self/TERMINATOR. | ||
| 454 | Node<E> activePred, activeSucc; | ||
| 455 | boolean isFirst, isLast; | ||
| 456 | int hops = 1; | ||
| 457 | |||
| 458 | // Find active predecessor | ||
| 459 | for (Node<E> p = prev; ; ++hops) { | ||
| 460 | if (p.item != null) { | ||
| 461 | activePred = p; | ||
| 462 | isFirst = false; | ||
| 463 | break; | ||
| 464 | } | ||
| 465 | Node<E> q = p.prev; | ||
| 466 | if (q == null) { | ||
| 467 | if (p.next == p) | ||
| 468 | return; | ||
| 469 | activePred = p; | ||
| 470 | isFirst = true; | ||
| 471 | break; | ||
| 472 | } | ||
| 473 | else if (p == q) | ||
| 474 | return; | ||
| 475 | else | ||
| 476 | p = q; | ||
| 477 | } | ||
| 478 | |||
| 479 | // Find active successor | ||
| 480 | for (Node<E> p = next; ; ++hops) { | ||
| 481 | if (p.item != null) { | ||
| 482 | activeSucc = p; | ||
| 483 | isLast = false; | ||
| 484 | break; | ||
| 485 | } | ||
| 486 | Node<E> q = p.next; | ||
| 487 | if (q == null) { | ||
| 488 | if (p.prev == p) | ||
| 489 | return; | ||
| 490 | activeSucc = p; | ||
| 491 | isLast = true; | ||
| 492 | break; | ||
| 493 | } | ||
| 494 | else if (p == q) | ||
| 495 | return; | ||
| 496 | else | ||
| 497 | p = q; | ||
| 498 | } | ||
| 499 | |||
| 500 | // TODO: better HOP heuristics | ||
| 501 | if (hops < HOPS | ||
| 502 | // always squeeze out interior deleted nodes | ||
| 503 | && (isFirst | isLast)) | ||
| 504 | return; | ||
| 505 | |||
| 506 | // Squeeze out deleted nodes between activePred and | ||
| 507 | // activeSucc, including x. | ||
| 508 | skipDeletedSuccessors(activePred); | ||
| 509 | skipDeletedPredecessors(activeSucc); | ||
| 510 | |||
| 511 | // Try to gc-unlink, if possible | ||
| 512 | if ((isFirst | isLast) && | ||
| 513 | |||
| 514 | // Recheck expected state of predecessor and successor | ||
| 515 | (activePred.next == activeSucc) && | ||
| 516 | (activeSucc.prev == activePred) && | ||
| 517 | (isFirst ? activePred.prev == null : activePred.item != null) && | ||
| 518 | (isLast ? activeSucc.next == null : activeSucc.item != null)) { | ||
| 519 | |||
| 520 | updateHead(); // Ensure x is not reachable from head | ||
| 521 | updateTail(); // Ensure x is not reachable from tail | ||
| 522 | |||
| 523 | // Finally, actually gc-unlink | ||
| 524 | x.lazySetPrev(isFirst ? prevTerminator() : x); | ||
| 525 | x.lazySetNext(isLast ? nextTerminator() : x); | ||
| 526 | } | ||
| 527 | } | ||
| 528 | } | ||
| 529 | |||
| 530 | /** | ||
| 531 | * Unlinks non-null first node. | ||
| 532 | */ | ||
| 533 | private void unlinkFirst(Node<E> first, Node<E> next) { | ||
| 534 | // assert first != null; | ||
| 535 | // assert next != null; | ||
| 536 | // assert first.item == null; | ||
| 537 | for (Node<E> o = null, p = next, q;;) { | ||
| 538 | if (p.item != null || (q = p.next) == null) { | ||
| 539 | if (o != null && p.prev != p && first.casNext(next, p)) { | ||
| 540 | skipDeletedPredecessors(p); | ||
| 541 | if (first.prev == null && | ||
| 542 | (p.next == null || p.item != null) && | ||
| 543 | p.prev == first) { | ||
| 544 | |||
| 545 | updateHead(); // Ensure o is not reachable from head | ||
| 546 | updateTail(); // Ensure o is not reachable from tail | ||
| 547 | |||
| 548 | // Finally, actually gc-unlink | ||
| 549 | o.lazySetNext(o); | ||
| 550 | o.lazySetPrev(prevTerminator()); | ||
| 551 | } | ||
| 552 | } | ||
| 553 | return; | ||
| 554 | } | ||
| 555 | else if (p == q) | ||
| 556 | return; | ||
| 557 | else { | ||
| 558 | o = p; | ||
| 559 | p = q; | ||
| 560 | } | ||
| 561 | } | ||
| 562 | } | ||
| 563 | |||
| 564 | /** | ||
| 565 | * Unlinks non-null last node. | ||
| 566 | */ | ||
| 567 | private void unlinkLast(Node<E> last, Node<E> prev) { | ||
| 568 | // assert last != null; | ||
| 569 | // assert prev != null; | ||
| 570 | // assert last.item == null; | ||
| 571 | for (Node<E> o = null, p = prev, q;;) { | ||
| 572 | if (p.item != null || (q = p.prev) == null) { | ||
| 573 | if (o != null && p.next != p && last.casPrev(prev, p)) { | ||
| 574 | skipDeletedSuccessors(p); | ||
| 575 | if (last.next == null && | ||
| 576 | (p.prev == null || p.item != null) && | ||
| 577 | p.next == last) { | ||
| 578 | |||
| 579 | updateHead(); // Ensure o is not reachable from head | ||
| 580 | updateTail(); // Ensure o is not reachable from tail | ||
| 581 | |||
| 582 | // Finally, actually gc-unlink | ||
| 583 | o.lazySetPrev(o); | ||
| 584 | o.lazySetNext(nextTerminator()); | ||
| 585 | } | ||
| 586 | } | ||
| 587 | return; | ||
| 588 | } | ||
| 589 | else if (p == q) | ||
| 590 | return; | ||
| 591 | else { | ||
| 592 | o = p; | ||
| 593 | p = q; | ||
| 594 | } | ||
| 595 | } | ||
| 596 | } | ||
| 597 | |||
| 598 | /** | ||
| 599 | * Guarantees that any node which was unlinked before a call to | ||
| 600 | * this method will be unreachable from head after it returns. | ||
| 601 | * Does not guarantee to eliminate slack, only that head will | ||
| 602 | * point to a node that was active while this method was running. | ||
| 603 | */ | ||
| 604 | private final void updateHead() { | ||
| 605 | // Either head already points to an active node, or we keep | ||
| 606 | // trying to cas it to the first node until it does. | ||
| 607 | Node<E> h, p, q; | ||
| 608 | restartFromHead: | ||
| 609 | while ((h = head).item == null && (p = h.prev) != null) { | ||
| 610 | for (;;) { | ||
| 611 | if ((q = p.prev) == null || | ||
| 612 | (q = (p = q).prev) == null) { | ||
| 613 | // It is possible that p is PREV_TERMINATOR, | ||
| 614 | // but if so, the CAS is guaranteed to fail. | ||
| 615 | if (casHead(h, p)) | ||
| 616 | return; | ||
| 617 | else | ||
| 618 | continue restartFromHead; | ||
| 619 | } | ||
| 620 | else if (h != head) | ||
| 621 | continue restartFromHead; | ||
| 622 | else | ||
| 623 | p = q; | ||
| 624 | } | ||
| 625 | } | ||
| 626 | } | ||
| 627 | |||
| 628 | /** | ||
| 629 | * Guarantees that any node which was unlinked before a call to | ||
| 630 | * this method will be unreachable from tail after it returns. | ||
| 631 | * Does not guarantee to eliminate slack, only that tail will | ||
| 632 | * point to a node that was active while this method was running. | ||
| 633 | */ | ||
| 634 | private final void updateTail() { | ||
| 635 | // Either tail already points to an active node, or we keep | ||
| 636 | // trying to cas it to the last node until it does. | ||
| 637 | Node<E> t, p, q; | ||
| 638 | restartFromTail: | ||
| 639 | while ((t = tail).item == null && (p = t.next) != null) { | ||
| 640 | for (;;) { | ||
| 641 | if ((q = p.next) == null || | ||
| 642 | (q = (p = q).next) == null) { | ||
| 643 | // It is possible that p is NEXT_TERMINATOR, | ||
| 644 | // but if so, the CAS is guaranteed to fail. | ||
| 645 | if (casTail(t, p)) | ||
| 646 | return; | ||
| 647 | else | ||
| 648 | continue restartFromTail; | ||
| 649 | } | ||
| 650 | else if (t != tail) | ||
| 651 | continue restartFromTail; | ||
| 652 | else | ||
| 653 | p = q; | ||
| 654 | } | ||
| 655 | } | ||
| 656 | } | ||
| 657 | |||
| 658 | private void skipDeletedPredecessors(Node<E> x) { | ||
| 659 | whileActive: | ||
| 660 | do { | ||
| 661 | Node<E> prev = x.prev; | ||
| 662 | // assert prev != null; | ||
| 663 | // assert x != NEXT_TERMINATOR; | ||
| 664 | // assert x != PREV_TERMINATOR; | ||
| 665 | Node<E> p = prev; | ||
| 666 | findActive: | ||
| 667 | for (;;) { | ||
| 668 | if (p.item != null) | ||
| 669 | break findActive; | ||
| 670 | Node<E> q = p.prev; | ||
| 671 | if (q == null) { | ||
| 672 | if (p.next == p) | ||
| 673 | continue whileActive; | ||
| 674 | break findActive; | ||
| 675 | } | ||
| 676 | else if (p == q) | ||
| 677 | continue whileActive; | ||
| 678 | else | ||
| 679 | p = q; | ||
| 680 | } | ||
| 681 | |||
| 682 | // found active CAS target | ||
| 683 | if (prev == p || x.casPrev(prev, p)) | ||
| 684 | return; | ||
| 685 | |||
| 686 | } while (x.item != null || x.next == null); | ||
| 687 | } | ||
| 688 | |||
| 689 | private void skipDeletedSuccessors(Node<E> x) { | ||
| 690 | whileActive: | ||
| 691 | do { | ||
| 692 | Node<E> next = x.next; | ||
| 693 | // assert next != null; | ||
| 694 | // assert x != NEXT_TERMINATOR; | ||
| 695 | // assert x != PREV_TERMINATOR; | ||
| 696 | Node<E> p = next; | ||
| 697 | findActive: | ||
| 698 | for (;;) { | ||
| 699 | if (p.item != null) | ||
| 700 | break findActive; | ||
| 701 | Node<E> q = p.next; | ||
| 702 | if (q == null) { | ||
| 703 | if (p.prev == p) | ||
| 704 | continue whileActive; | ||
| 705 | break findActive; | ||
| 706 | } | ||
| 707 | else if (p == q) | ||
| 708 | continue whileActive; | ||
| 709 | else | ||
| 710 | p = q; | ||
| 711 | } | ||
| 712 | |||
| 713 | // found active CAS target | ||
| 714 | if (next == p || x.casNext(next, p)) | ||
| 715 | return; | ||
| 716 | |||
| 717 | } while (x.item != null || x.prev == null); | ||
| 718 | } | ||
| 719 | |||
| 720 | /** | ||
| 721 | * Returns the successor of p, or the first node if p.next has been | ||
| 722 | * linked to self, which will only be true if traversing with a | ||
| 723 | * stale pointer that is now off the list. | ||
| 724 | */ | ||
| 725 | final Node<E> succ(Node<E> p) { | ||
| 726 | // TODO: should we skip deleted nodes here? | ||
| 727 | Node<E> q = p.next; | ||
| 728 | return (p == q) ? first() : q; | ||
| 729 | } | ||
| 730 | |||
| 731 | /** | ||
| 732 | * Returns the predecessor of p, or the last node if p.prev has been | ||
| 733 | * linked to self, which will only be true if traversing with a | ||
| 734 | * stale pointer that is now off the list. | ||
| 735 | */ | ||
| 736 | final Node<E> pred(Node<E> p) { | ||
| 737 | Node<E> q = p.prev; | ||
| 738 | return (p == q) ? last() : q; | ||
| 739 | } | ||
| 740 | |||
| 741 | /** | ||
| 742 | * Returns the first node, the unique node p for which: | ||
| 743 | * p.prev == null && p.next != p | ||
| 744 | * The returned node may or may not be logically deleted. | ||
| 745 | * Guarantees that head is set to the returned node. | ||
| 746 | */ | ||
| 747 | Node<E> first() { | ||
| 748 | restartFromHead: | ||
| 749 | for (;;) | ||
| 750 | for (Node<E> h = head, p = h, q;;) { | ||
| 751 | if ((q = p.prev) != null && | ||
| 752 | (q = (p = q).prev) != null) | ||
| 753 | // Check for head updates every other hop. | ||
| 754 | // If p == q, we are sure to follow head instead. | ||
| 755 | p = (h != (h = head)) ? h : q; | ||
| 756 | else if (p == h | ||
| 757 | // It is possible that p is PREV_TERMINATOR, | ||
| 758 | // but if so, the CAS is guaranteed to fail. | ||
| 759 | || casHead(h, p)) | ||
| 760 | return p; | ||
| 761 | else | ||
| 762 | continue restartFromHead; | ||
| 763 | } | ||
| 764 | } | ||
| 765 | |||
| 766 | /** | ||
| 767 | * Returns the last node, the unique node p for which: | ||
| 768 | * p.next == null && p.prev != p | ||
| 769 | * The returned node may or may not be logically deleted. | ||
| 770 | * Guarantees that tail is set to the returned node. | ||
| 771 | */ | ||
| 772 | Node<E> last() { | ||
| 773 | restartFromTail: | ||
| 774 | for (;;) | ||
| 775 | for (Node<E> t = tail, p = t, q;;) { | ||
| 776 | if ((q = p.next) != null && | ||
| 777 | (q = (p = q).next) != null) | ||
| 778 | // Check for tail updates every other hop. | ||
| 779 | // If p == q, we are sure to follow tail instead. | ||
| 780 | p = (t != (t = tail)) ? t : q; | ||
| 781 | else if (p == t | ||
| 782 | // It is possible that p is NEXT_TERMINATOR, | ||
| 783 | // but if so, the CAS is guaranteed to fail. | ||
| 784 | || casTail(t, p)) | ||
| 785 | return p; | ||
| 786 | else | ||
| 787 | continue restartFromTail; | ||
| 788 | } | ||
| 789 | } | ||
| 790 | |||
| 791 | // Minor convenience utilities | ||
| 792 | |||
| 793 | /** | ||
| 794 | * Throws NullPointerException if argument is null. | ||
| 795 | * | ||
| 796 | * @param v the element | ||
| 797 | */ | ||
| 798 | private static void checkNotNull(Object v) { | ||
| 799 | if (v == null) | ||
| 800 | throw new NullPointerException(); | ||
| 801 | } | ||
| 802 | |||
| 803 | /** | ||
| 804 | * Returns element unless it is null, in which case throws | ||
| 805 | * NoSuchElementException. | ||
| 806 | * | ||
| 807 | * @param v the element | ||
| 808 | * @return the element | ||
| 809 | */ | ||
| 810 | private E screenNullResult(E v) { | ||
| 811 | if (v == null) | ||
| 812 | throw new NoSuchElementException(); | ||
| 813 | return v; | ||
| 814 | } | ||
| 815 | |||
| 816 | /** | ||
| 817 | * Creates an array list and fills it with elements of this list. | ||
| 818 | * Used by toArray. | ||
| 819 | * | ||
| 820 | * @return the arrayList | ||
| 821 | */ | ||
| 822 | private ArrayList<E> toArrayList() { | ||
| 823 | ArrayList<E> list = new ArrayList<E>(); | ||
| 824 | for (Node<E> p = first(); p != null; p = succ(p)) { | ||
| 825 | E item = p.item; | ||
| 826 | if (item != null) | ||
| 827 | list.add(item); | ||
| 828 | } | ||
| 829 | return list; | ||
| 830 | } | ||
| 831 | |||
| 832 | /** | ||
| 833 | * Constructs an empty deque. | ||
| 834 | */ | ||
| 835 | public ConcurrentLinkedDeque() { | ||
| 836 | head = tail = new Node<E>(null); | ||
| 837 | } | ||
| 838 | |||
| 839 | /** | ||
| 840 | * Constructs a deque initially containing the elements of | ||
| 841 | * the given collection, added in traversal order of the | ||
| 842 | * collection's iterator. | ||
| 843 | * | ||
| 844 | * @param c the collection of elements to initially contain | ||
| 845 | * @throws NullPointerException if the specified collection or any | ||
| 846 | * of its elements are null | ||
| 847 | */ | ||
| 848 | public ConcurrentLinkedDeque(Collection<? extends E> c) { | ||
| 849 | // Copy c into a private chain of Nodes | ||
| 850 | Node<E> h = null, t = null; | ||
| 851 | for (E e : c) { | ||
| 852 | checkNotNull(e); | ||
| 853 | Node<E> newNode = new Node<E>(e); | ||
| 854 | if (h == null) | ||
| 855 | h = t = newNode; | ||
| 856 | else { | ||
| 857 | t.lazySetNext(newNode); | ||
| 858 | newNode.lazySetPrev(t); | ||
| 859 | t = newNode; | ||
| 860 | } | ||
| 861 | } | ||
| 862 | initHeadTail(h, t); | ||
| 863 | } | ||
| 864 | |||
| 865 | /** | ||
| 866 | * Initializes head and tail, ensuring invariants hold. | ||
| 867 | */ | ||
| 868 | private void initHeadTail(Node<E> h, Node<E> t) { | ||
| 869 | if (h == t) { | ||
| 870 | if (h == null) | ||
| 871 | h = t = new Node<E>(null); | ||
| 872 | else { | ||
| 873 | // Avoid edge case of a single Node with non-null item. | ||
| 874 | Node<E> newNode = new Node<E>(null); | ||
| 875 | t.lazySetNext(newNode); | ||
| 876 | newNode.lazySetPrev(t); | ||
| 877 | t = newNode; | ||
| 878 | } | ||
| 879 | } | ||
| 880 | head = h; | ||
| 881 | tail = t; | ||
| 882 | } | ||
| 883 | |||
| 884 | /** | ||
| 885 | * Inserts the specified element at the front of this deque. | ||
| 886 | * As the deque is unbounded, this method will never throw | ||
| 887 | * {@link IllegalStateException}. | ||
| 888 | * | ||
| 889 | * @throws NullPointerException if the specified element is null | ||
| 890 | */ | ||
| 891 | public void addFirst(E e) { | ||
| 892 | linkFirst(e); | ||
| 893 | } | ||
| 894 | |||
| 895 | /** | ||
| 896 | * Inserts the specified element at the end of this deque. | ||
| 897 | * As the deque is unbounded, this method will never throw | ||
| 898 | * {@link IllegalStateException}. | ||
| 899 | * | ||
| 900 | * <p>This method is equivalent to {@link #add}. | ||
| 901 | * | ||
| 902 | * @throws NullPointerException if the specified element is null | ||
| 903 | */ | ||
| 904 | public void addLast(E e) { | ||
| 905 | linkLast(e); | ||
| 906 | } | ||
| 907 | |||
| 908 | /** | ||
| 909 | * Inserts the specified element at the front of this deque. | ||
| 910 | * As the deque is unbounded, this method will never return {@code false}. | ||
| 911 | * | ||
| 912 | * @return {@code true} (as specified by {@link Deque#offerFirst}) | ||
| 913 | * @throws NullPointerException if the specified element is null | ||
| 914 | */ | ||
| 915 | public boolean offerFirst(E e) { | ||
| 916 | linkFirst(e); | ||
| 917 | return true; | ||
| 918 | } | ||
| 919 | |||
| 920 | /** | ||
| 921 | * Inserts the specified element at the end of this deque. | ||
| 922 | * As the deque is unbounded, this method will never return {@code false}. | ||
| 923 | * | ||
| 924 | * <p>This method is equivalent to {@link #add}. | ||
| 925 | * | ||
| 926 | * @return {@code true} (as specified by {@link Deque#offerLast}) | ||
| 927 | * @throws NullPointerException if the specified element is null | ||
| 928 | */ | ||
| 929 | public boolean offerLast(E e) { | ||
| 930 | linkLast(e); | ||
| 931 | return true; | ||
| 932 | } | ||
| 933 | |||
| 934 | public E peekFirst() { | ||
| 935 | for (Node<E> p = first(); p != null; p = succ(p)) { | ||
| 936 | E item = p.item; | ||
| 937 | if (item != null) | ||
| 938 | return item; | ||
| 939 | } | ||
| 940 | return null; | ||
| 941 | } | ||
| 942 | |||
| 943 | public E peekLast() { | ||
| 944 | for (Node<E> p = last(); p != null; p = pred(p)) { | ||
| 945 | E item = p.item; | ||
| 946 | if (item != null) | ||
| 947 | return item; | ||
| 948 | } | ||
| 949 | return null; | ||
| 950 | } | ||
| 951 | |||
| 952 | /** | ||
| 953 | * @throws NoSuchElementException {@inheritDoc} | ||
| 954 | */ | ||
| 955 | public E getFirst() { | ||
| 956 | return screenNullResult(peekFirst()); | ||
| 957 | } | ||
| 958 | |||
| 959 | /** | ||
| 960 | * @throws NoSuchElementException {@inheritDoc} | ||
| 961 | */ | ||
| 962 | public E getLast() { | ||
| 963 | return screenNullResult(peekLast()); | ||
| 964 | } | ||
| 965 | |||
| 966 | public E pollFirst() { | ||
| 967 | for (Node<E> p = first(); p != null; p = succ(p)) { | ||
| 968 | E item = p.item; | ||
| 969 | if (item != null && p.casItem(item, null)) { | ||
| 970 | unlink(p); | ||
| 971 | return item; | ||
| 972 | } | ||
| 973 | } | ||
| 974 | return null; | ||
| 975 | } | ||
| 976 | |||
| 977 | public E pollLast() { | ||
| 978 | for (Node<E> p = last(); p != null; p = pred(p)) { | ||
| 979 | E item = p.item; | ||
| 980 | if (item != null && p.casItem(item, null)) { | ||
| 981 | unlink(p); | ||
| 982 | return item; | ||
| 983 | } | ||
| 984 | } | ||
| 985 | return null; | ||
| 986 | } | ||
| 987 | |||
| 988 | /** | ||
| 989 | * @throws NoSuchElementException {@inheritDoc} | ||
| 990 | */ | ||
| 991 | public E removeFirst() { | ||
| 992 | return screenNullResult(pollFirst()); | ||
| 993 | } | ||
| 994 | |||
| 995 | /** | ||
| 996 | * @throws NoSuchElementException {@inheritDoc} | ||
| 997 | */ | ||
| 998 | public E removeLast() { | ||
| 999 | return screenNullResult(pollLast()); | ||
| 1000 | } | ||
| 1001 | |||
| 1002 | // *** Queue and stack methods *** | ||
| 1003 | |||
| 1004 | /** | ||
| 1005 | * Inserts the specified element at the tail of this deque. | ||
| 1006 | * As the deque is unbounded, this method will never return {@code false}. | ||
| 1007 | * | ||
| 1008 | * @return {@code true} (as specified by {@link Queue#offer}) | ||
| 1009 | * @throws NullPointerException if the specified element is null | ||
| 1010 | */ | ||
| 1011 | public boolean offer(E e) { | ||
| 1012 | return offerLast(e); | ||
| 1013 | } | ||
| 1014 | |||
| 1015 | /** | ||
| 1016 | * Inserts the specified element at the tail of this deque. | ||
| 1017 | * As the deque is unbounded, this method will never throw | ||
| 1018 | * {@link IllegalStateException} or return {@code false}. | ||
| 1019 | * | ||
| 1020 | * @return {@code true} (as specified by {@link Collection#add}) | ||
| 1021 | * @throws NullPointerException if the specified element is null | ||
| 1022 | */ | ||
| 1023 | public boolean add(E e) { | ||
| 1024 | return offerLast(e); | ||
| 1025 | } | ||
| 1026 | |||
| 1027 | public E poll() { return pollFirst(); } | ||
| 1028 | public E remove() { return removeFirst(); } | ||
| 1029 | public E peek() { return peekFirst(); } | ||
| 1030 | public E element() { return getFirst(); } | ||
| 1031 | public void push(E e) { addFirst(e); } | ||
| 1032 | public E pop() { return removeFirst(); } | ||
| 1033 | |||
| 1034 | /** | ||
| 1035 | * Removes the first element {@code e} such that | ||
| 1036 | * {@code o.equals(e)}, if such an element exists in this deque. | ||
| 1037 | * If the deque does not contain the element, it is unchanged. | ||
| 1038 | * | ||
| 1039 | * @param o element to be removed from this deque, if present | ||
| 1040 | * @return {@code true} if the deque contained the specified element | ||
| 1041 | * @throws NullPointerException if the specified element is null | ||
| 1042 | */ | ||
| 1043 | public boolean removeFirstOccurrence(Object o) { | ||
| 1044 | checkNotNull(o); | ||
| 1045 | for (Node<E> p = first(); p != null; p = succ(p)) { | ||
| 1046 | E item = p.item; | ||
| 1047 | if (item != null && o.equals(item) && p.casItem(item, null)) { | ||
| 1048 | unlink(p); | ||
| 1049 | return true; | ||
| 1050 | } | ||
| 1051 | } | ||
| 1052 | return false; | ||
| 1053 | } | ||
| 1054 | |||
| 1055 | /** | ||
| 1056 | * Removes the last element {@code e} such that | ||
| 1057 | * {@code o.equals(e)}, if such an element exists in this deque. | ||
| 1058 | * If the deque does not contain the element, it is unchanged. | ||
| 1059 | * | ||
| 1060 | * @param o element to be removed from this deque, if present | ||
| 1061 | * @return {@code true} if the deque contained the specified element | ||
| 1062 | * @throws NullPointerException if the specified element is null | ||
| 1063 | */ | ||
| 1064 | public boolean removeLastOccurrence(Object o) { | ||
| 1065 | checkNotNull(o); | ||
| 1066 | for (Node<E> p = last(); p != null; p = pred(p)) { | ||
| 1067 | E item = p.item; | ||
| 1068 | if (item != null && o.equals(item) && p.casItem(item, null)) { | ||
| 1069 | unlink(p); | ||
| 1070 | return true; | ||
| 1071 | } | ||
| 1072 | } | ||
| 1073 | return false; | ||
| 1074 | } | ||
| 1075 | |||
| 1076 | /** | ||
| 1077 | * Returns {@code true} if this deque contains at least one | ||
| 1078 | * element {@code e} such that {@code o.equals(e)}. | ||
| 1079 | * | ||
| 1080 | * @param o element whose presence in this deque is to be tested | ||
| 1081 | * @return {@code true} if this deque contains the specified element | ||
| 1082 | */ | ||
| 1083 | public boolean contains(Object o) { | ||
| 1084 | if (o == null) return false; | ||
| 1085 | for (Node<E> p = first(); p != null; p = succ(p)) { | ||
| 1086 | E item = p.item; | ||
| 1087 | if (item != null && o.equals(item)) | ||
| 1088 | return true; | ||
| 1089 | } | ||
| 1090 | return false; | ||
| 1091 | } | ||
| 1092 | |||
| 1093 | /** | ||
| 1094 | * Returns {@code true} if this collection contains no elements. | ||
| 1095 | * | ||
| 1096 | * @return {@code true} if this collection contains no elements | ||
| 1097 | */ | ||
| 1098 | public boolean isEmpty() { | ||
| 1099 | return peekFirst() == null; | ||
| 1100 | } | ||
| 1101 | |||
| 1102 | /** | ||
| 1103 | * Returns the number of elements in this deque. If this deque | ||
| 1104 | * contains more than {@code Integer.MAX_VALUE} elements, it | ||
| 1105 | * returns {@code Integer.MAX_VALUE}. | ||
| 1106 | * | ||
| 1107 | * <p>Beware that, unlike in most collections, this method is | ||
| 1108 | * <em>NOT</em> a constant-time operation. Because of the | ||
| 1109 | * asynchronous nature of these deques, determining the current | ||
| 1110 | * number of elements requires traversing them all to count them. | ||
| 1111 | * Additionally, it is possible for the size to change during | ||
| 1112 | * execution of this method, in which case the returned result | ||
| 1113 | * will be inaccurate. Thus, this method is typically not very | ||
| 1114 | * useful in concurrent applications. | ||
| 1115 | * | ||
| 1116 | * @return the number of elements in this deque | ||
| 1117 | */ | ||
| 1118 | public int size() { | ||
| 1119 | int count = 0; | ||
| 1120 | for (Node<E> p = first(); p != null; p = succ(p)) | ||
| 1121 | if (p.item != null) | ||
| 1122 | // Collection.size() spec says to max out | ||
| 1123 | if (++count == Integer.MAX_VALUE) | ||
| 1124 | break; | ||
| 1125 | return count; | ||
| 1126 | } | ||
| 1127 | |||
| 1128 | /** | ||
| 1129 | * Removes the first element {@code e} such that | ||
| 1130 | * {@code o.equals(e)}, if such an element exists in this deque. | ||
| 1131 | * If the deque does not contain the element, it is unchanged. | ||
| 1132 | * | ||
| 1133 | * @param o element to be removed from this deque, if present | ||
| 1134 | * @return {@code true} if the deque contained the specified element | ||
| 1135 | * @throws NullPointerException if the specified element is null | ||
| 1136 | */ | ||
| 1137 | public boolean remove(Object o) { | ||
| 1138 | return removeFirstOccurrence(o); | ||
| 1139 | } | ||
| 1140 | |||
| 1141 | /** | ||
| 1142 | * Appends all of the elements in the specified collection to the end of | ||
| 1143 | * this deque, in the order that they are returned by the specified | ||
| 1144 | * collection's iterator. Attempts to {@code addAll} of a deque to | ||
| 1145 | * itself result in {@code IllegalArgumentException}. | ||
| 1146 | * | ||
| 1147 | * @param c the elements to be inserted into this deque | ||
| 1148 | * @return {@code true} if this deque changed as a result of the call | ||
| 1149 | * @throws NullPointerException if the specified collection or any | ||
| 1150 | * of its elements are null | ||
| 1151 | * @throws IllegalArgumentException if the collection is this deque | ||
| 1152 | */ | ||
| 1153 | public boolean addAll(Collection<? extends E> c) { | ||
| 1154 | if (c == this) | ||
| 1155 | // As historically specified in AbstractQueue#addAll | ||
| 1156 | throw new IllegalArgumentException(); | ||
| 1157 | |||
| 1158 | // Copy c into a private chain of Nodes | ||
| 1159 | Node<E> beginningOfTheEnd = null, last = null; | ||
| 1160 | for (E e : c) { | ||
| 1161 | checkNotNull(e); | ||
| 1162 | Node<E> newNode = new Node<E>(e); | ||
| 1163 | if (beginningOfTheEnd == null) | ||
| 1164 | beginningOfTheEnd = last = newNode; | ||
| 1165 | else { | ||
| 1166 | last.lazySetNext(newNode); | ||
| 1167 | newNode.lazySetPrev(last); | ||
| 1168 | last = newNode; | ||
| 1169 | } | ||
| 1170 | } | ||
| 1171 | if (beginningOfTheEnd == null) | ||
| 1172 | return false; | ||
| 1173 | |||
| 1174 | // Atomically append the chain at the tail of this collection | ||
| 1175 | restartFromTail: | ||
| 1176 | for (;;) | ||
| 1177 | for (Node<E> t = tail, p = t, q;;) { | ||
| 1178 | if ((q = p.next) != null && | ||
| 1179 | (q = (p = q).next) != null) | ||
| 1180 | // Check for tail updates every other hop. | ||
| 1181 | // If p == q, we are sure to follow tail instead. | ||
| 1182 | p = (t != (t = tail)) ? t : q; | ||
| 1183 | else if (p.prev == p) // NEXT_TERMINATOR | ||
| 1184 | continue restartFromTail; | ||
| 1185 | else { | ||
| 1186 | // p is last node | ||
| 1187 | beginningOfTheEnd.lazySetPrev(p); // CAS piggyback | ||
| 1188 | if (p.casNext(null, beginningOfTheEnd)) { | ||
| 1189 | // Successful CAS is the linearization point | ||
| 1190 | // for all elements to be added to this deque. | ||
| 1191 | if (!casTail(t, last)) { | ||
| 1192 | // Try a little harder to update tail, | ||
| 1193 | // since we may be adding many elements. | ||
| 1194 | t = tail; | ||
| 1195 | if (last.next == null) | ||
| 1196 | casTail(t, last); | ||
| 1197 | } | ||
| 1198 | return true; | ||
| 1199 | } | ||
| 1200 | // Lost CAS race to another thread; re-read next | ||
| 1201 | } | ||
| 1202 | } | ||
| 1203 | } | ||
| 1204 | |||
| 1205 | /** | ||
| 1206 | * Removes all of the elements from this deque. | ||
| 1207 | */ | ||
| 1208 | public void clear() { | ||
| 1209 | while (pollFirst() != null) | ||
| 1210 | ; | ||
| 1211 | } | ||
| 1212 | |||
| 1213 | /** | ||
| 1214 | * Returns an array containing all of the elements in this deque, in | ||
| 1215 | * proper sequence (from first to last element). | ||
| 1216 | * | ||
| 1217 | * <p>The returned array will be "safe" in that no references to it are | ||
| 1218 | * maintained by this deque. (In other words, this method must allocate | ||
| 1219 | * a new array). The caller is thus free to modify the returned array. | ||
| 1220 | * | ||
| 1221 | * <p>This method acts as bridge between array-based and collection-based | ||
| 1222 | * APIs. | ||
| 1223 | * | ||
| 1224 | * @return an array containing all of the elements in this deque | ||
| 1225 | */ | ||
| 1226 | public Object[] toArray() { | ||
| 1227 | return toArrayList().toArray(); | ||
| 1228 | } | ||
| 1229 | |||
| 1230 | /** | ||
| 1231 | * Returns an array containing all of the elements in this deque, | ||
| 1232 | * in proper sequence (from first to last element); the runtime | ||
| 1233 | * type of the returned array is that of the specified array. If | ||
| 1234 | * the deque fits in the specified array, it is returned therein. | ||
| 1235 | * Otherwise, a new array is allocated with the runtime type of | ||
| 1236 | * the specified array and the size of this deque. | ||
| 1237 | * | ||
| 1238 | * <p>If this deque fits in the specified array with room to spare | ||
| 1239 | * (i.e., the array has more elements than this deque), the element in | ||
| 1240 | * the array immediately following the end of the deque is set to | ||
| 1241 | * {@code null}. | ||
| 1242 | * | ||
| 1243 | * <p>Like the {@link #toArray()} method, this method acts as | ||
| 1244 | * bridge between array-based and collection-based APIs. Further, | ||
| 1245 | * this method allows precise control over the runtime type of the | ||
| 1246 | * output array, and may, under certain circumstances, be used to | ||
| 1247 | * save allocation costs. | ||
| 1248 | * | ||
| 1249 | * <p>Suppose {@code x} is a deque known to contain only strings. | ||
| 1250 | * The following code can be used to dump the deque into a newly | ||
| 1251 | * allocated array of {@code String}: | ||
| 1252 | * | ||
| 1253 | * <pre> | ||
| 1254 | * String[] y = x.toArray(new String[0]);</pre> | ||
| 1255 | * | ||
| 1256 | * Note that {@code toArray(new Object[0])} is identical in function to | ||
| 1257 | * {@code toArray()}. | ||
| 1258 | * | ||
| 1259 | * @param a the array into which the elements of the deque are to | ||
| 1260 | * be stored, if it is big enough; otherwise, a new array of the | ||
| 1261 | * same runtime type is allocated for this purpose | ||
| 1262 | * @return an array containing all of the elements in this deque | ||
| 1263 | * @throws ArrayStoreException if the runtime type of the specified array | ||
| 1264 | * is not a supertype of the runtime type of every element in | ||
| 1265 | * this deque | ||
| 1266 | * @throws NullPointerException if the specified array is null | ||
| 1267 | */ | ||
| 1268 | public <T> T[] toArray(T[] a) { | ||
| 1269 | return toArrayList().toArray(a); | ||
| 1270 | } | ||
| 1271 | |||
| 1272 | /** | ||
| 1273 | * Returns an iterator over the elements in this deque in proper sequence. | ||
| 1274 | * The elements will be returned in order from first (head) to last (tail). | ||
| 1275 | * | ||
| 1276 | * <p>The returned iterator is a "weakly consistent" iterator that | ||
| 1277 | * will never throw {@link java.util.ConcurrentModificationException | ||
| 1278 | * ConcurrentModificationException}, and guarantees to traverse | ||
| 1279 | * elements as they existed upon construction of the iterator, and | ||
| 1280 | * may (but is not guaranteed to) reflect any modifications | ||
| 1281 | * subsequent to construction. | ||
| 1282 | * | ||
| 1283 | * @return an iterator over the elements in this deque in proper sequence | ||
| 1284 | */ | ||
| 1285 | public Iterator<E> iterator() { | ||
| 1286 | return new Itr(); | ||
| 1287 | } | ||
| 1288 | |||
| 1289 | /** | ||
| 1290 | * Returns an iterator over the elements in this deque in reverse | ||
| 1291 | * sequential order. The elements will be returned in order from | ||
| 1292 | * last (tail) to first (head). | ||
| 1293 | * | ||
| 1294 | * <p>The returned iterator is a "weakly consistent" iterator that | ||
| 1295 | * will never throw {@link java.util.ConcurrentModificationException | ||
| 1296 | * ConcurrentModificationException}, and guarantees to traverse | ||
| 1297 | * elements as they existed upon construction of the iterator, and | ||
| 1298 | * may (but is not guaranteed to) reflect any modifications | ||
| 1299 | * subsequent to construction. | ||
| 1300 | * | ||
| 1301 | * @return an iterator over the elements in this deque in reverse order | ||
| 1302 | */ | ||
| 1303 | public Iterator<E> descendingIterator() { | ||
| 1304 | return new DescendingItr(); | ||
| 1305 | } | ||
| 1306 | |||
| 1307 | private abstract class AbstractItr implements Iterator<E> { | ||
| 1308 | /** | ||
| 1309 | * Next node to return item for. | ||
| 1310 | */ | ||
| 1311 | private Node<E> nextNode; | ||
| 1312 | |||
| 1313 | /** | ||
| 1314 | * nextItem holds on to item fields because once we claim | ||
| 1315 | * that an element exists in hasNext(), we must return it in | ||
| 1316 | * the following next() call even if it was in the process of | ||
| 1317 | * being removed when hasNext() was called. | ||
| 1318 | */ | ||
| 1319 | private E nextItem; | ||
| 1320 | |||
| 1321 | /** | ||
| 1322 | * Node returned by most recent call to next. Needed by remove. | ||
| 1323 | * Reset to null if this element is deleted by a call to remove. | ||
| 1324 | */ | ||
| 1325 | private Node<E> lastRet; | ||
| 1326 | |||
| 1327 | abstract Node<E> startNode(); | ||
| 1328 | abstract Node<E> nextNode(Node<E> p); | ||
| 1329 | |||
| 1330 | AbstractItr() { | ||
| 1331 | advance(); | ||
| 1332 | } | ||
| 1333 | |||
| 1334 | /** | ||
| 1335 | * Sets nextNode and nextItem to next valid node, or to null | ||
| 1336 | * if no such. | ||
| 1337 | */ | ||
| 1338 | private void advance() { | ||
| 1339 | lastRet = nextNode; | ||
| 1340 | |||
| 1341 | Node<E> p = (nextNode == null) ? startNode() : nextNode(nextNode); | ||
| 1342 | for (;; p = nextNode(p)) { | ||
| 1343 | if (p == null) { | ||
| 1344 | // p might be active end or TERMINATOR node; both are OK | ||
| 1345 | nextNode = null; | ||
| 1346 | nextItem = null; | ||
| 1347 | break; | ||
| 1348 | } | ||
| 1349 | E item = p.item; | ||
| 1350 | if (item != null) { | ||
| 1351 | nextNode = p; | ||
| 1352 | nextItem = item; | ||
| 1353 | break; | ||
| 1354 | } | ||
| 1355 | } | ||
| 1356 | } | ||
| 1357 | |||
| 1358 | public boolean hasNext() { | ||
| 1359 | return nextItem != null; | ||
| 1360 | } | ||
| 1361 | |||
| 1362 | public E next() { | ||
| 1363 | E item = nextItem; | ||
| 1364 | if (item == null) throw new NoSuchElementException(); | ||
| 1365 | advance(); | ||
| 1366 | return item; | ||
| 1367 | } | ||
| 1368 | |||
| 1369 | public void remove() { | ||
| 1370 | Node<E> l = lastRet; | ||
| 1371 | if (l == null) throw new IllegalStateException(); | ||
| 1372 | l.item = null; | ||
| 1373 | unlink(l); | ||
| 1374 | lastRet = null; | ||
| 1375 | } | ||
| 1376 | } | ||
| 1377 | |||
| 1378 | /** Forward iterator */ | ||
| 1379 | private class Itr extends AbstractItr { | ||
| 1380 | Node<E> startNode() { return first(); } | ||
| 1381 | Node<E> nextNode(Node<E> p) { return succ(p); } | ||
| 1382 | } | ||
| 1383 | |||
| 1384 | /** Descending iterator */ | ||
| 1385 | private class DescendingItr extends AbstractItr { | ||
| 1386 | Node<E> startNode() { return last(); } | ||
| 1387 | Node<E> nextNode(Node<E> p) { return pred(p); } | ||
| 1388 | } | ||
| 1389 | |||
| 1390 | /** | ||
| 1391 | * Saves the state to a stream (that is, serializes it). | ||
| 1392 | * | ||
| 1393 | * @serialData All of the elements (each an {@code E}) in | ||
| 1394 | * the proper order, followed by a null | ||
| 1395 | * @param s the stream | ||
| 1396 | */ | ||
| 1397 | private void writeObject(java.io.ObjectOutputStream s) | ||
| 1398 | throws java.io.IOException { | ||
| 1399 | |||
| 1400 | // Write out any hidden stuff | ||
| 1401 | s.defaultWriteObject(); | ||
| 1402 | |||
| 1403 | // Write out all elements in the proper order. | ||
| 1404 | for (Node<E> p = first(); p != null; p = succ(p)) { | ||
| 1405 | E item = p.item; | ||
| 1406 | if (item != null) | ||
| 1407 | s.writeObject(item); | ||
| 1408 | } | ||
| 1409 | |||
| 1410 | // Use trailing null as sentinel | ||
| 1411 | s.writeObject(null); | ||
| 1412 | } | ||
| 1413 | |||
| 1414 | /** | ||
| 1415 | * Reconstitutes the instance from a stream (that is, deserializes it). | ||
| 1416 | * @param s the stream | ||
| 1417 | */ | ||
| 1418 | private void readObject(java.io.ObjectInputStream s) | ||
| 1419 | throws java.io.IOException, ClassNotFoundException { | ||
| 1420 | s.defaultReadObject(); | ||
| 1421 | |||
| 1422 | // Read in elements until trailing null sentinel found | ||
| 1423 | Node<E> h = null, t = null; | ||
| 1424 | Object item; | ||
| 1425 | while ((item = s.readObject()) != null) { | ||
| 1426 | @SuppressWarnings("unchecked") | ||
| 1427 | Node<E> newNode = new Node<E>((E) item); | ||
| 1428 | if (h == null) | ||
| 1429 | h = t = newNode; | ||
| 1430 | else { | ||
| 1431 | t.lazySetNext(newNode); | ||
| 1432 | newNode.lazySetPrev(t); | ||
| 1433 | t = newNode; | ||
| 1434 | } | ||
| 1435 | } | ||
| 1436 | initHeadTail(h, t); | ||
| 1437 | } | ||
| 1438 | |||
| 1439 | |||
| 1440 | private boolean casHead(Node<E> cmp, Node<E> val) { | ||
| 1441 | return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val); | ||
| 1442 | } | ||
| 1443 | |||
| 1444 | private boolean casTail(Node<E> cmp, Node<E> val) { | ||
| 1445 | return UNSAFE.compareAndSwapObject(this, tailOffset, cmp, val); | ||
| 1446 | } | ||
| 1447 | |||
| 1448 | // Unsafe mechanics | ||
| 1449 | |||
| 1450 | private static final sun.misc.Unsafe UNSAFE; | ||
| 1451 | private static final long headOffset; | ||
| 1452 | private static final long tailOffset; | ||
| 1453 | static { | ||
| 1454 | PREV_TERMINATOR = new Node<Object>(); | ||
| 1455 | PREV_TERMINATOR.next = PREV_TERMINATOR; | ||
| 1456 | NEXT_TERMINATOR = new Node<Object>(); | ||
| 1457 | NEXT_TERMINATOR.prev = NEXT_TERMINATOR; | ||
| 1458 | try { | ||
| 1459 | UNSAFE = sun.misc.Unsafe.getUnsafe(); | ||
| 1460 | Class k = ConcurrentLinkedDeque.class; | ||
| 1461 | headOffset = UNSAFE.objectFieldOffset | ||
| 1462 | (k.getDeclaredField("head")); | ||
| 1463 | tailOffset = UNSAFE.objectFieldOffset | ||
| 1464 | (k.getDeclaredField("tail")); | ||
| 1465 | } catch (Exception e) { | ||
| 1466 | throw new Error(e); | ||
| 1467 | } | ||
| 1468 | } | ||
| 1469 | } | ||
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,835 @@ | |||
| 1 | /* | ||
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 3 | * | ||
| 4 | * This code is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License version 2 only, as | ||
| 6 | * published by the Free Software Foundation. Oracle designates this | ||
| 7 | * particular file as subject to the "Classpath" exception as provided | ||
| 8 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 9 | * | ||
| 10 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 13 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 14 | * accompanied this code). | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License version | ||
| 17 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | * | ||
| 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 21 | * or visit www.oracle.com if you need additional information or have any | ||
| 22 | * questions. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * This file is available under and governed by the GNU General Public | ||
| 27 | * License version 2 only, as published by the Free Software Foundation. | ||
| 28 | * However, the following notice accompanied the original version of this | ||
| 29 | * file: | ||
| 30 | * | ||
| 31 | * Written by Doug Lea and Martin Buchholz with assistance from members of | ||
| 32 | * JCP JSR-166 Expert Group and released to the public domain, as explained | ||
| 33 | * at http://creativecommons.org/publicdomain/zero/1.0/ | ||
| 34 | */ | ||
| 35 | |||
| 36 | package java.util.concurrent; | ||
| 37 | |||
| 38 | import java.util.AbstractQueue; | ||
| 39 | import java.util.ArrayList; | ||
| 40 | import java.util.Collection; | ||
| 41 | import java.util.Iterator; | ||
| 42 | import java.util.NoSuchElementException; | ||
| 43 | import java.util.Queue; | ||
| 44 | |||
| 45 | /** | ||
| 46 | * An unbounded thread-safe {@linkplain Queue queue} based on linked nodes. | ||
| 47 | * This queue orders elements FIFO (first-in-first-out). | ||
| 48 | * The <em>head</em> of the queue is that element that has been on the | ||
| 49 | * queue the longest time. | ||
| 50 | * The <em>tail</em> of the queue is that element that has been on the | ||
| 51 | * queue the shortest time. New elements | ||
| 52 | * are inserted at the tail of the queue, and the queue retrieval | ||
| 53 | * operations obtain elements at the head of the queue. | ||
| 54 | * A {@code ConcurrentLinkedQueue} is an appropriate choice when | ||
| 55 | * many threads will share access to a common collection. | ||
| 56 | * Like most other concurrent collection implementations, this class | ||
| 57 | * does not permit the use of {@code null} elements. | ||
| 58 | * | ||
| 59 | * <p>This implementation employs an efficient "wait-free" | ||
| 60 | * algorithm based on one described in <a | ||
| 61 | * href="http://www.cs.rochester.edu/u/michael/PODC96.html"> Simple, | ||
| 62 | * Fast, and Practical Non-Blocking and Blocking Concurrent Queue | ||
| 63 | * Algorithms</a> by Maged M. Michael and Michael L. Scott. | ||
| 64 | * | ||
| 65 | * <p>Iterators are <i>weakly consistent</i>, returning elements | ||
| 66 | * reflecting the state of the queue at some point at or since the | ||
| 67 | * creation of the iterator. They do <em>not</em> throw {@link | ||
| 68 | * java.util.ConcurrentModificationException}, and may proceed concurrently | ||
| 69 | * with other operations. Elements contained in the queue since the creation | ||
| 70 | * of the iterator will be returned exactly once. | ||
| 71 | * | ||
| 72 | * <p>Beware that, unlike in most collections, the {@code size} method | ||
| 73 | * is <em>NOT</em> a constant-time operation. Because of the | ||
| 74 | * asynchronous nature of these queues, determining the current number | ||
| 75 | * of elements requires a traversal of the elements, and so may report | ||
| 76 | * inaccurate results if this collection is modified during traversal. | ||
| 77 | * Additionally, the bulk operations {@code addAll}, | ||
| 78 | * {@code removeAll}, {@code retainAll}, {@code containsAll}, | ||
| 79 | * {@code equals}, and {@code toArray} are <em>not</em> guaranteed | ||
| 80 | * to be performed atomically. For example, an iterator operating | ||
| 81 | * concurrently with an {@code addAll} operation might view only some | ||
| 82 | * of the added elements. | ||
| 83 | * | ||
| 84 | * <p>This class and its iterator implement all of the <em>optional</em> | ||
| 85 | * methods of the {@link Queue} and {@link Iterator} interfaces. | ||
| 86 | * | ||
| 87 | * <p>Memory consistency effects: As with other concurrent | ||
| 88 | * collections, actions in a thread prior to placing an object into a | ||
| 89 | * {@code ConcurrentLinkedQueue} | ||
| 90 | * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> | ||
| 91 | * actions subsequent to the access or removal of that element from | ||
| 92 | * the {@code ConcurrentLinkedQueue} in another thread. | ||
| 93 | * | ||
| 94 | * <p>This class is a member of the | ||
| 95 | * <a href="{@docRoot}/../technotes/guides/collections/index.html"> | ||
| 96 | * Java Collections Framework</a>. | ||
| 97 | * | ||
| 98 | * @since 1.5 | ||
| 99 | * @author Doug Lea | ||
| 100 | * @param <E> the type of elements held in this collection | ||
| 101 | * | ||
| 102 | */ | ||
| 103 | public class ConcurrentLinkedQueue<E> extends AbstractQueue<E> | ||
| 104 | implements Queue<E>, java.io.Serializable { | ||
| 105 | private static final long serialVersionUID = 196745693267521676L; | ||
| 106 | |||
| 107 | /* | ||
| 108 | * This is a modification of the Michael & Scott algorithm, | ||
| 109 | * adapted for a garbage-collected environment, with support for | ||
| 110 | * interior node deletion (to support remove(Object)). For | ||
| 111 | * explanation, read the paper. | ||
| 112 | * | ||
| 113 | * Note that like most non-blocking algorithms in this package, | ||
| 114 | * this implementation relies on the fact that in garbage | ||
| 115 | * collected systems, there is no possibility of ABA problems due | ||
| 116 | * to recycled nodes, so there is no need to use "counted | ||
| 117 | * pointers" or related techniques seen in versions used in | ||
| 118 | * non-GC'ed settings. | ||
| 119 | * | ||
| 120 | * The fundamental invariants are: | ||
| 121 | * - There is exactly one (last) Node with a null next reference, | ||
| 122 | * which is CASed when enqueueing. This last Node can be | ||
| 123 | * reached in O(1) time from tail, but tail is merely an | ||
| 124 | * optimization - it can always be reached in O(N) time from | ||
| 125 | * head as well. | ||
| 126 | * - The elements contained in the queue are the non-null items in | ||
| 127 | * Nodes that are reachable from head. CASing the item | ||
| 128 | * reference of a Node to null atomically removes it from the | ||
| 129 | * queue. Reachability of all elements from head must remain | ||
| 130 | * true even in the case of concurrent modifications that cause | ||
| 131 | * head to advance. A dequeued Node may remain in use | ||
| 132 | * indefinitely due to creation of an Iterator or simply a | ||
| 133 | * poll() that has lost its time slice. | ||
| 134 | * | ||
| 135 | * The above might appear to imply that all Nodes are GC-reachable | ||
| 136 | * from a predecessor dequeued Node. That would cause two problems: | ||
| 137 | * - allow a rogue Iterator to cause unbounded memory retention | ||
| 138 | * - cause cross-generational linking of old Nodes to new Nodes if | ||
| 139 | * a Node was tenured while live, which generational GCs have a | ||
| 140 | * hard time dealing with, causing repeated major collections. | ||
| 141 | * However, only non-deleted Nodes need to be reachable from | ||
| 142 | * dequeued Nodes, and reachability does not necessarily have to | ||
| 143 | * be of the kind understood by the GC. We use the trick of | ||
| 144 | * linking a Node that has just been dequeued to itself. Such a | ||
| 145 | * self-link implicitly means to advance to head. | ||
| 146 | * | ||
| 147 | * Both head and tail are permitted to lag. In fact, failing to | ||
| 148 | * update them every time one could is a significant optimization | ||
| 149 | * (fewer CASes). As with LinkedTransferQueue (see the internal | ||
| 150 | * documentation for that class), we use a slack threshold of two; | ||
| 151 | * that is, we update head/tail when the current pointer appears | ||
| 152 | * to be two or more steps away from the first/last node. | ||
| 153 | * | ||
| 154 | * Since head and tail are updated concurrently and independently, | ||
| 155 | * it is possible for tail to lag behind head (why not)? | ||
| 156 | * | ||
| 157 | * CASing a Node's item reference to null atomically removes the | ||
| 158 | * element from the queue. Iterators skip over Nodes with null | ||
| 159 | * items. Prior implementations of this class had a race between | ||
| 160 | * poll() and remove(Object) where the same element would appear | ||
| 161 | * to be successfully removed by two concurrent operations. The | ||
| 162 | * method remove(Object) also lazily unlinks deleted Nodes, but | ||
| 163 | * this is merely an optimization. | ||
| 164 | * | ||
| 165 | * When constructing a Node (before enqueuing it) we avoid paying | ||
| 166 | * for a volatile write to item by using Unsafe.putObject instead | ||
| 167 | * of a normal write. This allows the cost of enqueue to be | ||
| 168 | * "one-and-a-half" CASes. | ||
| 169 | * | ||
| 170 | * Both head and tail may or may not point to a Node with a | ||
| 171 | * non-null item. If the queue is empty, all items must of course | ||
| 172 | * be null. Upon creation, both head and tail refer to a dummy | ||
| 173 | * Node with null item. Both head and tail are only updated using | ||
| 174 | * CAS, so they never regress, although again this is merely an | ||
| 175 | * optimization. | ||
| 176 | */ | ||
| 177 | |||
| 178 | private static class Node<E> { | ||
| 179 | volatile E item; | ||
| 180 | volatile Node<E> next; | ||
| 181 | |||
| 182 | /** | ||
| 183 | * Constructs a new node. Uses relaxed write because item can | ||
| 184 | * only be seen after publication via casNext. | ||
| 185 | */ | ||
| 186 | Node(E item) { | ||
| 187 | UNSAFE.putObject(this, itemOffset, item); | ||
| 188 | } | ||
| 189 | |||
| 190 | boolean casItem(E cmp, E val) { | ||
| 191 | return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val); | ||
| 192 | } | ||
| 193 | |||
| 194 | void lazySetNext(Node<E> val) { | ||
| 195 | UNSAFE.putOrderedObject(this, nextOffset, val); | ||
| 196 | } | ||
| 197 | |||
| 198 | boolean casNext(Node<E> cmp, Node<E> val) { | ||
| 199 | return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val); | ||
| 200 | } | ||
| 201 | |||
| 202 | // Unsafe mechanics | ||
| 203 | |||
| 204 | private static final sun.misc.Unsafe UNSAFE; | ||
| 205 | private static final long itemOffset; | ||
| 206 | private static final long nextOffset; | ||
| 207 | |||
| 208 | static { | ||
| 209 | try { | ||
| 210 | UNSAFE = sun.misc.Unsafe.getUnsafe(); | ||
| 211 | Class k = Node.class; | ||
| 212 | itemOffset = UNSAFE.objectFieldOffset | ||
| 213 | (k.getDeclaredField("item")); | ||
| 214 | nextOffset = UNSAFE.objectFieldOffset | ||
| 215 | (k.getDeclaredField("next")); | ||
| 216 | } catch (Exception e) { | ||
| 217 | throw new Error(e); | ||
| 218 | } | ||
| 219 | } | ||
| 220 | } | ||
| 221 | |||
| 222 | /** | ||
| 223 | * A node from which the first live (non-deleted) node (if any) | ||
| 224 | * can be reached in O(1) time. | ||
| 225 | * Invariants: | ||
| 226 | * - all live nodes are reachable from head via succ() | ||
| 227 | * - head != null | ||
| 228 | * - (tmp = head).next != tmp || tmp != head | ||
| 229 | * Non-invariants: | ||
| 230 | * - head.item may or may not be null. | ||
| 231 | * - it is permitted for tail to lag behind head, that is, for tail | ||
| 232 | * to not be reachable from head! | ||
| 233 | */ | ||
| 234 | private transient volatile Node<E> head; | ||
| 235 | |||
| 236 | /** | ||
| 237 | * A node from which the last node on list (that is, the unique | ||
| 238 | * node with node.next == null) can be reached in O(1) time. | ||
| 239 | * Invariants: | ||
| 240 | * - the last node is always reachable from tail via succ() | ||
| 241 | * - tail != null | ||
| 242 | * Non-invariants: | ||
| 243 | * - tail.item may or may not be null. | ||
| 244 | * - it is permitted for tail to lag behind head, that is, for tail | ||
| 245 | * to not be reachable from head! | ||
| 246 | * - tail.next may or may not be self-pointing to tail. | ||
| 247 | */ | ||
| 248 | private transient volatile Node<E> tail; | ||
| 249 | |||
| 250 | |||
| 251 | /** | ||
| 252 | * Creates a {@code ConcurrentLinkedQueue} that is initially empty. | ||
| 253 | */ | ||
| 254 | public ConcurrentLinkedQueue() { | ||
| 255 | head = tail = new Node<E>(null); | ||
| 256 | } | ||
| 257 | |||
| 258 | /** | ||
| 259 | * Creates a {@code ConcurrentLinkedQueue} | ||
| 260 | * initially containing the elements of the given collection, | ||
| 261 | * added in traversal order of the collection's iterator. | ||
| 262 | * | ||
| 263 | * @param c the collection of elements to initially contain | ||
| 264 | * @throws NullPointerException if the specified collection or any | ||
| 265 | * of its elements are null | ||
| 266 | */ | ||
| 267 | public ConcurrentLinkedQueue(Collection<? extends E> c) { | ||
| 268 | Node<E> h = null, t = null; | ||
| 269 | for (E e : c) { | ||
| 270 | checkNotNull(e); | ||
| 271 | Node<E> newNode = new Node<E>(e); | ||
| 272 | if (h == null) | ||
| 273 | h = t = newNode; | ||
| 274 | else { | ||
| 275 | t.lazySetNext(newNode); | ||
| 276 | t = newNode; | ||
| 277 | } | ||
| 278 | } | ||
| 279 | if (h == null) | ||
| 280 | h = t = new Node<E>(null); | ||
| 281 | head = h; | ||
| 282 | tail = t; | ||
| 283 | } | ||
| 284 | |||
| 285 | // Have to override just to update the javadoc | ||
| 286 | |||
| 287 | /** | ||
| 288 | * Inserts the specified element at the tail of this queue. | ||
| 289 | * As the queue is unbounded, this method will never throw | ||
| 290 | * {@link IllegalStateException} or return {@code false}. | ||
| 291 | * | ||
| 292 | * @return {@code true} (as specified by {@link Collection#add}) | ||
| 293 | * @throws NullPointerException if the specified element is null | ||
| 294 | */ | ||
| 295 | public boolean add(E e) { | ||
| 296 | return offer(e); | ||
| 297 | } | ||
| 298 | |||
| 299 | /** | ||
| 300 | * Try to CAS head to p. If successful, repoint old head to itself | ||
| 301 | * as sentinel for succ(), below. | ||
| 302 | */ | ||
| 303 | final void updateHead(Node<E> h, Node<E> p) { | ||
| 304 | if (h != p && casHead(h, p)) | ||
| 305 | h.lazySetNext(h); | ||
| 306 | } | ||
| 307 | |||
| 308 | /** | ||
| 309 | * Returns the successor of p, or the head node if p.next has been | ||
| 310 | * linked to self, which will only be true if traversing with a | ||
| 311 | * stale pointer that is now off the list. | ||
| 312 | */ | ||
| 313 | final Node<E> succ(Node<E> p) { | ||
| 314 | Node<E> next = p.next; | ||
| 315 | return (p == next) ? head : next; | ||
| 316 | } | ||
| 317 | |||
| 318 | /** | ||
| 319 | * Inserts the specified element at the tail of this queue. | ||
| 320 | * As the queue is unbounded, this method will never return {@code false}. | ||
| 321 | * | ||
| 322 | * @return {@code true} (as specified by {@link Queue#offer}) | ||
| 323 | * @throws NullPointerException if the specified element is null | ||
| 324 | */ | ||
| 325 | public boolean offer(E e) { | ||
| 326 | checkNotNull(e); | ||
| 327 | final Node<E> newNode = new Node<E>(e); | ||
| 328 | |||
| 329 | for (Node<E> t = tail, p = t;;) { | ||
| 330 | Node<E> q = p.next; | ||
| 331 | if (q == null) { | ||
| 332 | // p is last node | ||
| 333 | if (p.casNext(null, newNode)) { | ||
| 334 | // Successful CAS is the linearization point | ||
| 335 | // for e to become an element of this queue, | ||
| 336 | // and for newNode to become "live". | ||
| 337 | if (p != t) // hop two nodes at a time | ||
| 338 | casTail(t, newNode); // Failure is OK. | ||
| 339 | return true; | ||
| 340 | } | ||
| 341 | // Lost CAS race to another thread; re-read next | ||
| 342 | } | ||
| 343 | else if (p == q) | ||
| 344 | // We have fallen off list. If tail is unchanged, it | ||
| 345 | // will also be off-list, in which case we need to | ||
| 346 | // jump to head, from which all live nodes are always | ||
| 347 | // reachable. Else the new tail is a better bet. | ||
| 348 | p = (t != (t = tail)) ? t : head; | ||
| 349 | else | ||
| 350 | // Check for tail updates after two hops. | ||
| 351 | p = (p != t && t != (t = tail)) ? t : q; | ||
| 352 | } | ||
| 353 | } | ||
| 354 | |||
| 355 | public E poll() { | ||
| 356 | restartFromHead: | ||
| 357 | for (;;) { | ||
| 358 | for (Node<E> h = head, p = h, q;;) { | ||
| 359 | E item = p.item; | ||
| 360 | |||
| 361 | if (item != null && p.casItem(item, null)) { | ||
| 362 | // Successful CAS is the linearization point | ||
| 363 | // for item to be removed from this queue. | ||
| 364 | if (p != h) // hop two nodes at a time | ||
| 365 | updateHead(h, ((q = p.next) != null) ? q : p); | ||
| 366 | return item; | ||
| 367 | } | ||
| 368 | else if ((q = p.next) == null) { | ||
| 369 | updateHead(h, p); | ||
| 370 | return null; | ||
| 371 | } | ||
| 372 | else if (p == q) | ||
| 373 | continue restartFromHead; | ||
| 374 | else | ||
| 375 | p = q; | ||
| 376 | } | ||
| 377 | } | ||
| 378 | } | ||
| 379 | |||
| 380 | public E peek() { | ||
| 381 | restartFromHead: | ||
| 382 | for (;;) { | ||
| 383 | for (Node<E> h = head, p = h, q;;) { | ||
| 384 | E item = p.item; | ||
| 385 | if (item != null || (q = p.next) == null) { | ||
| 386 | updateHead(h, p); | ||
| 387 | return item; | ||
| 388 | } | ||
| 389 | else if (p == q) | ||
| 390 | continue restartFromHead; | ||
| 391 | else | ||
| 392 | p = q; | ||
| 393 | } | ||
| 394 | } | ||
| 395 | } | ||
| 396 | |||
| 397 | /** | ||
| 398 | * Returns the first live (non-deleted) node on list, or null if none. | ||
| 399 | * This is yet another variant of poll/peek; here returning the | ||
| 400 | * first node, not element. We could make peek() a wrapper around | ||
| 401 | * first(), but that would cost an extra volatile read of item, | ||
| 402 | * and the need to add a retry loop to deal with the possibility | ||
| 403 | * of losing a race to a concurrent poll(). | ||
| 404 | */ | ||
| 405 | Node<E> first() { | ||
| 406 | restartFromHead: | ||
| 407 | for (;;) { | ||
| 408 | for (Node<E> h = head, p = h, q;;) { | ||
| 409 | boolean hasItem = (p.item != null); | ||
| 410 | if (hasItem || (q = p.next) == null) { | ||
| 411 | updateHead(h, p); | ||
| 412 | return hasItem ? p : null; | ||
| 413 | } | ||
| 414 | else if (p == q) | ||
| 415 | continue restartFromHead; | ||
| 416 | else | ||
| 417 | p = q; | ||
| 418 | } | ||
| 419 | } | ||
| 420 | } | ||
| 421 | |||
| 422 | /** | ||
| 423 | * Returns {@code true} if this queue contains no elements. | ||
| 424 | * | ||
| 425 | * @return {@code true} if this queue contains no elements | ||
| 426 | */ | ||
| 427 | public boolean isEmpty() { | ||
| 428 | return first() == null; | ||
| 429 | } | ||
| 430 | |||
| 431 | /** | ||
| 432 | * Returns the number of elements in this queue. If this queue | ||
| 433 | * contains more than {@code Integer.MAX_VALUE} elements, returns | ||
| 434 | * {@code Integer.MAX_VALUE}. | ||
| 435 | * | ||
| 436 | * <p>Beware that, unlike in most collections, this method is | ||
| 437 | * <em>NOT</em> a constant-time operation. Because of the | ||
| 438 | * asynchronous nature of these queues, determining the current | ||
| 439 | * number of elements requires an O(n) traversal. | ||
| 440 | * Additionally, if elements are added or removed during execution | ||
| 441 | * of this method, the returned result may be inaccurate. Thus, | ||
| 442 | * this method is typically not very useful in concurrent | ||
| 443 | * applications. | ||
| 444 | * | ||
| 445 | * @return the number of elements in this queue | ||
| 446 | */ | ||
| 447 | public int size() { | ||
| 448 | int count = 0; | ||
| 449 | for (Node<E> p = first(); p != null; p = succ(p)) | ||
| 450 | if (p.item != null) | ||
| 451 | // Collection.size() spec says to max out | ||
| 452 | if (++count == Integer.MAX_VALUE) | ||
| 453 | break; | ||
| 454 | return count; | ||
| 455 | } | ||
| 456 | |||
| 457 | /** | ||
| 458 | * Returns {@code true} if this queue contains the specified element. | ||
| 459 | * More formally, returns {@code true} if and only if this queue contains | ||
| 460 | * at least one element {@code e} such that {@code o.equals(e)}. | ||
| 461 | * | ||
| 462 | * @param o object to be checked for containment in this queue | ||
| 463 | * @return {@code true} if this queue contains the specified element | ||
| 464 | */ | ||
| 465 | public boolean contains(Object o) { | ||
| 466 | if (o == null) return false; | ||
| 467 | for (Node<E> p = first(); p != null; p = succ(p)) { | ||
| 468 | E item = p.item; | ||
| 469 | if (item != null && o.equals(item)) | ||
| 470 | return true; | ||
| 471 | } | ||
| 472 | return false; | ||
| 473 | } | ||
| 474 | |||
| 475 | /** | ||
| 476 | * Removes a single instance of the specified element from this queue, | ||
| 477 | * if it is present. More formally, removes an element {@code e} such | ||
| 478 | * that {@code o.equals(e)}, if this queue contains one or more such | ||
| 479 | * elements. | ||
| 480 | * Returns {@code true} if this queue contained the specified element | ||
| 481 | * (or equivalently, if this queue changed as a result of the call). | ||
| 482 | * | ||
| 483 | * @param o element to be removed from this queue, if present | ||
| 484 | * @return {@code true} if this queue changed as a result of the call | ||
| 485 | */ | ||
| 486 | public boolean remove(Object o) { | ||
| 487 | if (o == null) return false; | ||
| 488 | Node<E> pred = null; | ||
| 489 | for (Node<E> p = first(); p != null; p = succ(p)) { | ||
| 490 | E item = p.item; | ||
| 491 | if (item != null && | ||
| 492 | o.equals(item) && | ||
| 493 | p.casItem(item, null)) { | ||
| 494 | Node<E> next = succ(p); | ||
| 495 | if (pred != null && next != null) | ||
| 496 | pred.casNext(p, next); | ||
| 497 | return true; | ||
| 498 | } | ||
| 499 | pred = p; | ||
| 500 | } | ||
| 501 | return false; | ||
| 502 | } | ||
| 503 | |||
| 504 | /** | ||
| 505 | * Appends all of the elements in the specified collection to the end of | ||
| 506 | * this queue, in the order that they are returned by the specified | ||
| 507 | * collection's iterator. Attempts to {@code addAll} of a queue to | ||
| 508 | * itself result in {@code IllegalArgumentException}. | ||
| 509 | * | ||
| 510 | * @param c the elements to be inserted into this queue | ||
| 511 | * @return {@code true} if this queue changed as a result of the call | ||
| 512 | * @throws NullPointerException if the specified collection or any | ||
| 513 | * of its elements are null | ||
| 514 | * @throws IllegalArgumentException if the collection is this queue | ||
| 515 | */ | ||
| 516 | public boolean addAll(Collection<? extends E> c) { | ||
| 517 | if (c == this) | ||
| 518 | // As historically specified in AbstractQueue#addAll | ||
| 519 | throw new IllegalArgumentException(); | ||
| 520 | |||
| 521 | // Copy c into a private chain of Nodes | ||
| 522 | Node<E> beginningOfTheEnd = null, last = null; | ||
| 523 | for (E e : c) { | ||
| 524 | checkNotNull(e); | ||
| 525 | Node<E> newNode = new Node<E>(e); | ||
| 526 | if (beginningOfTheEnd == null) | ||
| 527 | beginningOfTheEnd = last = newNode; | ||
| 528 | else { | ||
| 529 | last.lazySetNext(newNode); | ||
| 530 | last = newNode; | ||
| 531 | } | ||
| 532 | } | ||
| 533 | if (beginningOfTheEnd == null) | ||
| 534 | return false; | ||
| 535 | |||
| 536 | // Atomically append the chain at the tail of this collection | ||
| 537 | for (Node<E> t = tail, p = t;;) { | ||
| 538 | Node<E> q = p.next; | ||
| 539 | if (q == null) { | ||
| 540 | // p is last node | ||
| 541 | if (p.casNext(null, beginningOfTheEnd)) { | ||
| 542 | // Successful CAS is the linearization point | ||
| 543 | // for all elements to be added to this queue. | ||
| 544 | if (!casTail(t, last)) { | ||
| 545 | // Try a little harder to update tail, | ||
| 546 | // since we may be adding many elements. | ||
| 547 | t = tail; | ||
| 548 | if (last.next == null) | ||
| 549 | casTail(t, last); | ||
| 550 | } | ||
| 551 | return true; | ||
| 552 | } | ||
| 553 | // Lost CAS race to another thread; re-read next | ||
| 554 | } | ||
| 555 | else if (p == q) | ||
| 556 | // We have fallen off list. If tail is unchanged, it | ||
| 557 | // will also be off-list, in which case we need to | ||
| 558 | // jump to head, from which all live nodes are always | ||
| 559 | // reachable. Else the new tail is a better bet. | ||
| 560 | p = (t != (t = tail)) ? t : head; | ||
| 561 | else | ||
| 562 | // Check for tail updates after two hops. | ||
| 563 | p = (p != t && t != (t = tail)) ? t : q; | ||
| 564 | } | ||
| 565 | } | ||
| 566 | |||
| 567 | /** | ||
| 568 | * Returns an array containing all of the elements in this queue, in | ||
| 569 | * proper sequence. | ||
| 570 | * | ||
| 571 | * <p>The returned array will be "safe" in that no references to it are | ||
| 572 | * maintained by this queue. (In other words, this method must allocate | ||
| 573 | * a new array). The caller is thus free to modify the returned array. | ||
| 574 | * | ||
| 575 | * <p>This method acts as bridge between array-based and collection-based | ||
| 576 | * APIs. | ||
| 577 | * | ||
| 578 | * @return an array containing all of the elements in this queue | ||
| 579 | */ | ||
| 580 | public Object[] toArray() { | ||
| 581 | // Use ArrayList to deal with resizing. | ||
| 582 | ArrayList<E> al = new ArrayList<E>(); | ||
| 583 | for (Node<E> p = first(); p != null; p = succ(p)) { | ||
| 584 | E item = p.item; | ||
| 585 | if (item != null) | ||
| 586 | al.add(item); | ||
| 587 | } | ||
| 588 | return al.toArray(); | ||
| 589 | } | ||
| 590 | |||
| 591 | /** | ||
| 592 | * Returns an array containing all of the elements in this queue, in | ||
| 593 | * proper sequence; the runtime type of the returned array is that of | ||
| 594 | * the specified array. If the queue fits in the specified array, it | ||
| 595 | * is returned therein. Otherwise, a new array is allocated with the | ||
| 596 | * runtime type of the specified array and the size of this queue. | ||
| 597 | * | ||
| 598 | * <p>If this queue fits in the specified array with room to spare | ||
| 599 | * (i.e., the array has more elements than this queue), the element in | ||
| 600 | * the array immediately following the end of the queue is set to | ||
| 601 | * {@code null}. | ||
| 602 | * | ||
| 603 | * <p>Like the {@link #toArray()} method, this method acts as bridge between | ||
| 604 | * array-based and collection-based APIs. Further, this method allows | ||
| 605 | * precise control over the runtime type of the output array, and may, | ||
| 606 | * under certain circumstances, be used to save allocation costs. | ||
| 607 | * | ||
| 608 | * <p>Suppose {@code x} is a queue known to contain only strings. | ||
| 609 | * The following code can be used to dump the queue into a newly | ||
| 610 | * allocated array of {@code String}: | ||
| 611 | * | ||
| 612 | * <pre> | ||
| 613 | * String[] y = x.toArray(new String[0]);</pre> | ||
| 614 | * | ||
| 615 | * Note that {@code toArray(new Object[0])} is identical in function to | ||
| 616 | * {@code toArray()}. | ||
| 617 | * | ||
| 618 | * @param a the array into which the elements of the queue are to | ||
| 619 | * be stored, if it is big enough; otherwise, a new array of the | ||
| 620 | * same runtime type is allocated for this purpose | ||
| 621 | * @return an array containing all of the elements in this queue | ||
| 622 | * @throws ArrayStoreException if the runtime type of the specified array | ||
| 623 | * is not a supertype of the runtime type of every element in | ||
| 624 | * this queue | ||
| 625 | * @throws NullPointerException if the specified array is null | ||
| 626 | */ | ||
| 627 | @SuppressWarnings("unchecked") | ||
| 628 | public <T> T[] toArray(T[] a) { | ||
| 629 | // try to use sent-in array | ||
| 630 | int k = 0; | ||
| 631 | Node<E> p; | ||
| 632 | for (p = first(); p != null && k < a.length; p = succ(p)) { | ||
| 633 | E item = p.item; | ||
| 634 | if (item != null) | ||
| 635 | a[k++] = (T)item; | ||
| 636 | } | ||
| 637 | if (p == null) { | ||
| 638 | if (k < a.length) | ||
| 639 | a[k] = null; | ||
| 640 | return a; | ||
| 641 | } | ||
| 642 | |||
| 643 | // If won't fit, use ArrayList version | ||
| 644 | ArrayList<E> al = new ArrayList<E>(); | ||
| 645 | for (Node<E> q = first(); q != null; q = succ(q)) { | ||
| 646 | E item = q.item; | ||
| 647 | if (item != null) | ||
| 648 | al.add(item); | ||
| 649 | } | ||
| 650 | return al.toArray(a); | ||
| 651 | } | ||
| 652 | |||
| 653 | /** | ||
| 654 | * Returns an iterator over the elements in this queue in proper sequence. | ||
| 655 | * The elements will be returned in order from first (head) to last (tail). | ||
| 656 | * | ||
| 657 | * <p>The returned iterator is a "weakly consistent" iterator that | ||
| 658 | * will never throw {@link java.util.ConcurrentModificationException | ||
| 659 | * ConcurrentModificationException}, and guarantees to traverse | ||
| 660 | * elements as they existed upon construction of the iterator, and | ||
| 661 | * may (but is not guaranteed to) reflect any modifications | ||
| 662 | * subsequent to construction. | ||
| 663 | * | ||
| 664 | * @return an iterator over the elements in this queue in proper sequence | ||
| 665 | */ | ||
| 666 | public Iterator<E> iterator() { | ||
| 667 | return new Itr(); | ||
| 668 | } | ||
| 669 | |||
| 670 | private class Itr implements Iterator<E> { | ||
| 671 | /** | ||
| 672 | * Next node to return item for. | ||
| 673 | */ | ||
| 674 | private Node<E> nextNode; | ||
| 675 | |||
| 676 | /** | ||
| 677 | * nextItem holds on to item fields because once we claim | ||
| 678 | * that an element exists in hasNext(), we must return it in | ||
| 679 | * the following next() call even if it was in the process of | ||
| 680 | * being removed when hasNext() was called. | ||
| 681 | */ | ||
| 682 | private E nextItem; | ||
| 683 | |||
| 684 | /** | ||
| 685 | * Node of the last returned item, to support remove. | ||
| 686 | */ | ||
| 687 | private Node<E> lastRet; | ||
| 688 | |||
| 689 | Itr() { | ||
| 690 | advance(); | ||
| 691 | } | ||
| 692 | |||
| 693 | /** | ||
| 694 | * Moves to next valid node and returns item to return for | ||
| 695 | * next(), or null if no such. | ||
| 696 | */ | ||
| 697 | private E advance() { | ||
| 698 | lastRet = nextNode; | ||
| 699 | E x = nextItem; | ||
| 700 | |||
| 701 | Node<E> pred, p; | ||
| 702 | if (nextNode == null) { | ||
| 703 | p = first(); | ||
| 704 | pred = null; | ||
| 705 | } else { | ||
| 706 | pred = nextNode; | ||
| 707 | p = succ(nextNode); | ||
| 708 | } | ||
| 709 | |||
| 710 | for (;;) { | ||
| 711 | if (p == null) { | ||
| 712 | nextNode = null; | ||
| 713 | nextItem = null; | ||
| 714 | return x; | ||
| 715 | } | ||
| 716 | E item = p.item; | ||
| 717 | if (item != null) { | ||
| 718 | nextNode = p; | ||
| 719 | nextItem = item; | ||
| 720 | return x; | ||
| 721 | } else { | ||
| 722 | // skip over nulls | ||
| 723 | Node<E> next = succ(p); | ||
| 724 | if (pred != null && next != null) | ||
| 725 | pred.casNext(p, next); | ||
| 726 | p = next; | ||
| 727 | } | ||
| 728 | } | ||
| 729 | } | ||
| 730 | |||
| 731 | public boolean hasNext() { | ||
| 732 | return nextNode != null; | ||
| 733 | } | ||
| 734 | |||
| 735 | public E next() { | ||
| 736 | if (nextNode == null) throw new NoSuchElementException(); | ||
| 737 | return advance(); | ||
| 738 | } | ||
| 739 | |||
| 740 | public void remove() { | ||
| 741 | Node<E> l = lastRet; | ||
| 742 | if (l == null) throw new IllegalStateException(); | ||
| 743 | // rely on a future traversal to relink. | ||
| 744 | l.item = null; | ||
| 745 | lastRet = null; | ||
| 746 | } | ||
| 747 | } | ||
| 748 | |||
| 749 | /** | ||
| 750 | * Saves the state to a stream (that is, serializes it). | ||
| 751 | * | ||
| 752 | * @serialData All of the elements (each an {@code E}) in | ||
| 753 | * the proper order, followed by a null | ||
| 754 | * @param s the stream | ||
| 755 | */ | ||
| 756 | private void writeObject(java.io.ObjectOutputStream s) | ||
| 757 | throws java.io.IOException { | ||
| 758 | |||
| 759 | // Write out any hidden stuff | ||
| 760 | s.defaultWriteObject(); | ||
| 761 | |||
| 762 | // Write out all elements in the proper order. | ||
| 763 | for (Node<E> p = first(); p != null; p = succ(p)) { | ||
| 764 | Object item = p.item; | ||
| 765 | if (item != null) | ||
| 766 | s.writeObject(item); | ||
| 767 | } | ||
| 768 | |||
| 769 | // Use trailing null as sentinel | ||
| 770 | s.writeObject(null); | ||
| 771 | } | ||
| 772 | |||
| 773 | /** | ||
| 774 | * Reconstitutes the instance from a stream (that is, deserializes it). | ||
| 775 | * @param s the stream | ||
| 776 | */ | ||
| 777 | private void readObject(java.io.ObjectInputStream s) | ||
| 778 | throws java.io.IOException, ClassNotFoundException { | ||
| 779 | s.defaultReadObject(); | ||
| 780 | |||
| 781 | // Read in elements until trailing null sentinel found | ||
| 782 | Node<E> h = null, t = null; | ||
| 783 | Object item; | ||
| 784 | while ((item = s.readObject()) != null) { | ||
| 785 | @SuppressWarnings("unchecked") | ||
| 786 | Node<E> newNode = new Node<E>((E) item); | ||
| 787 | if (h == null) | ||
| 788 | h = t = newNode; | ||
| 789 | else { | ||
| 790 | t.lazySetNext(newNode); | ||
| 791 | t = newNode; | ||
| 792 | } | ||
| 793 | } | ||
| 794 | if (h == null) | ||
| 795 | h = t = new Node<E>(null); | ||
| 796 | head = h; | ||
| 797 | tail = t; | ||
| 798 | } | ||
| 799 | |||
| 800 | /** | ||
| 801 | * Throws NullPointerException if argument is null. | ||
| 802 | * | ||
| 803 | * @param v the element | ||
| 804 | */ | ||
| 805 | private static void checkNotNull(Object v) { | ||
| 806 | if (v == null) | ||
| 807 | throw new NullPointerException(); | ||
| 808 | } | ||
| 809 | |||
| 810 | private boolean casTail(Node<E> cmp, Node<E> val) { | ||
| 811 | return UNSAFE.compareAndSwapObject(this, tailOffset, cmp, val); | ||
| 812 | } | ||
| 813 | |||
| 814 | private boolean casHead(Node<E> cmp, Node<E> val) { | ||
| 815 | return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val); | ||
| 816 | } | ||
| 817 | |||
| 818 | // Unsafe mechanics | ||
| 819 | |||
| 820 | private static final sun.misc.Unsafe UNSAFE; | ||
| 821 | private static final long headOffset; | ||
| 822 | private static final long tailOffset; | ||
| 823 | static { | ||
| 824 | try { | ||
| 825 | UNSAFE = sun.misc.Unsafe.getUnsafe(); | ||
| 826 | Class k = ConcurrentLinkedQueue.class; | ||
| 827 | headOffset = UNSAFE.objectFieldOffset | ||
| 828 | (k.getDeclaredField("head")); | ||
| 829 | tailOffset = UNSAFE.objectFieldOffset | ||
| 830 | (k.getDeclaredField("tail")); | ||
| 831 | } catch (Exception e) { | ||
| 832 | throw new Error(e); | ||
| 833 | } | ||
| 834 | } | ||
| 835 | } | ||
Binary file not shown.
| @@ -0,0 +1,165 @@ | |||
| 1 | /* | ||
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 3 | * | ||
| 4 | * This code is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License version 2 only, as | ||
| 6 | * published by the Free Software Foundation. Oracle designates this | ||
| 7 | * particular file as subject to the "Classpath" exception as provided | ||
| 8 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 9 | * | ||
| 10 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 13 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 14 | * accompanied this code). | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License version | ||
| 17 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | * | ||
| 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 21 | * or visit www.oracle.com if you need additional information or have any | ||
| 22 | * questions. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * This file is available under and governed by the GNU General Public | ||
| 27 | * License version 2 only, as published by the Free Software Foundation. | ||
| 28 | * However, the following notice accompanied the original version of this | ||
| 29 | * file: | ||
| 30 | * | ||
| 31 | * Written by Doug Lea with assistance from members of JCP JSR-166 | ||
| 32 | * Expert Group and released to the public domain, as explained at | ||
| 33 | * http://creativecommons.org/publicdomain/zero/1.0/ | ||
| 34 | */ | ||
| 35 | |||
| 36 | package java.util.concurrent; | ||
| 37 | import java.util.Map; | ||
| 38 | |||
| 39 | /** | ||
| 40 | * A {@link java.util.Map} providing additional atomic | ||
| 41 | * <tt>putIfAbsent</tt>, <tt>remove</tt>, and <tt>replace</tt> methods. | ||
| 42 | * | ||
| 43 | * <p>Memory consistency effects: As with other concurrent | ||
| 44 | * collections, actions in a thread prior to placing an object into a | ||
| 45 | * {@code ConcurrentMap} as a key or value | ||
| 46 | * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> | ||
| 47 | * actions subsequent to the access or removal of that object from | ||
| 48 | * the {@code ConcurrentMap} in another thread. | ||
| 49 | * | ||
| 50 | * <p>This interface is a member of the | ||
| 51 | * <a href="{@docRoot}/../technotes/guides/collections/index.html"> | ||
| 52 | * Java Collections Framework</a>. | ||
| 53 | * | ||
| 54 | * @since 1.5 | ||
| 55 | * @author Doug Lea | ||
| 56 | * @param <K> the type of keys maintained by this map | ||
| 57 | * @param <V> the type of mapped values | ||
| 58 | */ | ||
| 59 | public interface ConcurrentMap<K, V> extends Map<K, V> { | ||
| 60 | /** | ||
| 61 | * If the specified key is not already associated | ||
| 62 | * with a value, associate it with the given value. | ||
| 63 | * This is equivalent to | ||
| 64 | * <pre> | ||
| 65 | * if (!map.containsKey(key)) | ||
| 66 | * return map.put(key, value); | ||
| 67 | * else | ||
| 68 | * return map.get(key);</pre> | ||
| 69 | * except that the action is performed atomically. | ||
| 70 | * | ||
| 71 | * @param key key with which the specified value is to be associated | ||
| 72 | * @param value value to be associated with the specified key | ||
| 73 | * @return the previous value associated with the specified key, or | ||
| 74 | * <tt>null</tt> if there was no mapping for the key. | ||
| 75 | * (A <tt>null</tt> return can also indicate that the map | ||
| 76 | * previously associated <tt>null</tt> with the key, | ||
| 77 | * if the implementation supports null values.) | ||
| 78 | * @throws UnsupportedOperationException if the <tt>put</tt> operation | ||
| 79 | * is not supported by this map | ||
| 80 | * @throws ClassCastException if the class of the specified key or value | ||
| 81 | * prevents it from being stored in this map | ||
| 82 | * @throws NullPointerException if the specified key or value is null, | ||
| 83 | * and this map does not permit null keys or values | ||
| 84 | * @throws IllegalArgumentException if some property of the specified key | ||
| 85 | * or value prevents it from being stored in this map | ||
| 86 | * | ||
| 87 | */ | ||
| 88 | V putIfAbsent(K key, V value); | ||
| 89 | |||
| 90 | /** | ||
| 91 | * Removes the entry for a key only if currently mapped to a given value. | ||
| 92 | * This is equivalent to | ||
| 93 | * <pre> | ||
| 94 | * if (map.containsKey(key) && map.get(key).equals(value)) { | ||
| 95 | * map.remove(key); | ||
| 96 | * return true; | ||
| 97 | * } else return false;</pre> | ||
| 98 | * except that the action is performed atomically. | ||
| 99 | * | ||
| 100 | * @param key key with which the specified value is associated | ||
| 101 | * @param value value expected to be associated with the specified key | ||
| 102 | * @return <tt>true</tt> if the value was removed | ||
| 103 | * @throws UnsupportedOperationException if the <tt>remove</tt> operation | ||
| 104 | * is not supported by this map | ||
| 105 | * @throws ClassCastException if the key or value is of an inappropriate | ||
| 106 | * type for this map | ||
| 107 | * (<a href="../Collection.html#optional-restrictions">optional</a>) | ||
| 108 | * @throws NullPointerException if the specified key or value is null, | ||
| 109 | * and this map does not permit null keys or values | ||
| 110 | * (<a href="../Collection.html#optional-restrictions">optional</a>) | ||
| 111 | */ | ||
| 112 | boolean remove(Object key, Object value); | ||
| 113 | |||
| 114 | /** | ||
| 115 | * Replaces the entry for a key only if currently mapped to a given value. | ||
| 116 | * This is equivalent to | ||
| 117 | * <pre> | ||
| 118 | * if (map.containsKey(key) && map.get(key).equals(oldValue)) { | ||
| 119 | * map.put(key, newValue); | ||
| 120 | * return true; | ||
| 121 | * } else return false;</pre> | ||
| 122 | * except that the action is performed atomically. | ||
| 123 | * | ||
| 124 | * @param key key with which the specified value is associated | ||
| 125 | * @param oldValue value expected to be associated with the specified key | ||
| 126 | * @param newValue value to be associated with the specified key | ||
| 127 | * @return <tt>true</tt> if the value was replaced | ||
| 128 | * @throws UnsupportedOperationException if the <tt>put</tt> operation | ||
| 129 | * is not supported by this map | ||
| 130 | * @throws ClassCastException if the class of a specified key or value | ||
| 131 | * prevents it from being stored in this map | ||
| 132 | * @throws NullPointerException if a specified key or value is null, | ||
| 133 | * and this map does not permit null keys or values | ||
| 134 | * @throws IllegalArgumentException if some property of a specified key | ||
| 135 | * or value prevents it from being stored in this map | ||
| 136 | */ | ||
| 137 | boolean replace(K key, V oldValue, V newValue); | ||
| 138 | |||
| 139 | /** | ||
| 140 | * Replaces the entry for a key only if currently mapped to some value. | ||
| 141 | * This is equivalent to | ||
| 142 | * <pre> | ||
| 143 | * if (map.containsKey(key)) { | ||
| 144 | * return map.put(key, value); | ||
| 145 | * } else return null;</pre> | ||
| 146 | * except that the action is performed atomically. | ||
| 147 | * | ||
| 148 | * @param key key with which the specified value is associated | ||
| 149 | * @param value value to be associated with the specified key | ||
| 150 | * @return the previous value associated with the specified key, or | ||
| 151 | * <tt>null</tt> if there was no mapping for the key. | ||
| 152 | * (A <tt>null</tt> return can also indicate that the map | ||
| 153 | * previously associated <tt>null</tt> with the key, | ||
| 154 | * if the implementation supports null values.) | ||
| 155 | * @throws UnsupportedOperationException if the <tt>put</tt> operation | ||
| 156 | * is not supported by this map | ||
| 157 | * @throws ClassCastException if the class of the specified key or value | ||
| 158 | * prevents it from being stored in this map | ||
| 159 | * @throws NullPointerException if the specified key or value is null, | ||
| 160 | * and this map does not permit null keys or values | ||
| 161 | * @throws IllegalArgumentException if some property of the specified key | ||
| 162 | * or value prevents it from being stored in this map | ||
| 163 | */ | ||
| 164 | V replace(K key, V value); | ||
| 165 | } | ||
Binary file not shown.
| @@ -0,0 +1,177 @@ | |||
| 1 | /* | ||
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 3 | * | ||
| 4 | * This code is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License version 2 only, as | ||
| 6 | * published by the Free Software Foundation. Oracle designates this | ||
| 7 | * particular file as subject to the "Classpath" exception as provided | ||
| 8 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 9 | * | ||
| 10 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 13 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 14 | * accompanied this code). | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License version | ||
| 17 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | * | ||
| 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 21 | * or visit www.oracle.com if you need additional information or have any | ||
| 22 | * questions. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * This file is available under and governed by the GNU General Public | ||
| 27 | * License version 2 only, as published by the Free Software Foundation. | ||
| 28 | * However, the following notice accompanied the original version of this | ||
| 29 | * file: | ||
| 30 | * | ||
| 31 | * Written by Doug Lea with assistance from members of JCP JSR-166 | ||
| 32 | * Expert Group and released to the public domain, as explained at | ||
| 33 | * http://creativecommons.org/publicdomain/zero/1.0/ | ||
| 34 | */ | ||
| 35 | |||
| 36 | package java.util.concurrent; | ||
| 37 | import java.util.*; | ||
| 38 | |||
| 39 | /** | ||
| 40 | * A {@link ConcurrentMap} supporting {@link NavigableMap} operations, | ||
| 41 | * and recursively so for its navigable sub-maps. | ||
| 42 | * | ||
| 43 | * <p>This interface is a member of the | ||
| 44 | * <a href="{@docRoot}/../technotes/guides/collections/index.html"> | ||
| 45 | * Java Collections Framework</a>. | ||
| 46 | * | ||
| 47 | * @author Doug Lea | ||
| 48 | * @param <K> the type of keys maintained by this map | ||
| 49 | * @param <V> the type of mapped values | ||
| 50 | * @since 1.6 | ||
| 51 | */ | ||
| 52 | public interface ConcurrentNavigableMap<K,V> | ||
| 53 | extends ConcurrentMap<K,V>, NavigableMap<K,V> | ||
| 54 | { | ||
| 55 | /** | ||
| 56 | * @throws ClassCastException {@inheritDoc} | ||
| 57 | * @throws NullPointerException {@inheritDoc} | ||
| 58 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 59 | */ | ||
| 60 | ConcurrentNavigableMap<K,V> subMap(K fromKey, boolean fromInclusive, | ||
| 61 | K toKey, boolean toInclusive); | ||
| 62 | |||
| 63 | /** | ||
| 64 | * @throws ClassCastException {@inheritDoc} | ||
| 65 | * @throws NullPointerException {@inheritDoc} | ||
| 66 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 67 | */ | ||
| 68 | ConcurrentNavigableMap<K,V> headMap(K toKey, boolean inclusive); | ||
| 69 | |||
| 70 | |||
| 71 | /** | ||
| 72 | * @throws ClassCastException {@inheritDoc} | ||
| 73 | * @throws NullPointerException {@inheritDoc} | ||
| 74 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 75 | */ | ||
| 76 | ConcurrentNavigableMap<K,V> tailMap(K fromKey, boolean inclusive); | ||
| 77 | |||
| 78 | /** | ||
| 79 | * @throws ClassCastException {@inheritDoc} | ||
| 80 | * @throws NullPointerException {@inheritDoc} | ||
| 81 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 82 | */ | ||
| 83 | ConcurrentNavigableMap<K,V> subMap(K fromKey, K toKey); | ||
| 84 | |||
| 85 | /** | ||
| 86 | * @throws ClassCastException {@inheritDoc} | ||
| 87 | * @throws NullPointerException {@inheritDoc} | ||
| 88 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 89 | */ | ||
| 90 | ConcurrentNavigableMap<K,V> headMap(K toKey); | ||
| 91 | |||
| 92 | /** | ||
| 93 | * @throws ClassCastException {@inheritDoc} | ||
| 94 | * @throws NullPointerException {@inheritDoc} | ||
| 95 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 96 | */ | ||
| 97 | ConcurrentNavigableMap<K,V> tailMap(K fromKey); | ||
| 98 | |||
| 99 | /** | ||
| 100 | * Returns a reverse order view of the mappings contained in this map. | ||
| 101 | * The descending map is backed by this map, so changes to the map are | ||
| 102 | * reflected in the descending map, and vice-versa. | ||
| 103 | * | ||
| 104 | * <p>The returned map has an ordering equivalent to | ||
| 105 | * <tt>{@link Collections#reverseOrder(Comparator) Collections.reverseOrder}(comparator())</tt>. | ||
| 106 | * The expression {@code m.descendingMap().descendingMap()} returns a | ||
| 107 | * view of {@code m} essentially equivalent to {@code m}. | ||
| 108 | * | ||
| 109 | * @return a reverse order view of this map | ||
| 110 | */ | ||
| 111 | ConcurrentNavigableMap<K,V> descendingMap(); | ||
| 112 | |||
| 113 | /** | ||
| 114 | * Returns a {@link NavigableSet} view of the keys contained in this map. | ||
| 115 | * The set's iterator returns the keys in ascending order. | ||
| 116 | * The set is backed by the map, so changes to the map are | ||
| 117 | * reflected in the set, and vice-versa. The set supports element | ||
| 118 | * removal, which removes the corresponding mapping from the map, | ||
| 119 | * via the {@code Iterator.remove}, {@code Set.remove}, | ||
| 120 | * {@code removeAll}, {@code retainAll}, and {@code clear} | ||
| 121 | * operations. It does not support the {@code add} or {@code addAll} | ||
| 122 | * operations. | ||
| 123 | * | ||
| 124 | * <p>The view's {@code iterator} is a "weakly consistent" iterator | ||
| 125 | * that will never throw {@link ConcurrentModificationException}, | ||
| 126 | * and guarantees to traverse elements as they existed upon | ||
| 127 | * construction of the iterator, and may (but is not guaranteed to) | ||
| 128 | * reflect any modifications subsequent to construction. | ||
| 129 | * | ||
| 130 | * @return a navigable set view of the keys in this map | ||
| 131 | */ | ||
| 132 | public NavigableSet<K> navigableKeySet(); | ||
| 133 | |||
| 134 | /** | ||
| 135 | * Returns a {@link NavigableSet} view of the keys contained in this map. | ||
| 136 | * The set's iterator returns the keys in ascending order. | ||
| 137 | * The set is backed by the map, so changes to the map are | ||
| 138 | * reflected in the set, and vice-versa. The set supports element | ||
| 139 | * removal, which removes the corresponding mapping from the map, | ||
| 140 | * via the {@code Iterator.remove}, {@code Set.remove}, | ||
| 141 | * {@code removeAll}, {@code retainAll}, and {@code clear} | ||
| 142 | * operations. It does not support the {@code add} or {@code addAll} | ||
| 143 | * operations. | ||
| 144 | * | ||
| 145 | * <p>The view's {@code iterator} is a "weakly consistent" iterator | ||
| 146 | * that will never throw {@link ConcurrentModificationException}, | ||
| 147 | * and guarantees to traverse elements as they existed upon | ||
| 148 | * construction of the iterator, and may (but is not guaranteed to) | ||
| 149 | * reflect any modifications subsequent to construction. | ||
| 150 | * | ||
| 151 | * <p>This method is equivalent to method {@code navigableKeySet}. | ||
| 152 | * | ||
| 153 | * @return a navigable set view of the keys in this map | ||
| 154 | */ | ||
| 155 | NavigableSet<K> keySet(); | ||
| 156 | |||
| 157 | /** | ||
| 158 | * Returns a reverse order {@link NavigableSet} view of the keys contained in this map. | ||
| 159 | * The set's iterator returns the keys in descending order. | ||
| 160 | * The set is backed by the map, so changes to the map are | ||
| 161 | * reflected in the set, and vice-versa. The set supports element | ||
| 162 | * removal, which removes the corresponding mapping from the map, | ||
| 163 | * via the {@code Iterator.remove}, {@code Set.remove}, | ||
| 164 | * {@code removeAll}, {@code retainAll}, and {@code clear} | ||
| 165 | * operations. It does not support the {@code add} or {@code addAll} | ||
| 166 | * operations. | ||
| 167 | * | ||
| 168 | * <p>The view's {@code iterator} is a "weakly consistent" iterator | ||
| 169 | * that will never throw {@link ConcurrentModificationException}, | ||
| 170 | * and guarantees to traverse elements as they existed upon | ||
| 171 | * construction of the iterator, and may (but is not guaranteed to) | ||
| 172 | * reflect any modifications subsequent to construction. | ||
| 173 | * | ||
| 174 | * @return a reverse order navigable set view of the keys in this map | ||
| 175 | */ | ||
| 176 | public NavigableSet<K> descendingKeySet(); | ||
| 177 | } | ||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,3119 @@ | |||
| 1 | /* | ||
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 3 | * | ||
| 4 | * This code is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License version 2 only, as | ||
| 6 | * published by the Free Software Foundation. Oracle designates this | ||
| 7 | * particular file as subject to the "Classpath" exception as provided | ||
| 8 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 9 | * | ||
| 10 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 13 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 14 | * accompanied this code). | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License version | ||
| 17 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | * | ||
| 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 21 | * or visit www.oracle.com if you need additional information or have any | ||
| 22 | * questions. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * This file is available under and governed by the GNU General Public | ||
| 27 | * License version 2 only, as published by the Free Software Foundation. | ||
| 28 | * However, the following notice accompanied the original version of this | ||
| 29 | * file: | ||
| 30 | * | ||
| 31 | * Written by Doug Lea with assistance from members of JCP JSR-166 | ||
| 32 | * Expert Group and released to the public domain, as explained at | ||
| 33 | * http://creativecommons.org/publicdomain/zero/1.0/ | ||
| 34 | */ | ||
| 35 | |||
| 36 | package java.util.concurrent; | ||
| 37 | import java.util.*; | ||
| 38 | import java.util.concurrent.atomic.*; | ||
| 39 | |||
| 40 | /** | ||
| 41 | * A scalable concurrent {@link ConcurrentNavigableMap} implementation. | ||
| 42 | * The map is sorted according to the {@linkplain Comparable natural | ||
| 43 | * ordering} of its keys, or by a {@link Comparator} provided at map | ||
| 44 | * creation time, depending on which constructor is used. | ||
| 45 | * | ||
| 46 | * <p>This class implements a concurrent variant of <a | ||
| 47 | * href="http://en.wikipedia.org/wiki/Skip_list" target="_top">SkipLists</a> | ||
| 48 | * providing expected average <i>log(n)</i> time cost for the | ||
| 49 | * <tt>containsKey</tt>, <tt>get</tt>, <tt>put</tt> and | ||
| 50 | * <tt>remove</tt> operations and their variants. Insertion, removal, | ||
| 51 | * update, and access operations safely execute concurrently by | ||
| 52 | * multiple threads. Iterators are <i>weakly consistent</i>, returning | ||
| 53 | * elements reflecting the state of the map at some point at or since | ||
| 54 | * the creation of the iterator. They do <em>not</em> throw {@link | ||
| 55 | * ConcurrentModificationException}, and may proceed concurrently with | ||
| 56 | * other operations. Ascending key ordered views and their iterators | ||
| 57 | * are faster than descending ones. | ||
| 58 | * | ||
| 59 | * <p>All <tt>Map.Entry</tt> pairs returned by methods in this class | ||
| 60 | * and its views represent snapshots of mappings at the time they were | ||
| 61 | * produced. They do <em>not</em> support the <tt>Entry.setValue</tt> | ||
| 62 | * method. (Note however that it is possible to change mappings in the | ||
| 63 | * associated map using <tt>put</tt>, <tt>putIfAbsent</tt>, or | ||
| 64 | * <tt>replace</tt>, depending on exactly which effect you need.) | ||
| 65 | * | ||
| 66 | * <p>Beware that, unlike in most collections, the <tt>size</tt> | ||
| 67 | * method is <em>not</em> a constant-time operation. Because of the | ||
| 68 | * asynchronous nature of these maps, determining the current number | ||
| 69 | * of elements requires a traversal of the elements, and so may report | ||
| 70 | * inaccurate results if this collection is modified during traversal. | ||
| 71 | * Additionally, the bulk operations <tt>putAll</tt>, <tt>equals</tt>, | ||
| 72 | * <tt>toArray</tt>, <tt>containsValue</tt>, and <tt>clear</tt> are | ||
| 73 | * <em>not</em> guaranteed to be performed atomically. For example, an | ||
| 74 | * iterator operating concurrently with a <tt>putAll</tt> operation | ||
| 75 | * might view only some of the added elements. | ||
| 76 | * | ||
| 77 | * <p>This class and its views and iterators implement all of the | ||
| 78 | * <em>optional</em> methods of the {@link Map} and {@link Iterator} | ||
| 79 | * interfaces. Like most other concurrent collections, this class does | ||
| 80 | * <em>not</em> permit the use of <tt>null</tt> keys or values because some | ||
| 81 | * null return values cannot be reliably distinguished from the absence of | ||
| 82 | * elements. | ||
| 83 | * | ||
| 84 | * <p>This class is a member of the | ||
| 85 | * <a href="{@docRoot}/../technotes/guides/collections/index.html"> | ||
| 86 | * Java Collections Framework</a>. | ||
| 87 | * | ||
| 88 | * @author Doug Lea | ||
| 89 | * @param <K> the type of keys maintained by this map | ||
| 90 | * @param <V> the type of mapped values | ||
| 91 | * @since 1.6 | ||
| 92 | */ | ||
| 93 | public class ConcurrentSkipListMap<K,V> extends AbstractMap<K,V> | ||
| 94 | implements ConcurrentNavigableMap<K,V>, | ||
| 95 | Cloneable, | ||
| 96 | java.io.Serializable { | ||
| 97 | /* | ||
| 98 | * This class implements a tree-like two-dimensionally linked skip | ||
| 99 | * list in which the index levels are represented in separate | ||
| 100 | * nodes from the base nodes holding data. There are two reasons | ||
| 101 | * for taking this approach instead of the usual array-based | ||
| 102 | * structure: 1) Array based implementations seem to encounter | ||
| 103 | * more complexity and overhead 2) We can use cheaper algorithms | ||
| 104 | * for the heavily-traversed index lists than can be used for the | ||
| 105 | * base lists. Here's a picture of some of the basics for a | ||
| 106 | * possible list with 2 levels of index: | ||
| 107 | * | ||
| 108 | * Head nodes Index nodes | ||
| 109 | * +-+ right +-+ +-+ | ||
| 110 | * |2|---------------->| |--------------------->| |->null | ||
| 111 | * +-+ +-+ +-+ | ||
| 112 | * | down | | | ||
| 113 | * v v v | ||
| 114 | * +-+ +-+ +-+ +-+ +-+ +-+ | ||
| 115 | * |1|----------->| |->| |------>| |----------->| |------>| |->null | ||
| 116 | * +-+ +-+ +-+ +-+ +-+ +-+ | ||
| 117 | * v | | | | | | ||
| 118 | * Nodes next v v v v v | ||
| 119 | * +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ | ||
| 120 | * | |->|A|->|B|->|C|->|D|->|E|->|F|->|G|->|H|->|I|->|J|->|K|->null | ||
| 121 | * +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ | ||
| 122 | * | ||
| 123 | * The base lists use a variant of the HM linked ordered set | ||
| 124 | * algorithm. See Tim Harris, "A pragmatic implementation of | ||
| 125 | * non-blocking linked lists" | ||
| 126 | * http://www.cl.cam.ac.uk/~tlh20/publications.html and Maged | ||
| 127 | * Michael "High Performance Dynamic Lock-Free Hash Tables and | ||
| 128 | * List-Based Sets" | ||
| 129 | * http://www.research.ibm.com/people/m/michael/pubs.htm. The | ||
| 130 | * basic idea in these lists is to mark the "next" pointers of | ||
| 131 | * deleted nodes when deleting to avoid conflicts with concurrent | ||
| 132 | * insertions, and when traversing to keep track of triples | ||
| 133 | * (predecessor, node, successor) in order to detect when and how | ||
| 134 | * to unlink these deleted nodes. | ||
| 135 | * | ||
| 136 | * Rather than using mark-bits to mark list deletions (which can | ||
| 137 | * be slow and space-intensive using AtomicMarkedReference), nodes | ||
| 138 | * use direct CAS'able next pointers. On deletion, instead of | ||
| 139 | * marking a pointer, they splice in another node that can be | ||
| 140 | * thought of as standing for a marked pointer (indicating this by | ||
| 141 | * using otherwise impossible field values). Using plain nodes | ||
| 142 | * acts roughly like "boxed" implementations of marked pointers, | ||
| 143 | * but uses new nodes only when nodes are deleted, not for every | ||
| 144 | * link. This requires less space and supports faster | ||
| 145 | * traversal. Even if marked references were better supported by | ||
| 146 | * JVMs, traversal using this technique might still be faster | ||
| 147 | * because any search need only read ahead one more node than | ||
| 148 | * otherwise required (to check for trailing marker) rather than | ||
| 149 | * unmasking mark bits or whatever on each read. | ||
| 150 | * | ||
| 151 | * This approach maintains the essential property needed in the HM | ||
| 152 | * algorithm of changing the next-pointer of a deleted node so | ||
| 153 | * that any other CAS of it will fail, but implements the idea by | ||
| 154 | * changing the pointer to point to a different node, not by | ||
| 155 | * marking it. While it would be possible to further squeeze | ||
| 156 | * space by defining marker nodes not to have key/value fields, it | ||
| 157 | * isn't worth the extra type-testing overhead. The deletion | ||
| 158 | * markers are rarely encountered during traversal and are | ||
| 159 | * normally quickly garbage collected. (Note that this technique | ||
| 160 | * would not work well in systems without garbage collection.) | ||
| 161 | * | ||
| 162 | * In addition to using deletion markers, the lists also use | ||
| 163 | * nullness of value fields to indicate deletion, in a style | ||
| 164 | * similar to typical lazy-deletion schemes. If a node's value is | ||
| 165 | * null, then it is considered logically deleted and ignored even | ||
| 166 | * though it is still reachable. This maintains proper control of | ||
| 167 | * concurrent replace vs delete operations -- an attempted replace | ||
| 168 | * must fail if a delete beat it by nulling field, and a delete | ||
| 169 | * must return the last non-null value held in the field. (Note: | ||
| 170 | * Null, rather than some special marker, is used for value fields | ||
| 171 | * here because it just so happens to mesh with the Map API | ||
| 172 | * requirement that method get returns null if there is no | ||
| 173 | * mapping, which allows nodes to remain concurrently readable | ||
| 174 | * even when deleted. Using any other marker value here would be | ||
| 175 | * messy at best.) | ||
| 176 | * | ||
| 177 | * Here's the sequence of events for a deletion of node n with | ||
| 178 | * predecessor b and successor f, initially: | ||
| 179 | * | ||
| 180 | * +------+ +------+ +------+ | ||
| 181 | * ... | b |------>| n |----->| f | ... | ||
| 182 | * +------+ +------+ +------+ | ||
| 183 | * | ||
| 184 | * 1. CAS n's value field from non-null to null. | ||
| 185 | * From this point on, no public operations encountering | ||
| 186 | * the node consider this mapping to exist. However, other | ||
| 187 | * ongoing insertions and deletions might still modify | ||
| 188 | * n's next pointer. | ||
| 189 | * | ||
| 190 | * 2. CAS n's next pointer to point to a new marker node. | ||
| 191 | * From this point on, no other nodes can be appended to n. | ||
| 192 | * which avoids deletion errors in CAS-based linked lists. | ||
| 193 | * | ||
| 194 | * +------+ +------+ +------+ +------+ | ||
| 195 | * ... | b |------>| n |----->|marker|------>| f | ... | ||
| 196 | * +------+ +------+ +------+ +------+ | ||
| 197 | * | ||
| 198 | * 3. CAS b's next pointer over both n and its marker. | ||
| 199 | * From this point on, no new traversals will encounter n, | ||
| 200 | * and it can eventually be GCed. | ||
| 201 | * +------+ +------+ | ||
| 202 | * ... | b |----------------------------------->| f | ... | ||
| 203 | * +------+ +------+ | ||
| 204 | * | ||
| 205 | * A failure at step 1 leads to simple retry due to a lost race | ||
| 206 | * with another operation. Steps 2-3 can fail because some other | ||
| 207 | * thread noticed during a traversal a node with null value and | ||
| 208 | * helped out by marking and/or unlinking. This helping-out | ||
| 209 | * ensures that no thread can become stuck waiting for progress of | ||
| 210 | * the deleting thread. The use of marker nodes slightly | ||
| 211 | * complicates helping-out code because traversals must track | ||
| 212 | * consistent reads of up to four nodes (b, n, marker, f), not | ||
| 213 | * just (b, n, f), although the next field of a marker is | ||
| 214 | * immutable, and once a next field is CAS'ed to point to a | ||
| 215 | * marker, it never again changes, so this requires less care. | ||
| 216 | * | ||
| 217 | * Skip lists add indexing to this scheme, so that the base-level | ||
| 218 | * traversals start close to the locations being found, inserted | ||
| 219 | * or deleted -- usually base level traversals only traverse a few | ||
| 220 | * nodes. This doesn't change the basic algorithm except for the | ||
| 221 | * need to make sure base traversals start at predecessors (here, | ||
| 222 | * b) that are not (structurally) deleted, otherwise retrying | ||
| 223 | * after processing the deletion. | ||
| 224 | * | ||
| 225 | * Index levels are maintained as lists with volatile next fields, | ||
| 226 | * using CAS to link and unlink. Races are allowed in index-list | ||
| 227 | * operations that can (rarely) fail to link in a new index node | ||
| 228 | * or delete one. (We can't do this of course for data nodes.) | ||
| 229 | * However, even when this happens, the index lists remain sorted, | ||
| 230 | * so correctly serve as indices. This can impact performance, | ||
| 231 | * but since skip lists are probabilistic anyway, the net result | ||
| 232 | * is that under contention, the effective "p" value may be lower | ||
| 233 | * than its nominal value. And race windows are kept small enough | ||
| 234 | * that in practice these failures are rare, even under a lot of | ||
| 235 | * contention. | ||
| 236 | * | ||
| 237 | * The fact that retries (for both base and index lists) are | ||
| 238 | * relatively cheap due to indexing allows some minor | ||
| 239 | * simplifications of retry logic. Traversal restarts are | ||
| 240 | * performed after most "helping-out" CASes. This isn't always | ||
| 241 | * strictly necessary, but the implicit backoffs tend to help | ||
| 242 | * reduce other downstream failed CAS's enough to outweigh restart | ||
| 243 | * cost. This worsens the worst case, but seems to improve even | ||
| 244 | * highly contended cases. | ||
| 245 | * | ||
| 246 | * Unlike most skip-list implementations, index insertion and | ||
| 247 | * deletion here require a separate traversal pass occuring after | ||
| 248 | * the base-level action, to add or remove index nodes. This adds | ||
| 249 | * to single-threaded overhead, but improves contended | ||
| 250 | * multithreaded performance by narrowing interference windows, | ||
| 251 | * and allows deletion to ensure that all index nodes will be made | ||
| 252 | * unreachable upon return from a public remove operation, thus | ||
| 253 | * avoiding unwanted garbage retention. This is more important | ||
| 254 | * here than in some other data structures because we cannot null | ||
| 255 | * out node fields referencing user keys since they might still be | ||
| 256 | * read by other ongoing traversals. | ||
| 257 | * | ||
| 258 | * Indexing uses skip list parameters that maintain good search | ||
| 259 | * performance while using sparser-than-usual indices: The | ||
| 260 | * hardwired parameters k=1, p=0.5 (see method randomLevel) mean | ||
| 261 | * that about one-quarter of the nodes have indices. Of those that | ||
| 262 | * do, half have one level, a quarter have two, and so on (see | ||
| 263 | * Pugh's Skip List Cookbook, sec 3.4). The expected total space | ||
| 264 | * requirement for a map is slightly less than for the current | ||
| 265 | * implementation of java.util.TreeMap. | ||
| 266 | * | ||
| 267 | * Changing the level of the index (i.e, the height of the | ||
| 268 | * tree-like structure) also uses CAS. The head index has initial | ||
| 269 | * level/height of one. Creation of an index with height greater | ||
| 270 | * than the current level adds a level to the head index by | ||
| 271 | * CAS'ing on a new top-most head. To maintain good performance | ||
| 272 | * after a lot of removals, deletion methods heuristically try to | ||
| 273 | * reduce the height if the topmost levels appear to be empty. | ||
| 274 | * This may encounter races in which it possible (but rare) to | ||
| 275 | * reduce and "lose" a level just as it is about to contain an | ||
| 276 | * index (that will then never be encountered). This does no | ||
| 277 | * structural harm, and in practice appears to be a better option | ||
| 278 | * than allowing unrestrained growth of levels. | ||
| 279 | * | ||
| 280 | * The code for all this is more verbose than you'd like. Most | ||
| 281 | * operations entail locating an element (or position to insert an | ||
| 282 | * element). The code to do this can't be nicely factored out | ||
| 283 | * because subsequent uses require a snapshot of predecessor | ||
| 284 | * and/or successor and/or value fields which can't be returned | ||
| 285 | * all at once, at least not without creating yet another object | ||
| 286 | * to hold them -- creating such little objects is an especially | ||
| 287 | * bad idea for basic internal search operations because it adds | ||
| 288 | * to GC overhead. (This is one of the few times I've wished Java | ||
| 289 | * had macros.) Instead, some traversal code is interleaved within | ||
| 290 | * insertion and removal operations. The control logic to handle | ||
| 291 | * all the retry conditions is sometimes twisty. Most search is | ||
| 292 | * broken into 2 parts. findPredecessor() searches index nodes | ||
| 293 | * only, returning a base-level predecessor of the key. findNode() | ||
| 294 | * finishes out the base-level search. Even with this factoring, | ||
| 295 | * there is a fair amount of near-duplication of code to handle | ||
| 296 | * variants. | ||
| 297 | * | ||
| 298 | * For explanation of algorithms sharing at least a couple of | ||
| 299 | * features with this one, see Mikhail Fomitchev's thesis | ||
| 300 | * (http://www.cs.yorku.ca/~mikhail/), Keir Fraser's thesis | ||
| 301 | * (http://www.cl.cam.ac.uk/users/kaf24/), and Hakan Sundell's | ||
| 302 | * thesis (http://www.cs.chalmers.se/~phs/). | ||
| 303 | * | ||
| 304 | * Given the use of tree-like index nodes, you might wonder why | ||
| 305 | * this doesn't use some kind of search tree instead, which would | ||
| 306 | * support somewhat faster search operations. The reason is that | ||
| 307 | * there are no known efficient lock-free insertion and deletion | ||
| 308 | * algorithms for search trees. The immutability of the "down" | ||
| 309 | * links of index nodes (as opposed to mutable "left" fields in | ||
| 310 | * true trees) makes this tractable using only CAS operations. | ||
| 311 | * | ||
| 312 | * Notation guide for local variables | ||
| 313 | * Node: b, n, f for predecessor, node, successor | ||
| 314 | * Index: q, r, d for index node, right, down. | ||
| 315 | * t for another index node | ||
| 316 | * Head: h | ||
| 317 | * Levels: j | ||
| 318 | * Keys: k, key | ||
| 319 | * Values: v, value | ||
| 320 | * Comparisons: c | ||
| 321 | */ | ||
| 322 | |||
| 323 | private static final long serialVersionUID = -8627078645895051609L; | ||
| 324 | |||
| 325 | /** | ||
| 326 | * Generates the initial random seed for the cheaper per-instance | ||
| 327 | * random number generators used in randomLevel. | ||
| 328 | */ | ||
| 329 | private static final Random seedGenerator = new Random(); | ||
| 330 | |||
| 331 | /** | ||
| 332 | * Special value used to identify base-level header | ||
| 333 | */ | ||
| 334 | private static final Object BASE_HEADER = new Object(); | ||
| 335 | |||
| 336 | /** | ||
| 337 | * The topmost head index of the skiplist. | ||
| 338 | */ | ||
| 339 | private transient volatile HeadIndex<K,V> head; | ||
| 340 | |||
| 341 | /** | ||
| 342 | * The comparator used to maintain order in this map, or null | ||
| 343 | * if using natural ordering. | ||
| 344 | * @serial | ||
| 345 | */ | ||
| 346 | private final Comparator<? super K> comparator; | ||
| 347 | |||
| 348 | /** | ||
| 349 | * Seed for simple random number generator. Not volatile since it | ||
| 350 | * doesn't matter too much if different threads don't see updates. | ||
| 351 | */ | ||
| 352 | private transient int randomSeed; | ||
| 353 | |||
| 354 | /** Lazily initialized key set */ | ||
| 355 | private transient KeySet keySet; | ||
| 356 | /** Lazily initialized entry set */ | ||
| 357 | private transient EntrySet entrySet; | ||
| 358 | /** Lazily initialized values collection */ | ||
| 359 | private transient Values values; | ||
| 360 | /** Lazily initialized descending key set */ | ||
| 361 | private transient ConcurrentNavigableMap<K,V> descendingMap; | ||
| 362 | |||
| 363 | /** | ||
| 364 | * Initializes or resets state. Needed by constructors, clone, | ||
| 365 | * clear, readObject. and ConcurrentSkipListSet.clone. | ||
| 366 | * (Note that comparator must be separately initialized.) | ||
| 367 | */ | ||
| 368 | final void initialize() { | ||
| 369 | keySet = null; | ||
| 370 | entrySet = null; | ||
| 371 | values = null; | ||
| 372 | descendingMap = null; | ||
| 373 | randomSeed = seedGenerator.nextInt() | 0x0100; // ensure nonzero | ||
| 374 | head = new HeadIndex<K,V>(new Node<K,V>(null, BASE_HEADER, null), | ||
| 375 | null, null, 1); | ||
| 376 | } | ||
| 377 | |||
| 378 | /** | ||
| 379 | * compareAndSet head node | ||
| 380 | */ | ||
| 381 | private boolean casHead(HeadIndex<K,V> cmp, HeadIndex<K,V> val) { | ||
| 382 | return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val); | ||
| 383 | } | ||
| 384 | |||
| 385 | /* ---------------- Nodes -------------- */ | ||
| 386 | |||
| 387 | /** | ||
| 388 | * Nodes hold keys and values, and are singly linked in sorted | ||
| 389 | * order, possibly with some intervening marker nodes. The list is | ||
| 390 | * headed by a dummy node accessible as head.node. The value field | ||
| 391 | * is declared only as Object because it takes special non-V | ||
| 392 | * values for marker and header nodes. | ||
| 393 | */ | ||
| 394 | static final class Node<K,V> { | ||
| 395 | final K key; | ||
| 396 | volatile Object value; | ||
| 397 | volatile Node<K,V> next; | ||
| 398 | |||
| 399 | /** | ||
| 400 | * Creates a new regular node. | ||
| 401 | */ | ||
| 402 | Node(K key, Object value, Node<K,V> next) { | ||
| 403 | this.key = key; | ||
| 404 | this.value = value; | ||
| 405 | this.next = next; | ||
| 406 | } | ||
| 407 | |||
| 408 | /** | ||
| 409 | * Creates a new marker node. A marker is distinguished by | ||
| 410 | * having its value field point to itself. Marker nodes also | ||
| 411 | * have null keys, a fact that is exploited in a few places, | ||
| 412 | * but this doesn't distinguish markers from the base-level | ||
| 413 | * header node (head.node), which also has a null key. | ||
| 414 | */ | ||
| 415 | Node(Node<K,V> next) { | ||
| 416 | this.key = null; | ||
| 417 | this.value = this; | ||
| 418 | this.next = next; | ||
| 419 | } | ||
| 420 | |||
| 421 | /** | ||
| 422 | * compareAndSet value field | ||
| 423 | */ | ||
| 424 | boolean casValue(Object cmp, Object val) { | ||
| 425 | return UNSAFE.compareAndSwapObject(this, valueOffset, cmp, val); | ||
| 426 | } | ||
| 427 | |||
| 428 | /** | ||
| 429 | * compareAndSet next field | ||
| 430 | */ | ||
| 431 | boolean casNext(Node<K,V> cmp, Node<K,V> val) { | ||
| 432 | return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val); | ||
| 433 | } | ||
| 434 | |||
| 435 | /** | ||
| 436 | * Returns true if this node is a marker. This method isn't | ||
| 437 | * actually called in any current code checking for markers | ||
| 438 | * because callers will have already read value field and need | ||
| 439 | * to use that read (not another done here) and so directly | ||
| 440 | * test if value points to node. | ||
| 441 | * @param n a possibly null reference to a node | ||
| 442 | * @return true if this node is a marker node | ||
| 443 | */ | ||
| 444 | boolean isMarker() { | ||
| 445 | return value == this; | ||
| 446 | } | ||
| 447 | |||
| 448 | /** | ||
| 449 | * Returns true if this node is the header of base-level list. | ||
| 450 | * @return true if this node is header node | ||
| 451 | */ | ||
| 452 | boolean isBaseHeader() { | ||
| 453 | return value == BASE_HEADER; | ||
| 454 | } | ||
| 455 | |||
| 456 | /** | ||
| 457 | * Tries to append a deletion marker to this node. | ||
| 458 | * @param f the assumed current successor of this node | ||
| 459 | * @return true if successful | ||
| 460 | */ | ||
| 461 | boolean appendMarker(Node<K,V> f) { | ||
| 462 | return casNext(f, new Node<K,V>(f)); | ||
| 463 | } | ||
| 464 | |||
| 465 | /** | ||
| 466 | * Helps out a deletion by appending marker or unlinking from | ||
| 467 | * predecessor. This is called during traversals when value | ||
| 468 | * field seen to be null. | ||
| 469 | * @param b predecessor | ||
| 470 | * @param f successor | ||
| 471 | */ | ||
| 472 | void helpDelete(Node<K,V> b, Node<K,V> f) { | ||
| 473 | /* | ||
| 474 | * Rechecking links and then doing only one of the | ||
| 475 | * help-out stages per call tends to minimize CAS | ||
| 476 | * interference among helping threads. | ||
| 477 | */ | ||
| 478 | if (f == next && this == b.next) { | ||
| 479 | if (f == null || f.value != f) // not already marked | ||
| 480 | appendMarker(f); | ||
| 481 | else | ||
| 482 | b.casNext(this, f.next); | ||
| 483 | } | ||
| 484 | } | ||
| 485 | |||
| 486 | /** | ||
| 487 | * Returns value if this node contains a valid key-value pair, | ||
| 488 | * else null. | ||
| 489 | * @return this node's value if it isn't a marker or header or | ||
| 490 | * is deleted, else null. | ||
| 491 | */ | ||
| 492 | V getValidValue() { | ||
| 493 | Object v = value; | ||
| 494 | if (v == this || v == BASE_HEADER) | ||
| 495 | return null; | ||
| 496 | return (V)v; | ||
| 497 | } | ||
| 498 | |||
| 499 | /** | ||
| 500 | * Creates and returns a new SimpleImmutableEntry holding current | ||
| 501 | * mapping if this node holds a valid value, else null. | ||
| 502 | * @return new entry or null | ||
| 503 | */ | ||
| 504 | AbstractMap.SimpleImmutableEntry<K,V> createSnapshot() { | ||
| 505 | V v = getValidValue(); | ||
| 506 | if (v == null) | ||
| 507 | return null; | ||
| 508 | return new AbstractMap.SimpleImmutableEntry<K,V>(key, v); | ||
| 509 | } | ||
| 510 | |||
| 511 | // UNSAFE mechanics | ||
| 512 | |||
| 513 | private static final sun.misc.Unsafe UNSAFE; | ||
| 514 | private static final long valueOffset; | ||
| 515 | private static final long nextOffset; | ||
| 516 | |||
| 517 | static { | ||
| 518 | try { | ||
| 519 | UNSAFE = sun.misc.Unsafe.getUnsafe(); | ||
| 520 | Class k = Node.class; | ||
| 521 | valueOffset = UNSAFE.objectFieldOffset | ||
| 522 | (k.getDeclaredField("value")); | ||
| 523 | nextOffset = UNSAFE.objectFieldOffset | ||
| 524 | (k.getDeclaredField("next")); | ||
| 525 | } catch (Exception e) { | ||
| 526 | throw new Error(e); | ||
| 527 | } | ||
| 528 | } | ||
| 529 | } | ||
| 530 | |||
| 531 | /* ---------------- Indexing -------------- */ | ||
| 532 | |||
| 533 | /** | ||
| 534 | * Index nodes represent the levels of the skip list. Note that | ||
| 535 | * even though both Nodes and Indexes have forward-pointing | ||
| 536 | * fields, they have different types and are handled in different | ||
| 537 | * ways, that can't nicely be captured by placing field in a | ||
| 538 | * shared abstract class. | ||
| 539 | */ | ||
| 540 | static class Index<K,V> { | ||
| 541 | final Node<K,V> node; | ||
| 542 | final Index<K,V> down; | ||
| 543 | volatile Index<K,V> right; | ||
| 544 | |||
| 545 | /** | ||
| 546 | * Creates index node with given values. | ||
| 547 | */ | ||
| 548 | Index(Node<K,V> node, Index<K,V> down, Index<K,V> right) { | ||
| 549 | this.node = node; | ||
| 550 | this.down = down; | ||
| 551 | this.right = right; | ||
| 552 | } | ||
| 553 | |||
| 554 | /** | ||
| 555 | * compareAndSet right field | ||
| 556 | */ | ||
| 557 | final boolean casRight(Index<K,V> cmp, Index<K,V> val) { | ||
| 558 | return UNSAFE.compareAndSwapObject(this, rightOffset, cmp, val); | ||
| 559 | } | ||
| 560 | |||
| 561 | /** | ||
| 562 | * Returns true if the node this indexes has been deleted. | ||
| 563 | * @return true if indexed node is known to be deleted | ||
| 564 | */ | ||
| 565 | final boolean indexesDeletedNode() { | ||
| 566 | return node.value == null; | ||
| 567 | } | ||
| 568 | |||
| 569 | /** | ||
| 570 | * Tries to CAS newSucc as successor. To minimize races with | ||
| 571 | * unlink that may lose this index node, if the node being | ||
| 572 | * indexed is known to be deleted, it doesn't try to link in. | ||
| 573 | * @param succ the expected current successor | ||
| 574 | * @param newSucc the new successor | ||
| 575 | * @return true if successful | ||
| 576 | */ | ||
| 577 | final boolean link(Index<K,V> succ, Index<K,V> newSucc) { | ||
| 578 | Node<K,V> n = node; | ||
| 579 | newSucc.right = succ; | ||
| 580 | return n.value != null && casRight(succ, newSucc); | ||
| 581 | } | ||
| 582 | |||
| 583 | /** | ||
| 584 | * Tries to CAS right field to skip over apparent successor | ||
| 585 | * succ. Fails (forcing a retraversal by caller) if this node | ||
| 586 | * is known to be deleted. | ||
| 587 | * @param succ the expected current successor | ||
| 588 | * @return true if successful | ||
| 589 | */ | ||
| 590 | final boolean unlink(Index<K,V> succ) { | ||
| 591 | return !indexesDeletedNode() && casRight(succ, succ.right); | ||
| 592 | } | ||
| 593 | |||
| 594 | // Unsafe mechanics | ||
| 595 | private static final sun.misc.Unsafe UNSAFE; | ||
| 596 | private static final long rightOffset; | ||
| 597 | static { | ||
| 598 | try { | ||
| 599 | UNSAFE = sun.misc.Unsafe.getUnsafe(); | ||
| 600 | Class k = Index.class; | ||
| 601 | rightOffset = UNSAFE.objectFieldOffset | ||
| 602 | (k.getDeclaredField("right")); | ||
| 603 | } catch (Exception e) { | ||
| 604 | throw new Error(e); | ||
| 605 | } | ||
| 606 | } | ||
| 607 | } | ||
| 608 | |||
| 609 | /* ---------------- Head nodes -------------- */ | ||
| 610 | |||
| 611 | /** | ||
| 612 | * Nodes heading each level keep track of their level. | ||
| 613 | */ | ||
| 614 | static final class HeadIndex<K,V> extends Index<K,V> { | ||
| 615 | final int level; | ||
| 616 | HeadIndex(Node<K,V> node, Index<K,V> down, Index<K,V> right, int level) { | ||
| 617 | super(node, down, right); | ||
| 618 | this.level = level; | ||
| 619 | } | ||
| 620 | } | ||
| 621 | |||
| 622 | /* ---------------- Comparison utilities -------------- */ | ||
| 623 | |||
| 624 | /** | ||
| 625 | * Represents a key with a comparator as a Comparable. | ||
| 626 | * | ||
| 627 | * Because most sorted collections seem to use natural ordering on | ||
| 628 | * Comparables (Strings, Integers, etc), most internal methods are | ||
| 629 | * geared to use them. This is generally faster than checking | ||
| 630 | * per-comparison whether to use comparator or comparable because | ||
| 631 | * it doesn't require a (Comparable) cast for each comparison. | ||
| 632 | * (Optimizers can only sometimes remove such redundant checks | ||
| 633 | * themselves.) When Comparators are used, | ||
| 634 | * ComparableUsingComparators are created so that they act in the | ||
| 635 | * same way as natural orderings. This penalizes use of | ||
| 636 | * Comparators vs Comparables, which seems like the right | ||
| 637 | * tradeoff. | ||
| 638 | */ | ||
| 639 | static final class ComparableUsingComparator<K> implements Comparable<K> { | ||
| 640 | final K actualKey; | ||
| 641 | final Comparator<? super K> cmp; | ||
| 642 | ComparableUsingComparator(K key, Comparator<? super K> cmp) { | ||
| 643 | this.actualKey = key; | ||
| 644 | this.cmp = cmp; | ||
| 645 | } | ||
| 646 | public int compareTo(K k2) { | ||
| 647 | return cmp.compare(actualKey, k2); | ||
| 648 | } | ||
| 649 | } | ||
| 650 | |||
| 651 | /** | ||
| 652 | * If using comparator, return a ComparableUsingComparator, else | ||
| 653 | * cast key as Comparable, which may cause ClassCastException, | ||
| 654 | * which is propagated back to caller. | ||
| 655 | */ | ||
| 656 | private Comparable<? super K> comparable(Object key) | ||
| 657 | throws ClassCastException { | ||
| 658 | if (key == null) | ||
| 659 | throw new NullPointerException(); | ||
| 660 | if (comparator != null) | ||
| 661 | return new ComparableUsingComparator<K>((K)key, comparator); | ||
| 662 | else | ||
| 663 | return (Comparable<? super K>)key; | ||
| 664 | } | ||
| 665 | |||
| 666 | /** | ||
| 667 | * Compares using comparator or natural ordering. Used when the | ||
| 668 | * ComparableUsingComparator approach doesn't apply. | ||
| 669 | */ | ||
| 670 | int compare(K k1, K k2) throws ClassCastException { | ||
| 671 | Comparator<? super K> cmp = comparator; | ||
| 672 | if (cmp != null) | ||
| 673 | return cmp.compare(k1, k2); | ||
| 674 | else | ||
| 675 | return ((Comparable<? super K>)k1).compareTo(k2); | ||
| 676 | } | ||
| 677 | |||
| 678 | /** | ||
| 679 | * Returns true if given key greater than or equal to least and | ||
| 680 | * strictly less than fence, bypassing either test if least or | ||
| 681 | * fence are null. Needed mainly in submap operations. | ||
| 682 | */ | ||
| 683 | boolean inHalfOpenRange(K key, K least, K fence) { | ||
| 684 | if (key == null) | ||
| 685 | throw new NullPointerException(); | ||
| 686 | return ((least == null || compare(key, least) >= 0) && | ||
| 687 | (fence == null || compare(key, fence) < 0)); | ||
| 688 | } | ||
| 689 | |||
| 690 | /** | ||
| 691 | * Returns true if given key greater than or equal to least and less | ||
| 692 | * or equal to fence. Needed mainly in submap operations. | ||
| 693 | */ | ||
| 694 | boolean inOpenRange(K key, K least, K fence) { | ||
| 695 | if (key == null) | ||
| 696 | throw new NullPointerException(); | ||
| 697 | return ((least == null || compare(key, least) >= 0) && | ||
| 698 | (fence == null || compare(key, fence) <= 0)); | ||
| 699 | } | ||
| 700 | |||
| 701 | /* ---------------- Traversal -------------- */ | ||
| 702 | |||
| 703 | /** | ||
| 704 | * Returns a base-level node with key strictly less than given key, | ||
| 705 | * or the base-level header if there is no such node. Also | ||
| 706 | * unlinks indexes to deleted nodes found along the way. Callers | ||
| 707 | * rely on this side-effect of clearing indices to deleted nodes. | ||
| 708 | * @param key the key | ||
| 709 | * @return a predecessor of key | ||
| 710 | */ | ||
| 711 | private Node<K,V> findPredecessor(Comparable<? super K> key) { | ||
| 712 | if (key == null) | ||
| 713 | throw new NullPointerException(); // don't postpone errors | ||
| 714 | for (;;) { | ||
| 715 | Index<K,V> q = head; | ||
| 716 | Index<K,V> r = q.right; | ||
| 717 | for (;;) { | ||
| 718 | if (r != null) { | ||
| 719 | Node<K,V> n = r.node; | ||
| 720 | K k = n.key; | ||
| 721 | if (n.value == null) { | ||
| 722 | if (!q.unlink(r)) | ||
| 723 | break; // restart | ||
| 724 | r = q.right; // reread r | ||
| 725 | continue; | ||
| 726 | } | ||
| 727 | if (key.compareTo(k) > 0) { | ||
| 728 | q = r; | ||
| 729 | r = r.right; | ||
| 730 | continue; | ||
| 731 | } | ||
| 732 | } | ||
| 733 | Index<K,V> d = q.down; | ||
| 734 | if (d != null) { | ||
| 735 | q = d; | ||
| 736 | r = d.right; | ||
| 737 | } else | ||
| 738 | return q.node; | ||
| 739 | } | ||
| 740 | } | ||
| 741 | } | ||
| 742 | |||
| 743 | /** | ||
| 744 | * Returns node holding key or null if no such, clearing out any | ||
| 745 | * deleted nodes seen along the way. Repeatedly traverses at | ||
| 746 | * base-level looking for key starting at predecessor returned | ||
| 747 | * from findPredecessor, processing base-level deletions as | ||
| 748 | * encountered. Some callers rely on this side-effect of clearing | ||
| 749 | * deleted nodes. | ||
| 750 | * | ||
| 751 | * Restarts occur, at traversal step centered on node n, if: | ||
| 752 | * | ||
| 753 | * (1) After reading n's next field, n is no longer assumed | ||
| 754 | * predecessor b's current successor, which means that | ||
| 755 | * we don't have a consistent 3-node snapshot and so cannot | ||
| 756 | * unlink any subsequent deleted nodes encountered. | ||
| 757 | * | ||
| 758 | * (2) n's value field is null, indicating n is deleted, in | ||
| 759 | * which case we help out an ongoing structural deletion | ||
| 760 | * before retrying. Even though there are cases where such | ||
| 761 | * unlinking doesn't require restart, they aren't sorted out | ||
| 762 | * here because doing so would not usually outweigh cost of | ||
| 763 | * restarting. | ||
| 764 | * | ||
| 765 | * (3) n is a marker or n's predecessor's value field is null, | ||
| 766 | * indicating (among other possibilities) that | ||
| 767 | * findPredecessor returned a deleted node. We can't unlink | ||
| 768 | * the node because we don't know its predecessor, so rely | ||
| 769 | * on another call to findPredecessor to notice and return | ||
| 770 | * some earlier predecessor, which it will do. This check is | ||
| 771 | * only strictly needed at beginning of loop, (and the | ||
| 772 | * b.value check isn't strictly needed at all) but is done | ||
| 773 | * each iteration to help avoid contention with other | ||
| 774 | * threads by callers that will fail to be able to change | ||
| 775 | * links, and so will retry anyway. | ||
| 776 | * | ||
| 777 | * The traversal loops in doPut, doRemove, and findNear all | ||
| 778 | * include the same three kinds of checks. And specialized | ||
| 779 | * versions appear in findFirst, and findLast and their | ||
| 780 | * variants. They can't easily share code because each uses the | ||
| 781 | * reads of fields held in locals occurring in the orders they | ||
| 782 | * were performed. | ||
| 783 | * | ||
| 784 | * @param key the key | ||
| 785 | * @return node holding key, or null if no such | ||
| 786 | */ | ||
| 787 | private Node<K,V> findNode(Comparable<? super K> key) { | ||
| 788 | for (;;) { | ||
| 789 | Node<K,V> b = findPredecessor(key); | ||
| 790 | Node<K,V> n = b.next; | ||
| 791 | for (;;) { | ||
| 792 | if (n == null) | ||
| 793 | return null; | ||
| 794 | Node<K,V> f = n.next; | ||
| 795 | if (n != b.next) // inconsistent read | ||
| 796 | break; | ||
| 797 | Object v = n.value; | ||
| 798 | if (v == null) { // n is deleted | ||
| 799 | n.helpDelete(b, f); | ||
| 800 | break; | ||
| 801 | } | ||
| 802 | if (v == n || b.value == null) // b is deleted | ||
| 803 | break; | ||
| 804 | int c = key.compareTo(n.key); | ||
| 805 | if (c == 0) | ||
| 806 | return n; | ||
| 807 | if (c < 0) | ||
| 808 | return null; | ||
| 809 | b = n; | ||
| 810 | n = f; | ||
| 811 | } | ||
| 812 | } | ||
| 813 | } | ||
| 814 | |||
| 815 | /** | ||
| 816 | * Gets value for key using findNode. | ||
| 817 | * @param okey the key | ||
| 818 | * @return the value, or null if absent | ||
| 819 | */ | ||
| 820 | private V doGet(Object okey) { | ||
| 821 | Comparable<? super K> key = comparable(okey); | ||
| 822 | /* | ||
| 823 | * Loop needed here and elsewhere in case value field goes | ||
| 824 | * null just as it is about to be returned, in which case we | ||
| 825 | * lost a race with a deletion, so must retry. | ||
| 826 | */ | ||
| 827 | for (;;) { | ||
| 828 | Node<K,V> n = findNode(key); | ||
| 829 | if (n == null) | ||
| 830 | return null; | ||
| 831 | Object v = n.value; | ||
| 832 | if (v != null) | ||
| 833 | return (V)v; | ||
| 834 | } | ||
| 835 | } | ||
| 836 | |||
| 837 | /* ---------------- Insertion -------------- */ | ||
| 838 | |||
| 839 | /** | ||
| 840 | * Main insertion method. Adds element if not present, or | ||
| 841 | * replaces value if present and onlyIfAbsent is false. | ||
| 842 | * @param kkey the key | ||
| 843 | * @param value the value that must be associated with key | ||
| 844 | * @param onlyIfAbsent if should not insert if already present | ||
| 845 | * @return the old value, or null if newly inserted | ||
| 846 | */ | ||
| 847 | private V doPut(K kkey, V value, boolean onlyIfAbsent) { | ||
| 848 | Comparable<? super K> key = comparable(kkey); | ||
| 849 | for (;;) { | ||
| 850 | Node<K,V> b = findPredecessor(key); | ||
| 851 | Node<K,V> n = b.next; | ||
| 852 | for (;;) { | ||
| 853 | if (n != null) { | ||
| 854 | Node<K,V> f = n.next; | ||
| 855 | if (n != b.next) // inconsistent read | ||
| 856 | break; | ||
| 857 | Object v = n.value; | ||
| 858 | if (v == null) { // n is deleted | ||
| 859 | n.helpDelete(b, f); | ||
| 860 | break; | ||
| 861 | } | ||
| 862 | if (v == n || b.value == null) // b is deleted | ||
| 863 | break; | ||
| 864 | int c = key.compareTo(n.key); | ||
| 865 | if (c > 0) { | ||
| 866 | b = n; | ||
| 867 | n = f; | ||
| 868 | continue; | ||
| 869 | } | ||
| 870 | if (c == 0) { | ||
| 871 | if (onlyIfAbsent || n.casValue(v, value)) | ||
| 872 | return (V)v; | ||
| 873 | else | ||
| 874 | break; // restart if lost race to replace value | ||
| 875 | } | ||
| 876 | // else c < 0; fall through | ||
| 877 | } | ||
| 878 | |||
| 879 | Node<K,V> z = new Node<K,V>(kkey, value, n); | ||
| 880 | if (!b.casNext(n, z)) | ||
| 881 | break; // restart if lost race to append to b | ||
| 882 | int level = randomLevel(); | ||
| 883 | if (level > 0) | ||
| 884 | insertIndex(z, level); | ||
| 885 | return null; | ||
| 886 | } | ||
| 887 | } | ||
| 888 | } | ||
| 889 | |||
| 890 | /** | ||
| 891 | * Returns a random level for inserting a new node. | ||
| 892 | * Hardwired to k=1, p=0.5, max 31 (see above and | ||
| 893 | * Pugh's "Skip List Cookbook", sec 3.4). | ||
| 894 | * | ||
| 895 | * This uses the simplest of the generators described in George | ||
| 896 | * Marsaglia's "Xorshift RNGs" paper. This is not a high-quality | ||
| 897 | * generator but is acceptable here. | ||
| 898 | */ | ||
| 899 | private int randomLevel() { | ||
| 900 | int x = randomSeed; | ||
| 901 | x ^= x << 13; | ||
| 902 | x ^= x >>> 17; | ||
| 903 | randomSeed = x ^= x << 5; | ||
| 904 | if ((x & 0x80000001) != 0) // test highest and lowest bits | ||
| 905 | return 0; | ||
| 906 | int level = 1; | ||
| 907 | while (((x >>>= 1) & 1) != 0) ++level; | ||
| 908 | return level; | ||
| 909 | } | ||
| 910 | |||
| 911 | /** | ||
| 912 | * Creates and adds index nodes for the given node. | ||
| 913 | * @param z the node | ||
| 914 | * @param level the level of the index | ||
| 915 | */ | ||
| 916 | private void insertIndex(Node<K,V> z, int level) { | ||
| 917 | HeadIndex<K,V> h = head; | ||
| 918 | int max = h.level; | ||
| 919 | |||
| 920 | if (level <= max) { | ||
| 921 | Index<K,V> idx = null; | ||
| 922 | for (int i = 1; i <= level; ++i) | ||
| 923 | idx = new Index<K,V>(z, idx, null); | ||
| 924 | addIndex(idx, h, level); | ||
| 925 | |||
| 926 | } else { // Add a new level | ||
| 927 | /* | ||
| 928 | * To reduce interference by other threads checking for | ||
| 929 | * empty levels in tryReduceLevel, new levels are added | ||
| 930 | * with initialized right pointers. Which in turn requires | ||
| 931 | * keeping levels in an array to access them while | ||
| 932 | * creating new head index nodes from the opposite | ||
| 933 | * direction. | ||
| 934 | */ | ||
| 935 | level = max + 1; | ||
| 936 | Index<K,V>[] idxs = (Index<K,V>[])new Index[level+1]; | ||
| 937 | Index<K,V> idx = null; | ||
| 938 | for (int i = 1; i <= level; ++i) | ||
| 939 | idxs[i] = idx = new Index<K,V>(z, idx, null); | ||
| 940 | |||
| 941 | HeadIndex<K,V> oldh; | ||
| 942 | int k; | ||
| 943 | for (;;) { | ||
| 944 | oldh = head; | ||
| 945 | int oldLevel = oldh.level; | ||
| 946 | if (level <= oldLevel) { // lost race to add level | ||
| 947 | k = level; | ||
| 948 | break; | ||
| 949 | } | ||
| 950 | HeadIndex<K,V> newh = oldh; | ||
| 951 | Node<K,V> oldbase = oldh.node; | ||
| 952 | for (int j = oldLevel+1; j <= level; ++j) | ||
| 953 | newh = new HeadIndex<K,V>(oldbase, newh, idxs[j], j); | ||
| 954 | if (casHead(oldh, newh)) { | ||
| 955 | k = oldLevel; | ||
| 956 | break; | ||
| 957 | } | ||
| 958 | } | ||
| 959 | addIndex(idxs[k], oldh, k); | ||
| 960 | } | ||
| 961 | } | ||
| 962 | |||
| 963 | /** | ||
| 964 | * Adds given index nodes from given level down to 1. | ||
| 965 | * @param idx the topmost index node being inserted | ||
| 966 | * @param h the value of head to use to insert. This must be | ||
| 967 | * snapshotted by callers to provide correct insertion level | ||
| 968 | * @param indexLevel the level of the index | ||
| 969 | */ | ||
| 970 | private void addIndex(Index<K,V> idx, HeadIndex<K,V> h, int indexLevel) { | ||
| 971 | // Track next level to insert in case of retries | ||
| 972 | int insertionLevel = indexLevel; | ||
| 973 | Comparable<? super K> key = comparable(idx.node.key); | ||
| 974 | if (key == null) throw new NullPointerException(); | ||
| 975 | |||
| 976 | // Similar to findPredecessor, but adding index nodes along | ||
| 977 | // path to key. | ||
| 978 | for (;;) { | ||
| 979 | int j = h.level; | ||
| 980 | Index<K,V> q = h; | ||
| 981 | Index<K,V> r = q.right; | ||
| 982 | Index<K,V> t = idx; | ||
| 983 | for (;;) { | ||
| 984 | if (r != null) { | ||
| 985 | Node<K,V> n = r.node; | ||
| 986 | // compare before deletion check avoids needing recheck | ||
| 987 | int c = key.compareTo(n.key); | ||
| 988 | if (n.value == null) { | ||
| 989 | if (!q.unlink(r)) | ||
| 990 | break; | ||
| 991 | r = q.right; | ||
| 992 | continue; | ||
| 993 | } | ||
| 994 | if (c > 0) { | ||
| 995 | q = r; | ||
| 996 | r = r.right; | ||
| 997 | continue; | ||
| 998 | } | ||
| 999 | } | ||
| 1000 | |||
| 1001 | if (j == insertionLevel) { | ||
| 1002 | // Don't insert index if node already deleted | ||
| 1003 | if (t.indexesDeletedNode()) { | ||
| 1004 | findNode(key); // cleans up | ||
| 1005 | return; | ||
| 1006 | } | ||
| 1007 | if (!q.link(r, t)) | ||
| 1008 | break; // restart | ||
| 1009 | if (--insertionLevel == 0) { | ||
| 1010 | // need final deletion check before return | ||
| 1011 | if (t.indexesDeletedNode()) | ||
| 1012 | findNode(key); | ||
| 1013 | return; | ||
| 1014 | } | ||
| 1015 | } | ||
| 1016 | |||
| 1017 | if (--j >= insertionLevel && j < indexLevel) | ||
| 1018 | t = t.down; | ||
| 1019 | q = q.down; | ||
| 1020 | r = q.right; | ||
| 1021 | } | ||
| 1022 | } | ||
| 1023 | } | ||
| 1024 | |||
| 1025 | /* ---------------- Deletion -------------- */ | ||
| 1026 | |||
| 1027 | /** | ||
| 1028 | * Main deletion method. Locates node, nulls value, appends a | ||
| 1029 | * deletion marker, unlinks predecessor, removes associated index | ||
| 1030 | * nodes, and possibly reduces head index level. | ||
| 1031 | * | ||
| 1032 | * Index nodes are cleared out simply by calling findPredecessor. | ||
| 1033 | * which unlinks indexes to deleted nodes found along path to key, | ||
| 1034 | * which will include the indexes to this node. This is done | ||
| 1035 | * unconditionally. We can't check beforehand whether there are | ||
| 1036 | * index nodes because it might be the case that some or all | ||
| 1037 | * indexes hadn't been inserted yet for this node during initial | ||
| 1038 | * search for it, and we'd like to ensure lack of garbage | ||
| 1039 | * retention, so must call to be sure. | ||
| 1040 | * | ||
| 1041 | * @param okey the key | ||
| 1042 | * @param value if non-null, the value that must be | ||
| 1043 | * associated with key | ||
| 1044 | * @return the node, or null if not found | ||
| 1045 | */ | ||
| 1046 | final V doRemove(Object okey, Object value) { | ||
| 1047 | Comparable<? super K> key = comparable(okey); | ||
| 1048 | for (;;) { | ||
| 1049 | Node<K,V> b = findPredecessor(key); | ||
| 1050 | Node<K,V> n = b.next; | ||
| 1051 | for (;;) { | ||
| 1052 | if (n == null) | ||
| 1053 | return null; | ||
| 1054 | Node<K,V> f = n.next; | ||
| 1055 | if (n != b.next) // inconsistent read | ||
| 1056 | break; | ||
| 1057 | Object v = n.value; | ||
| 1058 | if (v == null) { // n is deleted | ||
| 1059 | n.helpDelete(b, f); | ||
| 1060 | break; | ||
| 1061 | } | ||
| 1062 | if (v == n || b.value == null) // b is deleted | ||
| 1063 | break; | ||
| 1064 | int c = key.compareTo(n.key); | ||
| 1065 | if (c < 0) | ||
| 1066 | return null; | ||
| 1067 | if (c > 0) { | ||
| 1068 | b = n; | ||
| 1069 | n = f; | ||
| 1070 | continue; | ||
| 1071 | } | ||
| 1072 | if (value != null && !value.equals(v)) | ||
| 1073 | return null; | ||
| 1074 | if (!n.casValue(v, null)) | ||
| 1075 | break; | ||
| 1076 | if (!n.appendMarker(f) || !b.casNext(n, f)) | ||
| 1077 | findNode(key); // Retry via findNode | ||
| 1078 | else { | ||
| 1079 | findPredecessor(key); // Clean index | ||
| 1080 | if (head.right == null) | ||
| 1081 | tryReduceLevel(); | ||
| 1082 | } | ||
| 1083 | return (V)v; | ||
| 1084 | } | ||
| 1085 | } | ||
| 1086 | } | ||
| 1087 | |||
| 1088 | /** | ||
| 1089 | * Possibly reduce head level if it has no nodes. This method can | ||
| 1090 | * (rarely) make mistakes, in which case levels can disappear even | ||
| 1091 | * though they are about to contain index nodes. This impacts | ||
| 1092 | * performance, not correctness. To minimize mistakes as well as | ||
| 1093 | * to reduce hysteresis, the level is reduced by one only if the | ||
| 1094 | * topmost three levels look empty. Also, if the removed level | ||
| 1095 | * looks non-empty after CAS, we try to change it back quick | ||
| 1096 | * before anyone notices our mistake! (This trick works pretty | ||
| 1097 | * well because this method will practically never make mistakes | ||
| 1098 | * unless current thread stalls immediately before first CAS, in | ||
| 1099 | * which case it is very unlikely to stall again immediately | ||
| 1100 | * afterwards, so will recover.) | ||
| 1101 | * | ||
| 1102 | * We put up with all this rather than just let levels grow | ||
| 1103 | * because otherwise, even a small map that has undergone a large | ||
| 1104 | * number of insertions and removals will have a lot of levels, | ||
| 1105 | * slowing down access more than would an occasional unwanted | ||
| 1106 | * reduction. | ||
| 1107 | */ | ||
| 1108 | private void tryReduceLevel() { | ||
| 1109 | HeadIndex<K,V> h = head; | ||
| 1110 | HeadIndex<K,V> d; | ||
| 1111 | HeadIndex<K,V> e; | ||
| 1112 | if (h.level > 3 && | ||
| 1113 | (d = (HeadIndex<K,V>)h.down) != null && | ||
| 1114 | (e = (HeadIndex<K,V>)d.down) != null && | ||
| 1115 | e.right == null && | ||
| 1116 | d.right == null && | ||
| 1117 | h.right == null && | ||
| 1118 | casHead(h, d) && // try to set | ||
| 1119 | h.right != null) // recheck | ||
| 1120 | casHead(d, h); // try to backout | ||
| 1121 | } | ||
| 1122 | |||
| 1123 | /* ---------------- Finding and removing first element -------------- */ | ||
| 1124 | |||
| 1125 | /** | ||
| 1126 | * Specialized variant of findNode to get first valid node. | ||
| 1127 | * @return first node or null if empty | ||
| 1128 | */ | ||
| 1129 | Node<K,V> findFirst() { | ||
| 1130 | for (;;) { | ||
| 1131 | Node<K,V> b = head.node; | ||
| 1132 | Node<K,V> n = b.next; | ||
| 1133 | if (n == null) | ||
| 1134 | return null; | ||
| 1135 | if (n.value != null) | ||
| 1136 | return n; | ||
| 1137 | n.helpDelete(b, n.next); | ||
| 1138 | } | ||
| 1139 | } | ||
| 1140 | |||
| 1141 | /** | ||
| 1142 | * Removes first entry; returns its snapshot. | ||
| 1143 | * @return null if empty, else snapshot of first entry | ||
| 1144 | */ | ||
| 1145 | Map.Entry<K,V> doRemoveFirstEntry() { | ||
| 1146 | for (;;) { | ||
| 1147 | Node<K,V> b = head.node; | ||
| 1148 | Node<K,V> n = b.next; | ||
| 1149 | if (n == null) | ||
| 1150 | return null; | ||
| 1151 | Node<K,V> f = n.next; | ||
| 1152 | if (n != b.next) | ||
| 1153 | continue; | ||
| 1154 | Object v = n.value; | ||
| 1155 | if (v == null) { | ||
| 1156 | n.helpDelete(b, f); | ||
| 1157 | continue; | ||
| 1158 | } | ||
| 1159 | if (!n.casValue(v, null)) | ||
| 1160 | continue; | ||
| 1161 | if (!n.appendMarker(f) || !b.casNext(n, f)) | ||
| 1162 | findFirst(); // retry | ||
| 1163 | clearIndexToFirst(); | ||
| 1164 | return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, (V)v); | ||
| 1165 | } | ||
| 1166 | } | ||
| 1167 | |||
| 1168 | /** | ||
| 1169 | * Clears out index nodes associated with deleted first entry. | ||
| 1170 | */ | ||
| 1171 | private void clearIndexToFirst() { | ||
| 1172 | for (;;) { | ||
| 1173 | Index<K,V> q = head; | ||
| 1174 | for (;;) { | ||
| 1175 | Index<K,V> r = q.right; | ||
| 1176 | if (r != null && r.indexesDeletedNode() && !q.unlink(r)) | ||
| 1177 | break; | ||
| 1178 | if ((q = q.down) == null) { | ||
| 1179 | if (head.right == null) | ||
| 1180 | tryReduceLevel(); | ||
| 1181 | return; | ||
| 1182 | } | ||
| 1183 | } | ||
| 1184 | } | ||
| 1185 | } | ||
| 1186 | |||
| 1187 | |||
| 1188 | /* ---------------- Finding and removing last element -------------- */ | ||
| 1189 | |||
| 1190 | /** | ||
| 1191 | * Specialized version of find to get last valid node. | ||
| 1192 | * @return last node or null if empty | ||
| 1193 | */ | ||
| 1194 | Node<K,V> findLast() { | ||
| 1195 | /* | ||
| 1196 | * findPredecessor can't be used to traverse index level | ||
| 1197 | * because this doesn't use comparisons. So traversals of | ||
| 1198 | * both levels are folded together. | ||
| 1199 | */ | ||
| 1200 | Index<K,V> q = head; | ||
| 1201 | for (;;) { | ||
| 1202 | Index<K,V> d, r; | ||
| 1203 | if ((r = q.right) != null) { | ||
| 1204 | if (r.indexesDeletedNode()) { | ||
| 1205 | q.unlink(r); | ||
| 1206 | q = head; // restart | ||
| 1207 | } | ||
| 1208 | else | ||
| 1209 | q = r; | ||
| 1210 | } else if ((d = q.down) != null) { | ||
| 1211 | q = d; | ||
| 1212 | } else { | ||
| 1213 | Node<K,V> b = q.node; | ||
| 1214 | Node<K,V> n = b.next; | ||
| 1215 | for (;;) { | ||
| 1216 | if (n == null) | ||
| 1217 | return b.isBaseHeader() ? null : b; | ||
| 1218 | Node<K,V> f = n.next; // inconsistent read | ||
| 1219 | if (n != b.next) | ||
| 1220 | break; | ||
| 1221 | Object v = n.value; | ||
| 1222 | if (v == null) { // n is deleted | ||
| 1223 | n.helpDelete(b, f); | ||
| 1224 | break; | ||
| 1225 | } | ||
| 1226 | if (v == n || b.value == null) // b is deleted | ||
| 1227 | break; | ||
| 1228 | b = n; | ||
| 1229 | n = f; | ||
| 1230 | } | ||
| 1231 | q = head; // restart | ||
| 1232 | } | ||
| 1233 | } | ||
| 1234 | } | ||
| 1235 | |||
| 1236 | /** | ||
| 1237 | * Specialized variant of findPredecessor to get predecessor of last | ||
| 1238 | * valid node. Needed when removing the last entry. It is possible | ||
| 1239 | * that all successors of returned node will have been deleted upon | ||
| 1240 | * return, in which case this method can be retried. | ||
| 1241 | * @return likely predecessor of last node | ||
| 1242 | */ | ||
| 1243 | private Node<K,V> findPredecessorOfLast() { | ||
| 1244 | for (;;) { | ||
| 1245 | Index<K,V> q = head; | ||
| 1246 | for (;;) { | ||
| 1247 | Index<K,V> d, r; | ||
| 1248 | if ((r = q.right) != null) { | ||
| 1249 | if (r.indexesDeletedNode()) { | ||
| 1250 | q.unlink(r); | ||
| 1251 | break; // must restart | ||
| 1252 | } | ||
| 1253 | // proceed as far across as possible without overshooting | ||
| 1254 | if (r.node.next != null) { | ||
| 1255 | q = r; | ||
| 1256 | continue; | ||
| 1257 | } | ||
| 1258 | } | ||
| 1259 | if ((d = q.down) != null) | ||
| 1260 | q = d; | ||
| 1261 | else | ||
| 1262 | return q.node; | ||
| 1263 | } | ||
| 1264 | } | ||
| 1265 | } | ||
| 1266 | |||
| 1267 | /** | ||
| 1268 | * Removes last entry; returns its snapshot. | ||
| 1269 | * Specialized variant of doRemove. | ||
| 1270 | * @return null if empty, else snapshot of last entry | ||
| 1271 | */ | ||
| 1272 | Map.Entry<K,V> doRemoveLastEntry() { | ||
| 1273 | for (;;) { | ||
| 1274 | Node<K,V> b = findPredecessorOfLast(); | ||
| 1275 | Node<K,V> n = b.next; | ||
| 1276 | if (n == null) { | ||
| 1277 | if (b.isBaseHeader()) // empty | ||
| 1278 | return null; | ||
| 1279 | else | ||
| 1280 | continue; // all b's successors are deleted; retry | ||
| 1281 | } | ||
| 1282 | for (;;) { | ||
| 1283 | Node<K,V> f = n.next; | ||
| 1284 | if (n != b.next) // inconsistent read | ||
| 1285 | break; | ||
| 1286 | Object v = n.value; | ||
| 1287 | if (v == null) { // n is deleted | ||
| 1288 | n.helpDelete(b, f); | ||
| 1289 | break; | ||
| 1290 | } | ||
| 1291 | if (v == n || b.value == null) // b is deleted | ||
| 1292 | break; | ||
| 1293 | if (f != null) { | ||
| 1294 | b = n; | ||
| 1295 | n = f; | ||
| 1296 | continue; | ||
| 1297 | } | ||
| 1298 | if (!n.casValue(v, null)) | ||
| 1299 | break; | ||
| 1300 | K key = n.key; | ||
| 1301 | Comparable<? super K> ck = comparable(key); | ||
| 1302 | if (!n.appendMarker(f) || !b.casNext(n, f)) | ||
| 1303 | findNode(ck); // Retry via findNode | ||
| 1304 | else { | ||
| 1305 | findPredecessor(ck); // Clean index | ||
| 1306 | if (head.right == null) | ||
| 1307 | tryReduceLevel(); | ||
| 1308 | } | ||
| 1309 | return new AbstractMap.SimpleImmutableEntry<K,V>(key, (V)v); | ||
| 1310 | } | ||
| 1311 | } | ||
| 1312 | } | ||
| 1313 | |||
| 1314 | /* ---------------- Relational operations -------------- */ | ||
| 1315 | |||
| 1316 | // Control values OR'ed as arguments to findNear | ||
| 1317 | |||
| 1318 | private static final int EQ = 1; | ||
| 1319 | private static final int LT = 2; | ||
| 1320 | private static final int GT = 0; // Actually checked as !LT | ||
| 1321 | |||
| 1322 | /** | ||
| 1323 | * Utility for ceiling, floor, lower, higher methods. | ||
| 1324 | * @param kkey the key | ||
| 1325 | * @param rel the relation -- OR'ed combination of EQ, LT, GT | ||
| 1326 | * @return nearest node fitting relation, or null if no such | ||
| 1327 | */ | ||
| 1328 | Node<K,V> findNear(K kkey, int rel) { | ||
| 1329 | Comparable<? super K> key = comparable(kkey); | ||
| 1330 | for (;;) { | ||
| 1331 | Node<K,V> b = findPredecessor(key); | ||
| 1332 | Node<K,V> n = b.next; | ||
| 1333 | for (;;) { | ||
| 1334 | if (n == null) | ||
| 1335 | return ((rel & LT) == 0 || b.isBaseHeader()) ? null : b; | ||
| 1336 | Node<K,V> f = n.next; | ||
| 1337 | if (n != b.next) // inconsistent read | ||
| 1338 | break; | ||
| 1339 | Object v = n.value; | ||
| 1340 | if (v == null) { // n is deleted | ||
| 1341 | n.helpDelete(b, f); | ||
| 1342 | break; | ||
| 1343 | } | ||
| 1344 | if (v == n || b.value == null) // b is deleted | ||
| 1345 | break; | ||
| 1346 | int c = key.compareTo(n.key); | ||
| 1347 | if ((c == 0 && (rel & EQ) != 0) || | ||
| 1348 | (c < 0 && (rel & LT) == 0)) | ||
| 1349 | return n; | ||
| 1350 | if ( c <= 0 && (rel & LT) != 0) | ||
| 1351 | return b.isBaseHeader() ? null : b; | ||
| 1352 | b = n; | ||
| 1353 | n = f; | ||
| 1354 | } | ||
| 1355 | } | ||
| 1356 | } | ||
| 1357 | |||
| 1358 | /** | ||
| 1359 | * Returns SimpleImmutableEntry for results of findNear. | ||
| 1360 | * @param key the key | ||
| 1361 | * @param rel the relation -- OR'ed combination of EQ, LT, GT | ||
| 1362 | * @return Entry fitting relation, or null if no such | ||
| 1363 | */ | ||
| 1364 | AbstractMap.SimpleImmutableEntry<K,V> getNear(K key, int rel) { | ||
| 1365 | for (;;) { | ||
| 1366 | Node<K,V> n = findNear(key, rel); | ||
| 1367 | if (n == null) | ||
| 1368 | return null; | ||
| 1369 | AbstractMap.SimpleImmutableEntry<K,V> e = n.createSnapshot(); | ||
| 1370 | if (e != null) | ||
| 1371 | return e; | ||
| 1372 | } | ||
| 1373 | } | ||
| 1374 | |||
| 1375 | |||
| 1376 | /* ---------------- Constructors -------------- */ | ||
| 1377 | |||
| 1378 | /** | ||
| 1379 | * Constructs a new, empty map, sorted according to the | ||
| 1380 | * {@linkplain Comparable natural ordering} of the keys. | ||
| 1381 | */ | ||
| 1382 | public ConcurrentSkipListMap() { | ||
| 1383 | this.comparator = null; | ||
| 1384 | initialize(); | ||
| 1385 | } | ||
| 1386 | |||
| 1387 | /** | ||
| 1388 | * Constructs a new, empty map, sorted according to the specified | ||
| 1389 | * comparator. | ||
| 1390 | * | ||
| 1391 | * @param comparator the comparator that will be used to order this map. | ||
| 1392 | * If <tt>null</tt>, the {@linkplain Comparable natural | ||
| 1393 | * ordering} of the keys will be used. | ||
| 1394 | */ | ||
| 1395 | public ConcurrentSkipListMap(Comparator<? super K> comparator) { | ||
| 1396 | this.comparator = comparator; | ||
| 1397 | initialize(); | ||
| 1398 | } | ||
| 1399 | |||
| 1400 | /** | ||
| 1401 | * Constructs a new map containing the same mappings as the given map, | ||
| 1402 | * sorted according to the {@linkplain Comparable natural ordering} of | ||
| 1403 | * the keys. | ||
| 1404 | * | ||
| 1405 | * @param m the map whose mappings are to be placed in this map | ||
| 1406 | * @throws ClassCastException if the keys in <tt>m</tt> are not | ||
| 1407 | * {@link Comparable}, or are not mutually comparable | ||
| 1408 | * @throws NullPointerException if the specified map or any of its keys | ||
| 1409 | * or values are null | ||
| 1410 | */ | ||
| 1411 | public ConcurrentSkipListMap(Map<? extends K, ? extends V> m) { | ||
| 1412 | this.comparator = null; | ||
| 1413 | initialize(); | ||
| 1414 | putAll(m); | ||
| 1415 | } | ||
| 1416 | |||
| 1417 | /** | ||
| 1418 | * Constructs a new map containing the same mappings and using the | ||
| 1419 | * same ordering as the specified sorted map. | ||
| 1420 | * | ||
| 1421 | * @param m the sorted map whose mappings are to be placed in this | ||
| 1422 | * map, and whose comparator is to be used to sort this map | ||
| 1423 | * @throws NullPointerException if the specified sorted map or any of | ||
| 1424 | * its keys or values are null | ||
| 1425 | */ | ||
| 1426 | public ConcurrentSkipListMap(SortedMap<K, ? extends V> m) { | ||
| 1427 | this.comparator = m.comparator(); | ||
| 1428 | initialize(); | ||
| 1429 | buildFromSorted(m); | ||
| 1430 | } | ||
| 1431 | |||
| 1432 | /** | ||
| 1433 | * Returns a shallow copy of this <tt>ConcurrentSkipListMap</tt> | ||
| 1434 | * instance. (The keys and values themselves are not cloned.) | ||
| 1435 | * | ||
| 1436 | * @return a shallow copy of this map | ||
| 1437 | */ | ||
| 1438 | public ConcurrentSkipListMap<K,V> clone() { | ||
| 1439 | ConcurrentSkipListMap<K,V> clone = null; | ||
| 1440 | try { | ||
| 1441 | clone = (ConcurrentSkipListMap<K,V>) super.clone(); | ||
| 1442 | } catch (CloneNotSupportedException e) { | ||
| 1443 | throw new InternalError(); | ||
| 1444 | } | ||
| 1445 | |||
| 1446 | clone.initialize(); | ||
| 1447 | clone.buildFromSorted(this); | ||
| 1448 | return clone; | ||
| 1449 | } | ||
| 1450 | |||
| 1451 | /** | ||
| 1452 | * Streamlined bulk insertion to initialize from elements of | ||
| 1453 | * given sorted map. Call only from constructor or clone | ||
| 1454 | * method. | ||
| 1455 | */ | ||
| 1456 | private void buildFromSorted(SortedMap<K, ? extends V> map) { | ||
| 1457 | if (map == null) | ||
| 1458 | throw new NullPointerException(); | ||
| 1459 | |||
| 1460 | HeadIndex<K,V> h = head; | ||
| 1461 | Node<K,V> basepred = h.node; | ||
| 1462 | |||
| 1463 | // Track the current rightmost node at each level. Uses an | ||
| 1464 | // ArrayList to avoid committing to initial or maximum level. | ||
| 1465 | ArrayList<Index<K,V>> preds = new ArrayList<Index<K,V>>(); | ||
| 1466 | |||
| 1467 | // initialize | ||
| 1468 | for (int i = 0; i <= h.level; ++i) | ||
| 1469 | preds.add(null); | ||
| 1470 | Index<K,V> q = h; | ||
| 1471 | for (int i = h.level; i > 0; --i) { | ||
| 1472 | preds.set(i, q); | ||
| 1473 | q = q.down; | ||
| 1474 | } | ||
| 1475 | |||
| 1476 | Iterator<? extends Map.Entry<? extends K, ? extends V>> it = | ||
| 1477 | map.entrySet().iterator(); | ||
| 1478 | while (it.hasNext()) { | ||
| 1479 | Map.Entry<? extends K, ? extends V> e = it.next(); | ||
| 1480 | int j = randomLevel(); | ||
| 1481 | if (j > h.level) j = h.level + 1; | ||
| 1482 | K k = e.getKey(); | ||
| 1483 | V v = e.getValue(); | ||
| 1484 | if (k == null || v == null) | ||
| 1485 | throw new NullPointerException(); | ||
| 1486 | Node<K,V> z = new Node<K,V>(k, v, null); | ||
| 1487 | basepred.next = z; | ||
| 1488 | basepred = z; | ||
| 1489 | if (j > 0) { | ||
| 1490 | Index<K,V> idx = null; | ||
| 1491 | for (int i = 1; i <= j; ++i) { | ||
| 1492 | idx = new Index<K,V>(z, idx, null); | ||
| 1493 | if (i > h.level) | ||
| 1494 | h = new HeadIndex<K,V>(h.node, h, idx, i); | ||
| 1495 | |||
| 1496 | if (i < preds.size()) { | ||
| 1497 | preds.get(i).right = idx; | ||
| 1498 | preds.set(i, idx); | ||
| 1499 | } else | ||
| 1500 | preds.add(idx); | ||
| 1501 | } | ||
| 1502 | } | ||
| 1503 | } | ||
| 1504 | head = h; | ||
| 1505 | } | ||
| 1506 | |||
| 1507 | /* ---------------- Serialization -------------- */ | ||
| 1508 | |||
| 1509 | /** | ||
| 1510 | * Save the state of this map to a stream. | ||
| 1511 | * | ||
| 1512 | * @serialData The key (Object) and value (Object) for each | ||
| 1513 | * key-value mapping represented by the map, followed by | ||
| 1514 | * <tt>null</tt>. The key-value mappings are emitted in key-order | ||
| 1515 | * (as determined by the Comparator, or by the keys' natural | ||
| 1516 | * ordering if no Comparator). | ||
| 1517 | */ | ||
| 1518 | private void writeObject(java.io.ObjectOutputStream s) | ||
| 1519 | throws java.io.IOException { | ||
| 1520 | // Write out the Comparator and any hidden stuff | ||
| 1521 | s.defaultWriteObject(); | ||
| 1522 | |||
| 1523 | // Write out keys and values (alternating) | ||
| 1524 | for (Node<K,V> n = findFirst(); n != null; n = n.next) { | ||
| 1525 | V v = n.getValidValue(); | ||
| 1526 | if (v != null) { | ||
| 1527 | s.writeObject(n.key); | ||
| 1528 | s.writeObject(v); | ||
| 1529 | } | ||
| 1530 | } | ||
| 1531 | s.writeObject(null); | ||
| 1532 | } | ||
| 1533 | |||
| 1534 | /** | ||
| 1535 | * Reconstitute the map from a stream. | ||
| 1536 | */ | ||
| 1537 | private void readObject(final java.io.ObjectInputStream s) | ||
| 1538 | throws java.io.IOException, ClassNotFoundException { | ||
| 1539 | // Read in the Comparator and any hidden stuff | ||
| 1540 | s.defaultReadObject(); | ||
| 1541 | // Reset transients | ||
| 1542 | initialize(); | ||
| 1543 | |||
| 1544 | /* | ||
| 1545 | * This is nearly identical to buildFromSorted, but is | ||
| 1546 | * distinct because readObject calls can't be nicely adapted | ||
| 1547 | * as the kind of iterator needed by buildFromSorted. (They | ||
| 1548 | * can be, but doing so requires type cheats and/or creation | ||
| 1549 | * of adaptor classes.) It is simpler to just adapt the code. | ||
| 1550 | */ | ||
| 1551 | |||
| 1552 | HeadIndex<K,V> h = head; | ||
| 1553 | Node<K,V> basepred = h.node; | ||
| 1554 | ArrayList<Index<K,V>> preds = new ArrayList<Index<K,V>>(); | ||
| 1555 | for (int i = 0; i <= h.level; ++i) | ||
| 1556 | preds.add(null); | ||
| 1557 | Index<K,V> q = h; | ||
| 1558 | for (int i = h.level; i > 0; --i) { | ||
| 1559 | preds.set(i, q); | ||
| 1560 | q = q.down; | ||
| 1561 | } | ||
| 1562 | |||
| 1563 | for (;;) { | ||
| 1564 | Object k = s.readObject(); | ||
| 1565 | if (k == null) | ||
| 1566 | break; | ||
| 1567 | Object v = s.readObject(); | ||
| 1568 | if (v == null) | ||
| 1569 | throw new NullPointerException(); | ||
| 1570 | K key = (K) k; | ||
| 1571 | V val = (V) v; | ||
| 1572 | int j = randomLevel(); | ||
| 1573 | if (j > h.level) j = h.level + 1; | ||
| 1574 | Node<K,V> z = new Node<K,V>(key, val, null); | ||
| 1575 | basepred.next = z; | ||
| 1576 | basepred = z; | ||
| 1577 | if (j > 0) { | ||
| 1578 | Index<K,V> idx = null; | ||
| 1579 | for (int i = 1; i <= j; ++i) { | ||
| 1580 | idx = new Index<K,V>(z, idx, null); | ||
| 1581 | if (i > h.level) | ||
| 1582 | h = new HeadIndex<K,V>(h.node, h, idx, i); | ||
| 1583 | |||
| 1584 | if (i < preds.size()) { | ||
| 1585 | preds.get(i).right = idx; | ||
| 1586 | preds.set(i, idx); | ||
| 1587 | } else | ||
| 1588 | preds.add(idx); | ||
| 1589 | } | ||
| 1590 | } | ||
| 1591 | } | ||
| 1592 | head = h; | ||
| 1593 | } | ||
| 1594 | |||
| 1595 | /* ------ Map API methods ------ */ | ||
| 1596 | |||
| 1597 | /** | ||
| 1598 | * Returns <tt>true</tt> if this map contains a mapping for the specified | ||
| 1599 | * key. | ||
| 1600 | * | ||
| 1601 | * @param key key whose presence in this map is to be tested | ||
| 1602 | * @return <tt>true</tt> if this map contains a mapping for the specified key | ||
| 1603 | * @throws ClassCastException if the specified key cannot be compared | ||
| 1604 | * with the keys currently in the map | ||
| 1605 | * @throws NullPointerException if the specified key is null | ||
| 1606 | */ | ||
| 1607 | public boolean containsKey(Object key) { | ||
| 1608 | return doGet(key) != null; | ||
| 1609 | } | ||
| 1610 | |||
| 1611 | /** | ||
| 1612 | * Returns the value to which the specified key is mapped, | ||
| 1613 | * or {@code null} if this map contains no mapping for the key. | ||
| 1614 | * | ||
| 1615 | * <p>More formally, if this map contains a mapping from a key | ||
| 1616 | * {@code k} to a value {@code v} such that {@code key} compares | ||
| 1617 | * equal to {@code k} according to the map's ordering, then this | ||
| 1618 | * method returns {@code v}; otherwise it returns {@code null}. | ||
| 1619 | * (There can be at most one such mapping.) | ||
| 1620 | * | ||
| 1621 | * @throws ClassCastException if the specified key cannot be compared | ||
| 1622 | * with the keys currently in the map | ||
| 1623 | * @throws NullPointerException if the specified key is null | ||
| 1624 | */ | ||
| 1625 | public V get(Object key) { | ||
| 1626 | return doGet(key); | ||
| 1627 | } | ||
| 1628 | |||
| 1629 | /** | ||
| 1630 | * Associates the specified value with the specified key in this map. | ||
| 1631 | * If the map previously contained a mapping for the key, the old | ||
| 1632 | * value is replaced. | ||
| 1633 | * | ||
| 1634 | * @param key key with which the specified value is to be associated | ||
| 1635 | * @param value value to be associated with the specified key | ||
| 1636 | * @return the previous value associated with the specified key, or | ||
| 1637 | * <tt>null</tt> if there was no mapping for the key | ||
| 1638 | * @throws ClassCastException if the specified key cannot be compared | ||
| 1639 | * with the keys currently in the map | ||
| 1640 | * @throws NullPointerException if the specified key or value is null | ||
| 1641 | */ | ||
| 1642 | public V put(K key, V value) { | ||
| 1643 | if (value == null) | ||
| 1644 | throw new NullPointerException(); | ||
| 1645 | return doPut(key, value, false); | ||
| 1646 | } | ||
| 1647 | |||
| 1648 | /** | ||
| 1649 | * Removes the mapping for the specified key from this map if present. | ||
| 1650 | * | ||
| 1651 | * @param key key for which mapping should be removed | ||
| 1652 | * @return the previous value associated with the specified key, or | ||
| 1653 | * <tt>null</tt> if there was no mapping for the key | ||
| 1654 | * @throws ClassCastException if the specified key cannot be compared | ||
| 1655 | * with the keys currently in the map | ||
| 1656 | * @throws NullPointerException if the specified key is null | ||
| 1657 | */ | ||
| 1658 | public V remove(Object key) { | ||
| 1659 | return doRemove(key, null); | ||
| 1660 | } | ||
| 1661 | |||
| 1662 | /** | ||
| 1663 | * Returns <tt>true</tt> if this map maps one or more keys to the | ||
| 1664 | * specified value. This operation requires time linear in the | ||
| 1665 | * map size. Additionally, it is possible for the map to change | ||
| 1666 | * during execution of this method, in which case the returned | ||
| 1667 | * result may be inaccurate. | ||
| 1668 | * | ||
| 1669 | * @param value value whose presence in this map is to be tested | ||
| 1670 | * @return <tt>true</tt> if a mapping to <tt>value</tt> exists; | ||
| 1671 | * <tt>false</tt> otherwise | ||
| 1672 | * @throws NullPointerException if the specified value is null | ||
| 1673 | */ | ||
| 1674 | public boolean containsValue(Object value) { | ||
| 1675 | if (value == null) | ||
| 1676 | throw new NullPointerException(); | ||
| 1677 | for (Node<K,V> n = findFirst(); n != null; n = n.next) { | ||
| 1678 | V v = n.getValidValue(); | ||
| 1679 | if (v != null && value.equals(v)) | ||
| 1680 | return true; | ||
| 1681 | } | ||
| 1682 | return false; | ||
| 1683 | } | ||
| 1684 | |||
| 1685 | /** | ||
| 1686 | * Returns the number of key-value mappings in this map. If this map | ||
| 1687 | * contains more than <tt>Integer.MAX_VALUE</tt> elements, it | ||
| 1688 | * returns <tt>Integer.MAX_VALUE</tt>. | ||
| 1689 | * | ||
| 1690 | * <p>Beware that, unlike in most collections, this method is | ||
| 1691 | * <em>NOT</em> a constant-time operation. Because of the | ||
| 1692 | * asynchronous nature of these maps, determining the current | ||
| 1693 | * number of elements requires traversing them all to count them. | ||
| 1694 | * Additionally, it is possible for the size to change during | ||
| 1695 | * execution of this method, in which case the returned result | ||
| 1696 | * will be inaccurate. Thus, this method is typically not very | ||
| 1697 | * useful in concurrent applications. | ||
| 1698 | * | ||
| 1699 | * @return the number of elements in this map | ||
| 1700 | */ | ||
| 1701 | public int size() { | ||
| 1702 | long count = 0; | ||
| 1703 | for (Node<K,V> n = findFirst(); n != null; n = n.next) { | ||
| 1704 | if (n.getValidValue() != null) | ||
| 1705 | ++count; | ||
| 1706 | } | ||
| 1707 | return (count >= Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int) count; | ||
| 1708 | } | ||
| 1709 | |||
| 1710 | /** | ||
| 1711 | * Returns <tt>true</tt> if this map contains no key-value mappings. | ||
| 1712 | * @return <tt>true</tt> if this map contains no key-value mappings | ||
| 1713 | */ | ||
| 1714 | public boolean isEmpty() { | ||
| 1715 | return findFirst() == null; | ||
| 1716 | } | ||
| 1717 | |||
| 1718 | /** | ||
| 1719 | * Removes all of the mappings from this map. | ||
| 1720 | */ | ||
| 1721 | public void clear() { | ||
| 1722 | initialize(); | ||
| 1723 | } | ||
| 1724 | |||
| 1725 | /* ---------------- View methods -------------- */ | ||
| 1726 | |||
| 1727 | /* | ||
| 1728 | * Note: Lazy initialization works for views because view classes | ||
| 1729 | * are stateless/immutable so it doesn't matter wrt correctness if | ||
| 1730 | * more than one is created (which will only rarely happen). Even | ||
| 1731 | * so, the following idiom conservatively ensures that the method | ||
| 1732 | * returns the one it created if it does so, not one created by | ||
| 1733 | * another racing thread. | ||
| 1734 | */ | ||
| 1735 | |||
| 1736 | /** | ||
| 1737 | * Returns a {@link NavigableSet} view of the keys contained in this map. | ||
| 1738 | * The set's iterator returns the keys in ascending order. | ||
| 1739 | * The set is backed by the map, so changes to the map are | ||
| 1740 | * reflected in the set, and vice-versa. The set supports element | ||
| 1741 | * removal, which removes the corresponding mapping from the map, | ||
| 1742 | * via the {@code Iterator.remove}, {@code Set.remove}, | ||
| 1743 | * {@code removeAll}, {@code retainAll}, and {@code clear} | ||
| 1744 | * operations. It does not support the {@code add} or {@code addAll} | ||
| 1745 | * operations. | ||
| 1746 | * | ||
| 1747 | * <p>The view's {@code iterator} is a "weakly consistent" iterator | ||
| 1748 | * that will never throw {@link ConcurrentModificationException}, | ||
| 1749 | * and guarantees to traverse elements as they existed upon | ||
| 1750 | * construction of the iterator, and may (but is not guaranteed to) | ||
| 1751 | * reflect any modifications subsequent to construction. | ||
| 1752 | * | ||
| 1753 | * <p>This method is equivalent to method {@code navigableKeySet}. | ||
| 1754 | * | ||
| 1755 | * @return a navigable set view of the keys in this map | ||
| 1756 | */ | ||
| 1757 | public NavigableSet<K> keySet() { | ||
| 1758 | KeySet ks = keySet; | ||
| 1759 | return (ks != null) ? ks : (keySet = new KeySet(this)); | ||
| 1760 | } | ||
| 1761 | |||
| 1762 | public NavigableSet<K> navigableKeySet() { | ||
| 1763 | KeySet ks = keySet; | ||
| 1764 | return (ks != null) ? ks : (keySet = new KeySet(this)); | ||
| 1765 | } | ||
| 1766 | |||
| 1767 | /** | ||
| 1768 | * Returns a {@link Collection} view of the values contained in this map. | ||
| 1769 | * The collection's iterator returns the values in ascending order | ||
| 1770 | * of the corresponding keys. | ||
| 1771 | * The collection is backed by the map, so changes to the map are | ||
| 1772 | * reflected in the collection, and vice-versa. The collection | ||
| 1773 | * supports element removal, which removes the corresponding | ||
| 1774 | * mapping from the map, via the <tt>Iterator.remove</tt>, | ||
| 1775 | * <tt>Collection.remove</tt>, <tt>removeAll</tt>, | ||
| 1776 | * <tt>retainAll</tt> and <tt>clear</tt> operations. It does not | ||
| 1777 | * support the <tt>add</tt> or <tt>addAll</tt> operations. | ||
| 1778 | * | ||
| 1779 | * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator | ||
| 1780 | * that will never throw {@link ConcurrentModificationException}, | ||
| 1781 | * and guarantees to traverse elements as they existed upon | ||
| 1782 | * construction of the iterator, and may (but is not guaranteed to) | ||
| 1783 | * reflect any modifications subsequent to construction. | ||
| 1784 | */ | ||
| 1785 | public Collection<V> values() { | ||
| 1786 | Values vs = values; | ||
| 1787 | return (vs != null) ? vs : (values = new Values(this)); | ||
| 1788 | } | ||
| 1789 | |||
| 1790 | /** | ||
| 1791 | * Returns a {@link Set} view of the mappings contained in this map. | ||
| 1792 | * The set's iterator returns the entries in ascending key order. | ||
| 1793 | * The set is backed by the map, so changes to the map are | ||
| 1794 | * reflected in the set, and vice-versa. The set supports element | ||
| 1795 | * removal, which removes the corresponding mapping from the map, | ||
| 1796 | * via the <tt>Iterator.remove</tt>, <tt>Set.remove</tt>, | ||
| 1797 | * <tt>removeAll</tt>, <tt>retainAll</tt> and <tt>clear</tt> | ||
| 1798 | * operations. It does not support the <tt>add</tt> or | ||
| 1799 | * <tt>addAll</tt> operations. | ||
| 1800 | * | ||
| 1801 | * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator | ||
| 1802 | * that will never throw {@link ConcurrentModificationException}, | ||
| 1803 | * and guarantees to traverse elements as they existed upon | ||
| 1804 | * construction of the iterator, and may (but is not guaranteed to) | ||
| 1805 | * reflect any modifications subsequent to construction. | ||
| 1806 | * | ||
| 1807 | * <p>The <tt>Map.Entry</tt> elements returned by | ||
| 1808 | * <tt>iterator.next()</tt> do <em>not</em> support the | ||
| 1809 | * <tt>setValue</tt> operation. | ||
| 1810 | * | ||
| 1811 | * @return a set view of the mappings contained in this map, | ||
| 1812 | * sorted in ascending key order | ||
| 1813 | */ | ||
| 1814 | public Set<Map.Entry<K,V>> entrySet() { | ||
| 1815 | EntrySet es = entrySet; | ||
| 1816 | return (es != null) ? es : (entrySet = new EntrySet(this)); | ||
| 1817 | } | ||
| 1818 | |||
| 1819 | public ConcurrentNavigableMap<K,V> descendingMap() { | ||
| 1820 | ConcurrentNavigableMap<K,V> dm = descendingMap; | ||
| 1821 | return (dm != null) ? dm : (descendingMap = new SubMap<K,V> | ||
| 1822 | (this, null, false, null, false, true)); | ||
| 1823 | } | ||
| 1824 | |||
| 1825 | public NavigableSet<K> descendingKeySet() { | ||
| 1826 | return descendingMap().navigableKeySet(); | ||
| 1827 | } | ||
| 1828 | |||
| 1829 | /* ---------------- AbstractMap Overrides -------------- */ | ||
| 1830 | |||
| 1831 | /** | ||
| 1832 | * Compares the specified object with this map for equality. | ||
| 1833 | * Returns <tt>true</tt> if the given object is also a map and the | ||
| 1834 | * two maps represent the same mappings. More formally, two maps | ||
| 1835 | * <tt>m1</tt> and <tt>m2</tt> represent the same mappings if | ||
| 1836 | * <tt>m1.entrySet().equals(m2.entrySet())</tt>. This | ||
| 1837 | * operation may return misleading results if either map is | ||
| 1838 | * concurrently modified during execution of this method. | ||
| 1839 | * | ||
| 1840 | * @param o object to be compared for equality with this map | ||
| 1841 | * @return <tt>true</tt> if the specified object is equal to this map | ||
| 1842 | */ | ||
| 1843 | public boolean equals(Object o) { | ||
| 1844 | if (o == this) | ||
| 1845 | return true; | ||
| 1846 | if (!(o instanceof Map)) | ||
| 1847 | return false; | ||
| 1848 | Map<?,?> m = (Map<?,?>) o; | ||
| 1849 | try { | ||
| 1850 | for (Map.Entry<K,V> e : this.entrySet()) | ||
| 1851 | if (! e.getValue().equals(m.get(e.getKey()))) | ||
| 1852 | return false; | ||
| 1853 | for (Map.Entry<?,?> e : m.entrySet()) { | ||
| 1854 | Object k = e.getKey(); | ||
| 1855 | Object v = e.getValue(); | ||
| 1856 | if (k == null || v == null || !v.equals(get(k))) | ||
| 1857 | return false; | ||
| 1858 | } | ||
| 1859 | return true; | ||
| 1860 | } catch (ClassCastException unused) { | ||
| 1861 | return false; | ||
| 1862 | } catch (NullPointerException unused) { | ||
| 1863 | return false; | ||
| 1864 | } | ||
| 1865 | } | ||
| 1866 | |||
| 1867 | /* ------ ConcurrentMap API methods ------ */ | ||
| 1868 | |||
| 1869 | /** | ||
| 1870 | * {@inheritDoc} | ||
| 1871 | * | ||
| 1872 | * @return the previous value associated with the specified key, | ||
| 1873 | * or <tt>null</tt> if there was no mapping for the key | ||
| 1874 | * @throws ClassCastException if the specified key cannot be compared | ||
| 1875 | * with the keys currently in the map | ||
| 1876 | * @throws NullPointerException if the specified key or value is null | ||
| 1877 | */ | ||
| 1878 | public V putIfAbsent(K key, V value) { | ||
| 1879 | if (value == null) | ||
| 1880 | throw new NullPointerException(); | ||
| 1881 | return doPut(key, value, true); | ||
| 1882 | } | ||
| 1883 | |||
| 1884 | /** | ||
| 1885 | * {@inheritDoc} | ||
| 1886 | * | ||
| 1887 | * @throws ClassCastException if the specified key cannot be compared | ||
| 1888 | * with the keys currently in the map | ||
| 1889 | * @throws NullPointerException if the specified key is null | ||
| 1890 | */ | ||
| 1891 | public boolean remove(Object key, Object value) { | ||
| 1892 | if (key == null) | ||
| 1893 | throw new NullPointerException(); | ||
| 1894 | if (value == null) | ||
| 1895 | return false; | ||
| 1896 | return doRemove(key, value) != null; | ||
| 1897 | } | ||
| 1898 | |||
| 1899 | /** | ||
| 1900 | * {@inheritDoc} | ||
| 1901 | * | ||
| 1902 | * @throws ClassCastException if the specified key cannot be compared | ||
| 1903 | * with the keys currently in the map | ||
| 1904 | * @throws NullPointerException if any of the arguments are null | ||
| 1905 | */ | ||
| 1906 | public boolean replace(K key, V oldValue, V newValue) { | ||
| 1907 | if (oldValue == null || newValue == null) | ||
| 1908 | throw new NullPointerException(); | ||
| 1909 | Comparable<? super K> k = comparable(key); | ||
| 1910 | for (;;) { | ||
| 1911 | Node<K,V> n = findNode(k); | ||
| 1912 | if (n == null) | ||
| 1913 | return false; | ||
| 1914 | Object v = n.value; | ||
| 1915 | if (v != null) { | ||
| 1916 | if (!oldValue.equals(v)) | ||
| 1917 | return false; | ||
| 1918 | if (n.casValue(v, newValue)) | ||
| 1919 | return true; | ||
| 1920 | } | ||
| 1921 | } | ||
| 1922 | } | ||
| 1923 | |||
| 1924 | /** | ||
| 1925 | * {@inheritDoc} | ||
| 1926 | * | ||
| 1927 | * @return the previous value associated with the specified key, | ||
| 1928 | * or <tt>null</tt> if there was no mapping for the key | ||
| 1929 | * @throws ClassCastException if the specified key cannot be compared | ||
| 1930 | * with the keys currently in the map | ||
| 1931 | * @throws NullPointerException if the specified key or value is null | ||
| 1932 | */ | ||
| 1933 | public V replace(K key, V value) { | ||
| 1934 | if (value == null) | ||
| 1935 | throw new NullPointerException(); | ||
| 1936 | Comparable<? super K> k = comparable(key); | ||
| 1937 | for (;;) { | ||
| 1938 | Node<K,V> n = findNode(k); | ||
| 1939 | if (n == null) | ||
| 1940 | return null; | ||
| 1941 | Object v = n.value; | ||
| 1942 | if (v != null && n.casValue(v, value)) | ||
| 1943 | return (V)v; | ||
| 1944 | } | ||
| 1945 | } | ||
| 1946 | |||
| 1947 | /* ------ SortedMap API methods ------ */ | ||
| 1948 | |||
| 1949 | public Comparator<? super K> comparator() { | ||
| 1950 | return comparator; | ||
| 1951 | } | ||
| 1952 | |||
| 1953 | /** | ||
| 1954 | * @throws NoSuchElementException {@inheritDoc} | ||
| 1955 | */ | ||
| 1956 | public K firstKey() { | ||
| 1957 | Node<K,V> n = findFirst(); | ||
| 1958 | if (n == null) | ||
| 1959 | throw new NoSuchElementException(); | ||
| 1960 | return n.key; | ||
| 1961 | } | ||
| 1962 | |||
| 1963 | /** | ||
| 1964 | * @throws NoSuchElementException {@inheritDoc} | ||
| 1965 | */ | ||
| 1966 | public K lastKey() { | ||
| 1967 | Node<K,V> n = findLast(); | ||
| 1968 | if (n == null) | ||
| 1969 | throw new NoSuchElementException(); | ||
| 1970 | return n.key; | ||
| 1971 | } | ||
| 1972 | |||
| 1973 | /** | ||
| 1974 | * @throws ClassCastException {@inheritDoc} | ||
| 1975 | * @throws NullPointerException if {@code fromKey} or {@code toKey} is null | ||
| 1976 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 1977 | */ | ||
| 1978 | public ConcurrentNavigableMap<K,V> subMap(K fromKey, | ||
| 1979 | boolean fromInclusive, | ||
| 1980 | K toKey, | ||
| 1981 | boolean toInclusive) { | ||
| 1982 | if (fromKey == null || toKey == null) | ||
| 1983 | throw new NullPointerException(); | ||
| 1984 | return new SubMap<K,V> | ||
| 1985 | (this, fromKey, fromInclusive, toKey, toInclusive, false); | ||
| 1986 | } | ||
| 1987 | |||
| 1988 | /** | ||
| 1989 | * @throws ClassCastException {@inheritDoc} | ||
| 1990 | * @throws NullPointerException if {@code toKey} is null | ||
| 1991 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 1992 | */ | ||
| 1993 | public ConcurrentNavigableMap<K,V> headMap(K toKey, | ||
| 1994 | boolean inclusive) { | ||
| 1995 | if (toKey == null) | ||
| 1996 | throw new NullPointerException(); | ||
| 1997 | return new SubMap<K,V> | ||
| 1998 | (this, null, false, toKey, inclusive, false); | ||
| 1999 | } | ||
| 2000 | |||
| 2001 | /** | ||
| 2002 | * @throws ClassCastException {@inheritDoc} | ||
| 2003 | * @throws NullPointerException if {@code fromKey} is null | ||
| 2004 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 2005 | */ | ||
| 2006 | public ConcurrentNavigableMap<K,V> tailMap(K fromKey, | ||
| 2007 | boolean inclusive) { | ||
| 2008 | if (fromKey == null) | ||
| 2009 | throw new NullPointerException(); | ||
| 2010 | return new SubMap<K,V> | ||
| 2011 | (this, fromKey, inclusive, null, false, false); | ||
| 2012 | } | ||
| 2013 | |||
| 2014 | /** | ||
| 2015 | * @throws ClassCastException {@inheritDoc} | ||
| 2016 | * @throws NullPointerException if {@code fromKey} or {@code toKey} is null | ||
| 2017 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 2018 | */ | ||
| 2019 | public ConcurrentNavigableMap<K,V> subMap(K fromKey, K toKey) { | ||
| 2020 | return subMap(fromKey, true, toKey, false); | ||
| 2021 | } | ||
| 2022 | |||
| 2023 | /** | ||
| 2024 | * @throws ClassCastException {@inheritDoc} | ||
| 2025 | * @throws NullPointerException if {@code toKey} is null | ||
| 2026 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 2027 | */ | ||
| 2028 | public ConcurrentNavigableMap<K,V> headMap(K toKey) { | ||
| 2029 | return headMap(toKey, false); | ||
| 2030 | } | ||
| 2031 | |||
| 2032 | /** | ||
| 2033 | * @throws ClassCastException {@inheritDoc} | ||
| 2034 | * @throws NullPointerException if {@code fromKey} is null | ||
| 2035 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 2036 | */ | ||
| 2037 | public ConcurrentNavigableMap<K,V> tailMap(K fromKey) { | ||
| 2038 | return tailMap(fromKey, true); | ||
| 2039 | } | ||
| 2040 | |||
| 2041 | /* ---------------- Relational operations -------------- */ | ||
| 2042 | |||
| 2043 | /** | ||
| 2044 | * Returns a key-value mapping associated with the greatest key | ||
| 2045 | * strictly less than the given key, or <tt>null</tt> if there is | ||
| 2046 | * no such key. The returned entry does <em>not</em> support the | ||
| 2047 | * <tt>Entry.setValue</tt> method. | ||
| 2048 | * | ||
| 2049 | * @throws ClassCastException {@inheritDoc} | ||
| 2050 | * @throws NullPointerException if the specified key is null | ||
| 2051 | */ | ||
| 2052 | public Map.Entry<K,V> lowerEntry(K key) { | ||
| 2053 | return getNear(key, LT); | ||
| 2054 | } | ||
| 2055 | |||
| 2056 | /** | ||
| 2057 | * @throws ClassCastException {@inheritDoc} | ||
| 2058 | * @throws NullPointerException if the specified key is null | ||
| 2059 | */ | ||
| 2060 | public K lowerKey(K key) { | ||
| 2061 | Node<K,V> n = findNear(key, LT); | ||
| 2062 | return (n == null) ? null : n.key; | ||
| 2063 | } | ||
| 2064 | |||
| 2065 | /** | ||
| 2066 | * Returns a key-value mapping associated with the greatest key | ||
| 2067 | * less than or equal to the given key, or <tt>null</tt> if there | ||
| 2068 | * is no such key. The returned entry does <em>not</em> support | ||
| 2069 | * the <tt>Entry.setValue</tt> method. | ||
| 2070 | * | ||
| 2071 | * @param key the key | ||
| 2072 | * @throws ClassCastException {@inheritDoc} | ||
| 2073 | * @throws NullPointerException if the specified key is null | ||
| 2074 | */ | ||
| 2075 | public Map.Entry<K,V> floorEntry(K key) { | ||
| 2076 | return getNear(key, LT|EQ); | ||
| 2077 | } | ||
| 2078 | |||
| 2079 | /** | ||
| 2080 | * @param key the key | ||
| 2081 | * @throws ClassCastException {@inheritDoc} | ||
| 2082 | * @throws NullPointerException if the specified key is null | ||
| 2083 | */ | ||
| 2084 | public K floorKey(K key) { | ||
| 2085 | Node<K,V> n = findNear(key, LT|EQ); | ||
| 2086 | return (n == null) ? null : n.key; | ||
| 2087 | } | ||
| 2088 | |||
| 2089 | /** | ||
| 2090 | * Returns a key-value mapping associated with the least key | ||
| 2091 | * greater than or equal to the given key, or <tt>null</tt> if | ||
| 2092 | * there is no such entry. The returned entry does <em>not</em> | ||
| 2093 | * support the <tt>Entry.setValue</tt> method. | ||
| 2094 | * | ||
| 2095 | * @throws ClassCastException {@inheritDoc} | ||
| 2096 | * @throws NullPointerException if the specified key is null | ||
| 2097 | */ | ||
| 2098 | public Map.Entry<K,V> ceilingEntry(K key) { | ||
| 2099 | return getNear(key, GT|EQ); | ||
| 2100 | } | ||
| 2101 | |||
| 2102 | /** | ||
| 2103 | * @throws ClassCastException {@inheritDoc} | ||
| 2104 | * @throws NullPointerException if the specified key is null | ||
| 2105 | */ | ||
| 2106 | public K ceilingKey(K key) { | ||
| 2107 | Node<K,V> n = findNear(key, GT|EQ); | ||
| 2108 | return (n == null) ? null : n.key; | ||
| 2109 | } | ||
| 2110 | |||
| 2111 | /** | ||
| 2112 | * Returns a key-value mapping associated with the least key | ||
| 2113 | * strictly greater than the given key, or <tt>null</tt> if there | ||
| 2114 | * is no such key. The returned entry does <em>not</em> support | ||
| 2115 | * the <tt>Entry.setValue</tt> method. | ||
| 2116 | * | ||
| 2117 | * @param key the key | ||
| 2118 | * @throws ClassCastException {@inheritDoc} | ||
| 2119 | * @throws NullPointerException if the specified key is null | ||
| 2120 | */ | ||
| 2121 | public Map.Entry<K,V> higherEntry(K key) { | ||
| 2122 | return getNear(key, GT); | ||
| 2123 | } | ||
| 2124 | |||
| 2125 | /** | ||
| 2126 | * @param key the key | ||
| 2127 | * @throws ClassCastException {@inheritDoc} | ||
| 2128 | * @throws NullPointerException if the specified key is null | ||
| 2129 | */ | ||
| 2130 | public K higherKey(K key) { | ||
| 2131 | Node<K,V> n = findNear(key, GT); | ||
| 2132 | return (n == null) ? null : n.key; | ||
| 2133 | } | ||
| 2134 | |||
| 2135 | /** | ||
| 2136 | * Returns a key-value mapping associated with the least | ||
| 2137 | * key in this map, or <tt>null</tt> if the map is empty. | ||
| 2138 | * The returned entry does <em>not</em> support | ||
| 2139 | * the <tt>Entry.setValue</tt> method. | ||
| 2140 | */ | ||
| 2141 | public Map.Entry<K,V> firstEntry() { | ||
| 2142 | for (;;) { | ||
| 2143 | Node<K,V> n = findFirst(); | ||
| 2144 | if (n == null) | ||
| 2145 | return null; | ||
| 2146 | AbstractMap.SimpleImmutableEntry<K,V> e = n.createSnapshot(); | ||
| 2147 | if (e != null) | ||
| 2148 | return e; | ||
| 2149 | } | ||
| 2150 | } | ||
| 2151 | |||
| 2152 | /** | ||
| 2153 | * Returns a key-value mapping associated with the greatest | ||
| 2154 | * key in this map, or <tt>null</tt> if the map is empty. | ||
| 2155 | * The returned entry does <em>not</em> support | ||
| 2156 | * the <tt>Entry.setValue</tt> method. | ||
| 2157 | */ | ||
| 2158 | public Map.Entry<K,V> lastEntry() { | ||
| 2159 | for (;;) { | ||
| 2160 | Node<K,V> n = findLast(); | ||
| 2161 | if (n == null) | ||
| 2162 | return null; | ||
| 2163 | AbstractMap.SimpleImmutableEntry<K,V> e = n.createSnapshot(); | ||
| 2164 | if (e != null) | ||
| 2165 | return e; | ||
| 2166 | } | ||
| 2167 | } | ||
| 2168 | |||
| 2169 | /** | ||
| 2170 | * Removes and returns a key-value mapping associated with | ||
| 2171 | * the least key in this map, or <tt>null</tt> if the map is empty. | ||
| 2172 | * The returned entry does <em>not</em> support | ||
| 2173 | * the <tt>Entry.setValue</tt> method. | ||
| 2174 | */ | ||
| 2175 | public Map.Entry<K,V> pollFirstEntry() { | ||
| 2176 | return doRemoveFirstEntry(); | ||
| 2177 | } | ||
| 2178 | |||
| 2179 | /** | ||
| 2180 | * Removes and returns a key-value mapping associated with | ||
| 2181 | * the greatest key in this map, or <tt>null</tt> if the map is empty. | ||
| 2182 | * The returned entry does <em>not</em> support | ||
| 2183 | * the <tt>Entry.setValue</tt> method. | ||
| 2184 | */ | ||
| 2185 | public Map.Entry<K,V> pollLastEntry() { | ||
| 2186 | return doRemoveLastEntry(); | ||
| 2187 | } | ||
| 2188 | |||
| 2189 | |||
| 2190 | /* ---------------- Iterators -------------- */ | ||
| 2191 | |||
| 2192 | /** | ||
| 2193 | * Base of iterator classes: | ||
| 2194 | */ | ||
| 2195 | abstract class Iter<T> implements Iterator<T> { | ||
| 2196 | /** the last node returned by next() */ | ||
| 2197 | Node<K,V> lastReturned; | ||
| 2198 | /** the next node to return from next(); */ | ||
| 2199 | Node<K,V> next; | ||
| 2200 | /** Cache of next value field to maintain weak consistency */ | ||
| 2201 | V nextValue; | ||
| 2202 | |||
| 2203 | /** Initializes ascending iterator for entire range. */ | ||
| 2204 | Iter() { | ||
| 2205 | for (;;) { | ||
| 2206 | next = findFirst(); | ||
| 2207 | if (next == null) | ||
| 2208 | break; | ||
| 2209 | Object x = next.value; | ||
| 2210 | if (x != null && x != next) { | ||
| 2211 | nextValue = (V) x; | ||
| 2212 | break; | ||
| 2213 | } | ||
| 2214 | } | ||
| 2215 | } | ||
| 2216 | |||
| 2217 | public final boolean hasNext() { | ||
| 2218 | return next != null; | ||
| 2219 | } | ||
| 2220 | |||
| 2221 | /** Advances next to higher entry. */ | ||
| 2222 | final void advance() { | ||
| 2223 | if (next == null) | ||
| 2224 | throw new NoSuchElementException(); | ||
| 2225 | lastReturned = next; | ||
| 2226 | for (;;) { | ||
| 2227 | next = next.next; | ||
| 2228 | if (next == null) | ||
| 2229 | break; | ||
| 2230 | Object x = next.value; | ||
| 2231 | if (x != null && x != next) { | ||
| 2232 | nextValue = (V) x; | ||
| 2233 | break; | ||
| 2234 | } | ||
| 2235 | } | ||
| 2236 | } | ||
| 2237 | |||
| 2238 | public void remove() { | ||
| 2239 | Node<K,V> l = lastReturned; | ||
| 2240 | if (l == null) | ||
| 2241 | throw new IllegalStateException(); | ||
| 2242 | // It would not be worth all of the overhead to directly | ||
| 2243 | // unlink from here. Using remove is fast enough. | ||
| 2244 | ConcurrentSkipListMap.this.remove(l.key); | ||
| 2245 | lastReturned = null; | ||
| 2246 | } | ||
| 2247 | |||
| 2248 | } | ||
| 2249 | |||
| 2250 | final class ValueIterator extends Iter<V> { | ||
| 2251 | public V next() { | ||
| 2252 | V v = nextValue; | ||
| 2253 | advance(); | ||
| 2254 | return v; | ||
| 2255 | } | ||
| 2256 | } | ||
| 2257 | |||
| 2258 | final class KeyIterator extends Iter<K> { | ||
| 2259 | public K next() { | ||
| 2260 | Node<K,V> n = next; | ||
| 2261 | advance(); | ||
| 2262 | return n.key; | ||
| 2263 | } | ||
| 2264 | } | ||
| 2265 | |||
| 2266 | final class EntryIterator extends Iter<Map.Entry<K,V>> { | ||
| 2267 | public Map.Entry<K,V> next() { | ||
| 2268 | Node<K,V> n = next; | ||
| 2269 | V v = nextValue; | ||
| 2270 | advance(); | ||
| 2271 | return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, v); | ||
| 2272 | } | ||
| 2273 | } | ||
| 2274 | |||
| 2275 | // Factory methods for iterators needed by ConcurrentSkipListSet etc | ||
| 2276 | |||
| 2277 | Iterator<K> keyIterator() { | ||
| 2278 | return new KeyIterator(); | ||
| 2279 | } | ||
| 2280 | |||
| 2281 | Iterator<V> valueIterator() { | ||
| 2282 | return new ValueIterator(); | ||
| 2283 | } | ||
| 2284 | |||
| 2285 | Iterator<Map.Entry<K,V>> entryIterator() { | ||
| 2286 | return new EntryIterator(); | ||
| 2287 | } | ||
| 2288 | |||
| 2289 | /* ---------------- View Classes -------------- */ | ||
| 2290 | |||
| 2291 | /* | ||
| 2292 | * View classes are static, delegating to a ConcurrentNavigableMap | ||
| 2293 | * to allow use by SubMaps, which outweighs the ugliness of | ||
| 2294 | * needing type-tests for Iterator methods. | ||
| 2295 | */ | ||
| 2296 | |||
| 2297 | static final <E> List<E> toList(Collection<E> c) { | ||
| 2298 | // Using size() here would be a pessimization. | ||
| 2299 | List<E> list = new ArrayList<E>(); | ||
| 2300 | for (E e : c) | ||
| 2301 | list.add(e); | ||
| 2302 | return list; | ||
| 2303 | } | ||
| 2304 | |||
| 2305 | static final class KeySet<E> | ||
| 2306 | extends AbstractSet<E> implements NavigableSet<E> { | ||
| 2307 | private final ConcurrentNavigableMap<E,Object> m; | ||
| 2308 | KeySet(ConcurrentNavigableMap<E,Object> map) { m = map; } | ||
| 2309 | public int size() { return m.size(); } | ||
| 2310 | public boolean isEmpty() { return m.isEmpty(); } | ||
| 2311 | public boolean contains(Object o) { return m.containsKey(o); } | ||
| 2312 | public boolean remove(Object o) { return m.remove(o) != null; } | ||
| 2313 | public void clear() { m.clear(); } | ||
| 2314 | public E lower(E e) { return m.lowerKey(e); } | ||
| 2315 | public E floor(E e) { return m.floorKey(e); } | ||
| 2316 | public E ceiling(E e) { return m.ceilingKey(e); } | ||
| 2317 | public E higher(E e) { return m.higherKey(e); } | ||
| 2318 | public Comparator<? super E> comparator() { return m.comparator(); } | ||
| 2319 | public E first() { return m.firstKey(); } | ||
| 2320 | public E last() { return m.lastKey(); } | ||
| 2321 | public E pollFirst() { | ||
| 2322 | Map.Entry<E,Object> e = m.pollFirstEntry(); | ||
| 2323 | return (e == null) ? null : e.getKey(); | ||
| 2324 | } | ||
| 2325 | public E pollLast() { | ||
| 2326 | Map.Entry<E,Object> e = m.pollLastEntry(); | ||
| 2327 | return (e == null) ? null : e.getKey(); | ||
| 2328 | } | ||
| 2329 | public Iterator<E> iterator() { | ||
| 2330 | if (m instanceof ConcurrentSkipListMap) | ||
| 2331 | return ((ConcurrentSkipListMap<E,Object>)m).keyIterator(); | ||
| 2332 | else | ||
| 2333 | return ((ConcurrentSkipListMap.SubMap<E,Object>)m).keyIterator(); | ||
| 2334 | } | ||
| 2335 | public boolean equals(Object o) { | ||
| 2336 | if (o == this) | ||
| 2337 | return true; | ||
| 2338 | if (!(o instanceof Set)) | ||
| 2339 | return false; | ||
| 2340 | Collection<?> c = (Collection<?>) o; | ||
| 2341 | try { | ||
| 2342 | return containsAll(c) && c.containsAll(this); | ||
| 2343 | } catch (ClassCastException unused) { | ||
| 2344 | return false; | ||
| 2345 | } catch (NullPointerException unused) { | ||
| 2346 | return false; | ||
| 2347 | } | ||
| 2348 | } | ||
| 2349 | public Object[] toArray() { return toList(this).toArray(); } | ||
| 2350 | public <T> T[] toArray(T[] a) { return toList(this).toArray(a); } | ||
| 2351 | public Iterator<E> descendingIterator() { | ||
| 2352 | return descendingSet().iterator(); | ||
| 2353 | } | ||
| 2354 | public NavigableSet<E> subSet(E fromElement, | ||
| 2355 | boolean fromInclusive, | ||
| 2356 | E toElement, | ||
| 2357 | boolean toInclusive) { | ||
| 2358 | return new KeySet<E>(m.subMap(fromElement, fromInclusive, | ||
| 2359 | toElement, toInclusive)); | ||
| 2360 | } | ||
| 2361 | public NavigableSet<E> headSet(E toElement, boolean inclusive) { | ||
| 2362 | return new KeySet<E>(m.headMap(toElement, inclusive)); | ||
| 2363 | } | ||
| 2364 | public NavigableSet<E> tailSet(E fromElement, boolean inclusive) { | ||
| 2365 | return new KeySet<E>(m.tailMap(fromElement, inclusive)); | ||
| 2366 | } | ||
| 2367 | public NavigableSet<E> subSet(E fromElement, E toElement) { | ||
| 2368 | return subSet(fromElement, true, toElement, false); | ||
| 2369 | } | ||
| 2370 | public NavigableSet<E> headSet(E toElement) { | ||
| 2371 | return headSet(toElement, false); | ||
| 2372 | } | ||
| 2373 | public NavigableSet<E> tailSet(E fromElement) { | ||
| 2374 | return tailSet(fromElement, true); | ||
| 2375 | } | ||
| 2376 | public NavigableSet<E> descendingSet() { | ||
| 2377 | return new KeySet(m.descendingMap()); | ||
| 2378 | } | ||
| 2379 | } | ||
| 2380 | |||
| 2381 | static final class Values<E> extends AbstractCollection<E> { | ||
| 2382 | private final ConcurrentNavigableMap<Object, E> m; | ||
| 2383 | Values(ConcurrentNavigableMap<Object, E> map) { | ||
| 2384 | m = map; | ||
| 2385 | } | ||
| 2386 | public Iterator<E> iterator() { | ||
| 2387 | if (m instanceof ConcurrentSkipListMap) | ||
| 2388 | return ((ConcurrentSkipListMap<Object,E>)m).valueIterator(); | ||
| 2389 | else | ||
| 2390 | return ((SubMap<Object,E>)m).valueIterator(); | ||
| 2391 | } | ||
| 2392 | public boolean isEmpty() { | ||
| 2393 | return m.isEmpty(); | ||
| 2394 | } | ||
| 2395 | public int size() { | ||
| 2396 | return m.size(); | ||
| 2397 | } | ||
| 2398 | public boolean contains(Object o) { | ||
| 2399 | return m.containsValue(o); | ||
| 2400 | } | ||
| 2401 | public void clear() { | ||
| 2402 | m.clear(); | ||
| 2403 | } | ||
| 2404 | public Object[] toArray() { return toList(this).toArray(); } | ||
| 2405 | public <T> T[] toArray(T[] a) { return toList(this).toArray(a); } | ||
| 2406 | } | ||
| 2407 | |||
| 2408 | static final class EntrySet<K1,V1> extends AbstractSet<Map.Entry<K1,V1>> { | ||
| 2409 | private final ConcurrentNavigableMap<K1, V1> m; | ||
| 2410 | EntrySet(ConcurrentNavigableMap<K1, V1> map) { | ||
| 2411 | m = map; | ||
| 2412 | } | ||
| 2413 | |||
| 2414 | public Iterator<Map.Entry<K1,V1>> iterator() { | ||
| 2415 | if (m instanceof ConcurrentSkipListMap) | ||
| 2416 | return ((ConcurrentSkipListMap<K1,V1>)m).entryIterator(); | ||
| 2417 | else | ||
| 2418 | return ((SubMap<K1,V1>)m).entryIterator(); | ||
| 2419 | } | ||
| 2420 | |||
| 2421 | public boolean contains(Object o) { | ||
| 2422 | if (!(o instanceof Map.Entry)) | ||
| 2423 | return false; | ||
| 2424 | Map.Entry<K1,V1> e = (Map.Entry<K1,V1>)o; | ||
| 2425 | V1 v = m.get(e.getKey()); | ||
| 2426 | return v != null && v.equals(e.getValue()); | ||
| 2427 | } | ||
| 2428 | public boolean remove(Object o) { | ||
| 2429 | if (!(o instanceof Map.Entry)) | ||
| 2430 | return false; | ||
| 2431 | Map.Entry<K1,V1> e = (Map.Entry<K1,V1>)o; | ||
| 2432 | return m.remove(e.getKey(), | ||
| 2433 | e.getValue()); | ||
| 2434 | } | ||
| 2435 | public boolean isEmpty() { | ||
| 2436 | return m.isEmpty(); | ||
| 2437 | } | ||
| 2438 | public int size() { | ||
| 2439 | return m.size(); | ||
| 2440 | } | ||
| 2441 | public void clear() { | ||
| 2442 | m.clear(); | ||
| 2443 | } | ||
| 2444 | public boolean equals(Object o) { | ||
| 2445 | if (o == this) | ||
| 2446 | return true; | ||
| 2447 | if (!(o instanceof Set)) | ||
| 2448 | return false; | ||
| 2449 | Collection<?> c = (Collection<?>) o; | ||
| 2450 | try { | ||
| 2451 | return containsAll(c) && c.containsAll(this); | ||
| 2452 | } catch (ClassCastException unused) { | ||
| 2453 | return false; | ||
| 2454 | } catch (NullPointerException unused) { | ||
| 2455 | return false; | ||
| 2456 | } | ||
| 2457 | } | ||
| 2458 | public Object[] toArray() { return toList(this).toArray(); } | ||
| 2459 | public <T> T[] toArray(T[] a) { return toList(this).toArray(a); } | ||
| 2460 | } | ||
| 2461 | |||
| 2462 | /** | ||
| 2463 | * Submaps returned by {@link ConcurrentSkipListMap} submap operations | ||
| 2464 | * represent a subrange of mappings of their underlying | ||
| 2465 | * maps. Instances of this class support all methods of their | ||
| 2466 | * underlying maps, differing in that mappings outside their range are | ||
| 2467 | * ignored, and attempts to add mappings outside their ranges result | ||
| 2468 | * in {@link IllegalArgumentException}. Instances of this class are | ||
| 2469 | * constructed only using the <tt>subMap</tt>, <tt>headMap</tt>, and | ||
| 2470 | * <tt>tailMap</tt> methods of their underlying maps. | ||
| 2471 | * | ||
| 2472 | * @serial include | ||
| 2473 | */ | ||
| 2474 | static final class SubMap<K,V> extends AbstractMap<K,V> | ||
| 2475 | implements ConcurrentNavigableMap<K,V>, Cloneable, | ||
| 2476 | java.io.Serializable { | ||
| 2477 | private static final long serialVersionUID = -7647078645895051609L; | ||
| 2478 | |||
| 2479 | /** Underlying map */ | ||
| 2480 | private final ConcurrentSkipListMap<K,V> m; | ||
| 2481 | /** lower bound key, or null if from start */ | ||
| 2482 | private final K lo; | ||
| 2483 | /** upper bound key, or null if to end */ | ||
| 2484 | private final K hi; | ||
| 2485 | /** inclusion flag for lo */ | ||
| 2486 | private final boolean loInclusive; | ||
| 2487 | /** inclusion flag for hi */ | ||
| 2488 | private final boolean hiInclusive; | ||
| 2489 | /** direction */ | ||
| 2490 | private final boolean isDescending; | ||
| 2491 | |||
| 2492 | // Lazily initialized view holders | ||
| 2493 | private transient KeySet<K> keySetView; | ||
| 2494 | private transient Set<Map.Entry<K,V>> entrySetView; | ||
| 2495 | private transient Collection<V> valuesView; | ||
| 2496 | |||
| 2497 | /** | ||
| 2498 | * Creates a new submap, initializing all fields | ||
| 2499 | */ | ||
| 2500 | SubMap(ConcurrentSkipListMap<K,V> map, | ||
| 2501 | K fromKey, boolean fromInclusive, | ||
| 2502 | K toKey, boolean toInclusive, | ||
| 2503 | boolean isDescending) { | ||
| 2504 | if (fromKey != null && toKey != null && | ||
| 2505 | map.compare(fromKey, toKey) > 0) | ||
| 2506 | throw new IllegalArgumentException("inconsistent range"); | ||
| 2507 | this.m = map; | ||
| 2508 | this.lo = fromKey; | ||
| 2509 | this.hi = toKey; | ||
| 2510 | this.loInclusive = fromInclusive; | ||
| 2511 | this.hiInclusive = toInclusive; | ||
| 2512 | this.isDescending = isDescending; | ||
| 2513 | } | ||
| 2514 | |||
| 2515 | /* ---------------- Utilities -------------- */ | ||
| 2516 | |||
| 2517 | private boolean tooLow(K key) { | ||
| 2518 | if (lo != null) { | ||
| 2519 | int c = m.compare(key, lo); | ||
| 2520 | if (c < 0 || (c == 0 && !loInclusive)) | ||
| 2521 | return true; | ||
| 2522 | } | ||
| 2523 | return false; | ||
| 2524 | } | ||
| 2525 | |||
| 2526 | private boolean tooHigh(K key) { | ||
| 2527 | if (hi != null) { | ||
| 2528 | int c = m.compare(key, hi); | ||
| 2529 | if (c > 0 || (c == 0 && !hiInclusive)) | ||
| 2530 | return true; | ||
| 2531 | } | ||
| 2532 | return false; | ||
| 2533 | } | ||
| 2534 | |||
| 2535 | private boolean inBounds(K key) { | ||
| 2536 | return !tooLow(key) && !tooHigh(key); | ||
| 2537 | } | ||
| 2538 | |||
| 2539 | private void checkKeyBounds(K key) throws IllegalArgumentException { | ||
| 2540 | if (key == null) | ||
| 2541 | throw new NullPointerException(); | ||
| 2542 | if (!inBounds(key)) | ||
| 2543 | throw new IllegalArgumentException("key out of range"); | ||
| 2544 | } | ||
| 2545 | |||
| 2546 | /** | ||
| 2547 | * Returns true if node key is less than upper bound of range | ||
| 2548 | */ | ||
| 2549 | private boolean isBeforeEnd(ConcurrentSkipListMap.Node<K,V> n) { | ||
| 2550 | if (n == null) | ||
| 2551 | return false; | ||
| 2552 | if (hi == null) | ||
| 2553 | return true; | ||
| 2554 | K k = n.key; | ||
| 2555 | if (k == null) // pass by markers and headers | ||
| 2556 | return true; | ||
| 2557 | int c = m.compare(k, hi); | ||
| 2558 | if (c > 0 || (c == 0 && !hiInclusive)) | ||
| 2559 | return false; | ||
| 2560 | return true; | ||
| 2561 | } | ||
| 2562 | |||
| 2563 | /** | ||
| 2564 | * Returns lowest node. This node might not be in range, so | ||
| 2565 | * most usages need to check bounds | ||
| 2566 | */ | ||
| 2567 | private ConcurrentSkipListMap.Node<K,V> loNode() { | ||
| 2568 | if (lo == null) | ||
| 2569 | return m.findFirst(); | ||
| 2570 | else if (loInclusive) | ||
| 2571 | return m.findNear(lo, m.GT|m.EQ); | ||
| 2572 | else | ||
| 2573 | return m.findNear(lo, m.GT); | ||
| 2574 | } | ||
| 2575 | |||
| 2576 | /** | ||
| 2577 | * Returns highest node. This node might not be in range, so | ||
| 2578 | * most usages need to check bounds | ||
| 2579 | */ | ||
| 2580 | private ConcurrentSkipListMap.Node<K,V> hiNode() { | ||
| 2581 | if (hi == null) | ||
| 2582 | return m.findLast(); | ||
| 2583 | else if (hiInclusive) | ||
| 2584 | return m.findNear(hi, m.LT|m.EQ); | ||
| 2585 | else | ||
| 2586 | return m.findNear(hi, m.LT); | ||
| 2587 | } | ||
| 2588 | |||
| 2589 | /** | ||
| 2590 | * Returns lowest absolute key (ignoring directonality) | ||
| 2591 | */ | ||
| 2592 | private K lowestKey() { | ||
| 2593 | ConcurrentSkipListMap.Node<K,V> n = loNode(); | ||
| 2594 | if (isBeforeEnd(n)) | ||
| 2595 | return n.key; | ||
| 2596 | else | ||
| 2597 | throw new NoSuchElementException(); | ||
| 2598 | } | ||
| 2599 | |||
| 2600 | /** | ||
| 2601 | * Returns highest absolute key (ignoring directonality) | ||
| 2602 | */ | ||
| 2603 | private K highestKey() { | ||
| 2604 | ConcurrentSkipListMap.Node<K,V> n = hiNode(); | ||
| 2605 | if (n != null) { | ||
| 2606 | K last = n.key; | ||
| 2607 | if (inBounds(last)) | ||
| 2608 | return last; | ||
| 2609 | } | ||
| 2610 | throw new NoSuchElementException(); | ||
| 2611 | } | ||
| 2612 | |||
| 2613 | private Map.Entry<K,V> lowestEntry() { | ||
| 2614 | for (;;) { | ||
| 2615 | ConcurrentSkipListMap.Node<K,V> n = loNode(); | ||
| 2616 | if (!isBeforeEnd(n)) | ||
| 2617 | return null; | ||
| 2618 | Map.Entry<K,V> e = n.createSnapshot(); | ||
| 2619 | if (e != null) | ||
| 2620 | return e; | ||
| 2621 | } | ||
| 2622 | } | ||
| 2623 | |||
| 2624 | private Map.Entry<K,V> highestEntry() { | ||
| 2625 | for (;;) { | ||
| 2626 | ConcurrentSkipListMap.Node<K,V> n = hiNode(); | ||
| 2627 | if (n == null || !inBounds(n.key)) | ||
| 2628 | return null; | ||
| 2629 | Map.Entry<K,V> e = n.createSnapshot(); | ||
| 2630 | if (e != null) | ||
| 2631 | return e; | ||
| 2632 | } | ||
| 2633 | } | ||
| 2634 | |||
| 2635 | private Map.Entry<K,V> removeLowest() { | ||
| 2636 | for (;;) { | ||
| 2637 | Node<K,V> n = loNode(); | ||
| 2638 | if (n == null) | ||
| 2639 | return null; | ||
| 2640 | K k = n.key; | ||
| 2641 | if (!inBounds(k)) | ||
| 2642 | return null; | ||
| 2643 | V v = m.doRemove(k, null); | ||
| 2644 | if (v != null) | ||
| 2645 | return new AbstractMap.SimpleImmutableEntry<K,V>(k, v); | ||
| 2646 | } | ||
| 2647 | } | ||
| 2648 | |||
| 2649 | private Map.Entry<K,V> removeHighest() { | ||
| 2650 | for (;;) { | ||
| 2651 | Node<K,V> n = hiNode(); | ||
| 2652 | if (n == null) | ||
| 2653 | return null; | ||
| 2654 | K k = n.key; | ||
| 2655 | if (!inBounds(k)) | ||
| 2656 | return null; | ||
| 2657 | V v = m.doRemove(k, null); | ||
| 2658 | if (v != null) | ||
| 2659 | return new AbstractMap.SimpleImmutableEntry<K,V>(k, v); | ||
| 2660 | } | ||
| 2661 | } | ||
| 2662 | |||
| 2663 | /** | ||
| 2664 | * Submap version of ConcurrentSkipListMap.getNearEntry | ||
| 2665 | */ | ||
| 2666 | private Map.Entry<K,V> getNearEntry(K key, int rel) { | ||
| 2667 | if (isDescending) { // adjust relation for direction | ||
| 2668 | if ((rel & m.LT) == 0) | ||
| 2669 | rel |= m.LT; | ||
| 2670 | else | ||
| 2671 | rel &= ~m.LT; | ||
| 2672 | } | ||
| 2673 | if (tooLow(key)) | ||
| 2674 | return ((rel & m.LT) != 0) ? null : lowestEntry(); | ||
| 2675 | if (tooHigh(key)) | ||
| 2676 | return ((rel & m.LT) != 0) ? highestEntry() : null; | ||
| 2677 | for (;;) { | ||
| 2678 | Node<K,V> n = m.findNear(key, rel); | ||
| 2679 | if (n == null || !inBounds(n.key)) | ||
| 2680 | return null; | ||
| 2681 | K k = n.key; | ||
| 2682 | V v = n.getValidValue(); | ||
| 2683 | if (v != null) | ||
| 2684 | return new AbstractMap.SimpleImmutableEntry<K,V>(k, v); | ||
| 2685 | } | ||
| 2686 | } | ||
| 2687 | |||
| 2688 | // Almost the same as getNearEntry, except for keys | ||
| 2689 | private K getNearKey(K key, int rel) { | ||
| 2690 | if (isDescending) { // adjust relation for direction | ||
| 2691 | if ((rel & m.LT) == 0) | ||
| 2692 | rel |= m.LT; | ||
| 2693 | else | ||
| 2694 | rel &= ~m.LT; | ||
| 2695 | } | ||
| 2696 | if (tooLow(key)) { | ||
| 2697 | if ((rel & m.LT) == 0) { | ||
| 2698 | ConcurrentSkipListMap.Node<K,V> n = loNode(); | ||
| 2699 | if (isBeforeEnd(n)) | ||
| 2700 | return n.key; | ||
| 2701 | } | ||
| 2702 | return null; | ||
| 2703 | } | ||
| 2704 | if (tooHigh(key)) { | ||
| 2705 | if ((rel & m.LT) != 0) { | ||
| 2706 | ConcurrentSkipListMap.Node<K,V> n = hiNode(); | ||
| 2707 | if (n != null) { | ||
| 2708 | K last = n.key; | ||
| 2709 | if (inBounds(last)) | ||
| 2710 | return last; | ||
| 2711 | } | ||
| 2712 | } | ||
| 2713 | return null; | ||
| 2714 | } | ||
| 2715 | for (;;) { | ||
| 2716 | Node<K,V> n = m.findNear(key, rel); | ||
| 2717 | if (n == null || !inBounds(n.key)) | ||
| 2718 | return null; | ||
| 2719 | K k = n.key; | ||
| 2720 | V v = n.getValidValue(); | ||
| 2721 | if (v != null) | ||
| 2722 | return k; | ||
| 2723 | } | ||
| 2724 | } | ||
| 2725 | |||
| 2726 | /* ---------------- Map API methods -------------- */ | ||
| 2727 | |||
| 2728 | public boolean containsKey(Object key) { | ||
| 2729 | if (key == null) throw new NullPointerException(); | ||
| 2730 | K k = (K)key; | ||
| 2731 | return inBounds(k) && m.containsKey(k); | ||
| 2732 | } | ||
| 2733 | |||
| 2734 | public V get(Object key) { | ||
| 2735 | if (key == null) throw new NullPointerException(); | ||
| 2736 | K k = (K)key; | ||
| 2737 | return ((!inBounds(k)) ? null : m.get(k)); | ||
| 2738 | } | ||
| 2739 | |||
| 2740 | public V put(K key, V value) { | ||
| 2741 | checkKeyBounds(key); | ||
| 2742 | return m.put(key, value); | ||
| 2743 | } | ||
| 2744 | |||
| 2745 | public V remove(Object key) { | ||
| 2746 | K k = (K)key; | ||
| 2747 | return (!inBounds(k)) ? null : m.remove(k); | ||
| 2748 | } | ||
| 2749 | |||
| 2750 | public int size() { | ||
| 2751 | long count = 0; | ||
| 2752 | for (ConcurrentSkipListMap.Node<K,V> n = loNode(); | ||
| 2753 | isBeforeEnd(n); | ||
| 2754 | n = n.next) { | ||
| 2755 | if (n.getValidValue() != null) | ||
| 2756 | ++count; | ||
| 2757 | } | ||
| 2758 | return count >= Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)count; | ||
| 2759 | } | ||
| 2760 | |||
| 2761 | public boolean isEmpty() { | ||
| 2762 | return !isBeforeEnd(loNode()); | ||
| 2763 | } | ||
| 2764 | |||
| 2765 | public boolean containsValue(Object value) { | ||
| 2766 | if (value == null) | ||
| 2767 | throw new NullPointerException(); | ||
| 2768 | for (ConcurrentSkipListMap.Node<K,V> n = loNode(); | ||
| 2769 | isBeforeEnd(n); | ||
| 2770 | n = n.next) { | ||
| 2771 | V v = n.getValidValue(); | ||
| 2772 | if (v != null && value.equals(v)) | ||
| 2773 | return true; | ||
| 2774 | } | ||
| 2775 | return false; | ||
| 2776 | } | ||
| 2777 | |||
| 2778 | public void clear() { | ||
| 2779 | for (ConcurrentSkipListMap.Node<K,V> n = loNode(); | ||
| 2780 | isBeforeEnd(n); | ||
| 2781 | n = n.next) { | ||
| 2782 | if (n.getValidValue() != null) | ||
| 2783 | m.remove(n.key); | ||
| 2784 | } | ||
| 2785 | } | ||
| 2786 | |||
| 2787 | /* ---------------- ConcurrentMap API methods -------------- */ | ||
| 2788 | |||
| 2789 | public V putIfAbsent(K key, V value) { | ||
| 2790 | checkKeyBounds(key); | ||
| 2791 | return m.putIfAbsent(key, value); | ||
| 2792 | } | ||
| 2793 | |||
| 2794 | public boolean remove(Object key, Object value) { | ||
| 2795 | K k = (K)key; | ||
| 2796 | return inBounds(k) && m.remove(k, value); | ||
| 2797 | } | ||
| 2798 | |||
| 2799 | public boolean replace(K key, V oldValue, V newValue) { | ||
| 2800 | checkKeyBounds(key); | ||
| 2801 | return m.replace(key, oldValue, newValue); | ||
| 2802 | } | ||
| 2803 | |||
| 2804 | public V replace(K key, V value) { | ||
| 2805 | checkKeyBounds(key); | ||
| 2806 | return m.replace(key, value); | ||
| 2807 | } | ||
| 2808 | |||
| 2809 | /* ---------------- SortedMap API methods -------------- */ | ||
| 2810 | |||
| 2811 | public Comparator<? super K> comparator() { | ||
| 2812 | Comparator<? super K> cmp = m.comparator(); | ||
| 2813 | if (isDescending) | ||
| 2814 | return Collections.reverseOrder(cmp); | ||
| 2815 | else | ||
| 2816 | return cmp; | ||
| 2817 | } | ||
| 2818 | |||
| 2819 | /** | ||
| 2820 | * Utility to create submaps, where given bounds override | ||
| 2821 | * unbounded(null) ones and/or are checked against bounded ones. | ||
| 2822 | */ | ||
| 2823 | private SubMap<K,V> newSubMap(K fromKey, | ||
| 2824 | boolean fromInclusive, | ||
| 2825 | K toKey, | ||
| 2826 | boolean toInclusive) { | ||
| 2827 | if (isDescending) { // flip senses | ||
| 2828 | K tk = fromKey; | ||
| 2829 | fromKey = toKey; | ||
| 2830 | toKey = tk; | ||
| 2831 | boolean ti = fromInclusive; | ||
| 2832 | fromInclusive = toInclusive; | ||
| 2833 | toInclusive = ti; | ||
| 2834 | } | ||
| 2835 | if (lo != null) { | ||
| 2836 | if (fromKey == null) { | ||
| 2837 | fromKey = lo; | ||
| 2838 | fromInclusive = loInclusive; | ||
| 2839 | } | ||
| 2840 | else { | ||
| 2841 | int c = m.compare(fromKey, lo); | ||
| 2842 | if (c < 0 || (c == 0 && !loInclusive && fromInclusive)) | ||
| 2843 | throw new IllegalArgumentException("key out of range"); | ||
| 2844 | } | ||
| 2845 | } | ||
| 2846 | if (hi != null) { | ||
| 2847 | if (toKey == null) { | ||
| 2848 | toKey = hi; | ||
| 2849 | toInclusive = hiInclusive; | ||
| 2850 | } | ||
| 2851 | else { | ||
| 2852 | int c = m.compare(toKey, hi); | ||
| 2853 | if (c > 0 || (c == 0 && !hiInclusive && toInclusive)) | ||
| 2854 | throw new IllegalArgumentException("key out of range"); | ||
| 2855 | } | ||
| 2856 | } | ||
| 2857 | return new SubMap<K,V>(m, fromKey, fromInclusive, | ||
| 2858 | toKey, toInclusive, isDescending); | ||
| 2859 | } | ||
| 2860 | |||
| 2861 | public SubMap<K,V> subMap(K fromKey, | ||
| 2862 | boolean fromInclusive, | ||
| 2863 | K toKey, | ||
| 2864 | boolean toInclusive) { | ||
| 2865 | if (fromKey == null || toKey == null) | ||
| 2866 | throw new NullPointerException(); | ||
| 2867 | return newSubMap(fromKey, fromInclusive, toKey, toInclusive); | ||
| 2868 | } | ||
| 2869 | |||
| 2870 | public SubMap<K,V> headMap(K toKey, | ||
| 2871 | boolean inclusive) { | ||
| 2872 | if (toKey == null) | ||
| 2873 | throw new NullPointerException(); | ||
| 2874 | return newSubMap(null, false, toKey, inclusive); | ||
| 2875 | } | ||
| 2876 | |||
| 2877 | public SubMap<K,V> tailMap(K fromKey, | ||
| 2878 | boolean inclusive) { | ||
| 2879 | if (fromKey == null) | ||
| 2880 | throw new NullPointerException(); | ||
| 2881 | return newSubMap(fromKey, inclusive, null, false); | ||
| 2882 | } | ||
| 2883 | |||
| 2884 | public SubMap<K,V> subMap(K fromKey, K toKey) { | ||
| 2885 | return subMap(fromKey, true, toKey, false); | ||
| 2886 | } | ||
| 2887 | |||
| 2888 | public SubMap<K,V> headMap(K toKey) { | ||
| 2889 | return headMap(toKey, false); | ||
| 2890 | } | ||
| 2891 | |||
| 2892 | public SubMap<K,V> tailMap(K fromKey) { | ||
| 2893 | return tailMap(fromKey, true); | ||
| 2894 | } | ||
| 2895 | |||
| 2896 | public SubMap<K,V> descendingMap() { | ||
| 2897 | return new SubMap<K,V>(m, lo, loInclusive, | ||
| 2898 | hi, hiInclusive, !isDescending); | ||
| 2899 | } | ||
| 2900 | |||
| 2901 | /* ---------------- Relational methods -------------- */ | ||
| 2902 | |||
| 2903 | public Map.Entry<K,V> ceilingEntry(K key) { | ||
| 2904 | return getNearEntry(key, (m.GT|m.EQ)); | ||
| 2905 | } | ||
| 2906 | |||
| 2907 | public K ceilingKey(K key) { | ||
| 2908 | return getNearKey(key, (m.GT|m.EQ)); | ||
| 2909 | } | ||
| 2910 | |||
| 2911 | public Map.Entry<K,V> lowerEntry(K key) { | ||
| 2912 | return getNearEntry(key, (m.LT)); | ||
| 2913 | } | ||
| 2914 | |||
| 2915 | public K lowerKey(K key) { | ||
| 2916 | return getNearKey(key, (m.LT)); | ||
| 2917 | } | ||
| 2918 | |||
| 2919 | public Map.Entry<K,V> floorEntry(K key) { | ||
| 2920 | return getNearEntry(key, (m.LT|m.EQ)); | ||
| 2921 | } | ||
| 2922 | |||
| 2923 | public K floorKey(K key) { | ||
| 2924 | return getNearKey(key, (m.LT|m.EQ)); | ||
| 2925 | } | ||
| 2926 | |||
| 2927 | public Map.Entry<K,V> higherEntry(K key) { | ||
| 2928 | return getNearEntry(key, (m.GT)); | ||
| 2929 | } | ||
| 2930 | |||
| 2931 | public K higherKey(K key) { | ||
| 2932 | return getNearKey(key, (m.GT)); | ||
| 2933 | } | ||
| 2934 | |||
| 2935 | public K firstKey() { | ||
| 2936 | return isDescending ? highestKey() : lowestKey(); | ||
| 2937 | } | ||
| 2938 | |||
| 2939 | public K lastKey() { | ||
| 2940 | return isDescending ? lowestKey() : highestKey(); | ||
| 2941 | } | ||
| 2942 | |||
| 2943 | public Map.Entry<K,V> firstEntry() { | ||
| 2944 | return isDescending ? highestEntry() : lowestEntry(); | ||
| 2945 | } | ||
| 2946 | |||
| 2947 | public Map.Entry<K,V> lastEntry() { | ||
| 2948 | return isDescending ? lowestEntry() : highestEntry(); | ||
| 2949 | } | ||
| 2950 | |||
| 2951 | public Map.Entry<K,V> pollFirstEntry() { | ||
| 2952 | return isDescending ? removeHighest() : removeLowest(); | ||
| 2953 | } | ||
| 2954 | |||
| 2955 | public Map.Entry<K,V> pollLastEntry() { | ||
| 2956 | return isDescending ? removeLowest() : removeHighest(); | ||
| 2957 | } | ||
| 2958 | |||
| 2959 | /* ---------------- Submap Views -------------- */ | ||
| 2960 | |||
| 2961 | public NavigableSet<K> keySet() { | ||
| 2962 | KeySet<K> ks = keySetView; | ||
| 2963 | return (ks != null) ? ks : (keySetView = new KeySet(this)); | ||
| 2964 | } | ||
| 2965 | |||
| 2966 | public NavigableSet<K> navigableKeySet() { | ||
| 2967 | KeySet<K> ks = keySetView; | ||
| 2968 | return (ks != null) ? ks : (keySetView = new KeySet(this)); | ||
| 2969 | } | ||
| 2970 | |||
| 2971 | public Collection<V> values() { | ||
| 2972 | Collection<V> vs = valuesView; | ||
| 2973 | return (vs != null) ? vs : (valuesView = new Values(this)); | ||
| 2974 | } | ||
| 2975 | |||
| 2976 | public Set<Map.Entry<K,V>> entrySet() { | ||
| 2977 | Set<Map.Entry<K,V>> es = entrySetView; | ||
| 2978 | return (es != null) ? es : (entrySetView = new EntrySet(this)); | ||
| 2979 | } | ||
| 2980 | |||
| 2981 | public NavigableSet<K> descendingKeySet() { | ||
| 2982 | return descendingMap().navigableKeySet(); | ||
| 2983 | } | ||
| 2984 | |||
| 2985 | Iterator<K> keyIterator() { | ||
| 2986 | return new SubMapKeyIterator(); | ||
| 2987 | } | ||
| 2988 | |||
| 2989 | Iterator<V> valueIterator() { | ||
| 2990 | return new SubMapValueIterator(); | ||
| 2991 | } | ||
| 2992 | |||
| 2993 | Iterator<Map.Entry<K,V>> entryIterator() { | ||
| 2994 | return new SubMapEntryIterator(); | ||
| 2995 | } | ||
| 2996 | |||
| 2997 | /** | ||
| 2998 | * Variant of main Iter class to traverse through submaps. | ||
| 2999 | */ | ||
| 3000 | abstract class SubMapIter<T> implements Iterator<T> { | ||
| 3001 | /** the last node returned by next() */ | ||
| 3002 | Node<K,V> lastReturned; | ||
| 3003 | /** the next node to return from next(); */ | ||
| 3004 | Node<K,V> next; | ||
| 3005 | /** Cache of next value field to maintain weak consistency */ | ||
| 3006 | V nextValue; | ||
| 3007 | |||
| 3008 | SubMapIter() { | ||
| 3009 | for (;;) { | ||
| 3010 | next = isDescending ? hiNode() : loNode(); | ||
| 3011 | if (next == null) | ||
| 3012 | break; | ||
| 3013 | Object x = next.value; | ||
| 3014 | if (x != null && x != next) { | ||
| 3015 | if (! inBounds(next.key)) | ||
| 3016 | next = null; | ||
| 3017 | else | ||
| 3018 | nextValue = (V) x; | ||
| 3019 | break; | ||
| 3020 | } | ||
| 3021 | } | ||
| 3022 | } | ||
| 3023 | |||
| 3024 | public final boolean hasNext() { | ||
| 3025 | return next != null; | ||
| 3026 | } | ||
| 3027 | |||
| 3028 | final void advance() { | ||
| 3029 | if (next == null) | ||
| 3030 | throw new NoSuchElementException(); | ||
| 3031 | lastReturned = next; | ||
| 3032 | if (isDescending) | ||
| 3033 | descend(); | ||
| 3034 | else | ||
| 3035 | ascend(); | ||
| 3036 | } | ||
| 3037 | |||
| 3038 | private void ascend() { | ||
| 3039 | for (;;) { | ||
| 3040 | next = next.next; | ||
| 3041 | if (next == null) | ||
| 3042 | break; | ||
| 3043 | Object x = next.value; | ||
| 3044 | if (x != null && x != next) { | ||
| 3045 | if (tooHigh(next.key)) | ||
| 3046 | next = null; | ||
| 3047 | else | ||
| 3048 | nextValue = (V) x; | ||
| 3049 | break; | ||
| 3050 | } | ||
| 3051 | } | ||
| 3052 | } | ||
| 3053 | |||
| 3054 | private void descend() { | ||
| 3055 | for (;;) { | ||
| 3056 | next = m.findNear(lastReturned.key, LT); | ||
| 3057 | if (next == null) | ||
| 3058 | break; | ||
| 3059 | Object x = next.value; | ||
| 3060 | if (x != null && x != next) { | ||
| 3061 | if (tooLow(next.key)) | ||
| 3062 | next = null; | ||
| 3063 | else | ||
| 3064 | nextValue = (V) x; | ||
| 3065 | break; | ||
| 3066 | } | ||
| 3067 | } | ||
| 3068 | } | ||
| 3069 | |||
| 3070 | public void remove() { | ||
| 3071 | Node<K,V> l = lastReturned; | ||
| 3072 | if (l == null) | ||
| 3073 | throw new IllegalStateException(); | ||
| 3074 | m.remove(l.key); | ||
| 3075 | lastReturned = null; | ||
| 3076 | } | ||
| 3077 | |||
| 3078 | } | ||
| 3079 | |||
| 3080 | final class SubMapValueIterator extends SubMapIter<V> { | ||
| 3081 | public V next() { | ||
| 3082 | V v = nextValue; | ||
| 3083 | advance(); | ||
| 3084 | return v; | ||
| 3085 | } | ||
| 3086 | } | ||
| 3087 | |||
| 3088 | final class SubMapKeyIterator extends SubMapIter<K> { | ||
| 3089 | public K next() { | ||
| 3090 | Node<K,V> n = next; | ||
| 3091 | advance(); | ||
| 3092 | return n.key; | ||
| 3093 | } | ||
| 3094 | } | ||
| 3095 | |||
| 3096 | final class SubMapEntryIterator extends SubMapIter<Map.Entry<K,V>> { | ||
| 3097 | public Map.Entry<K,V> next() { | ||
| 3098 | Node<K,V> n = next; | ||
| 3099 | V v = nextValue; | ||
| 3100 | advance(); | ||
| 3101 | return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, v); | ||
| 3102 | } | ||
| 3103 | } | ||
| 3104 | } | ||
| 3105 | |||
| 3106 | // Unsafe mechanics | ||
| 3107 | private static final sun.misc.Unsafe UNSAFE; | ||
| 3108 | private static final long headOffset; | ||
| 3109 | static { | ||
| 3110 | try { | ||
| 3111 | UNSAFE = sun.misc.Unsafe.getUnsafe(); | ||
| 3112 | Class k = ConcurrentSkipListMap.class; | ||
| 3113 | headOffset = UNSAFE.objectFieldOffset | ||
| 3114 | (k.getDeclaredField("head")); | ||
| 3115 | } catch (Exception e) { | ||
| 3116 | throw new Error(e); | ||
| 3117 | } | ||
| 3118 | } | ||
| 3119 | } | ||
Binary file not shown.
| @@ -0,0 +1,491 @@ | |||
| 1 | /* | ||
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 3 | * | ||
| 4 | * This code is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License version 2 only, as | ||
| 6 | * published by the Free Software Foundation. Oracle designates this | ||
| 7 | * particular file as subject to the "Classpath" exception as provided | ||
| 8 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 9 | * | ||
| 10 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 13 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 14 | * accompanied this code). | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License version | ||
| 17 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | * | ||
| 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 21 | * or visit www.oracle.com if you need additional information or have any | ||
| 22 | * questions. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * This file is available under and governed by the GNU General Public | ||
| 27 | * License version 2 only, as published by the Free Software Foundation. | ||
| 28 | * However, the following notice accompanied the original version of this | ||
| 29 | * file: | ||
| 30 | * | ||
| 31 | * Written by Doug Lea with assistance from members of JCP JSR-166 | ||
| 32 | * Expert Group and released to the public domain, as explained at | ||
| 33 | * http://creativecommons.org/publicdomain/zero/1.0/ | ||
| 34 | */ | ||
| 35 | |||
| 36 | package java.util.concurrent; | ||
| 37 | import java.util.*; | ||
| 38 | import sun.misc.Unsafe; | ||
| 39 | |||
| 40 | /** | ||
| 41 | * A scalable concurrent {@link NavigableSet} implementation based on | ||
| 42 | * a {@link ConcurrentSkipListMap}. The elements of the set are kept | ||
| 43 | * sorted according to their {@linkplain Comparable natural ordering}, | ||
| 44 | * or by a {@link Comparator} provided at set creation time, depending | ||
| 45 | * on which constructor is used. | ||
| 46 | * | ||
| 47 | * <p>This implementation provides expected average <i>log(n)</i> time | ||
| 48 | * cost for the <tt>contains</tt>, <tt>add</tt>, and <tt>remove</tt> | ||
| 49 | * operations and their variants. Insertion, removal, and access | ||
| 50 | * operations safely execute concurrently by multiple threads. | ||
| 51 | * Iterators are <i>weakly consistent</i>, returning elements | ||
| 52 | * reflecting the state of the set at some point at or since the | ||
| 53 | * creation of the iterator. They do <em>not</em> throw {@link | ||
| 54 | * ConcurrentModificationException}, and may proceed concurrently with | ||
| 55 | * other operations. Ascending ordered views and their iterators are | ||
| 56 | * faster than descending ones. | ||
| 57 | * | ||
| 58 | * <p>Beware that, unlike in most collections, the <tt>size</tt> | ||
| 59 | * method is <em>not</em> a constant-time operation. Because of the | ||
| 60 | * asynchronous nature of these sets, determining the current number | ||
| 61 | * of elements requires a traversal of the elements, and so may report | ||
| 62 | * inaccurate results if this collection is modified during traversal. | ||
| 63 | * Additionally, the bulk operations <tt>addAll</tt>, | ||
| 64 | * <tt>removeAll</tt>, <tt>retainAll</tt>, <tt>containsAll</tt>, | ||
| 65 | * <tt>equals</tt>, and <tt>toArray</tt> are <em>not</em> guaranteed | ||
| 66 | * to be performed atomically. For example, an iterator operating | ||
| 67 | * concurrently with an <tt>addAll</tt> operation might view only some | ||
| 68 | * of the added elements. | ||
| 69 | * | ||
| 70 | * <p>This class and its iterators implement all of the | ||
| 71 | * <em>optional</em> methods of the {@link Set} and {@link Iterator} | ||
| 72 | * interfaces. Like most other concurrent collection implementations, | ||
| 73 | * this class does not permit the use of <tt>null</tt> elements, | ||
| 74 | * because <tt>null</tt> arguments and return values cannot be reliably | ||
| 75 | * distinguished from the absence of elements. | ||
| 76 | * | ||
| 77 | * <p>This class is a member of the | ||
| 78 | * <a href="{@docRoot}/../technotes/guides/collections/index.html"> | ||
| 79 | * Java Collections Framework</a>. | ||
| 80 | * | ||
| 81 | * @author Doug Lea | ||
| 82 | * @param <E> the type of elements maintained by this set | ||
| 83 | * @since 1.6 | ||
| 84 | */ | ||
| 85 | public class ConcurrentSkipListSet<E> | ||
| 86 | extends AbstractSet<E> | ||
| 87 | implements NavigableSet<E>, Cloneable, java.io.Serializable { | ||
| 88 | |||
| 89 | private static final long serialVersionUID = -2479143111061671589L; | ||
| 90 | |||
| 91 | /** | ||
| 92 | * The underlying map. Uses Boolean.TRUE as value for each | ||
| 93 | * element. This field is declared final for the sake of thread | ||
| 94 | * safety, which entails some ugliness in clone() | ||
| 95 | */ | ||
| 96 | private final ConcurrentNavigableMap<E,Object> m; | ||
| 97 | |||
| 98 | /** | ||
| 99 | * Constructs a new, empty set that orders its elements according to | ||
| 100 | * their {@linkplain Comparable natural ordering}. | ||
| 101 | */ | ||
| 102 | public ConcurrentSkipListSet() { | ||
| 103 | m = new ConcurrentSkipListMap<E,Object>(); | ||
| 104 | } | ||
| 105 | |||
| 106 | /** | ||
| 107 | * Constructs a new, empty set that orders its elements according to | ||
| 108 | * the specified comparator. | ||
| 109 | * | ||
| 110 | * @param comparator the comparator that will be used to order this set. | ||
| 111 | * If <tt>null</tt>, the {@linkplain Comparable natural | ||
| 112 | * ordering} of the elements will be used. | ||
| 113 | */ | ||
| 114 | public ConcurrentSkipListSet(Comparator<? super E> comparator) { | ||
| 115 | m = new ConcurrentSkipListMap<E,Object>(comparator); | ||
| 116 | } | ||
| 117 | |||
| 118 | /** | ||
| 119 | * Constructs a new set containing the elements in the specified | ||
| 120 | * collection, that orders its elements according to their | ||
| 121 | * {@linkplain Comparable natural ordering}. | ||
| 122 | * | ||
| 123 | * @param c The elements that will comprise the new set | ||
| 124 | * @throws ClassCastException if the elements in <tt>c</tt> are | ||
| 125 | * not {@link Comparable}, or are not mutually comparable | ||
| 126 | * @throws NullPointerException if the specified collection or any | ||
| 127 | * of its elements are null | ||
| 128 | */ | ||
| 129 | public ConcurrentSkipListSet(Collection<? extends E> c) { | ||
| 130 | m = new ConcurrentSkipListMap<E,Object>(); | ||
| 131 | addAll(c); | ||
| 132 | } | ||
| 133 | |||
| 134 | /** | ||
| 135 | * Constructs a new set containing the same elements and using the | ||
| 136 | * same ordering as the specified sorted set. | ||
| 137 | * | ||
| 138 | * @param s sorted set whose elements will comprise the new set | ||
| 139 | * @throws NullPointerException if the specified sorted set or any | ||
| 140 | * of its elements are null | ||
| 141 | */ | ||
| 142 | public ConcurrentSkipListSet(SortedSet<E> s) { | ||
| 143 | m = new ConcurrentSkipListMap<E,Object>(s.comparator()); | ||
| 144 | addAll(s); | ||
| 145 | } | ||
| 146 | |||
| 147 | /** | ||
| 148 | * For use by submaps | ||
| 149 | */ | ||
| 150 | ConcurrentSkipListSet(ConcurrentNavigableMap<E,Object> m) { | ||
| 151 | this.m = m; | ||
| 152 | } | ||
| 153 | |||
| 154 | /** | ||
| 155 | * Returns a shallow copy of this <tt>ConcurrentSkipListSet</tt> | ||
| 156 | * instance. (The elements themselves are not cloned.) | ||
| 157 | * | ||
| 158 | * @return a shallow copy of this set | ||
| 159 | */ | ||
| 160 | public ConcurrentSkipListSet<E> clone() { | ||
| 161 | ConcurrentSkipListSet<E> clone = null; | ||
| 162 | try { | ||
| 163 | clone = (ConcurrentSkipListSet<E>) super.clone(); | ||
| 164 | clone.setMap(new ConcurrentSkipListMap(m)); | ||
| 165 | } catch (CloneNotSupportedException e) { | ||
| 166 | throw new InternalError(); | ||
| 167 | } | ||
| 168 | |||
| 169 | return clone; | ||
| 170 | } | ||
| 171 | |||
| 172 | /* ---------------- Set operations -------------- */ | ||
| 173 | |||
| 174 | /** | ||
| 175 | * Returns the number of elements in this set. If this set | ||
| 176 | * contains more than <tt>Integer.MAX_VALUE</tt> elements, it | ||
| 177 | * returns <tt>Integer.MAX_VALUE</tt>. | ||
| 178 | * | ||
| 179 | * <p>Beware that, unlike in most collections, this method is | ||
| 180 | * <em>NOT</em> a constant-time operation. Because of the | ||
| 181 | * asynchronous nature of these sets, determining the current | ||
| 182 | * number of elements requires traversing them all to count them. | ||
| 183 | * Additionally, it is possible for the size to change during | ||
| 184 | * execution of this method, in which case the returned result | ||
| 185 | * will be inaccurate. Thus, this method is typically not very | ||
| 186 | * useful in concurrent applications. | ||
| 187 | * | ||
| 188 | * @return the number of elements in this set | ||
| 189 | */ | ||
| 190 | public int size() { | ||
| 191 | return m.size(); | ||
| 192 | } | ||
| 193 | |||
| 194 | /** | ||
| 195 | * Returns <tt>true</tt> if this set contains no elements. | ||
| 196 | * @return <tt>true</tt> if this set contains no elements | ||
| 197 | */ | ||
| 198 | public boolean isEmpty() { | ||
| 199 | return m.isEmpty(); | ||
| 200 | } | ||
| 201 | |||
| 202 | /** | ||
| 203 | * Returns <tt>true</tt> if this set contains the specified element. | ||
| 204 | * More formally, returns <tt>true</tt> if and only if this set | ||
| 205 | * contains an element <tt>e</tt> such that <tt>o.equals(e)</tt>. | ||
| 206 | * | ||
| 207 | * @param o object to be checked for containment in this set | ||
| 208 | * @return <tt>true</tt> if this set contains the specified element | ||
| 209 | * @throws ClassCastException if the specified element cannot be | ||
| 210 | * compared with the elements currently in this set | ||
| 211 | * @throws NullPointerException if the specified element is null | ||
| 212 | */ | ||
| 213 | public boolean contains(Object o) { | ||
| 214 | return m.containsKey(o); | ||
| 215 | } | ||
| 216 | |||
| 217 | /** | ||
| 218 | * Adds the specified element to this set if it is not already present. | ||
| 219 | * More formally, adds the specified element <tt>e</tt> to this set if | ||
| 220 | * the set contains no element <tt>e2</tt> such that <tt>e.equals(e2)</tt>. | ||
| 221 | * If this set already contains the element, the call leaves the set | ||
| 222 | * unchanged and returns <tt>false</tt>. | ||
| 223 | * | ||
| 224 | * @param e element to be added to this set | ||
| 225 | * @return <tt>true</tt> if this set did not already contain the | ||
| 226 | * specified element | ||
| 227 | * @throws ClassCastException if <tt>e</tt> cannot be compared | ||
| 228 | * with the elements currently in this set | ||
| 229 | * @throws NullPointerException if the specified element is null | ||
| 230 | */ | ||
| 231 | public boolean add(E e) { | ||
| 232 | return m.putIfAbsent(e, Boolean.TRUE) == null; | ||
| 233 | } | ||
| 234 | |||
| 235 | /** | ||
| 236 | * Removes the specified element from this set if it is present. | ||
| 237 | * More formally, removes an element <tt>e</tt> such that | ||
| 238 | * <tt>o.equals(e)</tt>, if this set contains such an element. | ||
| 239 | * Returns <tt>true</tt> if this set contained the element (or | ||
| 240 | * equivalently, if this set changed as a result of the call). | ||
| 241 | * (This set will not contain the element once the call returns.) | ||
| 242 | * | ||
| 243 | * @param o object to be removed from this set, if present | ||
| 244 | * @return <tt>true</tt> if this set contained the specified element | ||
| 245 | * @throws ClassCastException if <tt>o</tt> cannot be compared | ||
| 246 | * with the elements currently in this set | ||
| 247 | * @throws NullPointerException if the specified element is null | ||
| 248 | */ | ||
| 249 | public boolean remove(Object o) { | ||
| 250 | return m.remove(o, Boolean.TRUE); | ||
| 251 | } | ||
| 252 | |||
| 253 | /** | ||
| 254 | * Removes all of the elements from this set. | ||
| 255 | */ | ||
| 256 | public void clear() { | ||
| 257 | m.clear(); | ||
| 258 | } | ||
| 259 | |||
| 260 | /** | ||
| 261 | * Returns an iterator over the elements in this set in ascending order. | ||
| 262 | * | ||
| 263 | * @return an iterator over the elements in this set in ascending order | ||
| 264 | */ | ||
| 265 | public Iterator<E> iterator() { | ||
| 266 | return m.navigableKeySet().iterator(); | ||
| 267 | } | ||
| 268 | |||
| 269 | /** | ||
| 270 | * Returns an iterator over the elements in this set in descending order. | ||
| 271 | * | ||
| 272 | * @return an iterator over the elements in this set in descending order | ||
| 273 | */ | ||
| 274 | public Iterator<E> descendingIterator() { | ||
| 275 | return m.descendingKeySet().iterator(); | ||
| 276 | } | ||
| 277 | |||
| 278 | |||
| 279 | /* ---------------- AbstractSet Overrides -------------- */ | ||
| 280 | |||
| 281 | /** | ||
| 282 | * Compares the specified object with this set for equality. Returns | ||
| 283 | * <tt>true</tt> if the specified object is also a set, the two sets | ||
| 284 | * have the same size, and every member of the specified set is | ||
| 285 | * contained in this set (or equivalently, every member of this set is | ||
| 286 | * contained in the specified set). This definition ensures that the | ||
| 287 | * equals method works properly across different implementations of the | ||
| 288 | * set interface. | ||
| 289 | * | ||
| 290 | * @param o the object to be compared for equality with this set | ||
| 291 | * @return <tt>true</tt> if the specified object is equal to this set | ||
| 292 | */ | ||
| 293 | public boolean equals(Object o) { | ||
| 294 | // Override AbstractSet version to avoid calling size() | ||
| 295 | if (o == this) | ||
| 296 | return true; | ||
| 297 | if (!(o instanceof Set)) | ||
| 298 | return false; | ||
| 299 | Collection<?> c = (Collection<?>) o; | ||
| 300 | try { | ||
| 301 | return containsAll(c) && c.containsAll(this); | ||
| 302 | } catch (ClassCastException unused) { | ||
| 303 | return false; | ||
| 304 | } catch (NullPointerException unused) { | ||
| 305 | return false; | ||
| 306 | } | ||
| 307 | } | ||
| 308 | |||
| 309 | /** | ||
| 310 | * Removes from this set all of its elements that are contained in | ||
| 311 | * the specified collection. If the specified collection is also | ||
| 312 | * a set, this operation effectively modifies this set so that its | ||
| 313 | * value is the <i>asymmetric set difference</i> of the two sets. | ||
| 314 | * | ||
| 315 | * @param c collection containing elements to be removed from this set | ||
| 316 | * @return <tt>true</tt> if this set changed as a result of the call | ||
| 317 | * @throws ClassCastException if the types of one or more elements in this | ||
| 318 | * set are incompatible with the specified collection | ||
| 319 | * @throws NullPointerException if the specified collection or any | ||
| 320 | * of its elements are null | ||
| 321 | */ | ||
| 322 | public boolean removeAll(Collection<?> c) { | ||
| 323 | // Override AbstractSet version to avoid unnecessary call to size() | ||
| 324 | boolean modified = false; | ||
| 325 | for (Iterator<?> i = c.iterator(); i.hasNext(); ) | ||
| 326 | if (remove(i.next())) | ||
| 327 | modified = true; | ||
| 328 | return modified; | ||
| 329 | } | ||
| 330 | |||
| 331 | /* ---------------- Relational operations -------------- */ | ||
| 332 | |||
| 333 | /** | ||
| 334 | * @throws ClassCastException {@inheritDoc} | ||
| 335 | * @throws NullPointerException if the specified element is null | ||
| 336 | */ | ||
| 337 | public E lower(E e) { | ||
| 338 | return m.lowerKey(e); | ||
| 339 | } | ||
| 340 | |||
| 341 | /** | ||
| 342 | * @throws ClassCastException {@inheritDoc} | ||
| 343 | * @throws NullPointerException if the specified element is null | ||
| 344 | */ | ||
| 345 | public E floor(E e) { | ||
| 346 | return m.floorKey(e); | ||
| 347 | } | ||
| 348 | |||
| 349 | /** | ||
| 350 | * @throws ClassCastException {@inheritDoc} | ||
| 351 | * @throws NullPointerException if the specified element is null | ||
| 352 | */ | ||
| 353 | public E ceiling(E e) { | ||
| 354 | return m.ceilingKey(e); | ||
| 355 | } | ||
| 356 | |||
| 357 | /** | ||
| 358 | * @throws ClassCastException {@inheritDoc} | ||
| 359 | * @throws NullPointerException if the specified element is null | ||
| 360 | */ | ||
| 361 | public E higher(E e) { | ||
| 362 | return m.higherKey(e); | ||
| 363 | } | ||
| 364 | |||
| 365 | public E pollFirst() { | ||
| 366 | Map.Entry<E,Object> e = m.pollFirstEntry(); | ||
| 367 | return (e == null) ? null : e.getKey(); | ||
| 368 | } | ||
| 369 | |||
| 370 | public E pollLast() { | ||
| 371 | Map.Entry<E,Object> e = m.pollLastEntry(); | ||
| 372 | return (e == null) ? null : e.getKey(); | ||
| 373 | } | ||
| 374 | |||
| 375 | |||
| 376 | /* ---------------- SortedSet operations -------------- */ | ||
| 377 | |||
| 378 | |||
| 379 | public Comparator<? super E> comparator() { | ||
| 380 | return m.comparator(); | ||
| 381 | } | ||
| 382 | |||
| 383 | /** | ||
| 384 | * @throws NoSuchElementException {@inheritDoc} | ||
| 385 | */ | ||
| 386 | public E first() { | ||
| 387 | return m.firstKey(); | ||
| 388 | } | ||
| 389 | |||
| 390 | /** | ||
| 391 | * @throws NoSuchElementException {@inheritDoc} | ||
| 392 | */ | ||
| 393 | public E last() { | ||
| 394 | return m.lastKey(); | ||
| 395 | } | ||
| 396 | |||
| 397 | /** | ||
| 398 | * @throws ClassCastException {@inheritDoc} | ||
| 399 | * @throws NullPointerException if {@code fromElement} or | ||
| 400 | * {@code toElement} is null | ||
| 401 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 402 | */ | ||
| 403 | public NavigableSet<E> subSet(E fromElement, | ||
| 404 | boolean fromInclusive, | ||
| 405 | E toElement, | ||
| 406 | boolean toInclusive) { | ||
| 407 | return new ConcurrentSkipListSet<E> | ||
| 408 | (m.subMap(fromElement, fromInclusive, | ||
| 409 | toElement, toInclusive)); | ||
| 410 | } | ||
| 411 | |||
| 412 | /** | ||
| 413 | * @throws ClassCastException {@inheritDoc} | ||
| 414 | * @throws NullPointerException if {@code toElement} is null | ||
| 415 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 416 | */ | ||
| 417 | public NavigableSet<E> headSet(E toElement, boolean inclusive) { | ||
| 418 | return new ConcurrentSkipListSet<E>(m.headMap(toElement, inclusive)); | ||
| 419 | } | ||
| 420 | |||
| 421 | /** | ||
| 422 | * @throws ClassCastException {@inheritDoc} | ||
| 423 | * @throws NullPointerException if {@code fromElement} is null | ||
| 424 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 425 | */ | ||
| 426 | public NavigableSet<E> tailSet(E fromElement, boolean inclusive) { | ||
| 427 | return new ConcurrentSkipListSet<E>(m.tailMap(fromElement, inclusive)); | ||
| 428 | } | ||
| 429 | |||
| 430 | /** | ||
| 431 | * @throws ClassCastException {@inheritDoc} | ||
| 432 | * @throws NullPointerException if {@code fromElement} or | ||
| 433 | * {@code toElement} is null | ||
| 434 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 435 | */ | ||
| 436 | public NavigableSet<E> subSet(E fromElement, E toElement) { | ||
| 437 | return subSet(fromElement, true, toElement, false); | ||
| 438 | } | ||
| 439 | |||
| 440 | /** | ||
| 441 | * @throws ClassCastException {@inheritDoc} | ||
| 442 | * @throws NullPointerException if {@code toElement} is null | ||
| 443 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 444 | */ | ||
| 445 | public NavigableSet<E> headSet(E toElement) { | ||
| 446 | return headSet(toElement, false); | ||
| 447 | } | ||
| 448 | |||
| 449 | /** | ||
| 450 | * @throws ClassCastException {@inheritDoc} | ||
| 451 | * @throws NullPointerException if {@code fromElement} is null | ||
| 452 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 453 | */ | ||
| 454 | public NavigableSet<E> tailSet(E fromElement) { | ||
| 455 | return tailSet(fromElement, true); | ||
| 456 | } | ||
| 457 | |||
| 458 | /** | ||
| 459 | * Returns a reverse order view of the elements contained in this set. | ||
| 460 | * The descending set is backed by this set, so changes to the set are | ||
| 461 | * reflected in the descending set, and vice-versa. | ||
| 462 | * | ||
| 463 | * <p>The returned set has an ordering equivalent to | ||
| 464 | * <tt>{@link Collections#reverseOrder(Comparator) Collections.reverseOrder}(comparator())</tt>. | ||
| 465 | * The expression {@code s.descendingSet().descendingSet()} returns a | ||
| 466 | * view of {@code s} essentially equivalent to {@code s}. | ||
| 467 | * | ||
| 468 | * @return a reverse order view of this set | ||
| 469 | */ | ||
| 470 | public NavigableSet<E> descendingSet() { | ||
| 471 | return new ConcurrentSkipListSet(m.descendingMap()); | ||
| 472 | } | ||
| 473 | |||
| 474 | // Support for resetting map in clone | ||
| 475 | private void setMap(ConcurrentNavigableMap<E,Object> map) { | ||
| 476 | UNSAFE.putObjectVolatile(this, mapOffset, map); | ||
| 477 | } | ||
| 478 | |||
| 479 | private static final sun.misc.Unsafe UNSAFE; | ||
| 480 | private static final long mapOffset; | ||
| 481 | static { | ||
| 482 | try { | ||
| 483 | UNSAFE = sun.misc.Unsafe.getUnsafe(); | ||
| 484 | Class k = ConcurrentSkipListSet.class; | ||
| 485 | mapOffset = UNSAFE.objectFieldOffset | ||
| 486 | (k.getDeclaredField("m")); | ||
| 487 | } catch (Exception e) { | ||
| 488 | throw new Error(e); | ||
| 489 | } | ||
| 490 | } | ||
| 491 | } | ||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,1340 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | /* | ||
| 27 | * Written by Doug Lea with assistance from members of JCP JSR-166 | ||
| 28 | * Expert Group. Adapted and released, under explicit permission, | ||
| 29 | * from JDK ArrayList.java which carries the following copyright: | ||
| 30 | * | ||
| 31 | * Copyright 1997 by Sun Microsystems, Inc., | ||
| 32 | * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A. | ||
| 33 | * All rights reserved. | ||
| 34 | */ | ||
| 35 | |||
| 36 | package java.util.concurrent; | ||
| 37 | import java.util.*; | ||
| 38 | import java.util.concurrent.locks.*; | ||
| 39 | import sun.misc.Unsafe; | ||
| 40 | |||
| 41 | /** | ||
| 42 | * A thread-safe variant of {@link java.util.ArrayList} in which all mutative | ||
| 43 | * operations (<tt>add</tt>, <tt>set</tt>, and so on) are implemented by | ||
| 44 | * making a fresh copy of the underlying array. | ||
| 45 | * | ||
| 46 | * <p> This is ordinarily too costly, but may be <em>more</em> efficient | ||
| 47 | * than alternatives when traversal operations vastly outnumber | ||
| 48 | * mutations, and is useful when you cannot or don't want to | ||
| 49 | * synchronize traversals, yet need to preclude interference among | ||
| 50 | * concurrent threads. The "snapshot" style iterator method uses a | ||
| 51 | * reference to the state of the array at the point that the iterator | ||
| 52 | * was created. This array never changes during the lifetime of the | ||
| 53 | * iterator, so interference is impossible and the iterator is | ||
| 54 | * guaranteed not to throw <tt>ConcurrentModificationException</tt>. | ||
| 55 | * The iterator will not reflect additions, removals, or changes to | ||
| 56 | * the list since the iterator was created. Element-changing | ||
| 57 | * operations on iterators themselves (<tt>remove</tt>, <tt>set</tt>, and | ||
| 58 | * <tt>add</tt>) are not supported. These methods throw | ||
| 59 | * <tt>UnsupportedOperationException</tt>. | ||
| 60 | * | ||
| 61 | * <p>All elements are permitted, including <tt>null</tt>. | ||
| 62 | * | ||
| 63 | * <p>Memory consistency effects: As with other concurrent | ||
| 64 | * collections, actions in a thread prior to placing an object into a | ||
| 65 | * {@code CopyOnWriteArrayList} | ||
| 66 | * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> | ||
| 67 | * actions subsequent to the access or removal of that element from | ||
| 68 | * the {@code CopyOnWriteArrayList} in another thread. | ||
| 69 | * | ||
| 70 | * <p>This class is a member of the | ||
| 71 | * <a href="{@docRoot}/../technotes/guides/collections/index.html"> | ||
| 72 | * Java Collections Framework</a>. | ||
| 73 | * | ||
| 74 | * @since 1.5 | ||
| 75 | * @author Doug Lea | ||
| 76 | * @param <E> the type of elements held in this collection | ||
| 77 | */ | ||
| 78 | public class CopyOnWriteArrayList<E> | ||
| 79 | implements List<E>, RandomAccess, Cloneable, java.io.Serializable { | ||
| 80 | private static final long serialVersionUID = 8673264195747942595L; | ||
| 81 | |||
| 82 | /** The lock protecting all mutators */ | ||
| 83 | transient final ReentrantLock lock = new ReentrantLock(); | ||
| 84 | |||
| 85 | /** The array, accessed only via getArray/setArray. */ | ||
| 86 | private volatile transient Object[] array; | ||
| 87 | |||
| 88 | /** | ||
| 89 | * Gets the array. Non-private so as to also be accessible | ||
| 90 | * from CopyOnWriteArraySet class. | ||
| 91 | */ | ||
| 92 | final Object[] getArray() { | ||
| 93 | return array; | ||
| 94 | } | ||
| 95 | |||
| 96 | /** | ||
| 97 | * Sets the array. | ||
| 98 | */ | ||
| 99 | final void setArray(Object[] a) { | ||
| 100 | array = a; | ||
| 101 | } | ||
| 102 | |||
| 103 | /** | ||
| 104 | * Creates an empty list. | ||
| 105 | */ | ||
| 106 | public CopyOnWriteArrayList() { | ||
| 107 | setArray(new Object[0]); | ||
| 108 | } | ||
| 109 | |||
| 110 | /** | ||
| 111 | * Creates a list containing the elements of the specified | ||
| 112 | * collection, in the order they are returned by the collection's | ||
| 113 | * iterator. | ||
| 114 | * | ||
| 115 | * @param c the collection of initially held elements | ||
| 116 | * @throws NullPointerException if the specified collection is null | ||
| 117 | */ | ||
| 118 | public CopyOnWriteArrayList(Collection<? extends E> c) { | ||
| 119 | Object[] elements = c.toArray(); | ||
| 120 | // c.toArray might (incorrectly) not return Object[] (see 6260652) | ||
| 121 | if (elements.getClass() != Object[].class) | ||
| 122 | elements = Arrays.copyOf(elements, elements.length, Object[].class); | ||
| 123 | setArray(elements); | ||
| 124 | } | ||
| 125 | |||
| 126 | /** | ||
| 127 | * Creates a list holding a copy of the given array. | ||
| 128 | * | ||
| 129 | * @param toCopyIn the array (a copy of this array is used as the | ||
| 130 | * internal array) | ||
| 131 | * @throws NullPointerException if the specified array is null | ||
| 132 | */ | ||
| 133 | public CopyOnWriteArrayList(E[] toCopyIn) { | ||
| 134 | setArray(Arrays.copyOf(toCopyIn, toCopyIn.length, Object[].class)); | ||
| 135 | } | ||
| 136 | |||
| 137 | /** | ||
| 138 | * Returns the number of elements in this list. | ||
| 139 | * | ||
| 140 | * @return the number of elements in this list | ||
| 141 | */ | ||
| 142 | public int size() { | ||
| 143 | return getArray().length; | ||
| 144 | } | ||
| 145 | |||
| 146 | /** | ||
| 147 | * Returns <tt>true</tt> if this list contains no elements. | ||
| 148 | * | ||
| 149 | * @return <tt>true</tt> if this list contains no elements | ||
| 150 | */ | ||
| 151 | public boolean isEmpty() { | ||
| 152 | return size() == 0; | ||
| 153 | } | ||
| 154 | |||
| 155 | /** | ||
| 156 | * Test for equality, coping with nulls. | ||
| 157 | */ | ||
| 158 | private static boolean eq(Object o1, Object o2) { | ||
| 159 | return (o1 == null ? o2 == null : o1.equals(o2)); | ||
| 160 | } | ||
| 161 | |||
| 162 | /** | ||
| 163 | * static version of indexOf, to allow repeated calls without | ||
| 164 | * needing to re-acquire array each time. | ||
| 165 | * @param o element to search for | ||
| 166 | * @param elements the array | ||
| 167 | * @param index first index to search | ||
| 168 | * @param fence one past last index to search | ||
| 169 | * @return index of element, or -1 if absent | ||
| 170 | */ | ||
| 171 | private static int indexOf(Object o, Object[] elements, | ||
| 172 | int index, int fence) { | ||
| 173 | if (o == null) { | ||
| 174 | for (int i = index; i < fence; i++) | ||
| 175 | if (elements[i] == null) | ||
| 176 | return i; | ||
| 177 | } else { | ||
| 178 | for (int i = index; i < fence; i++) | ||
| 179 | if (o.equals(elements[i])) | ||
| 180 | return i; | ||
| 181 | } | ||
| 182 | return -1; | ||
| 183 | } | ||
| 184 | |||
| 185 | /** | ||
| 186 | * static version of lastIndexOf. | ||
| 187 | * @param o element to search for | ||
| 188 | * @param elements the array | ||
| 189 | * @param index first index to search | ||
| 190 | * @return index of element, or -1 if absent | ||
| 191 | */ | ||
| 192 | private static int lastIndexOf(Object o, Object[] elements, int index) { | ||
| 193 | if (o == null) { | ||
| 194 | for (int i = index; i >= 0; i--) | ||
| 195 | if (elements[i] == null) | ||
| 196 | return i; | ||
| 197 | } else { | ||
| 198 | for (int i = index; i >= 0; i--) | ||
| 199 | if (o.equals(elements[i])) | ||
| 200 | return i; | ||
| 201 | } | ||
| 202 | return -1; | ||
| 203 | } | ||
| 204 | |||
| 205 | /** | ||
| 206 | * Returns <tt>true</tt> if this list contains the specified element. | ||
| 207 | * More formally, returns <tt>true</tt> if and only if this list contains | ||
| 208 | * at least one element <tt>e</tt> such that | ||
| 209 | * <tt>(o==null ? e==null : o.equals(e))</tt>. | ||
| 210 | * | ||
| 211 | * @param o element whose presence in this list is to be tested | ||
| 212 | * @return <tt>true</tt> if this list contains the specified element | ||
| 213 | */ | ||
| 214 | public boolean contains(Object o) { | ||
| 215 | Object[] elements = getArray(); | ||
| 216 | return indexOf(o, elements, 0, elements.length) >= 0; | ||
| 217 | } | ||
| 218 | |||
| 219 | /** | ||
| 220 | * {@inheritDoc} | ||
| 221 | */ | ||
| 222 | public int indexOf(Object o) { | ||
| 223 | Object[] elements = getArray(); | ||
| 224 | return indexOf(o, elements, 0, elements.length); | ||
| 225 | } | ||
| 226 | |||
| 227 | /** | ||
| 228 | * Returns the index of the first occurrence of the specified element in | ||
| 229 | * this list, searching forwards from <tt>index</tt>, or returns -1 if | ||
| 230 | * the element is not found. | ||
| 231 | * More formally, returns the lowest index <tt>i</tt> such that | ||
| 232 | * <tt>(i >= index && (e==null ? get(i)==null : e.equals(get(i))))</tt>, | ||
| 233 | * or -1 if there is no such index. | ||
| 234 | * | ||
| 235 | * @param e element to search for | ||
| 236 | * @param index index to start searching from | ||
| 237 | * @return the index of the first occurrence of the element in | ||
| 238 | * this list at position <tt>index</tt> or later in the list; | ||
| 239 | * <tt>-1</tt> if the element is not found. | ||
| 240 | * @throws IndexOutOfBoundsException if the specified index is negative | ||
| 241 | */ | ||
| 242 | public int indexOf(E e, int index) { | ||
| 243 | Object[] elements = getArray(); | ||
| 244 | return indexOf(e, elements, index, elements.length); | ||
| 245 | } | ||
| 246 | |||
| 247 | /** | ||
| 248 | * {@inheritDoc} | ||
| 249 | */ | ||
| 250 | public int lastIndexOf(Object o) { | ||
| 251 | Object[] elements = getArray(); | ||
| 252 | return lastIndexOf(o, elements, elements.length - 1); | ||
| 253 | } | ||
| 254 | |||
| 255 | /** | ||
| 256 | * Returns the index of the last occurrence of the specified element in | ||
| 257 | * this list, searching backwards from <tt>index</tt>, or returns -1 if | ||
| 258 | * the element is not found. | ||
| 259 | * More formally, returns the highest index <tt>i</tt> such that | ||
| 260 | * <tt>(i <= index && (e==null ? get(i)==null : e.equals(get(i))))</tt>, | ||
| 261 | * or -1 if there is no such index. | ||
| 262 | * | ||
| 263 | * @param e element to search for | ||
| 264 | * @param index index to start searching backwards from | ||
| 265 | * @return the index of the last occurrence of the element at position | ||
| 266 | * less than or equal to <tt>index</tt> in this list; | ||
| 267 | * -1 if the element is not found. | ||
| 268 | * @throws IndexOutOfBoundsException if the specified index is greater | ||
| 269 | * than or equal to the current size of this list | ||
| 270 | */ | ||
| 271 | public int lastIndexOf(E e, int index) { | ||
| 272 | Object[] elements = getArray(); | ||
| 273 | return lastIndexOf(e, elements, index); | ||
| 274 | } | ||
| 275 | |||
| 276 | /** | ||
| 277 | * Returns a shallow copy of this list. (The elements themselves | ||
| 278 | * are not copied.) | ||
| 279 | * | ||
| 280 | * @return a clone of this list | ||
| 281 | */ | ||
| 282 | public Object clone() { | ||
| 283 | try { | ||
| 284 | CopyOnWriteArrayList c = (CopyOnWriteArrayList)(super.clone()); | ||
| 285 | c.resetLock(); | ||
| 286 | return c; | ||
| 287 | } catch (CloneNotSupportedException e) { | ||
| 288 | // this shouldn't happen, since we are Cloneable | ||
| 289 | throw new InternalError(); | ||
| 290 | } | ||
| 291 | } | ||
| 292 | |||
| 293 | /** | ||
| 294 | * Returns an array containing all of the elements in this list | ||
| 295 | * in proper sequence (from first to last element). | ||
| 296 | * | ||
| 297 | * <p>The returned array will be "safe" in that no references to it are | ||
| 298 | * maintained by this list. (In other words, this method must allocate | ||
| 299 | * a new array). The caller is thus free to modify the returned array. | ||
| 300 | * | ||
| 301 | * <p>This method acts as bridge between array-based and collection-based | ||
| 302 | * APIs. | ||
| 303 | * | ||
| 304 | * @return an array containing all the elements in this list | ||
| 305 | */ | ||
| 306 | public Object[] toArray() { | ||
| 307 | Object[] elements = getArray(); | ||
| 308 | return Arrays.copyOf(elements, elements.length); | ||
| 309 | } | ||
| 310 | |||
| 311 | /** | ||
| 312 | * Returns an array containing all of the elements in this list in | ||
| 313 | * proper sequence (from first to last element); the runtime type of | ||
| 314 | * the returned array is that of the specified array. If the list fits | ||
| 315 | * in the specified array, it is returned therein. Otherwise, a new | ||
| 316 | * array is allocated with the runtime type of the specified array and | ||
| 317 | * the size of this list. | ||
| 318 | * | ||
| 319 | * <p>If this list fits in the specified array with room to spare | ||
| 320 | * (i.e., the array has more elements than this list), the element in | ||
| 321 | * the array immediately following the end of the list is set to | ||
| 322 | * <tt>null</tt>. (This is useful in determining the length of this | ||
| 323 | * list <i>only</i> if the caller knows that this list does not contain | ||
| 324 | * any null elements.) | ||
| 325 | * | ||
| 326 | * <p>Like the {@link #toArray()} method, this method acts as bridge between | ||
| 327 | * array-based and collection-based APIs. Further, this method allows | ||
| 328 | * precise control over the runtime type of the output array, and may, | ||
| 329 | * under certain circumstances, be used to save allocation costs. | ||
| 330 | * | ||
| 331 | * <p>Suppose <tt>x</tt> is a list known to contain only strings. | ||
| 332 | * The following code can be used to dump the list into a newly | ||
| 333 | * allocated array of <tt>String</tt>: | ||
| 334 | * | ||
| 335 | * <pre> | ||
| 336 | * String[] y = x.toArray(new String[0]);</pre> | ||
| 337 | * | ||
| 338 | * Note that <tt>toArray(new Object[0])</tt> is identical in function to | ||
| 339 | * <tt>toArray()</tt>. | ||
| 340 | * | ||
| 341 | * @param a the array into which the elements of the list are to | ||
| 342 | * be stored, if it is big enough; otherwise, a new array of the | ||
| 343 | * same runtime type is allocated for this purpose. | ||
| 344 | * @return an array containing all the elements in this list | ||
| 345 | * @throws ArrayStoreException if the runtime type of the specified array | ||
| 346 | * is not a supertype of the runtime type of every element in | ||
| 347 | * this list | ||
| 348 | * @throws NullPointerException if the specified array is null | ||
| 349 | */ | ||
| 350 | @SuppressWarnings("unchecked") | ||
| 351 | public <T> T[] toArray(T a[]) { | ||
| 352 | Object[] elements = getArray(); | ||
| 353 | int len = elements.length; | ||
| 354 | if (a.length < len) | ||
| 355 | return (T[]) Arrays.copyOf(elements, len, a.getClass()); | ||
| 356 | else { | ||
| 357 | System.arraycopy(elements, 0, a, 0, len); | ||
| 358 | if (a.length > len) | ||
| 359 | a[len] = null; | ||
| 360 | return a; | ||
| 361 | } | ||
| 362 | } | ||
| 363 | |||
| 364 | // Positional Access Operations | ||
| 365 | |||
| 366 | @SuppressWarnings("unchecked") | ||
| 367 | private E get(Object[] a, int index) { | ||
| 368 | return (E) a[index]; | ||
| 369 | } | ||
| 370 | |||
| 371 | /** | ||
| 372 | * {@inheritDoc} | ||
| 373 | * | ||
| 374 | * @throws IndexOutOfBoundsException {@inheritDoc} | ||
| 375 | */ | ||
| 376 | public E get(int index) { | ||
| 377 | return get(getArray(), index); | ||
| 378 | } | ||
| 379 | |||
| 380 | /** | ||
| 381 | * Replaces the element at the specified position in this list with the | ||
| 382 | * specified element. | ||
| 383 | * | ||
| 384 | * @throws IndexOutOfBoundsException {@inheritDoc} | ||
| 385 | */ | ||
| 386 | public E set(int index, E element) { | ||
| 387 | final ReentrantLock lock = this.lock; | ||
| 388 | lock.lock(); | ||
| 389 | try { | ||
| 390 | Object[] elements = getArray(); | ||
| 391 | E oldValue = get(elements, index); | ||
| 392 | |||
| 393 | if (oldValue != element) { | ||
| 394 | int len = elements.length; | ||
| 395 | Object[] newElements = Arrays.copyOf(elements, len); | ||
| 396 | newElements[index] = element; | ||
| 397 | setArray(newElements); | ||
| 398 | } else { | ||
| 399 | // Not quite a no-op; ensures volatile write semantics | ||
| 400 | setArray(elements); | ||
| 401 | } | ||
| 402 | return oldValue; | ||
| 403 | } finally { | ||
| 404 | lock.unlock(); | ||
| 405 | } | ||
| 406 | } | ||
| 407 | |||
| 408 | /** | ||
| 409 | * Appends the specified element to the end of this list. | ||
| 410 | * | ||
| 411 | * @param e element to be appended to this list | ||
| 412 | * @return <tt>true</tt> (as specified by {@link Collection#add}) | ||
| 413 | */ | ||
| 414 | public boolean add(E e) { | ||
| 415 | final ReentrantLock lock = this.lock; | ||
| 416 | lock.lock(); | ||
| 417 | try { | ||
| 418 | Object[] elements = getArray(); | ||
| 419 | int len = elements.length; | ||
| 420 | Object[] newElements = Arrays.copyOf(elements, len + 1); | ||
| 421 | newElements[len] = e; | ||
| 422 | setArray(newElements); | ||
| 423 | return true; | ||
| 424 | } finally { | ||
| 425 | lock.unlock(); | ||
| 426 | } | ||
| 427 | } | ||
| 428 | |||
| 429 | /** | ||
| 430 | * Inserts the specified element at the specified position in this | ||
| 431 | * list. Shifts the element currently at that position (if any) and | ||
| 432 | * any subsequent elements to the right (adds one to their indices). | ||
| 433 | * | ||
| 434 | * @throws IndexOutOfBoundsException {@inheritDoc} | ||
| 435 | */ | ||
| 436 | public void add(int index, E element) { | ||
| 437 | final ReentrantLock lock = this.lock; | ||
| 438 | lock.lock(); | ||
| 439 | try { | ||
| 440 | Object[] elements = getArray(); | ||
| 441 | int len = elements.length; | ||
| 442 | if (index > len || index < 0) | ||
| 443 | throw new IndexOutOfBoundsException("Index: "+index+ | ||
| 444 | ", Size: "+len); | ||
| 445 | Object[] newElements; | ||
| 446 | int numMoved = len - index; | ||
| 447 | if (numMoved == 0) | ||
| 448 | newElements = Arrays.copyOf(elements, len + 1); | ||
| 449 | else { | ||
| 450 | newElements = new Object[len + 1]; | ||
| 451 | System.arraycopy(elements, 0, newElements, 0, index); | ||
| 452 | System.arraycopy(elements, index, newElements, index + 1, | ||
| 453 | numMoved); | ||
| 454 | } | ||
| 455 | newElements[index] = element; | ||
| 456 | setArray(newElements); | ||
| 457 | } finally { | ||
| 458 | lock.unlock(); | ||
| 459 | } | ||
| 460 | } | ||
| 461 | |||
| 462 | /** | ||
| 463 | * Removes the element at the specified position in this list. | ||
| 464 | * Shifts any subsequent elements to the left (subtracts one from their | ||
| 465 | * indices). Returns the element that was removed from the list. | ||
| 466 | * | ||
| 467 | * @throws IndexOutOfBoundsException {@inheritDoc} | ||
| 468 | */ | ||
| 469 | public E remove(int index) { | ||
| 470 | final ReentrantLock lock = this.lock; | ||
| 471 | lock.lock(); | ||
| 472 | try { | ||
| 473 | Object[] elements = getArray(); | ||
| 474 | int len = elements.length; | ||
| 475 | E oldValue = get(elements, index); | ||
| 476 | int numMoved = len - index - 1; | ||
| 477 | if (numMoved == 0) | ||
| 478 | setArray(Arrays.copyOf(elements, len - 1)); | ||
| 479 | else { | ||
| 480 | Object[] newElements = new Object[len - 1]; | ||
| 481 | System.arraycopy(elements, 0, newElements, 0, index); | ||
| 482 | System.arraycopy(elements, index + 1, newElements, index, | ||
| 483 | numMoved); | ||
| 484 | setArray(newElements); | ||
| 485 | } | ||
| 486 | return oldValue; | ||
| 487 | } finally { | ||
| 488 | lock.unlock(); | ||
| 489 | } | ||
| 490 | } | ||
| 491 | |||
| 492 | /** | ||
| 493 | * Removes the first occurrence of the specified element from this list, | ||
| 494 | * if it is present. If this list does not contain the element, it is | ||
| 495 | * unchanged. More formally, removes the element with the lowest index | ||
| 496 | * <tt>i</tt> such that | ||
| 497 | * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt> | ||
| 498 | * (if such an element exists). Returns <tt>true</tt> if this list | ||
| 499 | * contained the specified element (or equivalently, if this list | ||
| 500 | * changed as a result of the call). | ||
| 501 | * | ||
| 502 | * @param o element to be removed from this list, if present | ||
| 503 | * @return <tt>true</tt> if this list contained the specified element | ||
| 504 | */ | ||
| 505 | public boolean remove(Object o) { | ||
| 506 | final ReentrantLock lock = this.lock; | ||
| 507 | lock.lock(); | ||
| 508 | try { | ||
| 509 | Object[] elements = getArray(); | ||
| 510 | int len = elements.length; | ||
| 511 | if (len != 0) { | ||
| 512 | // Copy while searching for element to remove | ||
| 513 | // This wins in the normal case of element being present | ||
| 514 | int newlen = len - 1; | ||
| 515 | Object[] newElements = new Object[newlen]; | ||
| 516 | |||
| 517 | for (int i = 0; i < newlen; ++i) { | ||
| 518 | if (eq(o, elements[i])) { | ||
| 519 | // found one; copy remaining and exit | ||
| 520 | for (int k = i + 1; k < len; ++k) | ||
| 521 | newElements[k-1] = elements[k]; | ||
| 522 | setArray(newElements); | ||
| 523 | return true; | ||
| 524 | } else | ||
| 525 | newElements[i] = elements[i]; | ||
| 526 | } | ||
| 527 | |||
| 528 | // special handling for last cell | ||
| 529 | if (eq(o, elements[newlen])) { | ||
| 530 | setArray(newElements); | ||
| 531 | return true; | ||
| 532 | } | ||
| 533 | } | ||
| 534 | return false; | ||
| 535 | } finally { | ||
| 536 | lock.unlock(); | ||
| 537 | } | ||
| 538 | } | ||
| 539 | |||
| 540 | /** | ||
| 541 | * Removes from this list all of the elements whose index is between | ||
| 542 | * <tt>fromIndex</tt>, inclusive, and <tt>toIndex</tt>, exclusive. | ||
| 543 | * Shifts any succeeding elements to the left (reduces their index). | ||
| 544 | * This call shortens the list by <tt>(toIndex - fromIndex)</tt> elements. | ||
| 545 | * (If <tt>toIndex==fromIndex</tt>, this operation has no effect.) | ||
| 546 | * | ||
| 547 | * @param fromIndex index of first element to be removed | ||
| 548 | * @param toIndex index after last element to be removed | ||
| 549 | * @throws IndexOutOfBoundsException if fromIndex or toIndex out of range | ||
| 550 | * ({@code{fromIndex < 0 || toIndex > size() || toIndex < fromIndex}) | ||
| 551 | */ | ||
| 552 | private void removeRange(int fromIndex, int toIndex) { | ||
| 553 | final ReentrantLock lock = this.lock; | ||
| 554 | lock.lock(); | ||
| 555 | try { | ||
| 556 | Object[] elements = getArray(); | ||
| 557 | int len = elements.length; | ||
| 558 | |||
| 559 | if (fromIndex < 0 || toIndex > len || toIndex < fromIndex) | ||
| 560 | throw new IndexOutOfBoundsException(); | ||
| 561 | int newlen = len - (toIndex - fromIndex); | ||
| 562 | int numMoved = len - toIndex; | ||
| 563 | if (numMoved == 0) | ||
| 564 | setArray(Arrays.copyOf(elements, newlen)); | ||
| 565 | else { | ||
| 566 | Object[] newElements = new Object[newlen]; | ||
| 567 | System.arraycopy(elements, 0, newElements, 0, fromIndex); | ||
| 568 | System.arraycopy(elements, toIndex, newElements, | ||
| 569 | fromIndex, numMoved); | ||
| 570 | setArray(newElements); | ||
| 571 | } | ||
| 572 | } finally { | ||
| 573 | lock.unlock(); | ||
| 574 | } | ||
| 575 | } | ||
| 576 | |||
| 577 | /** | ||
| 578 | * Append the element if not present. | ||
| 579 | * | ||
| 580 | * @param e element to be added to this list, if absent | ||
| 581 | * @return <tt>true</tt> if the element was added | ||
| 582 | */ | ||
| 583 | public boolean addIfAbsent(E e) { | ||
| 584 | final ReentrantLock lock = this.lock; | ||
| 585 | lock.lock(); | ||
| 586 | try { | ||
| 587 | // Copy while checking if already present. | ||
| 588 | // This wins in the most common case where it is not present | ||
| 589 | Object[] elements = getArray(); | ||
| 590 | int len = elements.length; | ||
| 591 | Object[] newElements = new Object[len + 1]; | ||
| 592 | for (int i = 0; i < len; ++i) { | ||
| 593 | if (eq(e, elements[i])) | ||
| 594 | return false; // exit, throwing away copy | ||
| 595 | else | ||
| 596 | newElements[i] = elements[i]; | ||
| 597 | } | ||
| 598 | newElements[len] = e; | ||
| 599 | setArray(newElements); | ||
| 600 | return true; | ||
| 601 | } finally { | ||
| 602 | lock.unlock(); | ||
| 603 | } | ||
| 604 | } | ||
| 605 | |||
| 606 | /** | ||
| 607 | * Returns <tt>true</tt> if this list contains all of the elements of the | ||
| 608 | * specified collection. | ||
| 609 | * | ||
| 610 | * @param c collection to be checked for containment in this list | ||
| 611 | * @return <tt>true</tt> if this list contains all of the elements of the | ||
| 612 | * specified collection | ||
| 613 | * @throws NullPointerException if the specified collection is null | ||
| 614 | * @see #contains(Object) | ||
| 615 | */ | ||
| 616 | public boolean containsAll(Collection<?> c) { | ||
| 617 | Object[] elements = getArray(); | ||
| 618 | int len = elements.length; | ||
| 619 | for (Object e : c) { | ||
| 620 | if (indexOf(e, elements, 0, len) < 0) | ||
| 621 | return false; | ||
| 622 | } | ||
| 623 | return true; | ||
| 624 | } | ||
| 625 | |||
| 626 | /** | ||
| 627 | * Removes from this list all of its elements that are contained in | ||
| 628 | * the specified collection. This is a particularly expensive operation | ||
| 629 | * in this class because of the need for an internal temporary array. | ||
| 630 | * | ||
| 631 | * @param c collection containing elements to be removed from this list | ||
| 632 | * @return <tt>true</tt> if this list changed as a result of the call | ||
| 633 | * @throws ClassCastException if the class of an element of this list | ||
| 634 | * is incompatible with the specified collection | ||
| 635 | * (<a href="../Collection.html#optional-restrictions">optional</a>) | ||
| 636 | * @throws NullPointerException if this list contains a null element and the | ||
| 637 | * specified collection does not permit null elements | ||
| 638 | * (<a href="../Collection.html#optional-restrictions">optional</a>), | ||
| 639 | * or if the specified collection is null | ||
| 640 | * @see #remove(Object) | ||
| 641 | */ | ||
| 642 | public boolean removeAll(Collection<?> c) { | ||
| 643 | final ReentrantLock lock = this.lock; | ||
| 644 | lock.lock(); | ||
| 645 | try { | ||
| 646 | Object[] elements = getArray(); | ||
| 647 | int len = elements.length; | ||
| 648 | if (len != 0) { | ||
| 649 | // temp array holds those elements we know we want to keep | ||
| 650 | int newlen = 0; | ||
| 651 | Object[] temp = new Object[len]; | ||
| 652 | for (int i = 0; i < len; ++i) { | ||
| 653 | Object element = elements[i]; | ||
| 654 | if (!c.contains(element)) | ||
| 655 | temp[newlen++] = element; | ||
| 656 | } | ||
| 657 | if (newlen != len) { | ||
| 658 | setArray(Arrays.copyOf(temp, newlen)); | ||
| 659 | return true; | ||
| 660 | } | ||
| 661 | } | ||
| 662 | return false; | ||
| 663 | } finally { | ||
| 664 | lock.unlock(); | ||
| 665 | } | ||
| 666 | } | ||
| 667 | |||
| 668 | /** | ||
| 669 | * Retains only the elements in this list that are contained in the | ||
| 670 | * specified collection. In other words, removes from this list all of | ||
| 671 | * its elements that are not contained in the specified collection. | ||
| 672 | * | ||
| 673 | * @param c collection containing elements to be retained in this list | ||
| 674 | * @return <tt>true</tt> if this list changed as a result of the call | ||
| 675 | * @throws ClassCastException if the class of an element of this list | ||
| 676 | * is incompatible with the specified collection | ||
| 677 | * (<a href="../Collection.html#optional-restrictions">optional</a>) | ||
| 678 | * @throws NullPointerException if this list contains a null element and the | ||
| 679 | * specified collection does not permit null elements | ||
| 680 | * (<a href="../Collection.html#optional-restrictions">optional</a>), | ||
| 681 | * or if the specified collection is null | ||
| 682 | * @see #remove(Object) | ||
| 683 | */ | ||
| 684 | public boolean retainAll(Collection<?> c) { | ||
| 685 | final ReentrantLock lock = this.lock; | ||
| 686 | lock.lock(); | ||
| 687 | try { | ||
| 688 | Object[] elements = getArray(); | ||
| 689 | int len = elements.length; | ||
| 690 | if (len != 0) { | ||
| 691 | // temp array holds those elements we know we want to keep | ||
| 692 | int newlen = 0; | ||
| 693 | Object[] temp = new Object[len]; | ||
| 694 | for (int i = 0; i < len; ++i) { | ||
| 695 | Object element = elements[i]; | ||
| 696 | if (c.contains(element)) | ||
| 697 | temp[newlen++] = element; | ||
| 698 | } | ||
| 699 | if (newlen != len) { | ||
| 700 | setArray(Arrays.copyOf(temp, newlen)); | ||
| 701 | return true; | ||
| 702 | } | ||
| 703 | } | ||
| 704 | return false; | ||
| 705 | } finally { | ||
| 706 | lock.unlock(); | ||
| 707 | } | ||
| 708 | } | ||
| 709 | |||
| 710 | /** | ||
| 711 | * Appends all of the elements in the specified collection that | ||
| 712 | * are not already contained in this list, to the end of | ||
| 713 | * this list, in the order that they are returned by the | ||
| 714 | * specified collection's iterator. | ||
| 715 | * | ||
| 716 | * @param c collection containing elements to be added to this list | ||
| 717 | * @return the number of elements added | ||
| 718 | * @throws NullPointerException if the specified collection is null | ||
| 719 | * @see #addIfAbsent(Object) | ||
| 720 | */ | ||
| 721 | public int addAllAbsent(Collection<? extends E> c) { | ||
| 722 | Object[] cs = c.toArray(); | ||
| 723 | if (cs.length == 0) | ||
| 724 | return 0; | ||
| 725 | Object[] uniq = new Object[cs.length]; | ||
| 726 | final ReentrantLock lock = this.lock; | ||
| 727 | lock.lock(); | ||
| 728 | try { | ||
| 729 | Object[] elements = getArray(); | ||
| 730 | int len = elements.length; | ||
| 731 | int added = 0; | ||
| 732 | for (int i = 0; i < cs.length; ++i) { // scan for duplicates | ||
| 733 | Object e = cs[i]; | ||
| 734 | if (indexOf(e, elements, 0, len) < 0 && | ||
| 735 | indexOf(e, uniq, 0, added) < 0) | ||
| 736 | uniq[added++] = e; | ||
| 737 | } | ||
| 738 | if (added > 0) { | ||
| 739 | Object[] newElements = Arrays.copyOf(elements, len + added); | ||
| 740 | System.arraycopy(uniq, 0, newElements, len, added); | ||
| 741 | setArray(newElements); | ||
| 742 | } | ||
| 743 | return added; | ||
| 744 | } finally { | ||
| 745 | lock.unlock(); | ||
| 746 | } | ||
| 747 | } | ||
| 748 | |||
| 749 | /** | ||
| 750 | * Removes all of the elements from this list. | ||
| 751 | * The list will be empty after this call returns. | ||
| 752 | */ | ||
| 753 | public void clear() { | ||
| 754 | final ReentrantLock lock = this.lock; | ||
| 755 | lock.lock(); | ||
| 756 | try { | ||
| 757 | setArray(new Object[0]); | ||
| 758 | } finally { | ||
| 759 | lock.unlock(); | ||
| 760 | } | ||
| 761 | } | ||
| 762 | |||
| 763 | /** | ||
| 764 | * Appends all of the elements in the specified collection to the end | ||
| 765 | * of this list, in the order that they are returned by the specified | ||
| 766 | * collection's iterator. | ||
| 767 | * | ||
| 768 | * @param c collection containing elements to be added to this list | ||
| 769 | * @return <tt>true</tt> if this list changed as a result of the call | ||
| 770 | * @throws NullPointerException if the specified collection is null | ||
| 771 | * @see #add(Object) | ||
| 772 | */ | ||
| 773 | public boolean addAll(Collection<? extends E> c) { | ||
| 774 | Object[] cs = c.toArray(); | ||
| 775 | if (cs.length == 0) | ||
| 776 | return false; | ||
| 777 | final ReentrantLock lock = this.lock; | ||
| 778 | lock.lock(); | ||
| 779 | try { | ||
| 780 | Object[] elements = getArray(); | ||
| 781 | int len = elements.length; | ||
| 782 | Object[] newElements = Arrays.copyOf(elements, len + cs.length); | ||
| 783 | System.arraycopy(cs, 0, newElements, len, cs.length); | ||
| 784 | setArray(newElements); | ||
| 785 | return true; | ||
| 786 | } finally { | ||
| 787 | lock.unlock(); | ||
| 788 | } | ||
| 789 | } | ||
| 790 | |||
| 791 | /** | ||
| 792 | * Inserts all of the elements in the specified collection into this | ||
| 793 | * list, starting at the specified position. Shifts the element | ||
| 794 | * currently at that position (if any) and any subsequent elements to | ||
| 795 | * the right (increases their indices). The new elements will appear | ||
| 796 | * in this list in the order that they are returned by the | ||
| 797 | * specified collection's iterator. | ||
| 798 | * | ||
| 799 | * @param index index at which to insert the first element | ||
| 800 | * from the specified collection | ||
| 801 | * @param c collection containing elements to be added to this list | ||
| 802 | * @return <tt>true</tt> if this list changed as a result of the call | ||
| 803 | * @throws IndexOutOfBoundsException {@inheritDoc} | ||
| 804 | * @throws NullPointerException if the specified collection is null | ||
| 805 | * @see #add(int,Object) | ||
| 806 | */ | ||
| 807 | public boolean addAll(int index, Collection<? extends E> c) { | ||
| 808 | Object[] cs = c.toArray(); | ||
| 809 | final ReentrantLock lock = this.lock; | ||
| 810 | lock.lock(); | ||
| 811 | try { | ||
| 812 | Object[] elements = getArray(); | ||
| 813 | int len = elements.length; | ||
| 814 | if (index > len || index < 0) | ||
| 815 | throw new IndexOutOfBoundsException("Index: "+index+ | ||
| 816 | ", Size: "+len); | ||
| 817 | if (cs.length == 0) | ||
| 818 | return false; | ||
| 819 | int numMoved = len - index; | ||
| 820 | Object[] newElements; | ||
| 821 | if (numMoved == 0) | ||
| 822 | newElements = Arrays.copyOf(elements, len + cs.length); | ||
| 823 | else { | ||
| 824 | newElements = new Object[len + cs.length]; | ||
| 825 | System.arraycopy(elements, 0, newElements, 0, index); | ||
| 826 | System.arraycopy(elements, index, | ||
| 827 | newElements, index + cs.length, | ||
| 828 | numMoved); | ||
| 829 | } | ||
| 830 | System.arraycopy(cs, 0, newElements, index, cs.length); | ||
| 831 | setArray(newElements); | ||
| 832 | return true; | ||
| 833 | } finally { | ||
| 834 | lock.unlock(); | ||
| 835 | } | ||
| 836 | } | ||
| 837 | |||
| 838 | /** | ||
| 839 | * Saves the state of the list to a stream (that is, serializes it). | ||
| 840 | * | ||
| 841 | * @serialData The length of the array backing the list is emitted | ||
| 842 | * (int), followed by all of its elements (each an Object) | ||
| 843 | * in the proper order. | ||
| 844 | * @param s the stream | ||
| 845 | */ | ||
| 846 | private void writeObject(java.io.ObjectOutputStream s) | ||
| 847 | throws java.io.IOException{ | ||
| 848 | |||
| 849 | s.defaultWriteObject(); | ||
| 850 | |||
| 851 | Object[] elements = getArray(); | ||
| 852 | // Write out array length | ||
| 853 | s.writeInt(elements.length); | ||
| 854 | |||
| 855 | // Write out all elements in the proper order. | ||
| 856 | for (Object element : elements) | ||
| 857 | s.writeObject(element); | ||
| 858 | } | ||
| 859 | |||
| 860 | /** | ||
| 861 | * Reconstitutes the list from a stream (that is, deserializes it). | ||
| 862 | * | ||
| 863 | * @param s the stream | ||
| 864 | */ | ||
| 865 | private void readObject(java.io.ObjectInputStream s) | ||
| 866 | throws java.io.IOException, ClassNotFoundException { | ||
| 867 | |||
| 868 | s.defaultReadObject(); | ||
| 869 | |||
| 870 | // bind to new lock | ||
| 871 | resetLock(); | ||
| 872 | |||
| 873 | // Read in array length and allocate array | ||
| 874 | int len = s.readInt(); | ||
| 875 | Object[] elements = new Object[len]; | ||
| 876 | |||
| 877 | // Read in all elements in the proper order. | ||
| 878 | for (int i = 0; i < len; i++) | ||
| 879 | elements[i] = s.readObject(); | ||
| 880 | setArray(elements); | ||
| 881 | } | ||
| 882 | |||
| 883 | /** | ||
| 884 | * Returns a string representation of this list. The string | ||
| 885 | * representation consists of the string representations of the list's | ||
| 886 | * elements in the order they are returned by its iterator, enclosed in | ||
| 887 | * square brackets (<tt>"[]"</tt>). Adjacent elements are separated by | ||
| 888 | * the characters <tt>", "</tt> (comma and space). Elements are | ||
| 889 | * converted to strings as by {@link String#valueOf(Object)}. | ||
| 890 | * | ||
| 891 | * @return a string representation of this list | ||
| 892 | */ | ||
| 893 | public String toString() { | ||
| 894 | return Arrays.toString(getArray()); | ||
| 895 | } | ||
| 896 | |||
| 897 | /** | ||
| 898 | * Compares the specified object with this list for equality. | ||
| 899 | * Returns {@code true} if the specified object is the same object | ||
| 900 | * as this object, or if it is also a {@link List} and the sequence | ||
| 901 | * of elements returned by an {@linkplain List#iterator() iterator} | ||
| 902 | * over the specified list is the same as the sequence returned by | ||
| 903 | * an iterator over this list. The two sequences are considered to | ||
| 904 | * be the same if they have the same length and corresponding | ||
| 905 | * elements at the same position in the sequence are <em>equal</em>. | ||
| 906 | * Two elements {@code e1} and {@code e2} are considered | ||
| 907 | * <em>equal</em> if {@code (e1==null ? e2==null : e1.equals(e2))}. | ||
| 908 | * | ||
| 909 | * @param o the object to be compared for equality with this list | ||
| 910 | * @return {@code true} if the specified object is equal to this list | ||
| 911 | */ | ||
| 912 | public boolean equals(Object o) { | ||
| 913 | if (o == this) | ||
| 914 | return true; | ||
| 915 | if (!(o instanceof List)) | ||
| 916 | return false; | ||
| 917 | |||
| 918 | List<?> list = (List<?>)(o); | ||
| 919 | Iterator<?> it = list.iterator(); | ||
| 920 | Object[] elements = getArray(); | ||
| 921 | int len = elements.length; | ||
| 922 | for (int i = 0; i < len; ++i) | ||
| 923 | if (!it.hasNext() || !eq(elements[i], it.next())) | ||
| 924 | return false; | ||
| 925 | if (it.hasNext()) | ||
| 926 | return false; | ||
| 927 | return true; | ||
| 928 | } | ||
| 929 | |||
| 930 | /** | ||
| 931 | * Returns the hash code value for this list. | ||
| 932 | * | ||
| 933 | * <p>This implementation uses the definition in {@link List#hashCode}. | ||
| 934 | * | ||
| 935 | * @return the hash code value for this list | ||
| 936 | */ | ||
| 937 | public int hashCode() { | ||
| 938 | int hashCode = 1; | ||
| 939 | Object[] elements = getArray(); | ||
| 940 | int len = elements.length; | ||
| 941 | for (int i = 0; i < len; ++i) { | ||
| 942 | Object obj = elements[i]; | ||
| 943 | hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode()); | ||
| 944 | } | ||
| 945 | return hashCode; | ||
| 946 | } | ||
| 947 | |||
| 948 | /** | ||
| 949 | * Returns an iterator over the elements in this list in proper sequence. | ||
| 950 | * | ||
| 951 | * <p>The returned iterator provides a snapshot of the state of the list | ||
| 952 | * when the iterator was constructed. No synchronization is needed while | ||
| 953 | * traversing the iterator. The iterator does <em>NOT</em> support the | ||
| 954 | * <tt>remove</tt> method. | ||
| 955 | * | ||
| 956 | * @return an iterator over the elements in this list in proper sequence | ||
| 957 | */ | ||
| 958 | public Iterator<E> iterator() { | ||
| 959 | return new COWIterator<E>(getArray(), 0); | ||
| 960 | } | ||
| 961 | |||
| 962 | /** | ||
| 963 | * {@inheritDoc} | ||
| 964 | * | ||
| 965 | * <p>The returned iterator provides a snapshot of the state of the list | ||
| 966 | * when the iterator was constructed. No synchronization is needed while | ||
| 967 | * traversing the iterator. The iterator does <em>NOT</em> support the | ||
| 968 | * <tt>remove</tt>, <tt>set</tt> or <tt>add</tt> methods. | ||
| 969 | */ | ||
| 970 | public ListIterator<E> listIterator() { | ||
| 971 | return new COWIterator<E>(getArray(), 0); | ||
| 972 | } | ||
| 973 | |||
| 974 | /** | ||
| 975 | * {@inheritDoc} | ||
| 976 | * | ||
| 977 | * <p>The returned iterator provides a snapshot of the state of the list | ||
| 978 | * when the iterator was constructed. No synchronization is needed while | ||
| 979 | * traversing the iterator. The iterator does <em>NOT</em> support the | ||
| 980 | * <tt>remove</tt>, <tt>set</tt> or <tt>add</tt> methods. | ||
| 981 | * | ||
| 982 | * @throws IndexOutOfBoundsException {@inheritDoc} | ||
| 983 | */ | ||
| 984 | public ListIterator<E> listIterator(final int index) { | ||
| 985 | Object[] elements = getArray(); | ||
| 986 | int len = elements.length; | ||
| 987 | if (index<0 || index>len) | ||
| 988 | throw new IndexOutOfBoundsException("Index: "+index); | ||
| 989 | |||
| 990 | return new COWIterator<E>(elements, index); | ||
| 991 | } | ||
| 992 | |||
| 993 | private static class COWIterator<E> implements ListIterator<E> { | ||
| 994 | /** Snapshot of the array */ | ||
| 995 | private final Object[] snapshot; | ||
| 996 | /** Index of element to be returned by subsequent call to next. */ | ||
| 997 | private int cursor; | ||
| 998 | |||
| 999 | private COWIterator(Object[] elements, int initialCursor) { | ||
| 1000 | cursor = initialCursor; | ||
| 1001 | snapshot = elements; | ||
| 1002 | } | ||
| 1003 | |||
| 1004 | public boolean hasNext() { | ||
| 1005 | return cursor < snapshot.length; | ||
| 1006 | } | ||
| 1007 | |||
| 1008 | public boolean hasPrevious() { | ||
| 1009 | return cursor > 0; | ||
| 1010 | } | ||
| 1011 | |||
| 1012 | @SuppressWarnings("unchecked") | ||
| 1013 | public E next() { | ||
| 1014 | if (! hasNext()) | ||
| 1015 | throw new NoSuchElementException(); | ||
| 1016 | return (E) snapshot[cursor++]; | ||
| 1017 | } | ||
| 1018 | |||
| 1019 | @SuppressWarnings("unchecked") | ||
| 1020 | public E previous() { | ||
| 1021 | if (! hasPrevious()) | ||
| 1022 | throw new NoSuchElementException(); | ||
| 1023 | return (E) snapshot[--cursor]; | ||
| 1024 | } | ||
| 1025 | |||
| 1026 | public int nextIndex() { | ||
| 1027 | return cursor; | ||
| 1028 | } | ||
| 1029 | |||
| 1030 | public int previousIndex() { | ||
| 1031 | return cursor-1; | ||
| 1032 | } | ||
| 1033 | |||
| 1034 | /** | ||
| 1035 | * Not supported. Always throws UnsupportedOperationException. | ||
| 1036 | * @throws UnsupportedOperationException always; <tt>remove</tt> | ||
| 1037 | * is not supported by this iterator. | ||
| 1038 | */ | ||
| 1039 | public void remove() { | ||
| 1040 | throw new UnsupportedOperationException(); | ||
| 1041 | } | ||
| 1042 | |||
| 1043 | /** | ||
| 1044 | * Not supported. Always throws UnsupportedOperationException. | ||
| 1045 | * @throws UnsupportedOperationException always; <tt>set</tt> | ||
| 1046 | * is not supported by this iterator. | ||
| 1047 | */ | ||
| 1048 | public void set(E e) { | ||
| 1049 | throw new UnsupportedOperationException(); | ||
| 1050 | } | ||
| 1051 | |||
| 1052 | /** | ||
| 1053 | * Not supported. Always throws UnsupportedOperationException. | ||
| 1054 | * @throws UnsupportedOperationException always; <tt>add</tt> | ||
| 1055 | * is not supported by this iterator. | ||
| 1056 | */ | ||
| 1057 | public void add(E e) { | ||
| 1058 | throw new UnsupportedOperationException(); | ||
| 1059 | } | ||
| 1060 | } | ||
| 1061 | |||
| 1062 | /** | ||
| 1063 | * Returns a view of the portion of this list between | ||
| 1064 | * <tt>fromIndex</tt>, inclusive, and <tt>toIndex</tt>, exclusive. | ||
| 1065 | * The returned list is backed by this list, so changes in the | ||
| 1066 | * returned list are reflected in this list. | ||
| 1067 | * | ||
| 1068 | * <p>The semantics of the list returned by this method become | ||
| 1069 | * undefined if the backing list (i.e., this list) is modified in | ||
| 1070 | * any way other than via the returned list. | ||
| 1071 | * | ||
| 1072 | * @param fromIndex low endpoint (inclusive) of the subList | ||
| 1073 | * @param toIndex high endpoint (exclusive) of the subList | ||
| 1074 | * @return a view of the specified range within this list | ||
| 1075 | * @throws IndexOutOfBoundsException {@inheritDoc} | ||
| 1076 | */ | ||
| 1077 | public List<E> subList(int fromIndex, int toIndex) { | ||
| 1078 | final ReentrantLock lock = this.lock; | ||
| 1079 | lock.lock(); | ||
| 1080 | try { | ||
| 1081 | Object[] elements = getArray(); | ||
| 1082 | int len = elements.length; | ||
| 1083 | if (fromIndex < 0 || toIndex > len || fromIndex > toIndex) | ||
| 1084 | throw new IndexOutOfBoundsException(); | ||
| 1085 | return new COWSubList<E>(this, fromIndex, toIndex); | ||
| 1086 | } finally { | ||
| 1087 | lock.unlock(); | ||
| 1088 | } | ||
| 1089 | } | ||
| 1090 | |||
| 1091 | /** | ||
| 1092 | * Sublist for CopyOnWriteArrayList. | ||
| 1093 | * This class extends AbstractList merely for convenience, to | ||
| 1094 | * avoid having to define addAll, etc. This doesn't hurt, but | ||
| 1095 | * is wasteful. This class does not need or use modCount | ||
| 1096 | * mechanics in AbstractList, but does need to check for | ||
| 1097 | * concurrent modification using similar mechanics. On each | ||
| 1098 | * operation, the array that we expect the backing list to use | ||
| 1099 | * is checked and updated. Since we do this for all of the | ||
| 1100 | * base operations invoked by those defined in AbstractList, | ||
| 1101 | * all is well. While inefficient, this is not worth | ||
| 1102 | * improving. The kinds of list operations inherited from | ||
| 1103 | * AbstractList are already so slow on COW sublists that | ||
| 1104 | * adding a bit more space/time doesn't seem even noticeable. | ||
| 1105 | */ | ||
| 1106 | private static class COWSubList<E> | ||
| 1107 | extends AbstractList<E> | ||
| 1108 | implements RandomAccess | ||
| 1109 | { | ||
| 1110 | private final CopyOnWriteArrayList<E> l; | ||
| 1111 | private final int offset; | ||
| 1112 | private int size; | ||
| 1113 | private Object[] expectedArray; | ||
| 1114 | |||
| 1115 | // only call this holding l's lock | ||
| 1116 | COWSubList(CopyOnWriteArrayList<E> list, | ||
| 1117 | int fromIndex, int toIndex) { | ||
| 1118 | l = list; | ||
| 1119 | expectedArray = l.getArray(); | ||
| 1120 | offset = fromIndex; | ||
| 1121 | size = toIndex - fromIndex; | ||
| 1122 | } | ||
| 1123 | |||
| 1124 | // only call this holding l's lock | ||
| 1125 | private void checkForComodification() { | ||
| 1126 | if (l.getArray() != expectedArray) | ||
| 1127 | throw new ConcurrentModificationException(); | ||
| 1128 | } | ||
| 1129 | |||
| 1130 | // only call this holding l's lock | ||
| 1131 | private void rangeCheck(int index) { | ||
| 1132 | if (index<0 || index>=size) | ||
| 1133 | throw new IndexOutOfBoundsException("Index: "+index+ | ||
| 1134 | ",Size: "+size); | ||
| 1135 | } | ||
| 1136 | |||
| 1137 | public E set(int index, E element) { | ||
| 1138 | final ReentrantLock lock = l.lock; | ||
| 1139 | lock.lock(); | ||
| 1140 | try { | ||
| 1141 | rangeCheck(index); | ||
| 1142 | checkForComodification(); | ||
| 1143 | E x = l.set(index+offset, element); | ||
| 1144 | expectedArray = l.getArray(); | ||
| 1145 | return x; | ||
| 1146 | } finally { | ||
| 1147 | lock.unlock(); | ||
| 1148 | } | ||
| 1149 | } | ||
| 1150 | |||
| 1151 | public E get(int index) { | ||
| 1152 | final ReentrantLock lock = l.lock; | ||
| 1153 | lock.lock(); | ||
| 1154 | try { | ||
| 1155 | rangeCheck(index); | ||
| 1156 | checkForComodification(); | ||
| 1157 | return l.get(index+offset); | ||
| 1158 | } finally { | ||
| 1159 | lock.unlock(); | ||
| 1160 | } | ||
| 1161 | } | ||
| 1162 | |||
| 1163 | public int size() { | ||
| 1164 | final ReentrantLock lock = l.lock; | ||
| 1165 | lock.lock(); | ||
| 1166 | try { | ||
| 1167 | checkForComodification(); | ||
| 1168 | return size; | ||
| 1169 | } finally { | ||
| 1170 | lock.unlock(); | ||
| 1171 | } | ||
| 1172 | } | ||
| 1173 | |||
| 1174 | public void add(int index, E element) { | ||
| 1175 | final ReentrantLock lock = l.lock; | ||
| 1176 | lock.lock(); | ||
| 1177 | try { | ||
| 1178 | checkForComodification(); | ||
| 1179 | if (index<0 || index>size) | ||
| 1180 | throw new IndexOutOfBoundsException(); | ||
| 1181 | l.add(index+offset, element); | ||
| 1182 | expectedArray = l.getArray(); | ||
| 1183 | size++; | ||
| 1184 | } finally { | ||
| 1185 | lock.unlock(); | ||
| 1186 | } | ||
| 1187 | } | ||
| 1188 | |||
| 1189 | public void clear() { | ||
| 1190 | final ReentrantLock lock = l.lock; | ||
| 1191 | lock.lock(); | ||
| 1192 | try { | ||
| 1193 | checkForComodification(); | ||
| 1194 | l.removeRange(offset, offset+size); | ||
| 1195 | expectedArray = l.getArray(); | ||
| 1196 | size = 0; | ||
| 1197 | } finally { | ||
| 1198 | lock.unlock(); | ||
| 1199 | } | ||
| 1200 | } | ||
| 1201 | |||
| 1202 | public E remove(int index) { | ||
| 1203 | final ReentrantLock lock = l.lock; | ||
| 1204 | lock.lock(); | ||
| 1205 | try { | ||
| 1206 | rangeCheck(index); | ||
| 1207 | checkForComodification(); | ||
| 1208 | E result = l.remove(index+offset); | ||
| 1209 | expectedArray = l.getArray(); | ||
| 1210 | size--; | ||
| 1211 | return result; | ||
| 1212 | } finally { | ||
| 1213 | lock.unlock(); | ||
| 1214 | } | ||
| 1215 | } | ||
| 1216 | |||
| 1217 | public boolean remove(Object o) { | ||
| 1218 | int index = indexOf(o); | ||
| 1219 | if (index == -1) | ||
| 1220 | return false; | ||
| 1221 | remove(index); | ||
| 1222 | return true; | ||
| 1223 | } | ||
| 1224 | |||
| 1225 | public Iterator<E> iterator() { | ||
| 1226 | final ReentrantLock lock = l.lock; | ||
| 1227 | lock.lock(); | ||
| 1228 | try { | ||
| 1229 | checkForComodification(); | ||
| 1230 | return new COWSubListIterator<E>(l, 0, offset, size); | ||
| 1231 | } finally { | ||
| 1232 | lock.unlock(); | ||
| 1233 | } | ||
| 1234 | } | ||
| 1235 | |||
| 1236 | public ListIterator<E> listIterator(final int index) { | ||
| 1237 | final ReentrantLock lock = l.lock; | ||
| 1238 | lock.lock(); | ||
| 1239 | try { | ||
| 1240 | checkForComodification(); | ||
| 1241 | if (index<0 || index>size) | ||
| 1242 | throw new IndexOutOfBoundsException("Index: "+index+ | ||
| 1243 | ", Size: "+size); | ||
| 1244 | return new COWSubListIterator<E>(l, index, offset, size); | ||
| 1245 | } finally { | ||
| 1246 | lock.unlock(); | ||
| 1247 | } | ||
| 1248 | } | ||
| 1249 | |||
| 1250 | public List<E> subList(int fromIndex, int toIndex) { | ||
| 1251 | final ReentrantLock lock = l.lock; | ||
| 1252 | lock.lock(); | ||
| 1253 | try { | ||
| 1254 | checkForComodification(); | ||
| 1255 | if (fromIndex<0 || toIndex>size) | ||
| 1256 | throw new IndexOutOfBoundsException(); | ||
| 1257 | return new COWSubList<E>(l, fromIndex + offset, | ||
| 1258 | toIndex + offset); | ||
| 1259 | } finally { | ||
| 1260 | lock.unlock(); | ||
| 1261 | } | ||
| 1262 | } | ||
| 1263 | |||
| 1264 | } | ||
| 1265 | |||
| 1266 | |||
| 1267 | private static class COWSubListIterator<E> implements ListIterator<E> { | ||
| 1268 | private final ListIterator<E> i; | ||
| 1269 | private final int index; | ||
| 1270 | private final int offset; | ||
| 1271 | private final int size; | ||
| 1272 | |||
| 1273 | COWSubListIterator(List<E> l, int index, int offset, | ||
| 1274 | int size) { | ||
| 1275 | this.index = index; | ||
| 1276 | this.offset = offset; | ||
| 1277 | this.size = size; | ||
| 1278 | i = l.listIterator(index+offset); | ||
| 1279 | } | ||
| 1280 | |||
| 1281 | public boolean hasNext() { | ||
| 1282 | return nextIndex() < size; | ||
| 1283 | } | ||
| 1284 | |||
| 1285 | public E next() { | ||
| 1286 | if (hasNext()) | ||
| 1287 | return i.next(); | ||
| 1288 | else | ||
| 1289 | throw new NoSuchElementException(); | ||
| 1290 | } | ||
| 1291 | |||
| 1292 | public boolean hasPrevious() { | ||
| 1293 | return previousIndex() >= 0; | ||
| 1294 | } | ||
| 1295 | |||
| 1296 | public E previous() { | ||
| 1297 | if (hasPrevious()) | ||
| 1298 | return i.previous(); | ||
| 1299 | else | ||
| 1300 | throw new NoSuchElementException(); | ||
| 1301 | } | ||
| 1302 | |||
| 1303 | public int nextIndex() { | ||
| 1304 | return i.nextIndex() - offset; | ||
| 1305 | } | ||
| 1306 | |||
| 1307 | public int previousIndex() { | ||
| 1308 | return i.previousIndex() - offset; | ||
| 1309 | } | ||
| 1310 | |||
| 1311 | public void remove() { | ||
| 1312 | throw new UnsupportedOperationException(); | ||
| 1313 | } | ||
| 1314 | |||
| 1315 | public void set(E e) { | ||
| 1316 | throw new UnsupportedOperationException(); | ||
| 1317 | } | ||
| 1318 | |||
| 1319 | public void add(E e) { | ||
| 1320 | throw new UnsupportedOperationException(); | ||
| 1321 | } | ||
| 1322 | } | ||
| 1323 | |||
| 1324 | // Support for resetting lock while deserializing | ||
| 1325 | private void resetLock() { | ||
| 1326 | UNSAFE.putObjectVolatile(this, lockOffset, new ReentrantLock()); | ||
| 1327 | } | ||
| 1328 | private static final sun.misc.Unsafe UNSAFE; | ||
| 1329 | private static final long lockOffset; | ||
| 1330 | static { | ||
| 1331 | try { | ||
| 1332 | UNSAFE = sun.misc.Unsafe.getUnsafe(); | ||
| 1333 | Class k = CopyOnWriteArrayList.class; | ||
| 1334 | lockOffset = UNSAFE.objectFieldOffset | ||
| 1335 | (k.getDeclaredField("lock")); | ||
| 1336 | } catch (Exception e) { | ||
| 1337 | throw new Error(e); | ||
| 1338 | } | ||
| 1339 | } | ||
| 1340 | } | ||
Binary file not shown.
| @@ -0,0 +1,392 @@ | |||
| 1 | /* | ||
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 3 | * | ||
| 4 | * This code is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License version 2 only, as | ||
| 6 | * published by the Free Software Foundation. Oracle designates this | ||
| 7 | * particular file as subject to the "Classpath" exception as provided | ||
| 8 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 9 | * | ||
| 10 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 13 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 14 | * accompanied this code). | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License version | ||
| 17 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | * | ||
| 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 21 | * or visit www.oracle.com if you need additional information or have any | ||
| 22 | * questions. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * This file is available under and governed by the GNU General Public | ||
| 27 | * License version 2 only, as published by the Free Software Foundation. | ||
| 28 | * However, the following notice accompanied the original version of this | ||
| 29 | * file: | ||
| 30 | * | ||
| 31 | * Written by Doug Lea with assistance from members of JCP JSR-166 | ||
| 32 | * Expert Group and released to the public domain, as explained at | ||
| 33 | * http://creativecommons.org/publicdomain/zero/1.0/ | ||
| 34 | */ | ||
| 35 | |||
| 36 | package java.util.concurrent; | ||
| 37 | import java.util.*; | ||
| 38 | |||
| 39 | /** | ||
| 40 | * A {@link java.util.Set} that uses an internal {@link CopyOnWriteArrayList} | ||
| 41 | * for all of its operations. Thus, it shares the same basic properties: | ||
| 42 | * <ul> | ||
| 43 | * <li>It is best suited for applications in which set sizes generally | ||
| 44 | * stay small, read-only operations | ||
| 45 | * vastly outnumber mutative operations, and you need | ||
| 46 | * to prevent interference among threads during traversal. | ||
| 47 | * <li>It is thread-safe. | ||
| 48 | * <li>Mutative operations (<tt>add</tt>, <tt>set</tt>, <tt>remove</tt>, etc.) | ||
| 49 | * are expensive since they usually entail copying the entire underlying | ||
| 50 | * array. | ||
| 51 | * <li>Iterators do not support the mutative <tt>remove</tt> operation. | ||
| 52 | * <li>Traversal via iterators is fast and cannot encounter | ||
| 53 | * interference from other threads. Iterators rely on | ||
| 54 | * unchanging snapshots of the array at the time the iterators were | ||
| 55 | * constructed. | ||
| 56 | * </ul> | ||
| 57 | * | ||
| 58 | * <p> <b>Sample Usage.</b> The following code sketch uses a | ||
| 59 | * copy-on-write set to maintain a set of Handler objects that | ||
| 60 | * perform some action upon state updates. | ||
| 61 | * | ||
| 62 | * <pre> {@code | ||
| 63 | * class Handler { void handle(); ... } | ||
| 64 | * | ||
| 65 | * class X { | ||
| 66 | * private final CopyOnWriteArraySet<Handler> handlers | ||
| 67 | * = new CopyOnWriteArraySet<Handler>(); | ||
| 68 | * public void addHandler(Handler h) { handlers.add(h); } | ||
| 69 | * | ||
| 70 | * private long internalState; | ||
| 71 | * private synchronized void changeState() { internalState = ...; } | ||
| 72 | * | ||
| 73 | * public void update() { | ||
| 74 | * changeState(); | ||
| 75 | * for (Handler handler : handlers) | ||
| 76 | * handler.handle(); | ||
| 77 | * } | ||
| 78 | * }}</pre> | ||
| 79 | * | ||
| 80 | * <p>This class is a member of the | ||
| 81 | * <a href="{@docRoot}/../technotes/guides/collections/index.html"> | ||
| 82 | * Java Collections Framework</a>. | ||
| 83 | * | ||
| 84 | * @see CopyOnWriteArrayList | ||
| 85 | * @since 1.5 | ||
| 86 | * @author Doug Lea | ||
| 87 | * @param <E> the type of elements held in this collection | ||
| 88 | */ | ||
| 89 | public class CopyOnWriteArraySet<E> extends AbstractSet<E> | ||
| 90 | implements java.io.Serializable { | ||
| 91 | private static final long serialVersionUID = 5457747651344034263L; | ||
| 92 | |||
| 93 | private final CopyOnWriteArrayList<E> al; | ||
| 94 | |||
| 95 | /** | ||
| 96 | * Creates an empty set. | ||
| 97 | */ | ||
| 98 | public CopyOnWriteArraySet() { | ||
| 99 | al = new CopyOnWriteArrayList<E>(); | ||
| 100 | } | ||
| 101 | |||
| 102 | /** | ||
| 103 | * Creates a set containing all of the elements of the specified | ||
| 104 | * collection. | ||
| 105 | * | ||
| 106 | * @param c the collection of elements to initially contain | ||
| 107 | * @throws NullPointerException if the specified collection is null | ||
| 108 | */ | ||
| 109 | public CopyOnWriteArraySet(Collection<? extends E> c) { | ||
| 110 | al = new CopyOnWriteArrayList<E>(); | ||
| 111 | al.addAllAbsent(c); | ||
| 112 | } | ||
| 113 | |||
| 114 | /** | ||
| 115 | * Returns the number of elements in this set. | ||
| 116 | * | ||
| 117 | * @return the number of elements in this set | ||
| 118 | */ | ||
| 119 | public int size() { | ||
| 120 | return al.size(); | ||
| 121 | } | ||
| 122 | |||
| 123 | /** | ||
| 124 | * Returns <tt>true</tt> if this set contains no elements. | ||
| 125 | * | ||
| 126 | * @return <tt>true</tt> if this set contains no elements | ||
| 127 | */ | ||
| 128 | public boolean isEmpty() { | ||
| 129 | return al.isEmpty(); | ||
| 130 | } | ||
| 131 | |||
| 132 | /** | ||
| 133 | * Returns <tt>true</tt> if this set contains the specified element. | ||
| 134 | * More formally, returns <tt>true</tt> if and only if this set | ||
| 135 | * contains an element <tt>e</tt> such that | ||
| 136 | * <tt>(o==null ? e==null : o.equals(e))</tt>. | ||
| 137 | * | ||
| 138 | * @param o element whose presence in this set is to be tested | ||
| 139 | * @return <tt>true</tt> if this set contains the specified element | ||
| 140 | */ | ||
| 141 | public boolean contains(Object o) { | ||
| 142 | return al.contains(o); | ||
| 143 | } | ||
| 144 | |||
| 145 | /** | ||
| 146 | * Returns an array containing all of the elements in this set. | ||
| 147 | * If this set makes any guarantees as to what order its elements | ||
| 148 | * are returned by its iterator, this method must return the | ||
| 149 | * elements in the same order. | ||
| 150 | * | ||
| 151 | * <p>The returned array will be "safe" in that no references to it | ||
| 152 | * are maintained by this set. (In other words, this method must | ||
| 153 | * allocate a new array even if this set is backed by an array). | ||
| 154 | * The caller is thus free to modify the returned array. | ||
| 155 | * | ||
| 156 | * <p>This method acts as bridge between array-based and collection-based | ||
| 157 | * APIs. | ||
| 158 | * | ||
| 159 | * @return an array containing all the elements in this set | ||
| 160 | */ | ||
| 161 | public Object[] toArray() { | ||
| 162 | return al.toArray(); | ||
| 163 | } | ||
| 164 | |||
| 165 | /** | ||
| 166 | * Returns an array containing all of the elements in this set; the | ||
| 167 | * runtime type of the returned array is that of the specified array. | ||
| 168 | * If the set fits in the specified array, it is returned therein. | ||
| 169 | * Otherwise, a new array is allocated with the runtime type of the | ||
| 170 | * specified array and the size of this set. | ||
| 171 | * | ||
| 172 | * <p>If this set fits in the specified array with room to spare | ||
| 173 | * (i.e., the array has more elements than this set), the element in | ||
| 174 | * the array immediately following the end of the set is set to | ||
| 175 | * <tt>null</tt>. (This is useful in determining the length of this | ||
| 176 | * set <i>only</i> if the caller knows that this set does not contain | ||
| 177 | * any null elements.) | ||
| 178 | * | ||
| 179 | * <p>If this set makes any guarantees as to what order its elements | ||
| 180 | * are returned by its iterator, this method must return the elements | ||
| 181 | * in the same order. | ||
| 182 | * | ||
| 183 | * <p>Like the {@link #toArray()} method, this method acts as bridge between | ||
| 184 | * array-based and collection-based APIs. Further, this method allows | ||
| 185 | * precise control over the runtime type of the output array, and may, | ||
| 186 | * under certain circumstances, be used to save allocation costs. | ||
| 187 | * | ||
| 188 | * <p>Suppose <tt>x</tt> is a set known to contain only strings. | ||
| 189 | * The following code can be used to dump the set into a newly allocated | ||
| 190 | * array of <tt>String</tt>: | ||
| 191 | * | ||
| 192 | * <pre> | ||
| 193 | * String[] y = x.toArray(new String[0]);</pre> | ||
| 194 | * | ||
| 195 | * Note that <tt>toArray(new Object[0])</tt> is identical in function to | ||
| 196 | * <tt>toArray()</tt>. | ||
| 197 | * | ||
| 198 | * @param a the array into which the elements of this set are to be | ||
| 199 | * stored, if it is big enough; otherwise, a new array of the same | ||
| 200 | * runtime type is allocated for this purpose. | ||
| 201 | * @return an array containing all the elements in this set | ||
| 202 | * @throws ArrayStoreException if the runtime type of the specified array | ||
| 203 | * is not a supertype of the runtime type of every element in this | ||
| 204 | * set | ||
| 205 | * @throws NullPointerException if the specified array is null | ||
| 206 | */ | ||
| 207 | public <T> T[] toArray(T[] a) { | ||
| 208 | return al.toArray(a); | ||
| 209 | } | ||
| 210 | |||
| 211 | /** | ||
| 212 | * Removes all of the elements from this set. | ||
| 213 | * The set will be empty after this call returns. | ||
| 214 | */ | ||
| 215 | public void clear() { | ||
| 216 | al.clear(); | ||
| 217 | } | ||
| 218 | |||
| 219 | /** | ||
| 220 | * Removes the specified element from this set if it is present. | ||
| 221 | * More formally, removes an element <tt>e</tt> such that | ||
| 222 | * <tt>(o==null ? e==null : o.equals(e))</tt>, | ||
| 223 | * if this set contains such an element. Returns <tt>true</tt> if | ||
| 224 | * this set contained the element (or equivalently, if this set | ||
| 225 | * changed as a result of the call). (This set will not contain the | ||
| 226 | * element once the call returns.) | ||
| 227 | * | ||
| 228 | * @param o object to be removed from this set, if present | ||
| 229 | * @return <tt>true</tt> if this set contained the specified element | ||
| 230 | */ | ||
| 231 | public boolean remove(Object o) { | ||
| 232 | return al.remove(o); | ||
| 233 | } | ||
| 234 | |||
| 235 | /** | ||
| 236 | * Adds the specified element to this set if it is not already present. | ||
| 237 | * More formally, adds the specified element <tt>e</tt> to this set if | ||
| 238 | * the set contains no element <tt>e2</tt> such that | ||
| 239 | * <tt>(e==null ? e2==null : e.equals(e2))</tt>. | ||
| 240 | * If this set already contains the element, the call leaves the set | ||
| 241 | * unchanged and returns <tt>false</tt>. | ||
| 242 | * | ||
| 243 | * @param e element to be added to this set | ||
| 244 | * @return <tt>true</tt> if this set did not already contain the specified | ||
| 245 | * element | ||
| 246 | */ | ||
| 247 | public boolean add(E e) { | ||
| 248 | return al.addIfAbsent(e); | ||
| 249 | } | ||
| 250 | |||
| 251 | /** | ||
| 252 | * Returns <tt>true</tt> if this set contains all of the elements of the | ||
| 253 | * specified collection. If the specified collection is also a set, this | ||
| 254 | * method returns <tt>true</tt> if it is a <i>subset</i> of this set. | ||
| 255 | * | ||
| 256 | * @param c collection to be checked for containment in this set | ||
| 257 | * @return <tt>true</tt> if this set contains all of the elements of the | ||
| 258 | * specified collection | ||
| 259 | * @throws NullPointerException if the specified collection is null | ||
| 260 | * @see #contains(Object) | ||
| 261 | */ | ||
| 262 | public boolean containsAll(Collection<?> c) { | ||
| 263 | return al.containsAll(c); | ||
| 264 | } | ||
| 265 | |||
| 266 | /** | ||
| 267 | * Adds all of the elements in the specified collection to this set if | ||
| 268 | * they're not already present. If the specified collection is also a | ||
| 269 | * set, the <tt>addAll</tt> operation effectively modifies this set so | ||
| 270 | * that its value is the <i>union</i> of the two sets. The behavior of | ||
| 271 | * this operation is undefined if the specified collection is modified | ||
| 272 | * while the operation is in progress. | ||
| 273 | * | ||
| 274 | * @param c collection containing elements to be added to this set | ||
| 275 | * @return <tt>true</tt> if this set changed as a result of the call | ||
| 276 | * @throws NullPointerException if the specified collection is null | ||
| 277 | * @see #add(Object) | ||
| 278 | */ | ||
| 279 | public boolean addAll(Collection<? extends E> c) { | ||
| 280 | return al.addAllAbsent(c) > 0; | ||
| 281 | } | ||
| 282 | |||
| 283 | /** | ||
| 284 | * Removes from this set all of its elements that are contained in the | ||
| 285 | * specified collection. If the specified collection is also a set, | ||
| 286 | * this operation effectively modifies this set so that its value is the | ||
| 287 | * <i>asymmetric set difference</i> of the two sets. | ||
| 288 | * | ||
| 289 | * @param c collection containing elements to be removed from this set | ||
| 290 | * @return <tt>true</tt> if this set changed as a result of the call | ||
| 291 | * @throws ClassCastException if the class of an element of this set | ||
| 292 | * is incompatible with the specified collection (optional) | ||
| 293 | * @throws NullPointerException if this set contains a null element and the | ||
| 294 | * specified collection does not permit null elements (optional), | ||
| 295 | * or if the specified collection is null | ||
| 296 | * @see #remove(Object) | ||
| 297 | */ | ||
| 298 | public boolean removeAll(Collection<?> c) { | ||
| 299 | return al.removeAll(c); | ||
| 300 | } | ||
| 301 | |||
| 302 | /** | ||
| 303 | * Retains only the elements in this set that are contained in the | ||
| 304 | * specified collection. In other words, removes from this set all of | ||
| 305 | * its elements that are not contained in the specified collection. If | ||
| 306 | * the specified collection is also a set, this operation effectively | ||
| 307 | * modifies this set so that its value is the <i>intersection</i> of the | ||
| 308 | * two sets. | ||
| 309 | * | ||
| 310 | * @param c collection containing elements to be retained in this set | ||
| 311 | * @return <tt>true</tt> if this set changed as a result of the call | ||
| 312 | * @throws ClassCastException if the class of an element of this set | ||
| 313 | * is incompatible with the specified collection (optional) | ||
| 314 | * @throws NullPointerException if this set contains a null element and the | ||
| 315 | * specified collection does not permit null elements (optional), | ||
| 316 | * or if the specified collection is null | ||
| 317 | * @see #remove(Object) | ||
| 318 | */ | ||
| 319 | public boolean retainAll(Collection<?> c) { | ||
| 320 | return al.retainAll(c); | ||
| 321 | } | ||
| 322 | |||
| 323 | /** | ||
| 324 | * Returns an iterator over the elements contained in this set | ||
| 325 | * in the order in which these elements were added. | ||
| 326 | * | ||
| 327 | * <p>The returned iterator provides a snapshot of the state of the set | ||
| 328 | * when the iterator was constructed. No synchronization is needed while | ||
| 329 | * traversing the iterator. The iterator does <em>NOT</em> support the | ||
| 330 | * <tt>remove</tt> method. | ||
| 331 | * | ||
| 332 | * @return an iterator over the elements in this set | ||
| 333 | */ | ||
| 334 | public Iterator<E> iterator() { | ||
| 335 | return al.iterator(); | ||
| 336 | } | ||
| 337 | |||
| 338 | /** | ||
| 339 | * Compares the specified object with this set for equality. | ||
| 340 | * Returns {@code true} if the specified object is the same object | ||
| 341 | * as this object, or if it is also a {@link Set} and the elements | ||
| 342 | * returned by an {@linkplain List#iterator() iterator} over the | ||
| 343 | * specified set are the same as the elements returned by an | ||
| 344 | * iterator over this set. More formally, the two iterators are | ||
| 345 | * considered to return the same elements if they return the same | ||
| 346 | * number of elements and for every element {@code e1} returned by | ||
| 347 | * the iterator over the specified set, there is an element | ||
| 348 | * {@code e2} returned by the iterator over this set such that | ||
| 349 | * {@code (e1==null ? e2==null : e1.equals(e2))}. | ||
| 350 | * | ||
| 351 | * @param o object to be compared for equality with this set | ||
| 352 | * @return {@code true} if the specified object is equal to this set | ||
| 353 | */ | ||
| 354 | public boolean equals(Object o) { | ||
| 355 | if (o == this) | ||
| 356 | return true; | ||
| 357 | if (!(o instanceof Set)) | ||
| 358 | return false; | ||
| 359 | Set<?> set = (Set<?>)(o); | ||
| 360 | Iterator<?> it = set.iterator(); | ||
| 361 | |||
| 362 | // Uses O(n^2) algorithm that is only appropriate | ||
| 363 | // for small sets, which CopyOnWriteArraySets should be. | ||
| 364 | |||
| 365 | // Use a single snapshot of underlying array | ||
| 366 | Object[] elements = al.getArray(); | ||
| 367 | int len = elements.length; | ||
| 368 | // Mark matched elements to avoid re-checking | ||
| 369 | boolean[] matched = new boolean[len]; | ||
| 370 | int k = 0; | ||
| 371 | outer: while (it.hasNext()) { | ||
| 372 | if (++k > len) | ||
| 373 | return false; | ||
| 374 | Object x = it.next(); | ||
| 375 | for (int i = 0; i < len; ++i) { | ||
| 376 | if (!matched[i] && eq(x, elements[i])) { | ||
| 377 | matched[i] = true; | ||
| 378 | continue outer; | ||
| 379 | } | ||
| 380 | } | ||
| 381 | return false; | ||
| 382 | } | ||
| 383 | return k == len; | ||
| 384 | } | ||
| 385 | |||
| 386 | /** | ||
| 387 | * Test for equality, coping with nulls. | ||
| 388 | */ | ||
| 389 | private static boolean eq(Object o1, Object o2) { | ||
| 390 | return (o1 == null ? o2 == null : o1.equals(o2)); | ||
| 391 | } | ||
| 392 | } | ||
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,320 @@ | |||
| 1 | /* | ||
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 3 | * | ||
| 4 | * This code is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License version 2 only, as | ||
| 6 | * published by the Free Software Foundation. Oracle designates this | ||
| 7 | * particular file as subject to the "Classpath" exception as provided | ||
| 8 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 9 | * | ||
| 10 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 13 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 14 | * accompanied this code). | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License version | ||
| 17 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | * | ||
| 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 21 | * or visit www.oracle.com if you need additional information or have any | ||
| 22 | * questions. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * This file is available under and governed by the GNU General Public | ||
| 27 | * License version 2 only, as published by the Free Software Foundation. | ||
| 28 | * However, the following notice accompanied the original version of this | ||
| 29 | * file: | ||
| 30 | * | ||
| 31 | * Written by Doug Lea with assistance from members of JCP JSR-166 | ||
| 32 | * Expert Group and released to the public domain, as explained at | ||
| 33 | * http://creativecommons.org/publicdomain/zero/1.0/ | ||
| 34 | */ | ||
| 35 | |||
| 36 | package java.util.concurrent; | ||
| 37 | import java.util.concurrent.locks.*; | ||
| 38 | import java.util.concurrent.atomic.*; | ||
| 39 | |||
| 40 | /** | ||
| 41 | * A synchronization aid that allows one or more threads to wait until | ||
| 42 | * a set of operations being performed in other threads completes. | ||
| 43 | * | ||
| 44 | * <p>A {@code CountDownLatch} is initialized with a given <em>count</em>. | ||
| 45 | * The {@link #await await} methods block until the current count reaches | ||
| 46 | * zero due to invocations of the {@link #countDown} method, after which | ||
| 47 | * all waiting threads are released and any subsequent invocations of | ||
| 48 | * {@link #await await} return immediately. This is a one-shot phenomenon | ||
| 49 | * -- the count cannot be reset. If you need a version that resets the | ||
| 50 | * count, consider using a {@link CyclicBarrier}. | ||
| 51 | * | ||
| 52 | * <p>A {@code CountDownLatch} is a versatile synchronization tool | ||
| 53 | * and can be used for a number of purposes. A | ||
| 54 | * {@code CountDownLatch} initialized with a count of one serves as a | ||
| 55 | * simple on/off latch, or gate: all threads invoking {@link #await await} | ||
| 56 | * wait at the gate until it is opened by a thread invoking {@link | ||
| 57 | * #countDown}. A {@code CountDownLatch} initialized to <em>N</em> | ||
| 58 | * can be used to make one thread wait until <em>N</em> threads have | ||
| 59 | * completed some action, or some action has been completed N times. | ||
| 60 | * | ||
| 61 | * <p>A useful property of a {@code CountDownLatch} is that it | ||
| 62 | * doesn't require that threads calling {@code countDown} wait for | ||
| 63 | * the count to reach zero before proceeding, it simply prevents any | ||
| 64 | * thread from proceeding past an {@link #await await} until all | ||
| 65 | * threads could pass. | ||
| 66 | * | ||
| 67 | * <p><b>Sample usage:</b> Here is a pair of classes in which a group | ||
| 68 | * of worker threads use two countdown latches: | ||
| 69 | * <ul> | ||
| 70 | * <li>The first is a start signal that prevents any worker from proceeding | ||
| 71 | * until the driver is ready for them to proceed; | ||
| 72 | * <li>The second is a completion signal that allows the driver to wait | ||
| 73 | * until all workers have completed. | ||
| 74 | * </ul> | ||
| 75 | * | ||
| 76 | * <pre> | ||
| 77 | * class Driver { // ... | ||
| 78 | * void main() throws InterruptedException { | ||
| 79 | * CountDownLatch startSignal = new CountDownLatch(1); | ||
| 80 | * CountDownLatch doneSignal = new CountDownLatch(N); | ||
| 81 | * | ||
| 82 | * for (int i = 0; i < N; ++i) // create and start threads | ||
| 83 | * new Thread(new Worker(startSignal, doneSignal)).start(); | ||
| 84 | * | ||
| 85 | * doSomethingElse(); // don't let run yet | ||
| 86 | * startSignal.countDown(); // let all threads proceed | ||
| 87 | * doSomethingElse(); | ||
| 88 | * doneSignal.await(); // wait for all to finish | ||
| 89 | * } | ||
| 90 | * } | ||
| 91 | * | ||
| 92 | * class Worker implements Runnable { | ||
| 93 | * private final CountDownLatch startSignal; | ||
| 94 | * private final CountDownLatch doneSignal; | ||
| 95 | * Worker(CountDownLatch startSignal, CountDownLatch doneSignal) { | ||
| 96 | * this.startSignal = startSignal; | ||
| 97 | * this.doneSignal = doneSignal; | ||
| 98 | * } | ||
| 99 | * public void run() { | ||
| 100 | * try { | ||
| 101 | * startSignal.await(); | ||
| 102 | * doWork(); | ||
| 103 | * doneSignal.countDown(); | ||
| 104 | * } catch (InterruptedException ex) {} // return; | ||
| 105 | * } | ||
| 106 | * | ||
| 107 | * void doWork() { ... } | ||
| 108 | * } | ||
| 109 | * | ||
| 110 | * </pre> | ||
| 111 | * | ||
| 112 | * <p>Another typical usage would be to divide a problem into N parts, | ||
| 113 | * describe each part with a Runnable that executes that portion and | ||
| 114 | * counts down on the latch, and queue all the Runnables to an | ||
| 115 | * Executor. When all sub-parts are complete, the coordinating thread | ||
| 116 | * will be able to pass through await. (When threads must repeatedly | ||
| 117 | * count down in this way, instead use a {@link CyclicBarrier}.) | ||
| 118 | * | ||
| 119 | * <pre> | ||
| 120 | * class Driver2 { // ... | ||
| 121 | * void main() throws InterruptedException { | ||
| 122 | * CountDownLatch doneSignal = new CountDownLatch(N); | ||
| 123 | * Executor e = ... | ||
| 124 | * | ||
| 125 | * for (int i = 0; i < N; ++i) // create and start threads | ||
| 126 | * e.execute(new WorkerRunnable(doneSignal, i)); | ||
| 127 | * | ||
| 128 | * doneSignal.await(); // wait for all to finish | ||
| 129 | * } | ||
| 130 | * } | ||
| 131 | * | ||
| 132 | * class WorkerRunnable implements Runnable { | ||
| 133 | * private final CountDownLatch doneSignal; | ||
| 134 | * private final int i; | ||
| 135 | * WorkerRunnable(CountDownLatch doneSignal, int i) { | ||
| 136 | * this.doneSignal = doneSignal; | ||
| 137 | * this.i = i; | ||
| 138 | * } | ||
| 139 | * public void run() { | ||
| 140 | * try { | ||
| 141 | * doWork(i); | ||
| 142 | * doneSignal.countDown(); | ||
| 143 | * } catch (InterruptedException ex) {} // return; | ||
| 144 | * } | ||
| 145 | * | ||
| 146 | * void doWork() { ... } | ||
| 147 | * } | ||
| 148 | * | ||
| 149 | * </pre> | ||
| 150 | * | ||
| 151 | * <p>Memory consistency effects: Until the count reaches | ||
| 152 | * zero, actions in a thread prior to calling | ||
| 153 | * {@code countDown()} | ||
| 154 | * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> | ||
| 155 | * actions following a successful return from a corresponding | ||
| 156 | * {@code await()} in another thread. | ||
| 157 | * | ||
| 158 | * @since 1.5 | ||
| 159 | * @author Doug Lea | ||
| 160 | */ | ||
| 161 | public class CountDownLatch { | ||
| 162 | /** | ||
| 163 | * Synchronization control For CountDownLatch. | ||
| 164 | * Uses AQS state to represent count. | ||
| 165 | */ | ||
| 166 | private static final class Sync extends AbstractQueuedSynchronizer { | ||
| 167 | private static final long serialVersionUID = 4982264981922014374L; | ||
| 168 | |||
| 169 | Sync(int count) { | ||
| 170 | setState(count); | ||
| 171 | } | ||
| 172 | |||
| 173 | int getCount() { | ||
| 174 | return getState(); | ||
| 175 | } | ||
| 176 | |||
| 177 | protected int tryAcquireShared(int acquires) { | ||
| 178 | return (getState() == 0) ? 1 : -1; | ||
| 179 | } | ||
| 180 | |||
| 181 | protected boolean tryReleaseShared(int releases) { | ||
| 182 | // Decrement count; signal when transition to zero | ||
| 183 | for (;;) { | ||
| 184 | int c = getState(); | ||
| 185 | if (c == 0) | ||
| 186 | return false; | ||
| 187 | int nextc = c-1; | ||
| 188 | if (compareAndSetState(c, nextc)) | ||
| 189 | return nextc == 0; | ||
| 190 | } | ||
| 191 | } | ||
| 192 | } | ||
| 193 | |||
| 194 | private final Sync sync; | ||
| 195 | |||
| 196 | /** | ||
| 197 | * Constructs a {@code CountDownLatch} initialized with the given count. | ||
| 198 | * | ||
| 199 | * @param count the number of times {@link #countDown} must be invoked | ||
| 200 | * before threads can pass through {@link #await} | ||
| 201 | * @throws IllegalArgumentException if {@code count} is negative | ||
| 202 | */ | ||
| 203 | public CountDownLatch(int count) { | ||
| 204 | if (count < 0) throw new IllegalArgumentException("count < 0"); | ||
| 205 | this.sync = new Sync(count); | ||
| 206 | } | ||
| 207 | |||
| 208 | /** | ||
| 209 | * Causes the current thread to wait until the latch has counted down to | ||
| 210 | * zero, unless the thread is {@linkplain Thread#interrupt interrupted}. | ||
| 211 | * | ||
| 212 | * <p>If the current count is zero then this method returns immediately. | ||
| 213 | * | ||
| 214 | * <p>If the current count is greater than zero then the current | ||
| 215 | * thread becomes disabled for thread scheduling purposes and lies | ||
| 216 | * dormant until one of two things happen: | ||
| 217 | * <ul> | ||
| 218 | * <li>The count reaches zero due to invocations of the | ||
| 219 | * {@link #countDown} method; or | ||
| 220 | * <li>Some other thread {@linkplain Thread#interrupt interrupts} | ||
| 221 | * the current thread. | ||
| 222 | * </ul> | ||
| 223 | * | ||
| 224 | * <p>If the current thread: | ||
| 225 | * <ul> | ||
| 226 | * <li>has its interrupted status set on entry to this method; or | ||
| 227 | * <li>is {@linkplain Thread#interrupt interrupted} while waiting, | ||
| 228 | * </ul> | ||
| 229 | * then {@link InterruptedException} is thrown and the current thread's | ||
| 230 | * interrupted status is cleared. | ||
| 231 | * | ||
| 232 | * @throws InterruptedException if the current thread is interrupted | ||
| 233 | * while waiting | ||
| 234 | */ | ||
| 235 | public void await() throws InterruptedException { | ||
| 236 | sync.acquireSharedInterruptibly(1); | ||
| 237 | } | ||
| 238 | |||
| 239 | /** | ||
| 240 | * Causes the current thread to wait until the latch has counted down to | ||
| 241 | * zero, unless the thread is {@linkplain Thread#interrupt interrupted}, | ||
| 242 | * or the specified waiting time elapses. | ||
| 243 | * | ||
| 244 | * <p>If the current count is zero then this method returns immediately | ||
| 245 | * with the value {@code true}. | ||
| 246 | * | ||
| 247 | * <p>If the current count is greater than zero then the current | ||
| 248 | * thread becomes disabled for thread scheduling purposes and lies | ||
| 249 | * dormant until one of three things happen: | ||
| 250 | * <ul> | ||
| 251 | * <li>The count reaches zero due to invocations of the | ||
| 252 | * {@link #countDown} method; or | ||
| 253 | * <li>Some other thread {@linkplain Thread#interrupt interrupts} | ||
| 254 | * the current thread; or | ||
| 255 | * <li>The specified waiting time elapses. | ||
| 256 | * </ul> | ||
| 257 | * | ||
| 258 | * <p>If the count reaches zero then the method returns with the | ||
| 259 | * value {@code true}. | ||
| 260 | * | ||
| 261 | * <p>If the current thread: | ||
| 262 | * <ul> | ||
| 263 | * <li>has its interrupted status set on entry to this method; or | ||
| 264 | * <li>is {@linkplain Thread#interrupt interrupted} while waiting, | ||
| 265 | * </ul> | ||
| 266 | * then {@link InterruptedException} is thrown and the current thread's | ||
| 267 | * interrupted status is cleared. | ||
| 268 | * | ||
| 269 | * <p>If the specified waiting time elapses then the value {@code false} | ||
| 270 | * is returned. If the time is less than or equal to zero, the method | ||
| 271 | * will not wait at all. | ||
| 272 | * | ||
| 273 | * @param timeout the maximum time to wait | ||
| 274 | * @param unit the time unit of the {@code timeout} argument | ||
| 275 | * @return {@code true} if the count reached zero and {@code false} | ||
| 276 | * if the waiting time elapsed before the count reached zero | ||
| 277 | * @throws InterruptedException if the current thread is interrupted | ||
| 278 | * while waiting | ||
| 279 | */ | ||
| 280 | public boolean await(long timeout, TimeUnit unit) | ||
| 281 | throws InterruptedException { | ||
| 282 | return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout)); | ||
| 283 | } | ||
| 284 | |||
| 285 | /** | ||
| 286 | * Decrements the count of the latch, releasing all waiting threads if | ||
| 287 | * the count reaches zero. | ||
| 288 | * | ||
| 289 | * <p>If the current count is greater than zero then it is decremented. | ||
| 290 | * If the new count is zero then all waiting threads are re-enabled for | ||
| 291 | * thread scheduling purposes. | ||
| 292 | * | ||
| 293 | * <p>If the current count equals zero then nothing happens. | ||
| 294 | */ | ||
| 295 | public void countDown() { | ||
| 296 | sync.releaseShared(1); | ||
| 297 | } | ||
| 298 | |||
| 299 | /** | ||
| 300 | * Returns the current count. | ||
| 301 | * | ||
| 302 | * <p>This method is typically used for debugging and testing purposes. | ||
| 303 | * | ||
| 304 | * @return the current count | ||
| 305 | */ | ||
| 306 | public long getCount() { | ||
| 307 | return sync.getCount(); | ||
| 308 | } | ||
| 309 | |||
| 310 | /** | ||
| 311 | * Returns a string identifying this latch, as well as its state. | ||
| 312 | * The state, in brackets, includes the String {@code "Count ="} | ||
| 313 | * followed by the current count. | ||
| 314 | * | ||
| 315 | * @return a string identifying this latch, as well as its state | ||
| 316 | */ | ||
| 317 | public String toString() { | ||
| 318 | return super.toString() + "[Count = " + sync.getCount() + "]"; | ||
| 319 | } | ||
| 320 | } | ||
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,483 @@ | |||
| 1 | /* | ||
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 3 | * | ||
| 4 | * This code is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License version 2 only, as | ||
| 6 | * published by the Free Software Foundation. Oracle designates this | ||
| 7 | * particular file as subject to the "Classpath" exception as provided | ||
| 8 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 9 | * | ||
| 10 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 13 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 14 | * accompanied this code). | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License version | ||
| 17 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | * | ||
| 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 21 | * or visit www.oracle.com if you need additional information or have any | ||
| 22 | * questions. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * This file is available under and governed by the GNU General Public | ||
| 27 | * License version 2 only, as published by the Free Software Foundation. | ||
| 28 | * However, the following notice accompanied the original version of this | ||
| 29 | * file: | ||
| 30 | * | ||
| 31 | * Written by Doug Lea with assistance from members of JCP JSR-166 | ||
| 32 | * Expert Group and released to the public domain, as explained at | ||
| 33 | * http://creativecommons.org/publicdomain/zero/1.0/ | ||
| 34 | */ | ||
| 35 | |||
| 36 | package java.util.concurrent; | ||
| 37 | import java.util.concurrent.locks.*; | ||
| 38 | |||
| 39 | /** | ||
| 40 | * A synchronization aid that allows a set of threads to all wait for | ||
| 41 | * each other to reach a common barrier point. CyclicBarriers are | ||
| 42 | * useful in programs involving a fixed sized party of threads that | ||
| 43 | * must occasionally wait for each other. The barrier is called | ||
| 44 | * <em>cyclic</em> because it can be re-used after the waiting threads | ||
| 45 | * are released. | ||
| 46 | * | ||
| 47 | * <p>A <tt>CyclicBarrier</tt> supports an optional {@link Runnable} command | ||
| 48 | * that is run once per barrier point, after the last thread in the party | ||
| 49 | * arrives, but before any threads are released. | ||
| 50 | * This <em>barrier action</em> is useful | ||
| 51 | * for updating shared-state before any of the parties continue. | ||
| 52 | * | ||
| 53 | * <p><b>Sample usage:</b> Here is an example of | ||
| 54 | * using a barrier in a parallel decomposition design: | ||
| 55 | * <pre> | ||
| 56 | * class Solver { | ||
| 57 | * final int N; | ||
| 58 | * final float[][] data; | ||
| 59 | * final CyclicBarrier barrier; | ||
| 60 | * | ||
| 61 | * class Worker implements Runnable { | ||
| 62 | * int myRow; | ||
| 63 | * Worker(int row) { myRow = row; } | ||
| 64 | * public void run() { | ||
| 65 | * while (!done()) { | ||
| 66 | * processRow(myRow); | ||
| 67 | * | ||
| 68 | * try { | ||
| 69 | * barrier.await(); | ||
| 70 | * } catch (InterruptedException ex) { | ||
| 71 | * return; | ||
| 72 | * } catch (BrokenBarrierException ex) { | ||
| 73 | * return; | ||
| 74 | * } | ||
| 75 | * } | ||
| 76 | * } | ||
| 77 | * } | ||
| 78 | * | ||
| 79 | * public Solver(float[][] matrix) { | ||
| 80 | * data = matrix; | ||
| 81 | * N = matrix.length; | ||
| 82 | * barrier = new CyclicBarrier(N, | ||
| 83 | * new Runnable() { | ||
| 84 | * public void run() { | ||
| 85 | * mergeRows(...); | ||
| 86 | * } | ||
| 87 | * }); | ||
| 88 | * for (int i = 0; i < N; ++i) | ||
| 89 | * new Thread(new Worker(i)).start(); | ||
| 90 | * | ||
| 91 | * waitUntilDone(); | ||
| 92 | * } | ||
| 93 | * } | ||
| 94 | * </pre> | ||
| 95 | * Here, each worker thread processes a row of the matrix then waits at the | ||
| 96 | * barrier until all rows have been processed. When all rows are processed | ||
| 97 | * the supplied {@link Runnable} barrier action is executed and merges the | ||
| 98 | * rows. If the merger | ||
| 99 | * determines that a solution has been found then <tt>done()</tt> will return | ||
| 100 | * <tt>true</tt> and each worker will terminate. | ||
| 101 | * | ||
| 102 | * <p>If the barrier action does not rely on the parties being suspended when | ||
| 103 | * it is executed, then any of the threads in the party could execute that | ||
| 104 | * action when it is released. To facilitate this, each invocation of | ||
| 105 | * {@link #await} returns the arrival index of that thread at the barrier. | ||
| 106 | * You can then choose which thread should execute the barrier action, for | ||
| 107 | * example: | ||
| 108 | * <pre> if (barrier.await() == 0) { | ||
| 109 | * // log the completion of this iteration | ||
| 110 | * }</pre> | ||
| 111 | * | ||
| 112 | * <p>The <tt>CyclicBarrier</tt> uses an all-or-none breakage model | ||
| 113 | * for failed synchronization attempts: If a thread leaves a barrier | ||
| 114 | * point prematurely because of interruption, failure, or timeout, all | ||
| 115 | * other threads waiting at that barrier point will also leave | ||
| 116 | * abnormally via {@link BrokenBarrierException} (or | ||
| 117 | * {@link InterruptedException} if they too were interrupted at about | ||
| 118 | * the same time). | ||
| 119 | * | ||
| 120 | * <p>Memory consistency effects: Actions in a thread prior to calling | ||
| 121 | * {@code await()} | ||
| 122 | * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> | ||
| 123 | * actions that are part of the barrier action, which in turn | ||
| 124 | * <i>happen-before</i> actions following a successful return from the | ||
| 125 | * corresponding {@code await()} in other threads. | ||
| 126 | * | ||
| 127 | * @since 1.5 | ||
| 128 | * @see CountDownLatch | ||
| 129 | * | ||
| 130 | * @author Doug Lea | ||
| 131 | */ | ||
| 132 | public class CyclicBarrier { | ||
| 133 | /** | ||
| 134 | * Each use of the barrier is represented as a generation instance. | ||
| 135 | * The generation changes whenever the barrier is tripped, or | ||
| 136 | * is reset. There can be many generations associated with threads | ||
| 137 | * using the barrier - due to the non-deterministic way the lock | ||
| 138 | * may be allocated to waiting threads - but only one of these | ||
| 139 | * can be active at a time (the one to which <tt>count</tt> applies) | ||
| 140 | * and all the rest are either broken or tripped. | ||
| 141 | * There need not be an active generation if there has been a break | ||
| 142 | * but no subsequent reset. | ||
| 143 | */ | ||
| 144 | private static class Generation { | ||
| 145 | boolean broken = false; | ||
| 146 | } | ||
| 147 | |||
| 148 | /** The lock for guarding barrier entry */ | ||
| 149 | private final ReentrantLock lock = new ReentrantLock(); | ||
| 150 | /** Condition to wait on until tripped */ | ||
| 151 | private final Condition trip = lock.newCondition(); | ||
| 152 | /** The number of parties */ | ||
| 153 | private final int parties; | ||
| 154 | /* The command to run when tripped */ | ||
| 155 | private final Runnable barrierCommand; | ||
| 156 | /** The current generation */ | ||
| 157 | private Generation generation = new Generation(); | ||
| 158 | |||
| 159 | /** | ||
| 160 | * Number of parties still waiting. Counts down from parties to 0 | ||
| 161 | * on each generation. It is reset to parties on each new | ||
| 162 | * generation or when broken. | ||
| 163 | */ | ||
| 164 | private int count; | ||
| 165 | |||
| 166 | /** | ||
| 167 | * Updates state on barrier trip and wakes up everyone. | ||
| 168 | * Called only while holding lock. | ||
| 169 | */ | ||
| 170 | private void nextGeneration() { | ||
| 171 | // signal completion of last generation | ||
| 172 | trip.signalAll(); | ||
| 173 | // set up next generation | ||
| 174 | count = parties; | ||
| 175 | generation = new Generation(); | ||
| 176 | } | ||
| 177 | |||
| 178 | /** | ||
| 179 | * Sets current barrier generation as broken and wakes up everyone. | ||
| 180 | * Called only while holding lock. | ||
| 181 | */ | ||
| 182 | private void breakBarrier() { | ||
| 183 | generation.broken = true; | ||
| 184 | count = parties; | ||
| 185 | trip.signalAll(); | ||
| 186 | } | ||
| 187 | |||
| 188 | /** | ||
| 189 | * Main barrier code, covering the various policies. | ||
| 190 | */ | ||
| 191 | private int dowait(boolean timed, long nanos) | ||
| 192 | throws InterruptedException, BrokenBarrierException, | ||
| 193 | TimeoutException { | ||
| 194 | final ReentrantLock lock = this.lock; | ||
| 195 | lock.lock(); | ||
| 196 | try { | ||
| 197 | final Generation g = generation; | ||
| 198 | |||
| 199 | if (g.broken) | ||
| 200 | throw new BrokenBarrierException(); | ||
| 201 | |||
| 202 | if (Thread.interrupted()) { | ||
| 203 | breakBarrier(); | ||
| 204 | throw new InterruptedException(); | ||
| 205 | } | ||
| 206 | |||
| 207 | int index = --count; | ||
| 208 | if (index == 0) { // tripped | ||
| 209 | boolean ranAction = false; | ||
| 210 | try { | ||
| 211 | final Runnable command = barrierCommand; | ||
| 212 | if (command != null) | ||
| 213 | command.run(); | ||
| 214 | ranAction = true; | ||
| 215 | nextGeneration(); | ||
| 216 | return 0; | ||
| 217 | } finally { | ||
| 218 | if (!ranAction) | ||
| 219 | breakBarrier(); | ||
| 220 | } | ||
| 221 | } | ||
| 222 | |||
| 223 | // loop until tripped, broken, interrupted, or timed out | ||
| 224 | for (;;) { | ||
| 225 | try { | ||
| 226 | if (!timed) | ||
| 227 | trip.await(); | ||
| 228 | else if (nanos > 0L) | ||
| 229 | nanos = trip.awaitNanos(nanos); | ||
| 230 | } catch (InterruptedException ie) { | ||
| 231 | if (g == generation && ! g.broken) { | ||
| 232 | breakBarrier(); | ||
| 233 | throw ie; | ||
| 234 | } else { | ||
| 235 | // We're about to finish waiting even if we had not | ||
| 236 | // been interrupted, so this interrupt is deemed to | ||
| 237 | // "belong" to subsequent execution. | ||
| 238 | Thread.currentThread().interrupt(); | ||
| 239 | } | ||
| 240 | } | ||
| 241 | |||
| 242 | if (g.broken) | ||
| 243 | throw new BrokenBarrierException(); | ||
| 244 | |||
| 245 | if (g != generation) | ||
| 246 | return index; | ||
| 247 | |||
| 248 | if (timed && nanos <= 0L) { | ||
| 249 | breakBarrier(); | ||
| 250 | throw new TimeoutException(); | ||
| 251 | } | ||
| 252 | } | ||
| 253 | } finally { | ||
| 254 | lock.unlock(); | ||
| 255 | } | ||
| 256 | } | ||
| 257 | |||
| 258 | /** | ||
| 259 | * Creates a new <tt>CyclicBarrier</tt> that will trip when the | ||
| 260 | * given number of parties (threads) are waiting upon it, and which | ||
| 261 | * will execute the given barrier action when the barrier is tripped, | ||
| 262 | * performed by the last thread entering the barrier. | ||
| 263 | * | ||
| 264 | * @param parties the number of threads that must invoke {@link #await} | ||
| 265 | * before the barrier is tripped | ||
| 266 | * @param barrierAction the command to execute when the barrier is | ||
| 267 | * tripped, or {@code null} if there is no action | ||
| 268 | * @throws IllegalArgumentException if {@code parties} is less than 1 | ||
| 269 | */ | ||
| 270 | public CyclicBarrier(int parties, Runnable barrierAction) { | ||
| 271 | if (parties <= 0) throw new IllegalArgumentException(); | ||
| 272 | this.parties = parties; | ||
| 273 | this.count = parties; | ||
| 274 | this.barrierCommand = barrierAction; | ||
| 275 | } | ||
| 276 | |||
| 277 | /** | ||
| 278 | * Creates a new <tt>CyclicBarrier</tt> that will trip when the | ||
| 279 | * given number of parties (threads) are waiting upon it, and | ||
| 280 | * does not perform a predefined action when the barrier is tripped. | ||
| 281 | * | ||
| 282 | * @param parties the number of threads that must invoke {@link #await} | ||
| 283 | * before the barrier is tripped | ||
| 284 | * @throws IllegalArgumentException if {@code parties} is less than 1 | ||
| 285 | */ | ||
| 286 | public CyclicBarrier(int parties) { | ||
| 287 | this(parties, null); | ||
| 288 | } | ||
| 289 | |||
| 290 | /** | ||
| 291 | * Returns the number of parties required to trip this barrier. | ||
| 292 | * | ||
| 293 | * @return the number of parties required to trip this barrier | ||
| 294 | */ | ||
| 295 | public int getParties() { | ||
| 296 | return parties; | ||
| 297 | } | ||
| 298 | |||
| 299 | /** | ||
| 300 | * Waits until all {@linkplain #getParties parties} have invoked | ||
| 301 | * <tt>await</tt> on this barrier. | ||
| 302 | * | ||
| 303 | * <p>If the current thread is not the last to arrive then it is | ||
| 304 | * disabled for thread scheduling purposes and lies dormant until | ||
| 305 | * one of the following things happens: | ||
| 306 | * <ul> | ||
| 307 | * <li>The last thread arrives; or | ||
| 308 | * <li>Some other thread {@linkplain Thread#interrupt interrupts} | ||
| 309 | * the current thread; or | ||
| 310 | * <li>Some other thread {@linkplain Thread#interrupt interrupts} | ||
| 311 | * one of the other waiting threads; or | ||
| 312 | * <li>Some other thread times out while waiting for barrier; or | ||
| 313 | * <li>Some other thread invokes {@link #reset} on this barrier. | ||
| 314 | * </ul> | ||
| 315 | * | ||
| 316 | * <p>If the current thread: | ||
| 317 | * <ul> | ||
| 318 | * <li>has its interrupted status set on entry to this method; or | ||
| 319 | * <li>is {@linkplain Thread#interrupt interrupted} while waiting | ||
| 320 | * </ul> | ||
| 321 | * then {@link InterruptedException} is thrown and the current thread's | ||
| 322 | * interrupted status is cleared. | ||
| 323 | * | ||
| 324 | * <p>If the barrier is {@link #reset} while any thread is waiting, | ||
| 325 | * or if the barrier {@linkplain #isBroken is broken} when | ||
| 326 | * <tt>await</tt> is invoked, or while any thread is waiting, then | ||
| 327 | * {@link BrokenBarrierException} is thrown. | ||
| 328 | * | ||
| 329 | * <p>If any thread is {@linkplain Thread#interrupt interrupted} while waiting, | ||
| 330 | * then all other waiting threads will throw | ||
| 331 | * {@link BrokenBarrierException} and the barrier is placed in the broken | ||
| 332 | * state. | ||
| 333 | * | ||
| 334 | * <p>If the current thread is the last thread to arrive, and a | ||
| 335 | * non-null barrier action was supplied in the constructor, then the | ||
| 336 | * current thread runs the action before allowing the other threads to | ||
| 337 | * continue. | ||
| 338 | * If an exception occurs during the barrier action then that exception | ||
| 339 | * will be propagated in the current thread and the barrier is placed in | ||
| 340 | * the broken state. | ||
| 341 | * | ||
| 342 | * @return the arrival index of the current thread, where index | ||
| 343 | * <tt>{@link #getParties()} - 1</tt> indicates the first | ||
| 344 | * to arrive and zero indicates the last to arrive | ||
| 345 | * @throws InterruptedException if the current thread was interrupted | ||
| 346 | * while waiting | ||
| 347 | * @throws BrokenBarrierException if <em>another</em> thread was | ||
| 348 | * interrupted or timed out while the current thread was | ||
| 349 | * waiting, or the barrier was reset, or the barrier was | ||
| 350 | * broken when {@code await} was called, or the barrier | ||
| 351 | * action (if present) failed due an exception. | ||
| 352 | */ | ||
| 353 | public int await() throws InterruptedException, BrokenBarrierException { | ||
| 354 | try { | ||
| 355 | return dowait(false, 0L); | ||
| 356 | } catch (TimeoutException toe) { | ||
| 357 | throw new Error(toe); // cannot happen; | ||
| 358 | } | ||
| 359 | } | ||
| 360 | |||
| 361 | /** | ||
| 362 | * Waits until all {@linkplain #getParties parties} have invoked | ||
| 363 | * <tt>await</tt> on this barrier, or the specified waiting time elapses. | ||
| 364 | * | ||
| 365 | * <p>If the current thread is not the last to arrive then it is | ||
| 366 | * disabled for thread scheduling purposes and lies dormant until | ||
| 367 | * one of the following things happens: | ||
| 368 | * <ul> | ||
| 369 | * <li>The last thread arrives; or | ||
| 370 | * <li>The specified timeout elapses; or | ||
| 371 | * <li>Some other thread {@linkplain Thread#interrupt interrupts} | ||
| 372 | * the current thread; or | ||
| 373 | * <li>Some other thread {@linkplain Thread#interrupt interrupts} | ||
| 374 | * one of the other waiting threads; or | ||
| 375 | * <li>Some other thread times out while waiting for barrier; or | ||
| 376 | * <li>Some other thread invokes {@link #reset} on this barrier. | ||
| 377 | * </ul> | ||
| 378 | * | ||
| 379 | * <p>If the current thread: | ||
| 380 | * <ul> | ||
| 381 | * <li>has its interrupted status set on entry to this method; or | ||
| 382 | * <li>is {@linkplain Thread#interrupt interrupted} while waiting | ||
| 383 | * </ul> | ||
| 384 | * then {@link InterruptedException} is thrown and the current thread's | ||
| 385 | * interrupted status is cleared. | ||
| 386 | * | ||
| 387 | * <p>If the specified waiting time elapses then {@link TimeoutException} | ||
| 388 | * is thrown. If the time is less than or equal to zero, the | ||
| 389 | * method will not wait at all. | ||
| 390 | * | ||
| 391 | * <p>If the barrier is {@link #reset} while any thread is waiting, | ||
| 392 | * or if the barrier {@linkplain #isBroken is broken} when | ||
| 393 | * <tt>await</tt> is invoked, or while any thread is waiting, then | ||
| 394 | * {@link BrokenBarrierException} is thrown. | ||
| 395 | * | ||
| 396 | * <p>If any thread is {@linkplain Thread#interrupt interrupted} while | ||
| 397 | * waiting, then all other waiting threads will throw {@link | ||
| 398 | * BrokenBarrierException} and the barrier is placed in the broken | ||
| 399 | * state. | ||
| 400 | * | ||
| 401 | * <p>If the current thread is the last thread to arrive, and a | ||
| 402 | * non-null barrier action was supplied in the constructor, then the | ||
| 403 | * current thread runs the action before allowing the other threads to | ||
| 404 | * continue. | ||
| 405 | * If an exception occurs during the barrier action then that exception | ||
| 406 | * will be propagated in the current thread and the barrier is placed in | ||
| 407 | * the broken state. | ||
| 408 | * | ||
| 409 | * @param timeout the time to wait for the barrier | ||
| 410 | * @param unit the time unit of the timeout parameter | ||
| 411 | * @return the arrival index of the current thread, where index | ||
| 412 | * <tt>{@link #getParties()} - 1</tt> indicates the first | ||
| 413 | * to arrive and zero indicates the last to arrive | ||
| 414 | * @throws InterruptedException if the current thread was interrupted | ||
| 415 | * while waiting | ||
| 416 | * @throws TimeoutException if the specified timeout elapses | ||
| 417 | * @throws BrokenBarrierException if <em>another</em> thread was | ||
| 418 | * interrupted or timed out while the current thread was | ||
| 419 | * waiting, or the barrier was reset, or the barrier was broken | ||
| 420 | * when {@code await} was called, or the barrier action (if | ||
| 421 | * present) failed due an exception | ||
| 422 | */ | ||
| 423 | public int await(long timeout, TimeUnit unit) | ||
| 424 | throws InterruptedException, | ||
| 425 | BrokenBarrierException, | ||
| 426 | TimeoutException { | ||
| 427 | return dowait(true, unit.toNanos(timeout)); | ||
| 428 | } | ||
| 429 | |||
| 430 | /** | ||
| 431 | * Queries if this barrier is in a broken state. | ||
| 432 | * | ||
| 433 | * @return {@code true} if one or more parties broke out of this | ||
| 434 | * barrier due to interruption or timeout since | ||
| 435 | * construction or the last reset, or a barrier action | ||
| 436 | * failed due to an exception; {@code false} otherwise. | ||
| 437 | */ | ||
| 438 | public boolean isBroken() { | ||
| 439 | final ReentrantLock lock = this.lock; | ||
| 440 | lock.lock(); | ||
| 441 | try { | ||
| 442 | return generation.broken; | ||
| 443 | } finally { | ||
| 444 | lock.unlock(); | ||
| 445 | } | ||
| 446 | } | ||
| 447 | |||
| 448 | /** | ||
| 449 | * Resets the barrier to its initial state. If any parties are | ||
| 450 | * currently waiting at the barrier, they will return with a | ||
| 451 | * {@link BrokenBarrierException}. Note that resets <em>after</em> | ||
| 452 | * a breakage has occurred for other reasons can be complicated to | ||
| 453 | * carry out; threads need to re-synchronize in some other way, | ||
| 454 | * and choose one to perform the reset. It may be preferable to | ||
| 455 | * instead create a new barrier for subsequent use. | ||
| 456 | */ | ||
| 457 | public void reset() { | ||
| 458 | final ReentrantLock lock = this.lock; | ||
| 459 | lock.lock(); | ||
| 460 | try { | ||
| 461 | breakBarrier(); // break the current generation | ||
| 462 | nextGeneration(); // start a new generation | ||
| 463 | } finally { | ||
| 464 | lock.unlock(); | ||
| 465 | } | ||
| 466 | } | ||
| 467 | |||
| 468 | /** | ||
| 469 | * Returns the number of parties currently waiting at the barrier. | ||
| 470 | * This method is primarily useful for debugging and assertions. | ||
| 471 | * | ||
| 472 | * @return the number of parties currently blocked in {@link #await} | ||
| 473 | */ | ||
| 474 | public int getNumberWaiting() { | ||
| 475 | final ReentrantLock lock = this.lock; | ||
| 476 | lock.lock(); | ||
| 477 | try { | ||
| 478 | return parties - count; | ||
| 479 | } finally { | ||
| 480 | lock.unlock(); | ||
| 481 | } | ||
| 482 | } | ||
| 483 | } | ||
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,546 @@ | |||
| 1 | /* | ||
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 3 | * | ||
| 4 | * This code is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License version 2 only, as | ||
| 6 | * published by the Free Software Foundation. Oracle designates this | ||
| 7 | * particular file as subject to the "Classpath" exception as provided | ||
| 8 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 9 | * | ||
| 10 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 13 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 14 | * accompanied this code). | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License version | ||
| 17 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | * | ||
| 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 21 | * or visit www.oracle.com if you need additional information or have any | ||
| 22 | * questions. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * This file is available under and governed by the GNU General Public | ||
| 27 | * License version 2 only, as published by the Free Software Foundation. | ||
| 28 | * However, the following notice accompanied the original version of this | ||
| 29 | * file: | ||
| 30 | * | ||
| 31 | * Written by Doug Lea with assistance from members of JCP JSR-166 | ||
| 32 | * Expert Group and released to the public domain, as explained at | ||
| 33 | * http://creativecommons.org/publicdomain/zero/1.0/ | ||
| 34 | */ | ||
| 35 | |||
| 36 | |||
| 37 | package java.util.concurrent; | ||
| 38 | import java.util.concurrent.locks.*; | ||
| 39 | import java.util.*; | ||
| 40 | |||
| 41 | /** | ||
| 42 | * An unbounded {@linkplain BlockingQueue blocking queue} of | ||
| 43 | * <tt>Delayed</tt> elements, in which an element can only be taken | ||
| 44 | * when its delay has expired. The <em>head</em> of the queue is that | ||
| 45 | * <tt>Delayed</tt> element whose delay expired furthest in the | ||
| 46 | * past. If no delay has expired there is no head and <tt>poll</tt> | ||
| 47 | * will return <tt>null</tt>. Expiration occurs when an element's | ||
| 48 | * <tt>getDelay(TimeUnit.NANOSECONDS)</tt> method returns a value less | ||
| 49 | * than or equal to zero. Even though unexpired elements cannot be | ||
| 50 | * removed using <tt>take</tt> or <tt>poll</tt>, they are otherwise | ||
| 51 | * treated as normal elements. For example, the <tt>size</tt> method | ||
| 52 | * returns the count of both expired and unexpired elements. | ||
| 53 | * This queue does not permit null elements. | ||
| 54 | * | ||
| 55 | * <p>This class and its iterator implement all of the | ||
| 56 | * <em>optional</em> methods of the {@link Collection} and {@link | ||
| 57 | * Iterator} interfaces. | ||
| 58 | * | ||
| 59 | * <p>This class is a member of the | ||
| 60 | * <a href="{@docRoot}/../technotes/guides/collections/index.html"> | ||
| 61 | * Java Collections Framework</a>. | ||
| 62 | * | ||
| 63 | * @since 1.5 | ||
| 64 | * @author Doug Lea | ||
| 65 | * @param <E> the type of elements held in this collection | ||
| 66 | */ | ||
| 67 | |||
| 68 | public class DelayQueue<E extends Delayed> extends AbstractQueue<E> | ||
| 69 | implements BlockingQueue<E> { | ||
| 70 | |||
| 71 | private transient final ReentrantLock lock = new ReentrantLock(); | ||
| 72 | private final PriorityQueue<E> q = new PriorityQueue<E>(); | ||
| 73 | |||
| 74 | /** | ||
| 75 | * Thread designated to wait for the element at the head of | ||
| 76 | * the queue. This variant of the Leader-Follower pattern | ||
| 77 | * (http://www.cs.wustl.edu/~schmidt/POSA/POSA2/) serves to | ||
| 78 | * minimize unnecessary timed waiting. When a thread becomes | ||
| 79 | * the leader, it waits only for the next delay to elapse, but | ||
| 80 | * other threads await indefinitely. The leader thread must | ||
| 81 | * signal some other thread before returning from take() or | ||
| 82 | * poll(...), unless some other thread becomes leader in the | ||
| 83 | * interim. Whenever the head of the queue is replaced with | ||
| 84 | * an element with an earlier expiration time, the leader | ||
| 85 | * field is invalidated by being reset to null, and some | ||
| 86 | * waiting thread, but not necessarily the current leader, is | ||
| 87 | * signalled. So waiting threads must be prepared to acquire | ||
| 88 | * and lose leadership while waiting. | ||
| 89 | */ | ||
| 90 | private Thread leader = null; | ||
| 91 | |||
| 92 | /** | ||
| 93 | * Condition signalled when a newer element becomes available | ||
| 94 | * at the head of the queue or a new thread may need to | ||
| 95 | * become leader. | ||
| 96 | */ | ||
| 97 | private final Condition available = lock.newCondition(); | ||
| 98 | |||
| 99 | /** | ||
| 100 | * Creates a new <tt>DelayQueue</tt> that is initially empty. | ||
| 101 | */ | ||
| 102 | public DelayQueue() {} | ||
| 103 | |||
| 104 | /** | ||
| 105 | * Creates a <tt>DelayQueue</tt> initially containing the elements of the | ||
| 106 | * given collection of {@link Delayed} instances. | ||
| 107 | * | ||
| 108 | * @param c the collection of elements to initially contain | ||
| 109 | * @throws NullPointerException if the specified collection or any | ||
| 110 | * of its elements are null | ||
| 111 | */ | ||
| 112 | public DelayQueue(Collection<? extends E> c) { | ||
| 113 | this.addAll(c); | ||
| 114 | } | ||
| 115 | |||
| 116 | /** | ||
| 117 | * Inserts the specified element into this delay queue. | ||
| 118 | * | ||
| 119 | * @param e the element to add | ||
| 120 | * @return <tt>true</tt> (as specified by {@link Collection#add}) | ||
| 121 | * @throws NullPointerException if the specified element is null | ||
| 122 | */ | ||
| 123 | public boolean add(E e) { | ||
| 124 | return offer(e); | ||
| 125 | } | ||
| 126 | |||
| 127 | /** | ||
| 128 | * Inserts the specified element into this delay queue. | ||
| 129 | * | ||
| 130 | * @param e the element to add | ||
| 131 | * @return <tt>true</tt> | ||
| 132 | * @throws NullPointerException if the specified element is null | ||
| 133 | */ | ||
| 134 | public boolean offer(E e) { | ||
| 135 | final ReentrantLock lock = this.lock; | ||
| 136 | lock.lock(); | ||
| 137 | try { | ||
| 138 | q.offer(e); | ||
| 139 | if (q.peek() == e) { | ||
| 140 | leader = null; | ||
| 141 | available.signal(); | ||
| 142 | } | ||
| 143 | return true; | ||
| 144 | } finally { | ||
| 145 | lock.unlock(); | ||
| 146 | } | ||
| 147 | } | ||
| 148 | |||
| 149 | /** | ||
| 150 | * Inserts the specified element into this delay queue. As the queue is | ||
| 151 | * unbounded this method will never block. | ||
| 152 | * | ||
| 153 | * @param e the element to add | ||
| 154 | * @throws NullPointerException {@inheritDoc} | ||
| 155 | */ | ||
| 156 | public void put(E e) { | ||
| 157 | offer(e); | ||
| 158 | } | ||
| 159 | |||
| 160 | /** | ||
| 161 | * Inserts the specified element into this delay queue. As the queue is | ||
| 162 | * unbounded this method will never block. | ||
| 163 | * | ||
| 164 | * @param e the element to add | ||
| 165 | * @param timeout This parameter is ignored as the method never blocks | ||
| 166 | * @param unit This parameter is ignored as the method never blocks | ||
| 167 | * @return <tt>true</tt> | ||
| 168 | * @throws NullPointerException {@inheritDoc} | ||
| 169 | */ | ||
| 170 | public boolean offer(E e, long timeout, TimeUnit unit) { | ||
| 171 | return offer(e); | ||
| 172 | } | ||
| 173 | |||
| 174 | /** | ||
| 175 | * Retrieves and removes the head of this queue, or returns <tt>null</tt> | ||
| 176 | * if this queue has no elements with an expired delay. | ||
| 177 | * | ||
| 178 | * @return the head of this queue, or <tt>null</tt> if this | ||
| 179 | * queue has no elements with an expired delay | ||
| 180 | */ | ||
| 181 | public E poll() { | ||
| 182 | final ReentrantLock lock = this.lock; | ||
| 183 | lock.lock(); | ||
| 184 | try { | ||
| 185 | E first = q.peek(); | ||
| 186 | if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0) | ||
| 187 | return null; | ||
| 188 | else | ||
| 189 | return q.poll(); | ||
| 190 | } finally { | ||
| 191 | lock.unlock(); | ||
| 192 | } | ||
| 193 | } | ||
| 194 | |||
| 195 | /** | ||
| 196 | * Retrieves and removes the head of this queue, waiting if necessary | ||
| 197 | * until an element with an expired delay is available on this queue. | ||
| 198 | * | ||
| 199 | * @return the head of this queue | ||
| 200 | * @throws InterruptedException {@inheritDoc} | ||
| 201 | */ | ||
| 202 | public E take() throws InterruptedException { | ||
| 203 | final ReentrantLock lock = this.lock; | ||
| 204 | lock.lockInterruptibly(); | ||
| 205 | try { | ||
| 206 | for (;;) { | ||
| 207 | E first = q.peek(); | ||
| 208 | if (first == null) | ||
| 209 | available.await(); | ||
| 210 | else { | ||
| 211 | long delay = first.getDelay(TimeUnit.NANOSECONDS); | ||
| 212 | if (delay <= 0) | ||
| 213 | return q.poll(); | ||
| 214 | else if (leader != null) | ||
| 215 | available.await(); | ||
| 216 | else { | ||
| 217 | Thread thisThread = Thread.currentThread(); | ||
| 218 | leader = thisThread; | ||
| 219 | try { | ||
| 220 | available.awaitNanos(delay); | ||
| 221 | } finally { | ||
| 222 | if (leader == thisThread) | ||
| 223 | leader = null; | ||
| 224 | } | ||
| 225 | } | ||
| 226 | } | ||
| 227 | } | ||
| 228 | } finally { | ||
| 229 | if (leader == null && q.peek() != null) | ||
| 230 | available.signal(); | ||
| 231 | lock.unlock(); | ||
| 232 | } | ||
| 233 | } | ||
| 234 | |||
| 235 | /** | ||
| 236 | * Retrieves and removes the head of this queue, waiting if necessary | ||
| 237 | * until an element with an expired delay is available on this queue, | ||
| 238 | * or the specified wait time expires. | ||
| 239 | * | ||
| 240 | * @return the head of this queue, or <tt>null</tt> if the | ||
| 241 | * specified waiting time elapses before an element with | ||
| 242 | * an expired delay becomes available | ||
| 243 | * @throws InterruptedException {@inheritDoc} | ||
| 244 | */ | ||
| 245 | public E poll(long timeout, TimeUnit unit) throws InterruptedException { | ||
| 246 | long nanos = unit.toNanos(timeout); | ||
| 247 | final ReentrantLock lock = this.lock; | ||
| 248 | lock.lockInterruptibly(); | ||
| 249 | try { | ||
| 250 | for (;;) { | ||
| 251 | E first = q.peek(); | ||
| 252 | if (first == null) { | ||
| 253 | if (nanos <= 0) | ||
| 254 | return null; | ||
| 255 | else | ||
| 256 | nanos = available.awaitNanos(nanos); | ||
| 257 | } else { | ||
| 258 | long delay = first.getDelay(TimeUnit.NANOSECONDS); | ||
| 259 | if (delay <= 0) | ||
| 260 | return q.poll(); | ||
| 261 | if (nanos <= 0) | ||
| 262 | return null; | ||
| 263 | if (nanos < delay || leader != null) | ||
| 264 | nanos = available.awaitNanos(nanos); | ||
| 265 | else { | ||
| 266 | Thread thisThread = Thread.currentThread(); | ||
| 267 | leader = thisThread; | ||
| 268 | try { | ||
| 269 | long timeLeft = available.awaitNanos(delay); | ||
| 270 | nanos -= delay - timeLeft; | ||
| 271 | } finally { | ||
| 272 | if (leader == thisThread) | ||
| 273 | leader = null; | ||
| 274 | } | ||
| 275 | } | ||
| 276 | } | ||
| 277 | } | ||
| 278 | } finally { | ||
| 279 | if (leader == null && q.peek() != null) | ||
| 280 | available.signal(); | ||
| 281 | lock.unlock(); | ||
| 282 | } | ||
| 283 | } | ||
| 284 | |||
| 285 | /** | ||
| 286 | * Retrieves, but does not remove, the head of this queue, or | ||
| 287 | * returns <tt>null</tt> if this queue is empty. Unlike | ||
| 288 | * <tt>poll</tt>, if no expired elements are available in the queue, | ||
| 289 | * this method returns the element that will expire next, | ||
| 290 | * if one exists. | ||
| 291 | * | ||
| 292 | * @return the head of this queue, or <tt>null</tt> if this | ||
| 293 | * queue is empty. | ||
| 294 | */ | ||
| 295 | public E peek() { | ||
| 296 | final ReentrantLock lock = this.lock; | ||
| 297 | lock.lock(); | ||
| 298 | try { | ||
| 299 | return q.peek(); | ||
| 300 | } finally { | ||
| 301 | lock.unlock(); | ||
| 302 | } | ||
| 303 | } | ||
| 304 | |||
| 305 | public int size() { | ||
| 306 | final ReentrantLock lock = this.lock; | ||
| 307 | lock.lock(); | ||
| 308 | try { | ||
| 309 | return q.size(); | ||
| 310 | } finally { | ||
| 311 | lock.unlock(); | ||
| 312 | } | ||
| 313 | } | ||
| 314 | |||
| 315 | /** | ||
| 316 | * @throws UnsupportedOperationException {@inheritDoc} | ||
| 317 | * @throws ClassCastException {@inheritDoc} | ||
| 318 | * @throws NullPointerException {@inheritDoc} | ||
| 319 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 320 | */ | ||
| 321 | public int drainTo(Collection<? super E> c) { | ||
| 322 | if (c == null) | ||
| 323 | throw new NullPointerException(); | ||
| 324 | if (c == this) | ||
| 325 | throw new IllegalArgumentException(); | ||
| 326 | final ReentrantLock lock = this.lock; | ||
| 327 | lock.lock(); | ||
| 328 | try { | ||
| 329 | int n = 0; | ||
| 330 | for (;;) { | ||
| 331 | E first = q.peek(); | ||
| 332 | if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0) | ||
| 333 | break; | ||
| 334 | c.add(q.poll()); | ||
| 335 | ++n; | ||
| 336 | } | ||
| 337 | return n; | ||
| 338 | } finally { | ||
| 339 | lock.unlock(); | ||
| 340 | } | ||
| 341 | } | ||
| 342 | |||
| 343 | /** | ||
| 344 | * @throws UnsupportedOperationException {@inheritDoc} | ||
| 345 | * @throws ClassCastException {@inheritDoc} | ||
| 346 | * @throws NullPointerException {@inheritDoc} | ||
| 347 | * @throws IllegalArgumentException {@inheritDoc} | ||
| 348 | */ | ||
| 349 | public int drainTo(Collection<? super E> c, int maxElements) { | ||
| 350 | if (c == null) | ||
| 351 | throw new NullPointerException(); | ||
| 352 | if (c == this) | ||
| 353 | throw new IllegalArgumentException(); | ||
| 354 | if (maxElements <= 0) | ||
| 355 | return 0; | ||
| 356 | final ReentrantLock lock = this.lock; | ||
| 357 | lock.lock(); | ||
| 358 | try { | ||
| 359 | int n = 0; | ||
| 360 | while (n < maxElements) { | ||
| 361 | E first = q.peek(); | ||
| 362 | if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0) | ||
| 363 | break; | ||
| 364 | c.add(q.poll()); | ||
| 365 | ++n; | ||
| 366 | } | ||
| 367 | return n; | ||
| 368 | } finally { | ||
| 369 | lock.unlock(); | ||
| 370 | } | ||
| 371 | } | ||
| 372 | |||
| 373 | /** | ||
| 374 | * Atomically removes all of the elements from this delay queue. | ||
| 375 | * The queue will be empty after this call returns. | ||
| 376 | * Elements with an unexpired delay are not waited for; they are | ||
| 377 | * simply discarded from the queue. | ||
| 378 | */ | ||
| 379 | public void clear() { | ||
| 380 | final ReentrantLock lock = this.lock; | ||
| 381 | lock.lock(); | ||
| 382 | try { | ||
| 383 | q.clear(); | ||
| 384 | } finally { | ||
| 385 | lock.unlock(); | ||
| 386 | } | ||
| 387 | } | ||
| 388 | |||
| 389 | /** | ||
| 390 | * Always returns <tt>Integer.MAX_VALUE</tt> because | ||
| 391 | * a <tt>DelayQueue</tt> is not capacity constrained. | ||
| 392 | * | ||
| 393 | * @return <tt>Integer.MAX_VALUE</tt> | ||
| 394 | */ | ||
| 395 | public int remainingCapacity() { | ||
| 396 | return Integer.MAX_VALUE; | ||
| 397 | } | ||
| 398 | |||
| 399 | /** | ||
| 400 | * Returns an array containing all of the elements in this queue. | ||
| 401 | * The returned array elements are in no particular order. | ||
| 402 | * | ||
| 403 | * <p>The returned array will be "safe" in that no references to it are | ||
| 404 | * maintained by this queue. (In other words, this method must allocate | ||
| 405 | * a new array). The caller is thus free to modify the returned array. | ||
| 406 | * | ||
| 407 | * <p>This method acts as bridge between array-based and collection-based | ||
| 408 | * APIs. | ||
| 409 | * | ||
| 410 | * @return an array containing all of the elements in this queue | ||
| 411 | */ | ||
| 412 | public Object[] toArray() { | ||
| 413 | final ReentrantLock lock = this.lock; | ||
| 414 | lock.lock(); | ||
| 415 | try { | ||
| 416 | return q.toArray(); | ||
| 417 | } finally { | ||
| 418 | lock.unlock(); | ||
| 419 | } | ||
| 420 | } | ||
| 421 | |||
| 422 | /** | ||
| 423 | * Returns an array containing all of the elements in this queue; the | ||
| 424 | * runtime type of the returned array is that of the specified array. | ||
| 425 | * The returned array elements are in no particular order. | ||
| 426 | * If the queue fits in the specified array, it is returned therein. | ||
| 427 | * Otherwise, a new array is allocated with the runtime type of the | ||
| 428 | * specified array and the size of this queue. | ||
| 429 | * | ||
| 430 | * <p>If this queue fits in the specified array with room to spare | ||
| 431 | * (i.e., the array has more elements than this queue), the element in | ||
| 432 | * the array immediately following the end of the queue is set to | ||
| 433 | * <tt>null</tt>. | ||
| 434 | * | ||
| 435 | * <p>Like the {@link #toArray()} method, this method acts as bridge between | ||
| 436 | * array-based and collection-based APIs. Further, this method allows | ||
| 437 | * precise control over the runtime type of the output array, and may, | ||
| 438 | * under certain circumstances, be used to save allocation costs. | ||
| 439 | * | ||
| 440 | * <p>The following code can be used to dump a delay queue into a newly | ||
| 441 | * allocated array of <tt>Delayed</tt>: | ||
| 442 | * | ||
| 443 | * <pre> | ||
| 444 | * Delayed[] a = q.toArray(new Delayed[0]);</pre> | ||
| 445 | * | ||
| 446 | * Note that <tt>toArray(new Object[0])</tt> is identical in function to | ||
| 447 | * <tt>toArray()</tt>. | ||
| 448 | * | ||
| 449 | * @param a the array into which the elements of the queue are to | ||
| 450 | * be stored, if it is big enough; otherwise, a new array of the | ||
| 451 | * same runtime type is allocated for this purpose | ||
| 452 | * @return an array containing all of the elements in this queue | ||
| 453 | * @throws ArrayStoreException if the runtime type of the specified array | ||
| 454 | * is not a supertype of the runtime type of every element in | ||
| 455 | * this queue | ||
| 456 | * @throws NullPointerException if the specified array is null | ||
| 457 | */ | ||
| 458 | public <T> T[] toArray(T[] a) { | ||
| 459 | final ReentrantLock lock = this.lock; | ||
| 460 | lock.lock(); | ||
| 461 | try { | ||
| 462 | return q.toArray(a); | ||
| 463 | } finally { | ||
| 464 | lock.unlock(); | ||
| 465 | } | ||
| 466 | } | ||
| 467 | |||
| 468 | /** | ||
| 469 | * Removes a single instance of the specified element from this | ||
| 470 | * queue, if it is present, whether or not it has expired. | ||
| 471 | */ | ||
| 472 | public boolean remove(Object o) { | ||
| 473 | final ReentrantLock lock = this.lock; | ||
| 474 | lock.lock(); | ||
| 475 | try { | ||
| 476 | return q.remove(o); | ||
| 477 | } finally { | ||
| 478 | lock.unlock(); | ||
| 479 | } | ||
| 480 | } | ||
| 481 | |||
| 482 | /** | ||
| 483 | * Returns an iterator over all the elements (both expired and | ||
| 484 | * unexpired) in this queue. The iterator does not return the | ||
| 485 | * elements in any particular order. | ||
| 486 | * | ||
| 487 | * <p>The returned iterator is a "weakly consistent" iterator that | ||
| 488 | * will never throw {@link java.util.ConcurrentModificationException | ||
| 489 | * ConcurrentModificationException}, and guarantees to traverse | ||
| 490 | * elements as they existed upon construction of the iterator, and | ||
| 491 | * may (but is not guaranteed to) reflect any modifications | ||
| 492 | * subsequent to construction. | ||
| 493 | * | ||
| 494 | * @return an iterator over the elements in this queue | ||
| 495 | */ | ||
| 496 | public Iterator<E> iterator() { | ||
| 497 | return new Itr(toArray()); | ||
| 498 | } | ||
| 499 | |||
| 500 | /** | ||
| 501 | * Snapshot iterator that works off copy of underlying q array. | ||
| 502 | */ | ||
| 503 | private class Itr implements Iterator<E> { | ||
| 504 | final Object[] array; // Array of all elements | ||
| 505 | int cursor; // index of next element to return; | ||
| 506 | int lastRet; // index of last element, or -1 if no such | ||
| 507 | |||
| 508 | Itr(Object[] array) { | ||
| 509 | lastRet = -1; | ||
| 510 | this.array = array; | ||
| 511 | } | ||
| 512 | |||
| 513 | public boolean hasNext() { | ||
| 514 | return cursor < array.length; | ||
| 515 | } | ||
| 516 | |||
| 517 | @SuppressWarnings("unchecked") | ||
| 518 | public E next() { | ||
| 519 | if (cursor >= array.length) | ||
| 520 | throw new NoSuchElementException(); | ||
| 521 | lastRet = cursor; | ||
| 522 | return (E)array[cursor++]; | ||
| 523 | } | ||
| 524 | |||
| 525 | public void remove() { | ||
| 526 | if (lastRet < 0) | ||
| 527 | throw new IllegalStateException(); | ||
| 528 | Object x = array[lastRet]; | ||
| 529 | lastRet = -1; | ||
| 530 | // Traverse underlying queue to find == element, | ||
| 531 | // not just a .equals element. | ||
| 532 | lock.lock(); | ||
| 533 | try { | ||
| 534 | for (Iterator it = q.iterator(); it.hasNext(); ) { | ||
| 535 | if (it.next() == x) { | ||
| 536 | it.remove(); | ||
| 537 | return; | ||
| 538 | } | ||
| 539 | } | ||
| 540 | } finally { | ||
| 541 | lock.unlock(); | ||
| 542 | } | ||
| 543 | } | ||
| 544 | } | ||
| 545 | |||
| 546 | } | ||
Binary file not shown.
| @@ -0,0 +1,62 @@ | |||
| 1 | /* | ||
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 3 | * | ||
| 4 | * This code is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License version 2 only, as | ||
| 6 | * published by the Free Software Foundation. Oracle designates this | ||
| 7 | * particular file as subject to the "Classpath" exception as provided | ||
| 8 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 9 | * | ||
| 10 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 13 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 14 | * accompanied this code). | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License version | ||
| 17 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | * | ||
| 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 21 | * or visit www.oracle.com if you need additional information or have any | ||
| 22 | * questions. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * This file is available under and governed by the GNU General Public | ||
| 27 | * License version 2 only, as published by the Free Software Foundation. | ||
| 28 | * However, the following notice accompanied the original version of this | ||
| 29 | * file: | ||
| 30 | * | ||
| 31 | * Written by Doug Lea with assistance from members of JCP JSR-166 | ||
| 32 | * Expert Group and released to the public domain, as explained at | ||
| 33 | * http://creativecommons.org/publicdomain/zero/1.0/ | ||
| 34 | */ | ||
| 35 | |||
| 36 | package java.util.concurrent; | ||
| 37 | |||
| 38 | import java.util.*; | ||
| 39 | |||
| 40 | /** | ||
| 41 | * A mix-in style interface for marking objects that should be | ||
| 42 | * acted upon after a given delay. | ||
| 43 | * | ||
| 44 | * <p>An implementation of this interface must define a | ||
| 45 | * <tt>compareTo</tt> method that provides an ordering consistent with | ||
| 46 | * its <tt>getDelay</tt> method. | ||
| 47 | * | ||
| 48 | * @since 1.5 | ||
| 49 | * @author Doug Lea | ||
| 50 | */ | ||
| 51 | public interface Delayed extends Comparable<Delayed> { | ||
| 52 | |||
| 53 | /** | ||
| 54 | * Returns the remaining delay associated with this object, in the | ||
| 55 | * given time unit. | ||
| 56 | * | ||
| 57 | * @param unit the time unit | ||
| 58 | * @return the remaining delay; zero or negative values indicate | ||
| 59 | * that the delay has already elapsed | ||
| 60 | */ | ||
| 61 | long getDelay(TimeUnit unit); | ||
| 62 | } | ||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,687 @@ | |||
| 1 | /* | ||
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 3 | * | ||
| 4 | * This code is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License version 2 only, as | ||
| 6 | * published by the Free Software Foundation. Oracle designates this | ||
| 7 | * particular file as subject to the "Classpath" exception as provided | ||
| 8 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 9 | * | ||
| 10 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 13 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 14 | * accompanied this code). | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License version | ||
| 17 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | * | ||
| 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 21 | * or visit www.oracle.com if you need additional information or have any | ||
| 22 | * questions. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * This file is available under and governed by the GNU General Public | ||
| 27 | * License version 2 only, as published by the Free Software Foundation. | ||
| 28 | * However, the following notice accompanied the original version of this | ||
| 29 | * file: | ||
| 30 | * | ||
| 31 | * Written by Doug Lea, Bill Scherer, and Michael Scott with | ||
| 32 | * assistance from members of JCP JSR-166 Expert Group and released to | ||
| 33 | * the public domain, as explained at | ||
| 34 | * http://creativecommons.org/publicdomain/zero/1.0/ | ||
| 35 | */ | ||
| 36 | |||
| 37 | package java.util.concurrent; | ||
| 38 | import java.util.concurrent.atomic.*; | ||
| 39 | import java.util.concurrent.locks.LockSupport; | ||
| 40 | |||
| 41 | /** | ||
| 42 | * A synchronization point at which threads can pair and swap elements | ||
| 43 | * within pairs. Each thread presents some object on entry to the | ||
| 44 | * {@link #exchange exchange} method, matches with a partner thread, | ||
| 45 | * and receives its partner's object on return. An Exchanger may be | ||
| 46 | * viewed as a bidirectional form of a {@link SynchronousQueue}. | ||
| 47 | * Exchangers may be useful in applications such as genetic algorithms | ||
| 48 | * and pipeline designs. | ||
| 49 | * | ||
| 50 | * <p><b>Sample Usage:</b> | ||
| 51 | * Here are the highlights of a class that uses an {@code Exchanger} | ||
| 52 | * to swap buffers between threads so that the thread filling the | ||
| 53 | * buffer gets a freshly emptied one when it needs it, handing off the | ||
| 54 | * filled one to the thread emptying the buffer. | ||
| 55 | * <pre>{@code | ||
| 56 | * class FillAndEmpty { | ||
| 57 | * Exchanger<DataBuffer> exchanger = new Exchanger<DataBuffer>(); | ||
| 58 | * DataBuffer initialEmptyBuffer = ... a made-up type | ||
| 59 | * DataBuffer initialFullBuffer = ... | ||
| 60 | * | ||
| 61 | * class FillingLoop implements Runnable { | ||
| 62 | * public void run() { | ||
| 63 | * DataBuffer currentBuffer = initialEmptyBuffer; | ||
| 64 | * try { | ||
| 65 | * while (currentBuffer != null) { | ||
| 66 | * addToBuffer(currentBuffer); | ||
| 67 | * if (currentBuffer.isFull()) | ||
| 68 | * currentBuffer = exchanger.exchange(currentBuffer); | ||
| 69 | * } | ||
| 70 | * } catch (InterruptedException ex) { ... handle ... } | ||
| 71 | * } | ||
| 72 | * } | ||
| 73 | * | ||
| 74 | * class EmptyingLoop implements Runnable { | ||
| 75 | * public void run() { | ||
| 76 | * DataBuffer currentBuffer = initialFullBuffer; | ||
| 77 | * try { | ||
| 78 | * while (currentBuffer != null) { | ||
| 79 | * takeFromBuffer(currentBuffer); | ||
| 80 | * if (currentBuffer.isEmpty()) | ||
| 81 | * currentBuffer = exchanger.exchange(currentBuffer); | ||
| 82 | * } | ||
| 83 | * } catch (InterruptedException ex) { ... handle ...} | ||
| 84 | * } | ||
| 85 | * } | ||
| 86 | * | ||
| 87 | * void start() { | ||
| 88 | * new Thread(new FillingLoop()).start(); | ||
| 89 | * new Thread(new EmptyingLoop()).start(); | ||
| 90 | * } | ||
| 91 | * } | ||
| 92 | * }</pre> | ||
| 93 | * | ||
| 94 | * <p>Memory consistency effects: For each pair of threads that | ||
| 95 | * successfully exchange objects via an {@code Exchanger}, actions | ||
| 96 | * prior to the {@code exchange()} in each thread | ||
| 97 | * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> | ||
| 98 | * those subsequent to a return from the corresponding {@code exchange()} | ||
| 99 | * in the other thread. | ||
| 100 | * | ||
| 101 | * @since 1.5 | ||
| 102 | * @author Doug Lea and Bill Scherer and Michael Scott | ||
| 103 | * @param <V> The type of objects that may be exchanged | ||
| 104 | */ | ||
| 105 | public class Exchanger<V> { | ||
| 106 | /* | ||
| 107 | * Algorithm Description: | ||
| 108 | * | ||
| 109 | * The basic idea is to maintain a "slot", which is a reference to | ||
| 110 | * a Node containing both an Item to offer and a "hole" waiting to | ||
| 111 | * get filled in. If an incoming "occupying" thread sees that the | ||
| 112 | * slot is null, it CAS'es (compareAndSets) a Node there and waits | ||
| 113 | * for another to invoke exchange. That second "fulfilling" thread | ||
| 114 | * sees that the slot is non-null, and so CASes it back to null, | ||
| 115 | * also exchanging items by CASing the hole, plus waking up the | ||
| 116 | * occupying thread if it is blocked. In each case CAS'es may | ||
| 117 | * fail because a slot at first appears non-null but is null upon | ||
| 118 | * CAS, or vice-versa. So threads may need to retry these | ||
| 119 | * actions. | ||
| 120 | * | ||
| 121 | * This simple approach works great when there are only a few | ||
| 122 | * threads using an Exchanger, but performance rapidly | ||
| 123 | * deteriorates due to CAS contention on the single slot when | ||
| 124 | * there are lots of threads using an exchanger. So instead we use | ||
| 125 | * an "arena"; basically a kind of hash table with a dynamically | ||
| 126 | * varying number of slots, any one of which can be used by | ||
| 127 | * threads performing an exchange. Incoming threads pick slots | ||
| 128 | * based on a hash of their Thread ids. If an incoming thread | ||
| 129 | * fails to CAS in its chosen slot, it picks an alternative slot | ||
| 130 | * instead. And similarly from there. If a thread successfully | ||
| 131 | * CASes into a slot but no other thread arrives, it tries | ||
| 132 | * another, heading toward the zero slot, which always exists even | ||
| 133 | * if the table shrinks. The particular mechanics controlling this | ||
| 134 | * are as follows: | ||
| 135 | * | ||
| 136 | * Waiting: Slot zero is special in that it is the only slot that | ||
| 137 | * exists when there is no contention. A thread occupying slot | ||
| 138 | * zero will block if no thread fulfills it after a short spin. | ||
| 139 | * In other cases, occupying threads eventually give up and try | ||
| 140 | * another slot. Waiting threads spin for a while (a period that | ||
| 141 | * should be a little less than a typical context-switch time) | ||
| 142 | * before either blocking (if slot zero) or giving up (if other | ||
| 143 | * slots) and restarting. There is no reason for threads to block | ||
| 144 | * unless there are unlikely to be any other threads present. | ||
| 145 | * Occupants are mainly avoiding memory contention so sit there | ||
| 146 | * quietly polling for a shorter period than it would take to | ||
| 147 | * block and then unblock them. Non-slot-zero waits that elapse | ||
| 148 | * because of lack of other threads waste around one extra | ||
| 149 | * context-switch time per try, which is still on average much | ||
| 150 | * faster than alternative approaches. | ||
| 151 | * | ||
| 152 | * Sizing: Usually, using only a few slots suffices to reduce | ||
| 153 | * contention. Especially with small numbers of threads, using | ||
| 154 | * too many slots can lead to just as poor performance as using | ||
| 155 | * too few of them, and there's not much room for error. The | ||
| 156 | * variable "max" maintains the number of slots actually in | ||
| 157 | * use. It is increased when a thread sees too many CAS | ||
| 158 | * failures. (This is analogous to resizing a regular hash table | ||
| 159 | * based on a target load factor, except here, growth steps are | ||
| 160 | * just one-by-one rather than proportional.) Growth requires | ||
| 161 | * contention failures in each of three tried slots. Requiring | ||
| 162 | * multiple failures for expansion copes with the fact that some | ||
| 163 | * failed CASes are not due to contention but instead to simple | ||
| 164 | * races between two threads or thread pre-emptions occurring | ||
| 165 | * between reading and CASing. Also, very transient peak | ||
| 166 | * contention can be much higher than the average sustainable | ||
| 167 | * levels. An attempt to decrease the max limit is usually made | ||
| 168 | * when a non-slot-zero wait elapses without being fulfilled. | ||
| 169 | * Threads experiencing elapsed waits move closer to zero, so | ||
| 170 | * eventually find existing (or future) threads even if the table | ||
| 171 | * has been shrunk due to inactivity. The chosen mechanics and | ||
| 172 | * thresholds for growing and shrinking are intrinsically | ||
| 173 | * entangled with indexing and hashing inside the exchange code, | ||
| 174 | * and can't be nicely abstracted out. | ||
| 175 | * | ||
| 176 | * Hashing: Each thread picks its initial slot to use in accord | ||
| 177 | * with a simple hashcode. The sequence is the same on each | ||
| 178 | * encounter by any given thread, but effectively random across | ||
| 179 | * threads. Using arenas encounters the classic cost vs quality | ||
| 180 | * tradeoffs of all hash tables. Here, we use a one-step FNV-1a | ||
| 181 | * hash code based on the current thread's Thread.getId(), along | ||
| 182 | * with a cheap approximation to a mod operation to select an | ||
| 183 | * index. The downside of optimizing index selection in this way | ||
| 184 | * is that the code is hardwired to use a maximum table size of | ||
| 185 | * 32. But this value more than suffices for known platforms and | ||
| 186 | * applications. | ||
| 187 | * | ||
| 188 | * Probing: On sensed contention of a selected slot, we probe | ||
| 189 | * sequentially through the table, analogously to linear probing | ||
| 190 | * after collision in a hash table. (We move circularly, in | ||
| 191 | * reverse order, to mesh best with table growth and shrinkage | ||
| 192 | * rules.) Except that to minimize the effects of false-alarms | ||
| 193 | * and cache thrashing, we try the first selected slot twice | ||
| 194 | * before moving. | ||
| 195 | * | ||
| 196 | * Padding: Even with contention management, slots are heavily | ||
| 197 | * contended, so use cache-padding to avoid poor memory | ||
| 198 | * performance. Because of this, slots are lazily constructed | ||
| 199 | * only when used, to avoid wasting this space unnecessarily. | ||
| 200 | * While isolation of locations is not much of an issue at first | ||
| 201 | * in an application, as time goes on and garbage-collectors | ||
| 202 | * perform compaction, slots are very likely to be moved adjacent | ||
| 203 | * to each other, which can cause much thrashing of cache lines on | ||
| 204 | * MPs unless padding is employed. | ||
| 205 | * | ||
| 206 | * This is an improvement of the algorithm described in the paper | ||
| 207 | * "A Scalable Elimination-based Exchange Channel" by William | ||
| 208 | * Scherer, Doug Lea, and Michael Scott in Proceedings of SCOOL05 | ||
| 209 | * workshop. Available at: http://hdl.handle.net/1802/2104 | ||
| 210 | */ | ||
| 211 | |||
| 212 | /** The number of CPUs, for sizing and spin control */ | ||
| 213 | private static final int NCPU = Runtime.getRuntime().availableProcessors(); | ||
| 214 | |||
| 215 | /** | ||
| 216 | * The capacity of the arena. Set to a value that provides more | ||
| 217 | * than enough space to handle contention. On small machines | ||
| 218 | * most slots won't be used, but it is still not wasted because | ||
| 219 | * the extra space provides some machine-level address padding | ||
| 220 | * to minimize interference with heavily CAS'ed Slot locations. | ||
| 221 | * And on very large machines, performance eventually becomes | ||
| 222 | * bounded by memory bandwidth, not numbers of threads/CPUs. | ||
| 223 | * This constant cannot be changed without also modifying | ||
| 224 | * indexing and hashing algorithms. | ||
| 225 | */ | ||
| 226 | private static final int CAPACITY = 32; | ||
| 227 | |||
| 228 | /** | ||
| 229 | * The value of "max" that will hold all threads without | ||
| 230 | * contention. When this value is less than CAPACITY, some | ||
| 231 | * otherwise wasted expansion can be avoided. | ||
| 232 | */ | ||
| 233 | private static final int FULL = | ||
| 234 | Math.max(0, Math.min(CAPACITY, NCPU / 2) - 1); | ||
| 235 | |||
| 236 | /** | ||
| 237 | * The number of times to spin (doing nothing except polling a | ||
| 238 | * memory location) before blocking or giving up while waiting to | ||
| 239 | * be fulfilled. Should be zero on uniprocessors. On | ||
| 240 | * multiprocessors, this value should be large enough so that two | ||
| 241 | * threads exchanging items as fast as possible block only when | ||
| 242 | * one of them is stalled (due to GC or preemption), but not much | ||
| 243 | * longer, to avoid wasting CPU resources. Seen differently, this | ||
| 244 | * value is a little over half the number of cycles of an average | ||
| 245 | * context switch time on most systems. The value here is | ||
| 246 | * approximately the average of those across a range of tested | ||
| 247 | * systems. | ||
| 248 | */ | ||
| 249 | private static final int SPINS = (NCPU == 1) ? 0 : 2000; | ||
| 250 | |||
| 251 | /** | ||
| 252 | * The number of times to spin before blocking in timed waits. | ||
| 253 | * Timed waits spin more slowly because checking the time takes | ||
| 254 | * time. The best value relies mainly on the relative rate of | ||
| 255 | * System.nanoTime vs memory accesses. The value is empirically | ||
| 256 | * derived to work well across a variety of systems. | ||
| 257 | */ | ||
| 258 | private static final int TIMED_SPINS = SPINS / 20; | ||
| 259 | |||
| 260 | /** | ||
| 261 | * Sentinel item representing cancellation of a wait due to | ||
| 262 | * interruption, timeout, or elapsed spin-waits. This value is | ||
| 263 | * placed in holes on cancellation, and used as a return value | ||
| 264 | * from waiting methods to indicate failure to set or get hole. | ||
| 265 | */ | ||
| 266 | private static final Object CANCEL = new Object(); | ||
| 267 | |||
| 268 | /** | ||
| 269 | * Value representing null arguments/returns from public | ||
| 270 | * methods. This disambiguates from internal requirement that | ||
| 271 | * holes start out as null to mean they are not yet set. | ||
| 272 | */ | ||
| 273 | private static final Object NULL_ITEM = new Object(); | ||
| 274 | |||
| 275 | /** | ||
| 276 | * Nodes hold partially exchanged data. This class | ||
| 277 | * opportunistically subclasses AtomicReference to represent the | ||
| 278 | * hole. So get() returns hole, and compareAndSet CAS'es value | ||
| 279 | * into hole. This class cannot be parameterized as "V" because | ||
| 280 | * of the use of non-V CANCEL sentinels. | ||
| 281 | */ | ||
| 282 | private static final class Node extends AtomicReference<Object> { | ||
| 283 | /** The element offered by the Thread creating this node. */ | ||
| 284 | public final Object item; | ||
| 285 | |||
| 286 | /** The Thread waiting to be signalled; null until waiting. */ | ||
| 287 | public volatile Thread waiter; | ||
| 288 | |||
| 289 | /** | ||
| 290 | * Creates node with given item and empty hole. | ||
| 291 | * @param item the item | ||
| 292 | */ | ||
| 293 | public Node(Object item) { | ||
| 294 | this.item = item; | ||
| 295 | } | ||
| 296 | } | ||
| 297 | |||
| 298 | /** | ||
| 299 | * A Slot is an AtomicReference with heuristic padding to lessen | ||
| 300 | * cache effects of this heavily CAS'ed location. While the | ||
| 301 | * padding adds noticeable space, all slots are created only on | ||
| 302 | * demand, and there will be more than one of them only when it | ||
| 303 | * would improve throughput more than enough to outweigh using | ||
| 304 | * extra space. | ||
| 305 | */ | ||
| 306 | private static final class Slot extends AtomicReference<Object> { | ||
| 307 | // Improve likelihood of isolation on <= 64 byte cache lines | ||
| 308 | long q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, qa, qb, qc, qd, qe; | ||
| 309 | } | ||
| 310 | |||
| 311 | /** | ||
| 312 | * Slot array. Elements are lazily initialized when needed. | ||
| 313 | * Declared volatile to enable double-checked lazy construction. | ||
| 314 | */ | ||
| 315 | private volatile Slot[] arena = new Slot[CAPACITY]; | ||
| 316 | |||
| 317 | /** | ||
| 318 | * The maximum slot index being used. The value sometimes | ||
| 319 | * increases when a thread experiences too many CAS contentions, | ||
| 320 | * and sometimes decreases when a spin-wait elapses. Changes | ||
| 321 | * are performed only via compareAndSet, to avoid stale values | ||
| 322 | * when a thread happens to stall right before setting. | ||
| 323 | */ | ||
| 324 | private final AtomicInteger max = new AtomicInteger(); | ||
| 325 | |||
| 326 | /** | ||
| 327 | * Main exchange function, handling the different policy variants. | ||
| 328 | * Uses Object, not "V" as argument and return value to simplify | ||
| 329 | * handling of sentinel values. Callers from public methods decode | ||
| 330 | * and cast accordingly. | ||
| 331 | * | ||
| 332 | * @param item the (non-null) item to exchange | ||
| 333 | * @param timed true if the wait is timed | ||
| 334 | * @param nanos if timed, the maximum wait time | ||
| 335 | * @return the other thread's item, or CANCEL if interrupted or timed out | ||
| 336 | */ | ||
| 337 | private Object doExchange(Object item, boolean timed, long nanos) { | ||
| 338 | Node me = new Node(item); // Create in case occupying | ||
| 339 | int index = hashIndex(); // Index of current slot | ||
| 340 | int fails = 0; // Number of CAS failures | ||
| 341 | |||
| 342 | for (;;) { | ||
| 343 | Object y; // Contents of current slot | ||
| 344 | Slot slot = arena[index]; | ||
| 345 | if (slot == null) // Lazily initialize slots | ||
| 346 | createSlot(index); // Continue loop to reread | ||
| 347 | else if ((y = slot.get()) != null && // Try to fulfill | ||
| 348 | slot.compareAndSet(y, null)) { | ||
| 349 | Node you = (Node)y; // Transfer item | ||
| 350 | if (you.compareAndSet(null, item)) { | ||
| 351 | LockSupport.unpark(you.waiter); | ||
| 352 | return you.item; | ||
| 353 | } // Else cancelled; continue | ||
| 354 | } | ||
| 355 | else if (y == null && // Try to occupy | ||
| 356 | slot.compareAndSet(null, me)) { | ||
| 357 | if (index == 0) // Blocking wait for slot 0 | ||
| 358 | return timed ? | ||
| 359 | awaitNanos(me, slot, nanos) : | ||
| 360 | await(me, slot); | ||
| 361 | Object v = spinWait(me, slot); // Spin wait for non-0 | ||
| 362 | if (v != CANCEL) | ||
| 363 | return v; | ||
| 364 | me = new Node(item); // Throw away cancelled node | ||
| 365 | int m = max.get(); | ||
| 366 | if (m > (index >>>= 1)) // Decrease index | ||
| 367 | max.compareAndSet(m, m - 1); // Maybe shrink table | ||
| 368 | } | ||
| 369 | else if (++fails > 1) { // Allow 2 fails on 1st slot | ||
| 370 | int m = max.get(); | ||
| 371 | if (fails > 3 && m < FULL && max.compareAndSet(m, m + 1)) | ||
| 372 | index = m + 1; // Grow on 3rd failed slot | ||
| 373 | else if (--index < 0) | ||
| 374 | index = m; // Circularly traverse | ||
| 375 | } | ||
| 376 | } | ||
| 377 | } | ||
| 378 | |||
| 379 | /** | ||
| 380 | * Returns a hash index for the current thread. Uses a one-step | ||
| 381 | * FNV-1a hash code (http://www.isthe.com/chongo/tech/comp/fnv/) | ||
| 382 | * based on the current thread's Thread.getId(). These hash codes | ||
| 383 | * have more uniform distribution properties with respect to small | ||
| 384 | * moduli (here 1-31) than do other simple hashing functions. | ||
| 385 | * | ||
| 386 | * <p>To return an index between 0 and max, we use a cheap | ||
| 387 | * approximation to a mod operation, that also corrects for bias | ||
| 388 | * due to non-power-of-2 remaindering (see {@link | ||
| 389 | * java.util.Random#nextInt}). Bits of the hashcode are masked | ||
| 390 | * with "nbits", the ceiling power of two of table size (looked up | ||
| 391 | * in a table packed into three ints). If too large, this is | ||
| 392 | * retried after rotating the hash by nbits bits, while forcing new | ||
| 393 | * top bit to 0, which guarantees eventual termination (although | ||
| 394 | * with a non-random-bias). This requires an average of less than | ||
| 395 | * 2 tries for all table sizes, and has a maximum 2% difference | ||
| 396 | * from perfectly uniform slot probabilities when applied to all | ||
| 397 | * possible hash codes for sizes less than 32. | ||
| 398 | * | ||
| 399 | * @return a per-thread-random index, 0 <= index < max | ||
| 400 | */ | ||
| 401 | private final int hashIndex() { | ||
| 402 | long id = Thread.currentThread().getId(); | ||
| 403 | int hash = (((int)(id ^ (id >>> 32))) ^ 0x811c9dc5) * 0x01000193; | ||
| 404 | |||
| 405 | int m = max.get(); | ||
| 406 | int nbits = (((0xfffffc00 >> m) & 4) | // Compute ceil(log2(m+1)) | ||
| 407 | ((0x000001f8 >>> m) & 2) | // The constants hold | ||
| 408 | ((0xffff00f2 >>> m) & 1)); // a lookup table | ||
| 409 | int index; | ||
| 410 | while ((index = hash & ((1 << nbits) - 1)) > m) // May retry on | ||
| 411 | hash = (hash >>> nbits) | (hash << (33 - nbits)); // non-power-2 m | ||
| 412 | return index; | ||
| 413 | } | ||
| 414 | |||
| 415 | /** | ||
| 416 | * Creates a new slot at given index. Called only when the slot | ||
| 417 | * appears to be null. Relies on double-check using builtin | ||
| 418 | * locks, since they rarely contend. This in turn relies on the | ||
| 419 | * arena array being declared volatile. | ||
| 420 | * | ||
| 421 | * @param index the index to add slot at | ||
| 422 | */ | ||
| 423 | private void createSlot(int index) { | ||
| 424 | // Create slot outside of lock to narrow sync region | ||
| 425 | Slot newSlot = new Slot(); | ||
| 426 | Slot[] a = arena; | ||
| 427 | synchronized (a) { | ||
| 428 | if (a[index] == null) | ||
| 429 | a[index] = newSlot; | ||
| 430 | } | ||
| 431 | } | ||
| 432 | |||
| 433 | /** | ||
| 434 | * Tries to cancel a wait for the given node waiting in the given | ||
| 435 | * slot, if so, helping clear the node from its slot to avoid | ||
| 436 | * garbage retention. | ||
| 437 | * | ||
| 438 | * @param node the waiting node | ||
| 439 | * @param the slot it is waiting in | ||
| 440 | * @return true if successfully cancelled | ||
| 441 | */ | ||
| 442 | private static boolean tryCancel(Node node, Slot slot) { | ||
| 443 | if (!node.compareAndSet(null, CANCEL)) | ||
| 444 | return false; | ||
| 445 | if (slot.get() == node) // pre-check to minimize contention | ||
| 446 | slot.compareAndSet(node, null); | ||
| 447 | return true; | ||
| 448 | } | ||
| 449 | |||
| 450 | // Three forms of waiting. Each just different enough not to merge | ||
| 451 | // code with others. | ||
| 452 | |||
| 453 | /** | ||
| 454 | * Spin-waits for hole for a non-0 slot. Fails if spin elapses | ||
| 455 | * before hole filled. Does not check interrupt, relying on check | ||
| 456 | * in public exchange method to abort if interrupted on entry. | ||
| 457 | * | ||
| 458 | * @param node the waiting node | ||
| 459 | * @return on success, the hole; on failure, CANCEL | ||
| 460 | */ | ||
| 461 | private static Object spinWait(Node node, Slot slot) { | ||
| 462 | int spins = SPINS; | ||
| 463 | for (;;) { | ||
| 464 | Object v = node.get(); | ||
| 465 | if (v != null) | ||
| 466 | return v; | ||
| 467 | else if (spins > 0) | ||
| 468 | --spins; | ||
| 469 | else | ||
| 470 | tryCancel(node, slot); | ||
| 471 | } | ||
| 472 | } | ||
| 473 | |||
| 474 | /** | ||
| 475 | * Waits for (by spinning and/or blocking) and gets the hole | ||
| 476 | * filled in by another thread. Fails if interrupted before | ||
| 477 | * hole filled. | ||
| 478 | * | ||
| 479 | * When a node/thread is about to block, it sets its waiter field | ||
| 480 | * and then rechecks state at least one more time before actually | ||
| 481 | * parking, thus covering race vs fulfiller noticing that waiter | ||
| 482 | * is non-null so should be woken. | ||
| 483 | * | ||
| 484 | * Thread interruption status is checked only surrounding calls to | ||
| 485 | * park. The caller is assumed to have checked interrupt status | ||
| 486 | * on entry. | ||
| 487 | * | ||
| 488 | * @param node the waiting node | ||
| 489 | * @return on success, the hole; on failure, CANCEL | ||
| 490 | */ | ||
| 491 | private static Object await(Node node, Slot slot) { | ||
| 492 | Thread w = Thread.currentThread(); | ||
| 493 | int spins = SPINS; | ||
| 494 | for (;;) { | ||
| 495 | Object v = node.get(); | ||
| 496 | if (v != null) | ||
| 497 | return v; | ||
| 498 | else if (spins > 0) // Spin-wait phase | ||
| 499 | --spins; | ||
| 500 | else if (node.waiter == null) // Set up to block next | ||
| 501 | node.waiter = w; | ||
| 502 | else if (w.isInterrupted()) // Abort on interrupt | ||
| 503 | tryCancel(node, slot); | ||
| 504 | else // Block | ||
| 505 | LockSupport.park(node); | ||
| 506 | } | ||
| 507 | } | ||
| 508 | |||
| 509 | /** | ||
| 510 | * Waits for (at index 0) and gets the hole filled in by another | ||
| 511 | * thread. Fails if timed out or interrupted before hole filled. | ||
| 512 | * Same basic logic as untimed version, but a bit messier. | ||
| 513 | * | ||
| 514 | * @param node the waiting node | ||
| 515 | * @param nanos the wait time | ||
| 516 | * @return on success, the hole; on failure, CANCEL | ||
| 517 | */ | ||
| 518 | private Object awaitNanos(Node node, Slot slot, long nanos) { | ||
| 519 | int spins = TIMED_SPINS; | ||
| 520 | long lastTime = 0; | ||
| 521 | Thread w = null; | ||
| 522 | for (;;) { | ||
| 523 | Object v = node.get(); | ||
| 524 | if (v != null) | ||
| 525 | return v; | ||
| 526 | long now = System.nanoTime(); | ||
| 527 | if (w == null) | ||
| 528 | w = Thread.currentThread(); | ||
| 529 | else | ||
| 530 | nanos -= now - lastTime; | ||
| 531 | lastTime = now; | ||
| 532 | if (nanos > 0) { | ||
| 533 | if (spins > 0) | ||
| 534 | --spins; | ||
| 535 | else if (node.waiter == null) | ||
| 536 | node.waiter = w; | ||
| 537 | else if (w.isInterrupted()) | ||
| 538 | tryCancel(node, slot); | ||
| 539 | else | ||
| 540 | LockSupport.parkNanos(node, nanos); | ||
| 541 | } | ||
| 542 | else if (tryCancel(node, slot) && !w.isInterrupted()) | ||
| 543 | return scanOnTimeout(node); | ||
| 544 | } | ||
| 545 | } | ||
| 546 | |||
| 547 | /** | ||
| 548 | * Sweeps through arena checking for any waiting threads. Called | ||
| 549 | * only upon return from timeout while waiting in slot 0. When a | ||
| 550 | * thread gives up on a timed wait, it is possible that a | ||
| 551 | * previously-entered thread is still waiting in some other | ||
| 552 | * slot. So we scan to check for any. This is almost always | ||
| 553 | * overkill, but decreases the likelihood of timeouts when there | ||
| 554 | * are other threads present to far less than that in lock-based | ||
| 555 | * exchangers in which earlier-arriving threads may still be | ||
| 556 | * waiting on entry locks. | ||
| 557 | * | ||
| 558 | * @param node the waiting node | ||
| 559 | * @return another thread's item, or CANCEL | ||
| 560 | */ | ||
| 561 | private Object scanOnTimeout(Node node) { | ||
| 562 | Object y; | ||
| 563 | for (int j = arena.length - 1; j >= 0; --j) { | ||
| 564 | Slot slot = arena[j]; | ||
| 565 | if (slot != null) { | ||
| 566 | while ((y = slot.get()) != null) { | ||
| 567 | if (slot.compareAndSet(y, null)) { | ||
| 568 | Node you = (Node)y; | ||
| 569 | if (you.compareAndSet(null, node.item)) { | ||
| 570 | LockSupport.unpark(you.waiter); | ||
| 571 | return you.item; | ||
| 572 | } | ||
| 573 | } | ||
| 574 | } | ||
| 575 | } | ||
| 576 | } | ||
| 577 | return CANCEL; | ||
| 578 | } | ||
| 579 | |||
| 580 | /** | ||
| 581 | * Creates a new Exchanger. | ||
| 582 | */ | ||
| 583 | public Exchanger() { | ||
| 584 | } | ||
| 585 | |||
| 586 | /** | ||
| 587 | * Waits for another thread to arrive at this exchange point (unless | ||
| 588 | * the current thread is {@linkplain Thread#interrupt interrupted}), | ||
| 589 | * and then transfers the given object to it, receiving its object | ||
| 590 | * in return. | ||
| 591 | * | ||
| 592 | * <p>If another thread is already waiting at the exchange point then | ||
| 593 | * it is resumed for thread scheduling purposes and receives the object | ||
| 594 | * passed in by the current thread. The current thread returns immediately, | ||
| 595 | * receiving the object passed to the exchange by that other thread. | ||
| 596 | * | ||
| 597 | * <p>If no other thread is already waiting at the exchange then the | ||
| 598 | * current thread is disabled for thread scheduling purposes and lies | ||
| 599 | * dormant until one of two things happens: | ||
| 600 | * <ul> | ||
| 601 | * <li>Some other thread enters the exchange; or | ||
| 602 | * <li>Some other thread {@linkplain Thread#interrupt interrupts} | ||
| 603 | * the current thread. | ||
| 604 | * </ul> | ||
| 605 | * <p>If the current thread: | ||
| 606 | * <ul> | ||
| 607 | * <li>has its interrupted status set on entry to this method; or | ||
| 608 | * <li>is {@linkplain Thread#interrupt interrupted} while waiting | ||
| 609 | * for the exchange, | ||
| 610 | * </ul> | ||
| 611 | * then {@link InterruptedException} is thrown and the current thread's | ||
| 612 | * interrupted status is cleared. | ||
| 613 | * | ||
| 614 | * @param x the object to exchange | ||
| 615 | * @return the object provided by the other thread | ||
| 616 | * @throws InterruptedException if the current thread was | ||
| 617 | * interrupted while waiting | ||
| 618 | */ | ||
| 619 | public V exchange(V x) throws InterruptedException { | ||
| 620 | if (!Thread.interrupted()) { | ||
| 621 | Object v = doExchange((x == null) ? NULL_ITEM : x, false, 0); | ||
| 622 | if (v == NULL_ITEM) | ||
| 623 | return null; | ||
| 624 | if (v != CANCEL) | ||
| 625 | return (V)v; | ||
| 626 | Thread.interrupted(); // Clear interrupt status on IE throw | ||
| 627 | } | ||
| 628 | throw new InterruptedException(); | ||
| 629 | } | ||
| 630 | |||
| 631 | /** | ||
| 632 | * Waits for another thread to arrive at this exchange point (unless | ||
| 633 | * the current thread is {@linkplain Thread#interrupt interrupted} or | ||
| 634 | * the specified waiting time elapses), and then transfers the given | ||
| 635 | * object to it, receiving its object in return. | ||
| 636 | * | ||
| 637 | * <p>If another thread is already waiting at the exchange point then | ||
| 638 | * it is resumed for thread scheduling purposes and receives the object | ||
| 639 | * passed in by the current thread. The current thread returns immediately, | ||
| 640 | * receiving the object passed to the exchange by that other thread. | ||
| 641 | * | ||
| 642 | * <p>If no other thread is already waiting at the exchange then the | ||
| 643 | * current thread is disabled for thread scheduling purposes and lies | ||
| 644 | * dormant until one of three things happens: | ||
| 645 | * <ul> | ||
| 646 | * <li>Some other thread enters the exchange; or | ||
| 647 | * <li>Some other thread {@linkplain Thread#interrupt interrupts} | ||
| 648 | * the current thread; or | ||
| 649 | * <li>The specified waiting time elapses. | ||
| 650 | * </ul> | ||
| 651 | * <p>If the current thread: | ||
| 652 | * <ul> | ||
| 653 | * <li>has its interrupted status set on entry to this method; or | ||
| 654 | * <li>is {@linkplain Thread#interrupt interrupted} while waiting | ||
| 655 | * for the exchange, | ||
| 656 | * </ul> | ||
| 657 | * then {@link InterruptedException} is thrown and the current thread's | ||
| 658 | * interrupted status is cleared. | ||
| 659 | * | ||
| 660 | * <p>If the specified waiting time elapses then {@link | ||
| 661 | * TimeoutException} is thrown. If the time is less than or equal | ||
| 662 | * to zero, the method will not wait at all. | ||
| 663 | * | ||
| 664 | * @param x the object to exchange | ||
| 665 | * @param timeout the maximum time to wait | ||
| 666 | * @param unit the time unit of the <tt>timeout</tt> argument | ||
| 667 | * @return the object provided by the other thread | ||
| 668 | * @throws InterruptedException if the current thread was | ||
| 669 | * interrupted while waiting | ||
| 670 | * @throws TimeoutException if the specified waiting time elapses | ||
| 671 | * before another thread enters the exchange | ||
| 672 | */ | ||
| 673 | public V exchange(V x, long timeout, TimeUnit unit) | ||
| 674 | throws InterruptedException, TimeoutException { | ||
| 675 | if (!Thread.interrupted()) { | ||
| 676 | Object v = doExchange((x == null) ? NULL_ITEM : x, | ||
| 677 | true, unit.toNanos(timeout)); | ||
| 678 | if (v == NULL_ITEM) | ||
| 679 | return null; | ||
| 680 | if (v != CANCEL) | ||
| 681 | return (V)v; | ||
| 682 | if (!Thread.interrupted()) | ||
| 683 | throw new TimeoutException(); | ||
| 684 | } | ||
| 685 | throw new InterruptedException(); | ||
| 686 | } | ||
| 687 | } | ||
Binary file not shown.
| @@ -0,0 +1,94 @@ | |||
| 1 | /* | ||
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 3 | * | ||
| 4 | * This code is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License version 2 only, as | ||
| 6 | * published by the Free Software Foundation. Oracle designates this | ||
| 7 | * particular file as subject to the "Classpath" exception as provided | ||
| 8 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 9 | * | ||
| 10 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 13 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 14 | * accompanied this code). | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License version | ||
| 17 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | * | ||
| 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 21 | * or visit www.oracle.com if you need additional information or have any | ||
| 22 | * questions. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * This file is available under and governed by the GNU General Public | ||
| 27 | * License version 2 only, as published by the Free Software Foundation. | ||
| 28 | * However, the following notice accompanied the original version of this | ||
| 29 | * file: | ||
| 30 | * | ||
| 31 | * Written by Doug Lea with assistance from members of JCP JSR-166 | ||
| 32 | * Expert Group and released to the public domain, as explained at | ||
| 33 | * http://creativecommons.org/publicdomain/zero/1.0/ | ||
| 34 | */ | ||
| 35 | |||
| 36 | package java.util.concurrent; | ||
| 37 | |||
| 38 | /** | ||
| 39 | * Exception thrown when attempting to retrieve the result of a task | ||
| 40 | * that aborted by throwing an exception. This exception can be | ||
| 41 | * inspected using the {@link #getCause()} method. | ||
| 42 | * | ||
| 43 | * @see Future | ||
| 44 | * @since 1.5 | ||
| 45 | * @author Doug Lea | ||
| 46 | */ | ||
| 47 | public class ExecutionException extends Exception { | ||
| 48 | private static final long serialVersionUID = 7830266012832686185L; | ||
| 49 | |||
| 50 | /** | ||
| 51 | * Constructs an <tt>ExecutionException</tt> with no detail message. | ||
| 52 | * The cause is not initialized, and may subsequently be | ||
| 53 | * initialized by a call to {@link #initCause(Throwable) initCause}. | ||
| 54 | */ | ||
| 55 | protected ExecutionException() { } | ||
| 56 | |||
| 57 | /** | ||
| 58 | * Constructs an <tt>ExecutionException</tt> with the specified detail | ||
| 59 | * message. The cause is not initialized, and may subsequently be | ||
| 60 | * initialized by a call to {@link #initCause(Throwable) initCause}. | ||
| 61 | * | ||
| 62 | * @param message the detail message | ||
| 63 | */ | ||
| 64 | protected ExecutionException(String message) { | ||
| 65 | super(message); | ||
| 66 | } | ||
| 67 | |||
| 68 | /** | ||
| 69 | * Constructs an <tt>ExecutionException</tt> with the specified detail | ||
| 70 | * message and cause. | ||
| 71 | * | ||
| 72 | * @param message the detail message | ||
| 73 | * @param cause the cause (which is saved for later retrieval by the | ||
| 74 | * {@link #getCause()} method) | ||
| 75 | */ | ||
| 76 | public ExecutionException(String message, Throwable cause) { | ||
| 77 | super(message, cause); | ||
| 78 | } | ||
| 79 | |||
| 80 | /** | ||
| 81 | * Constructs an <tt>ExecutionException</tt> with the specified cause. | ||
| 82 | * The detail message is set to: | ||
| 83 | * <pre> | ||
| 84 | * (cause == null ? null : cause.toString())</pre> | ||
| 85 | * (which typically contains the class and detail message of | ||
| 86 | * <tt>cause</tt>). | ||
| 87 | * | ||
| 88 | * @param cause the cause (which is saved for later retrieval by the | ||
| 89 | * {@link #getCause()} method) | ||
| 90 | */ | ||
| 91 | public ExecutionException(Throwable cause) { | ||
| 92 | super(cause); | ||
| 93 | } | ||
| 94 | } | ||
Binary file not shown.
| @@ -0,0 +1,141 @@ | |||
| 1 | /* | ||
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 3 | * | ||
| 4 | * This code is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License version 2 only, as | ||
| 6 | * published by the Free Software Foundation. Oracle designates this | ||
| 7 | * particular file as subject to the "Classpath" exception as provided | ||
| 8 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 9 | * | ||
| 10 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 13 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 14 | * accompanied this code). | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License version | ||
| 17 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | * | ||
| 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 21 | * or visit www.oracle.com if you need additional information or have any | ||
| 22 | * questions. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * This file is available under and governed by the GNU General Public | ||
| 27 | * License version 2 only, as published by the Free Software Foundation. | ||
| 28 | * However, the following notice accompanied the original version of this | ||
| 29 | * file: | ||
| 30 | * | ||
| 31 | * Written by Doug Lea with assistance from members of JCP JSR-166 | ||
| 32 | * Expert Group and released to the public domain, as explained at | ||
| 33 | * http://creativecommons.org/publicdomain/zero/1.0/ | ||
| 34 | */ | ||
| 35 | |||
| 36 | package java.util.concurrent; | ||
| 37 | |||
| 38 | /** | ||
| 39 | * An object that executes submitted {@link Runnable} tasks. This | ||
| 40 | * interface provides a way of decoupling task submission from the | ||
| 41 | * mechanics of how each task will be run, including details of thread | ||
| 42 | * use, scheduling, etc. An <tt>Executor</tt> is normally used | ||
| 43 | * instead of explicitly creating threads. For example, rather than | ||
| 44 | * invoking <tt>new Thread(new(RunnableTask())).start()</tt> for each | ||
| 45 | * of a set of tasks, you might use: | ||
| 46 | * | ||
| 47 | * <pre> | ||
| 48 | * Executor executor = <em>anExecutor</em>; | ||
| 49 | * executor.execute(new RunnableTask1()); | ||
| 50 | * executor.execute(new RunnableTask2()); | ||
| 51 | * ... | ||
| 52 | * </pre> | ||
| 53 | * | ||
| 54 | * However, the <tt>Executor</tt> interface does not strictly | ||
| 55 | * require that execution be asynchronous. In the simplest case, an | ||
| 56 | * executor can run the submitted task immediately in the caller's | ||
| 57 | * thread: | ||
| 58 | * | ||
| 59 | * <pre> | ||
| 60 | * class DirectExecutor implements Executor { | ||
| 61 | * public void execute(Runnable r) { | ||
| 62 | * r.run(); | ||
| 63 | * } | ||
| 64 | * }</pre> | ||
| 65 | * | ||
| 66 | * More typically, tasks are executed in some thread other | ||
| 67 | * than the caller's thread. The executor below spawns a new thread | ||
| 68 | * for each task. | ||
| 69 | * | ||
| 70 | * <pre> | ||
| 71 | * class ThreadPerTaskExecutor implements Executor { | ||
| 72 | * public void execute(Runnable r) { | ||
| 73 | * new Thread(r).start(); | ||
| 74 | * } | ||
| 75 | * }</pre> | ||
| 76 | * | ||
| 77 | * Many <tt>Executor</tt> implementations impose some sort of | ||
| 78 | * limitation on how and when tasks are scheduled. The executor below | ||
| 79 | * serializes the submission of tasks to a second executor, | ||
| 80 | * illustrating a composite executor. | ||
| 81 | * | ||
| 82 | * <pre> {@code | ||
| 83 | * class SerialExecutor implements Executor { | ||
| 84 | * final Queue<Runnable> tasks = new ArrayDeque<Runnable>(); | ||
| 85 | * final Executor executor; | ||
| 86 | * Runnable active; | ||
| 87 | * | ||
| 88 | * SerialExecutor(Executor executor) { | ||
| 89 | * this.executor = executor; | ||
| 90 | * } | ||
| 91 | * | ||
| 92 | * public synchronized void execute(final Runnable r) { | ||
| 93 | * tasks.offer(new Runnable() { | ||
| 94 | * public void run() { | ||
| 95 | * try { | ||
| 96 | * r.run(); | ||
| 97 | * } finally { | ||
| 98 | * scheduleNext(); | ||
| 99 | * } | ||
| 100 | * } | ||
| 101 | * }); | ||
| 102 | * if (active == null) { | ||
| 103 | * scheduleNext(); | ||
| 104 | * } | ||
| 105 | * } | ||
| 106 | * | ||
| 107 | * protected synchronized void scheduleNext() { | ||
| 108 | * if ((active = tasks.poll()) != null) { | ||
| 109 | * executor.execute(active); | ||
| 110 | * } | ||
| 111 | * } | ||
| 112 | * }}</pre> | ||
| 113 | * | ||
| 114 | * The <tt>Executor</tt> implementations provided in this package | ||
| 115 | * implement {@link ExecutorService}, which is a more extensive | ||
| 116 | * interface. The {@link ThreadPoolExecutor} class provides an | ||
| 117 | * extensible thread pool implementation. The {@link Executors} class | ||
| 118 | * provides convenient factory methods for these Executors. | ||
| 119 | * | ||
| 120 | * <p>Memory consistency effects: Actions in a thread prior to | ||
| 121 | * submitting a {@code Runnable} object to an {@code Executor} | ||
| 122 | * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> | ||
| 123 | * its execution begins, perhaps in another thread. | ||
| 124 | * | ||
| 125 | * @since 1.5 | ||
| 126 | * @author Doug Lea | ||
| 127 | */ | ||
| 128 | public interface Executor { | ||
| 129 | |||
| 130 | /** | ||
| 131 | * Executes the given command at some time in the future. The command | ||
| 132 | * may execute in a new thread, in a pooled thread, or in the calling | ||
| 133 | * thread, at the discretion of the <tt>Executor</tt> implementation. | ||
| 134 | * | ||
| 135 | * @param command the runnable task | ||
| 136 | * @throws RejectedExecutionException if this task cannot be | ||
| 137 | * accepted for execution. | ||
| 138 | * @throws NullPointerException if command is null | ||
| 139 | */ | ||
| 140 | void execute(Runnable command); | ||
| 141 | } | ||
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,205 @@ | |||
| 1 | /* | ||
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 3 | * | ||
| 4 | * This code is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License version 2 only, as | ||
| 6 | * published by the Free Software Foundation. Oracle designates this | ||
| 7 | * particular file as subject to the "Classpath" exception as provided | ||
| 8 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 9 | * | ||
| 10 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 13 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 14 | * accompanied this code). | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License version | ||
| 17 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | * | ||
| 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 21 | * or visit www.oracle.com if you need additional information or have any | ||
| 22 | * questions. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * This file is available under and governed by the GNU General Public | ||
| 27 | * License version 2 only, as published by the Free Software Foundation. | ||
| 28 | * However, the following notice accompanied the original version of this | ||
| 29 | * file: | ||
| 30 | * | ||
| 31 | * Written by Doug Lea with assistance from members of JCP JSR-166 | ||
| 32 | * Expert Group and released to the public domain, as explained at | ||
| 33 | * http://creativecommons.org/publicdomain/zero/1.0/ | ||
| 34 | */ | ||
| 35 | |||
| 36 | package java.util.concurrent; | ||
| 37 | |||
| 38 | /** | ||
| 39 | * A {@link CompletionService} that uses a supplied {@link Executor} | ||
| 40 | * to execute tasks. This class arranges that submitted tasks are, | ||
| 41 | * upon completion, placed on a queue accessible using {@code take}. | ||
| 42 | * The class is lightweight enough to be suitable for transient use | ||
| 43 | * when processing groups of tasks. | ||
| 44 | * | ||
| 45 | * <p> | ||
| 46 | * | ||
| 47 | * <b>Usage Examples.</b> | ||
| 48 | * | ||
| 49 | * Suppose you have a set of solvers for a certain problem, each | ||
| 50 | * returning a value of some type {@code Result}, and would like to | ||
| 51 | * run them concurrently, processing the results of each of them that | ||
| 52 | * return a non-null value, in some method {@code use(Result r)}. You | ||
| 53 | * could write this as: | ||
| 54 | * | ||
| 55 | * <pre> {@code | ||
| 56 | * void solve(Executor e, | ||
| 57 | * Collection<Callable<Result>> solvers) | ||
| 58 | * throws InterruptedException, ExecutionException { | ||
| 59 | * CompletionService<Result> ecs | ||
| 60 | * = new ExecutorCompletionService<Result>(e); | ||
| 61 | * for (Callable<Result> s : solvers) | ||
| 62 | * ecs.submit(s); | ||
| 63 | * int n = solvers.size(); | ||
| 64 | * for (int i = 0; i < n; ++i) { | ||
| 65 | * Result r = ecs.take().get(); | ||
| 66 | * if (r != null) | ||
| 67 | * use(r); | ||
| 68 | * } | ||
| 69 | * }}</pre> | ||
| 70 | * | ||
| 71 | * Suppose instead that you would like to use the first non-null result | ||
| 72 | * of the set of tasks, ignoring any that encounter exceptions, | ||
| 73 | * and cancelling all other tasks when the first one is ready: | ||
| 74 | * | ||
| 75 | * <pre> {@code | ||
| 76 | * void solve(Executor e, | ||
| 77 | * Collection<Callable<Result>> solvers) | ||
| 78 | * throws InterruptedException { | ||
| 79 | * CompletionService<Result> ecs | ||
| 80 | * = new ExecutorCompletionService<Result>(e); | ||
| 81 | * int n = solvers.size(); | ||
| 82 | * List<Future<Result>> futures | ||
| 83 | * = new ArrayList<Future<Result>>(n); | ||
| 84 | * Result result = null; | ||
| 85 | * try { | ||
| 86 | * for (Callable<Result> s : solvers) | ||
| 87 | * futures.add(ecs.submit(s)); | ||
| 88 | * for (int i = 0; i < n; ++i) { | ||
| 89 | * try { | ||
| 90 | * Result r = ecs.take().get(); | ||
| 91 | * if (r != null) { | ||
| 92 | * result = r; | ||
| 93 | * break; | ||
| 94 | * } | ||
| 95 | * } catch (ExecutionException ignore) {} | ||
| 96 | * } | ||
| 97 | * } | ||
| 98 | * finally { | ||
| 99 | * for (Future<Result> f : futures) | ||
| 100 | * f.cancel(true); | ||
| 101 | * } | ||
| 102 | * | ||
| 103 | * if (result != null) | ||
| 104 | * use(result); | ||
| 105 | * }}</pre> | ||
| 106 | */ | ||
| 107 | public class ExecutorCompletionService<V> implements CompletionService<V> { | ||
| 108 | private final Executor executor; | ||
| 109 | private final AbstractExecutorService aes; | ||
| 110 | private final BlockingQueue<Future<V>> completionQueue; | ||
| 111 | |||
| 112 | /** | ||
| 113 | * FutureTask extension to enqueue upon completion | ||
| 114 | */ | ||
| 115 | private class QueueingFuture extends FutureTask<Void> { | ||
| 116 | QueueingFuture(RunnableFuture<V> task) { | ||
| 117 | super(task, null); | ||
| 118 | this.task = task; | ||
| 119 | } | ||
| 120 | protected void done() { completionQueue.add(task); } | ||
| 121 | private final Future<V> task; | ||
| 122 | } | ||
| 123 | |||
| 124 | private RunnableFuture<V> newTaskFor(Callable<V> task) { | ||
| 125 | if (aes == null) | ||
| 126 | return new FutureTask<V>(task); | ||
| 127 | else | ||
| 128 | return aes.newTaskFor(task); | ||
| 129 | } | ||
| 130 | |||
| 131 | private RunnableFuture<V> newTaskFor(Runnable task, V result) { | ||
| 132 | if (aes == null) | ||
| 133 | return new FutureTask<V>(task, result); | ||
| 134 | else | ||
| 135 | return aes.newTaskFor(task, result); | ||
| 136 | } | ||
| 137 | |||
| 138 | /** | ||
| 139 | * Creates an ExecutorCompletionService using the supplied | ||
| 140 | * executor for base task execution and a | ||
| 141 | * {@link LinkedBlockingQueue} as a completion queue. | ||
| 142 | * | ||
| 143 | * @param executor the executor to use | ||
| 144 | * @throws NullPointerException if executor is {@code null} | ||
| 145 | */ | ||
| 146 | public ExecutorCompletionService(Executor executor) { | ||
| 147 | if (executor == null) | ||
| 148 | throw new NullPointerException(); | ||
| 149 | this.executor = executor; | ||
| 150 | this.aes = (executor instanceof AbstractExecutorService) ? | ||
| 151 | (AbstractExecutorService) executor : null; | ||
| 152 | this.completionQueue = new LinkedBlockingQueue<Future<V>>(); | ||
| 153 | } | ||
| 154 | |||
| 155 | /** | ||
| 156 | * Creates an ExecutorCompletionService using the supplied | ||
| 157 | * executor for base task execution and the supplied queue as its | ||
| 158 | * completion queue. | ||
| 159 | * | ||
| 160 | * @param executor the executor to use | ||
| 161 | * @param completionQueue the queue to use as the completion queue | ||
| 162 | * normally one dedicated for use by this service. This | ||
| 163 | * queue is treated as unbounded -- failed attempted | ||
| 164 | * {@code Queue.add} operations for completed taskes cause | ||
| 165 | * them not to be retrievable. | ||
| 166 | * @throws NullPointerException if executor or completionQueue are {@code null} | ||
| 167 | */ | ||
| 168 | public ExecutorCompletionService(Executor executor, | ||
| 169 | BlockingQueue<Future<V>> completionQueue) { | ||
| 170 | if (executor == null || completionQueue == null) | ||
| 171 | throw new NullPointerException(); | ||
| 172 | this.executor = executor; | ||
| 173 | this.aes = (executor instanceof AbstractExecutorService) ? | ||
| 174 | (AbstractExecutorService) executor : null; | ||
| 175 | this.completionQueue = completionQueue; | ||
| 176 | } | ||
| 177 | |||
| 178 | public Future<V> submit(Callable<V> task) { | ||
| 179 | if (task == null) throw new NullPointerException(); | ||
| 180 | RunnableFuture<V> f = newTaskFor(task); | ||
| 181 | executor.execute(new QueueingFuture(f)); | ||
| 182 | return f; | ||
| 183 | } | ||
| 184 | |||
| 185 | public Future<V> submit(Runnable task, V result) { | ||
| 186 | if (task == null) throw new NullPointerException(); | ||
| 187 | RunnableFuture<V> f = newTaskFor(task, result); | ||
| 188 | executor.execute(new QueueingFuture(f)); | ||
| 189 | return f; | ||
| 190 | } | ||
| 191 | |||
| 192 | public Future<V> take() throws InterruptedException { | ||
| 193 | return completionQueue.take(); | ||
| 194 | } | ||
| 195 | |||
| 196 | public Future<V> poll() { | ||
| 197 | return completionQueue.poll(); | ||
| 198 | } | ||
| 199 | |||
| 200 | public Future<V> poll(long timeout, TimeUnit unit) | ||
| 201 | throws InterruptedException { | ||
| 202 | return completionQueue.poll(timeout, unit); | ||
| 203 | } | ||
| 204 | |||
| 205 | } | ||
Binary file not shown.
| @@ -0,0 +1,370 @@ | |||
| 1 | /* | ||
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 3 | * | ||
| 4 | * This code is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License version 2 only, as | ||
| 6 | * published by the Free Software Foundation. Oracle designates this | ||
| 7 | * particular file as subject to the "Classpath" exception as provided | ||
| 8 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 9 | * | ||
| 10 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 13 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 14 | * accompanied this code). | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License version | ||
| 17 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | * | ||
| 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 21 | * or visit www.oracle.com if you need additional information or have any | ||
| 22 | * questions. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * This file is available under and governed by the GNU General Public | ||
| 27 | * License version 2 only, as published by the Free Software Foundation. | ||
| 28 | * However, the following notice accompanied the original version of this | ||
| 29 | * file: | ||
| 30 | * | ||
| 31 | * Written by Doug Lea with assistance from members of JCP JSR-166 | ||
| 32 | * Expert Group and released to the public domain, as explained at | ||
| 33 | * http://creativecommons.org/publicdomain/zero/1.0/ | ||
| 34 | */ | ||
| 35 | |||
| 36 | package java.util.concurrent; | ||
| 37 | import java.util.List; | ||
| 38 | import java.util.Collection; | ||
| 39 | import java.security.PrivilegedAction; | ||
| 40 | import java.security.PrivilegedExceptionAction; | ||
| 41 | |||
| 42 | /** | ||
| 43 | * An {@link Executor} that provides methods to manage termination and | ||
| 44 | * methods that can produce a {@link Future} for tracking progress of | ||
| 45 | * one or more asynchronous tasks. | ||
| 46 | * | ||
| 47 | * <p> An <tt>ExecutorService</tt> can be shut down, which will cause | ||
| 48 | * it to reject new tasks. Two different methods are provided for | ||
| 49 | * shutting down an <tt>ExecutorService</tt>. The {@link #shutdown} | ||
| 50 | * method will allow previously submitted tasks to execute before | ||
| 51 | * terminating, while the {@link #shutdownNow} method prevents waiting | ||
| 52 | * tasks from starting and attempts to stop currently executing tasks. | ||
| 53 | * Upon termination, an executor has no tasks actively executing, no | ||
| 54 | * tasks awaiting execution, and no new tasks can be submitted. An | ||
| 55 | * unused <tt>ExecutorService</tt> should be shut down to allow | ||
| 56 | * reclamation of its resources. | ||
| 57 | * | ||
| 58 | * <p> Method <tt>submit</tt> extends base method {@link | ||
| 59 | * Executor#execute} by creating and returning a {@link Future} that | ||
| 60 | * can be used to cancel execution and/or wait for completion. | ||
| 61 | * Methods <tt>invokeAny</tt> and <tt>invokeAll</tt> perform the most | ||
| 62 | * commonly useful forms of bulk execution, executing a collection of | ||
| 63 | * tasks and then waiting for at least one, or all, to | ||
| 64 | * complete. (Class {@link ExecutorCompletionService} can be used to | ||
| 65 | * write customized variants of these methods.) | ||
| 66 | * | ||
| 67 | * <p>The {@link Executors} class provides factory methods for the | ||
| 68 | * executor services provided in this package. | ||
| 69 | * | ||
| 70 | * <h3>Usage Examples</h3> | ||
| 71 | * | ||
| 72 | * Here is a sketch of a network service in which threads in a thread | ||
| 73 | * pool service incoming requests. It uses the preconfigured {@link | ||
| 74 | * Executors#newFixedThreadPool} factory method: | ||
| 75 | * | ||
| 76 | * <pre> | ||
| 77 | * class NetworkService implements Runnable { | ||
| 78 | * private final ServerSocket serverSocket; | ||
| 79 | * private final ExecutorService pool; | ||
| 80 | * | ||
| 81 | * public NetworkService(int port, int poolSize) | ||
| 82 | * throws IOException { | ||
| 83 | * serverSocket = new ServerSocket(port); | ||
| 84 | * pool = Executors.newFixedThreadPool(poolSize); | ||
| 85 | * } | ||
| 86 | * | ||
| 87 | * public void run() { // run the service | ||
| 88 | * try { | ||
| 89 | * for (;;) { | ||
| 90 | * pool.execute(new Handler(serverSocket.accept())); | ||
| 91 | * } | ||
| 92 | * } catch (IOException ex) { | ||
| 93 | * pool.shutdown(); | ||
| 94 | * } | ||
| 95 | * } | ||
| 96 | * } | ||
| 97 | * | ||
| 98 | * class Handler implements Runnable { | ||
| 99 | * private final Socket socket; | ||
| 100 | * Handler(Socket socket) { this.socket = socket; } | ||
| 101 | * public void run() { | ||
| 102 | * // read and service request on socket | ||
| 103 | * } | ||
| 104 | * } | ||
| 105 | * </pre> | ||
| 106 | * | ||
| 107 | * The following method shuts down an <tt>ExecutorService</tt> in two phases, | ||
| 108 | * first by calling <tt>shutdown</tt> to reject incoming tasks, and then | ||
| 109 | * calling <tt>shutdownNow</tt>, if necessary, to cancel any lingering tasks: | ||
| 110 | * | ||
| 111 | * <pre> | ||
| 112 | * void shutdownAndAwaitTermination(ExecutorService pool) { | ||
| 113 | * pool.shutdown(); // Disable new tasks from being submitted | ||
| 114 | * try { | ||
| 115 | * // Wait a while for existing tasks to terminate | ||
| 116 | * if (!pool.awaitTermination(60, TimeUnit.SECONDS)) { | ||
| 117 | * pool.shutdownNow(); // Cancel currently executing tasks | ||
| 118 | * // Wait a while for tasks to respond to being cancelled | ||
| 119 | * if (!pool.awaitTermination(60, TimeUnit.SECONDS)) | ||
| 120 | * System.err.println("Pool did not terminate"); | ||
| 121 | * } | ||
| 122 | * } catch (InterruptedException ie) { | ||
| 123 | * // (Re-)Cancel if current thread also interrupted | ||
| 124 | * pool.shutdownNow(); | ||
| 125 | * // Preserve interrupt status | ||
| 126 | * Thread.currentThread().interrupt(); | ||
| 127 | * } | ||
| 128 | * } | ||
| 129 | * </pre> | ||
| 130 | * | ||
| 131 | * <p>Memory consistency effects: Actions in a thread prior to the | ||
| 132 | * submission of a {@code Runnable} or {@code Callable} task to an | ||
| 133 | * {@code ExecutorService} | ||
| 134 | * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> | ||
| 135 | * any actions taken by that task, which in turn <i>happen-before</i> the | ||
| 136 | * result is retrieved via {@code Future.get()}. | ||
| 137 | * | ||
| 138 | * @since 1.5 | ||
| 139 | * @author Doug Lea | ||
| 140 | */ | ||
| 141 | public interface ExecutorService extends Executor { | ||
| 142 | |||
| 143 | /** | ||
| 144 | * Initiates an orderly shutdown in which previously submitted | ||
| 145 | * tasks are executed, but no new tasks will be accepted. | ||
| 146 | * Invocation has no additional effect if already shut down. | ||
| 147 | * | ||
| 148 | * <p>This method does not wait for previously submitted tasks to | ||
| 149 | * complete execution. Use {@link #awaitTermination awaitTermination} | ||
| 150 | * to do that. | ||
| 151 | * | ||
| 152 | * @throws SecurityException if a security manager exists and | ||
| 153 | * shutting down this ExecutorService may manipulate | ||
| 154 | * threads that the caller is not permitted to modify | ||
| 155 | * because it does not hold {@link | ||
| 156 | * java.lang.RuntimePermission}<tt>("modifyThread")</tt>, | ||
| 157 | * or the security manager's <tt>checkAccess</tt> method | ||
| 158 | * denies access. | ||
| 159 | */ | ||
| 160 | void shutdown(); | ||
| 161 | |||
| 162 | /** | ||
| 163 | * Attempts to stop all actively executing tasks, halts the | ||
| 164 | * processing of waiting tasks, and returns a list of the tasks | ||
| 165 | * that were awaiting execution. | ||
| 166 | * | ||
| 167 | * <p>This method does not wait for actively executing tasks to | ||
| 168 | * terminate. Use {@link #awaitTermination awaitTermination} to | ||
| 169 | * do that. | ||
| 170 | * | ||
| 171 | * <p>There are no guarantees beyond best-effort attempts to stop | ||
| 172 | * processing actively executing tasks. For example, typical | ||
| 173 | * implementations will cancel via {@link Thread#interrupt}, so any | ||
| 174 | * task that fails to respond to interrupts may never terminate. | ||
| 175 | * | ||
| 176 | * @return list of tasks that never commenced execution | ||
| 177 | * @throws SecurityException if a security manager exists and | ||
| 178 | * shutting down this ExecutorService may manipulate | ||
| 179 | * threads that the caller is not permitted to modify | ||
| 180 | * because it does not hold {@link | ||
| 181 | * java.lang.RuntimePermission}<tt>("modifyThread")</tt>, | ||
| 182 | * or the security manager's <tt>checkAccess</tt> method | ||
| 183 | * denies access. | ||
| 184 | */ | ||
| 185 | List<Runnable> shutdownNow(); | ||
| 186 | |||
| 187 | /** | ||
| 188 | * Returns <tt>true</tt> if this executor has been shut down. | ||
| 189 | * | ||
| 190 | * @return <tt>true</tt> if this executor has been shut down | ||
| 191 | */ | ||
| 192 | boolean isShutdown(); | ||
| 193 | |||
| 194 | /** | ||
| 195 | * Returns <tt>true</tt> if all tasks have completed following shut down. | ||
| 196 | * Note that <tt>isTerminated</tt> is never <tt>true</tt> unless | ||
| 197 | * either <tt>shutdown</tt> or <tt>shutdownNow</tt> was called first. | ||
| 198 | * | ||
| 199 | * @return <tt>true</tt> if all tasks have completed following shut down | ||
| 200 | */ | ||
| 201 | boolean isTerminated(); | ||
| 202 | |||
| 203 | /** | ||
| 204 | * Blocks until all tasks have completed execution after a shutdown | ||
| 205 | * request, or the timeout occurs, or the current thread is | ||
| 206 | * interrupted, whichever happens first. | ||
| 207 | * | ||
| 208 | * @param timeout the maximum time to wait | ||
| 209 | * @param unit the time unit of the timeout argument | ||
| 210 | * @return <tt>true</tt> if this executor terminated and | ||
| 211 | * <tt>false</tt> if the timeout elapsed before termination | ||
| 212 | * @throws InterruptedException if interrupted while waiting | ||
| 213 | */ | ||
| 214 | boolean awaitTermination(long timeout, TimeUnit unit) | ||
| 215 | throws InterruptedException; | ||
| 216 | |||
| 217 | |||
| 218 | /** | ||
| 219 | * Submits a value-returning task for execution and returns a | ||
| 220 | * Future representing the pending results of the task. The | ||
| 221 | * Future's <tt>get</tt> method will return the task's result upon | ||
| 222 | * successful completion. | ||
| 223 | * | ||
| 224 | * <p> | ||
| 225 | * If you would like to immediately block waiting | ||
| 226 | * for a task, you can use constructions of the form | ||
| 227 | * <tt>result = exec.submit(aCallable).get();</tt> | ||
| 228 | * | ||
| 229 | * <p> Note: The {@link Executors} class includes a set of methods | ||
| 230 | * that can convert some other common closure-like objects, | ||
| 231 | * for example, {@link java.security.PrivilegedAction} to | ||
| 232 | * {@link Callable} form so they can be submitted. | ||
| 233 | * | ||
| 234 | * @param task the task to submit | ||
| 235 | * @return a Future representing pending completion of the task | ||
| 236 | * @throws RejectedExecutionException if the task cannot be | ||
| 237 | * scheduled for execution | ||
| 238 | * @throws NullPointerException if the task is null | ||
| 239 | */ | ||
| 240 | <T> Future<T> submit(Callable<T> task); | ||
| 241 | |||
| 242 | /** | ||
| 243 | * Submits a Runnable task for execution and returns a Future | ||
| 244 | * representing that task. The Future's <tt>get</tt> method will | ||
| 245 | * return the given result upon successful completion. | ||
| 246 | * | ||
| 247 | * @param task the task to submit | ||
| 248 | * @param result the result to return | ||
| 249 | * @return a Future representing pending completion of the task | ||
| 250 | * @throws RejectedExecutionException if the task cannot be | ||
| 251 | * scheduled for execution | ||
| 252 | * @throws NullPointerException if the task is null | ||
| 253 | */ | ||
| 254 | <T> Future<T> submit(Runnable task, T result); | ||
| 255 | |||
| 256 | /** | ||
| 257 | * Submits a Runnable task for execution and returns a Future | ||
| 258 | * representing that task. The Future's <tt>get</tt> method will | ||
| 259 | * return <tt>null</tt> upon <em>successful</em> completion. | ||
| 260 | * | ||
| 261 | * @param task the task to submit | ||
| 262 | * @return a Future representing pending completion of the task | ||
| 263 | * @throws RejectedExecutionException if the task cannot be | ||
| 264 | * scheduled for execution | ||
| 265 | * @throws NullPointerException if the task is null | ||
| 266 | */ | ||
| 267 | Future<?> submit(Runnable task); | ||
| 268 | |||
| 269 | /** | ||
| 270 | * Executes the given tasks, returning a list of Futures holding | ||
| 271 | * their status and results when all complete. | ||
| 272 | * {@link Future#isDone} is <tt>true</tt> for each | ||
| 273 | * element of the returned list. | ||
| 274 | * Note that a <em>completed</em> task could have | ||
| 275 | * terminated either normally or by throwing an exception. | ||
| 276 | * The results of this method are undefined if the given | ||
| 277 | * collection is modified while this operation is in progress. | ||
| 278 | * | ||
| 279 | * @param tasks the collection of tasks | ||
| 280 | * @return A list of Futures representing the tasks, in the same | ||
| 281 | * sequential order as produced by the iterator for the | ||
| 282 | * given task list, each of which has completed. | ||
| 283 | * @throws InterruptedException if interrupted while waiting, in | ||
| 284 | * which case unfinished tasks are cancelled. | ||
| 285 | * @throws NullPointerException if tasks or any of its elements are <tt>null</tt> | ||
| 286 | * @throws RejectedExecutionException if any task cannot be | ||
| 287 | * scheduled for execution | ||
| 288 | */ | ||
| 289 | |||
| 290 | <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) | ||
| 291 | throws InterruptedException; | ||
| 292 | |||
| 293 | /** | ||
| 294 | * Executes the given tasks, returning a list of Futures holding | ||
| 295 | * their status and results | ||
| 296 | * when all complete or the timeout expires, whichever happens first. | ||
| 297 | * {@link Future#isDone} is <tt>true</tt> for each | ||
| 298 | * element of the returned list. | ||
| 299 | * Upon return, tasks that have not completed are cancelled. | ||
| 300 | * Note that a <em>completed</em> task could have | ||
| 301 | * terminated either normally or by throwing an exception. | ||
| 302 | * The results of this method are undefined if the given | ||
| 303 | * collection is modified while this operation is in progress. | ||
| 304 | * | ||
| 305 | * @param tasks the collection of tasks | ||
| 306 | * @param timeout the maximum time to wait | ||
| 307 | * @param unit the time unit of the timeout argument | ||
| 308 | * @return a list of Futures representing the tasks, in the same | ||
| 309 | * sequential order as produced by the iterator for the | ||
| 310 | * given task list. If the operation did not time out, | ||
| 311 | * each task will have completed. If it did time out, some | ||
| 312 | * of these tasks will not have completed. | ||
| 313 | * @throws InterruptedException if interrupted while waiting, in | ||
| 314 | * which case unfinished tasks are cancelled | ||
| 315 | * @throws NullPointerException if tasks, any of its elements, or | ||
| 316 | * unit are <tt>null</tt> | ||
| 317 | * @throws RejectedExecutionException if any task cannot be scheduled | ||
| 318 | * for execution | ||
| 319 | */ | ||
| 320 | <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, | ||
| 321 | long timeout, TimeUnit unit) | ||
| 322 | throws InterruptedException; | ||
| 323 | |||
| 324 | /** | ||
| 325 | * Executes the given tasks, returning the result | ||
| 326 | * of one that has completed successfully (i.e., without throwing | ||
| 327 | * an exception), if any do. Upon normal or exceptional return, | ||
| 328 | * tasks that have not completed are cancelled. | ||
| 329 | * The results of this method are undefined if the given | ||
| 330 | * collection is modified while this operation is in progress. | ||
| 331 | * | ||
| 332 | * @param tasks the collection of tasks | ||
| 333 | * @return the result returned by one of the tasks | ||
| 334 | * @throws InterruptedException if interrupted while waiting | ||
| 335 | * @throws NullPointerException if tasks or any element task | ||
| 336 | * subject to execution is <tt>null</tt> | ||
| 337 | * @throws IllegalArgumentException if tasks is empty | ||
| 338 | * @throws ExecutionException if no task successfully completes | ||
| 339 | * @throws RejectedExecutionException if tasks cannot be scheduled | ||
| 340 | * for execution | ||
| 341 | */ | ||
| 342 | <T> T invokeAny(Collection<? extends Callable<T>> tasks) | ||
| 343 | throws InterruptedException, ExecutionException; | ||
| 344 | |||
| 345 | /** | ||
| 346 | * Executes the given tasks, returning the result | ||
| 347 | * of one that has completed successfully (i.e., without throwing | ||
| 348 | * an exception), if any do before the given timeout elapses. | ||
| 349 | * Upon normal or exceptional return, tasks that have not | ||
| 350 | * completed are cancelled. | ||
| 351 | * The results of this method are undefined if the given | ||
| 352 | * collection is modified while this operation is in progress. | ||
| 353 | * | ||
| 354 | * @param tasks the collection of tasks | ||
| 355 | * @param timeout the maximum time to wait | ||
| 356 | * @param unit the time unit of the timeout argument | ||
| 357 | * @return the result returned by one of the tasks. | ||
| 358 | * @throws InterruptedException if interrupted while waiting | ||
| 359 | * @throws NullPointerException if tasks, or unit, or any element | ||
| 360 | * task subject to execution is <tt>null</tt> | ||
| 361 | * @throws TimeoutException if the given timeout elapses before | ||
| 362 | * any task successfully completes | ||
| 363 | * @throws ExecutionException if no task successfully completes | ||
| 364 | * @throws RejectedExecutionException if tasks cannot be scheduled | ||
| 365 | * for execution | ||
| 366 | */ | ||
| 367 | <T> T invokeAny(Collection<? extends Callable<T>> tasks, | ||
| 368 | long timeout, TimeUnit unit) | ||
| 369 | throws InterruptedException, ExecutionException, TimeoutException; | ||
| 370 | } | ||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,706 @@ | |||
| 1 | /* | ||
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 3 | * | ||
| 4 | * This code is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License version 2 only, as | ||
| 6 | * published by the Free Software Foundation. Oracle designates this | ||
| 7 | * particular file as subject to the "Classpath" exception as provided | ||
| 8 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 9 | * | ||
| 10 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 13 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 14 | * accompanied this code). | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License version | ||
| 17 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | * | ||
| 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 21 | * or visit www.oracle.com if you need additional information or have any | ||
| 22 | * questions. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * This file is available under and governed by the GNU General Public | ||
| 27 | * License version 2 only, as published by the Free Software Foundation. | ||
| 28 | * However, the following notice accompanied the original version of this | ||
| 29 | * file: | ||
| 30 | * | ||
| 31 | * Written by Doug Lea with assistance from members of JCP JSR-166 | ||
| 32 | * Expert Group and released to the public domain, as explained at | ||
| 33 | * http://creativecommons.org/publicdomain/zero/1.0/ | ||
| 34 | */ | ||
| 35 | |||
| 36 | package java.util.concurrent; | ||
| 37 | import java.util.*; | ||
| 38 | import java.util.concurrent.atomic.AtomicInteger; | ||
| 39 | import java.security.AccessControlContext; | ||
| 40 | import java.security.AccessController; | ||
| 41 | import java.security.PrivilegedAction; | ||
| 42 | import java.security.PrivilegedExceptionAction; | ||
| 43 | import java.security.PrivilegedActionException; | ||
| 44 | import java.security.AccessControlException; | ||
| 45 | import sun.security.util.SecurityConstants; | ||
| 46 | |||
| 47 | /** | ||
| 48 | * Factory and utility methods for {@link Executor}, {@link | ||
| 49 | * ExecutorService}, {@link ScheduledExecutorService}, {@link | ||
| 50 | * ThreadFactory}, and {@link Callable} classes defined in this | ||
| 51 | * package. This class supports the following kinds of methods: | ||
| 52 | * | ||
| 53 | * <ul> | ||
| 54 | * <li> Methods that create and return an {@link ExecutorService} | ||
| 55 | * set up with commonly useful configuration settings. | ||
| 56 | * <li> Methods that create and return a {@link ScheduledExecutorService} | ||
| 57 | * set up with commonly useful configuration settings. | ||
| 58 | * <li> Methods that create and return a "wrapped" ExecutorService, that | ||
| 59 | * disables reconfiguration by making implementation-specific methods | ||
| 60 | * inaccessible. | ||
| 61 | * <li> Methods that create and return a {@link ThreadFactory} | ||
| 62 | * that sets newly created threads to a known state. | ||
| 63 | * <li> Methods that create and return a {@link Callable} | ||
| 64 | * out of other closure-like forms, so they can be used | ||
| 65 | * in execution methods requiring <tt>Callable</tt>. | ||
| 66 | * </ul> | ||
| 67 | * | ||
| 68 | * @since 1.5 | ||
| 69 | * @author Doug Lea | ||
| 70 | */ | ||
| 71 | public class Executors { | ||
| 72 | |||
| 73 | /** | ||
| 74 | * Creates a thread pool that reuses a fixed number of threads | ||
| 75 | * operating off a shared unbounded queue. At any point, at most | ||
| 76 | * <tt>nThreads</tt> threads will be active processing tasks. | ||
| 77 | * If additional tasks are submitted when all threads are active, | ||
| 78 | * they will wait in the queue until a thread is available. | ||
| 79 | * If any thread terminates due to a failure during execution | ||
| 80 | * prior to shutdown, a new one will take its place if needed to | ||
| 81 | * execute subsequent tasks. The threads in the pool will exist | ||
| 82 | * until it is explicitly {@link ExecutorService#shutdown shutdown}. | ||
| 83 | * | ||
| 84 | * @param nThreads the number of threads in the pool | ||
| 85 | * @return the newly created thread pool | ||
| 86 | * @throws IllegalArgumentException if {@code nThreads <= 0} | ||
| 87 | */ | ||
| 88 | public static ExecutorService newFixedThreadPool(int nThreads) { | ||
| 89 | return new ThreadPoolExecutor(nThreads, nThreads, | ||
| 90 | 0L, TimeUnit.MILLISECONDS, | ||
| 91 | new LinkedBlockingQueue<Runnable>()); | ||
| 92 | } | ||
| 93 | |||
| 94 | /** | ||
| 95 | * Creates a thread pool that reuses a fixed number of threads | ||
| 96 | * operating off a shared unbounded queue, using the provided | ||
| 97 | * ThreadFactory to create new threads when needed. At any point, | ||
| 98 | * at most <tt>nThreads</tt> threads will be active processing | ||
| 99 | * tasks. If additional tasks are submitted when all threads are | ||
| 100 | * active, they will wait in the queue until a thread is | ||
| 101 | * available. If any thread terminates due to a failure during | ||
| 102 | * execution prior to shutdown, a new one will take its place if | ||
| 103 | * needed to execute subsequent tasks. The threads in the pool will | ||
| 104 | * exist until it is explicitly {@link ExecutorService#shutdown | ||
| 105 | * shutdown}. | ||
| 106 | * | ||
| 107 | * @param nThreads the number of threads in the pool | ||
| 108 | * @param threadFactory the factory to use when creating new threads | ||
| 109 | * @return the newly created thread pool | ||
| 110 | * @throws NullPointerException if threadFactory is null | ||
| 111 | * @throws IllegalArgumentException if {@code nThreads <= 0} | ||
| 112 | */ | ||
| 113 | public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) { | ||
| 114 | return new ThreadPoolExecutor(nThreads, nThreads, | ||
| 115 | 0L, TimeUnit.MILLISECONDS, | ||
| 116 | new LinkedBlockingQueue<Runnable>(), | ||
| 117 | threadFactory); | ||
| 118 | } | ||
| 119 | |||
| 120 | /** | ||
| 121 | * Creates an Executor that uses a single worker thread operating | ||
| 122 | * off an unbounded queue. (Note however that if this single | ||
| 123 | * thread terminates due to a failure during execution prior to | ||
| 124 | * shutdown, a new one will take its place if needed to execute | ||
| 125 | * subsequent tasks.) Tasks are guaranteed to execute | ||
| 126 | * sequentially, and no more than one task will be active at any | ||
| 127 | * given time. Unlike the otherwise equivalent | ||
| 128 | * <tt>newFixedThreadPool(1)</tt> the returned executor is | ||
| 129 | * guaranteed not to be reconfigurable to use additional threads. | ||
| 130 | * | ||
| 131 | * @return the newly created single-threaded Executor | ||
| 132 | */ | ||
| 133 | public static ExecutorService newSingleThreadExecutor() { | ||
| 134 | return new FinalizableDelegatedExecutorService | ||
| 135 | (new ThreadPoolExecutor(1, 1, | ||
| 136 | 0L, TimeUnit.MILLISECONDS, | ||
| 137 | new LinkedBlockingQueue<Runnable>())); | ||
| 138 | } | ||
| 139 | |||
| 140 | /** | ||
| 141 | * Creates an Executor that uses a single worker thread operating | ||
| 142 | * off an unbounded queue, and uses the provided ThreadFactory to | ||
| 143 | * create a new thread when needed. Unlike the otherwise | ||
| 144 | * equivalent <tt>newFixedThreadPool(1, threadFactory)</tt> the | ||
| 145 | * returned executor is guaranteed not to be reconfigurable to use | ||
| 146 | * additional threads. | ||
| 147 | * | ||
| 148 | * @param threadFactory the factory to use when creating new | ||
| 149 | * threads | ||
| 150 | * | ||
| 151 | * @return the newly created single-threaded Executor | ||
| 152 | * @throws NullPointerException if threadFactory is null | ||
| 153 | */ | ||
| 154 | public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) { | ||
| 155 | return new FinalizableDelegatedExecutorService | ||
| 156 | (new ThreadPoolExecutor(1, 1, | ||
| 157 | 0L, TimeUnit.MILLISECONDS, | ||
| 158 | new LinkedBlockingQueue<Runnable>(), | ||
| 159 | threadFactory)); | ||
| 160 | } | ||
| 161 | |||
| 162 | /** | ||
| 163 | * Creates a thread pool that creates new threads as needed, but | ||
| 164 | * will reuse previously constructed threads when they are | ||
| 165 | * available. These pools will typically improve the performance | ||
| 166 | * of programs that execute many short-lived asynchronous tasks. | ||
| 167 | * Calls to <tt>execute</tt> will reuse previously constructed | ||
| 168 | * threads if available. If no existing thread is available, a new | ||
| 169 | * thread will be created and added to the pool. Threads that have | ||
| 170 | * not been used for sixty seconds are terminated and removed from | ||
| 171 | * the cache. Thus, a pool that remains idle for long enough will | ||
| 172 | * not consume any resources. Note that pools with similar | ||
| 173 | * properties but different details (for example, timeout parameters) | ||
| 174 | * may be created using {@link ThreadPoolExecutor} constructors. | ||
| 175 | * | ||
| 176 | * @return the newly created thread pool | ||
| 177 | */ | ||
| 178 | public static ExecutorService newCachedThreadPool() { | ||
| 179 | return new ThreadPoolExecutor(0, Integer.MAX_VALUE, | ||
| 180 | 60L, TimeUnit.SECONDS, | ||
| 181 | new SynchronousQueue<Runnable>()); | ||
| 182 | } | ||
| 183 | |||
| 184 | /** | ||
| 185 | * Creates a thread pool that creates new threads as needed, but | ||
| 186 | * will reuse previously constructed threads when they are | ||
| 187 | * available, and uses the provided | ||
| 188 | * ThreadFactory to create new threads when needed. | ||
| 189 | * @param threadFactory the factory to use when creating new threads | ||
| 190 | * @return the newly created thread pool | ||
| 191 | * @throws NullPointerException if threadFactory is null | ||
| 192 | */ | ||
| 193 | public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) { | ||
| 194 | return new ThreadPoolExecutor(0, Integer.MAX_VALUE, | ||
| 195 | 60L, TimeUnit.SECONDS, | ||
| 196 | new SynchronousQueue<Runnable>(), | ||
| 197 | threadFactory); | ||
| 198 | } | ||
| 199 | |||
| 200 | /** | ||
| 201 | * Creates a single-threaded executor that can schedule commands | ||
| 202 | * to run after a given delay, or to execute periodically. | ||
| 203 | * (Note however that if this single | ||
| 204 | * thread terminates due to a failure during execution prior to | ||
| 205 | * shutdown, a new one will take its place if needed to execute | ||
| 206 | * subsequent tasks.) Tasks are guaranteed to execute | ||
| 207 | * sequentially, and no more than one task will be active at any | ||
| 208 | * given time. Unlike the otherwise equivalent | ||
| 209 | * <tt>newScheduledThreadPool(1)</tt> the returned executor is | ||
| 210 | * guaranteed not to be reconfigurable to use additional threads. | ||
| 211 | * @return the newly created scheduled executor | ||
| 212 | */ | ||
| 213 | public static ScheduledExecutorService newSingleThreadScheduledExecutor() { | ||
| 214 | return new DelegatedScheduledExecutorService | ||
| 215 | (new ScheduledThreadPoolExecutor(1)); | ||
| 216 | } | ||
| 217 | |||
| 218 | /** | ||
| 219 | * Creates a single-threaded executor that can schedule commands | ||
| 220 | * to run after a given delay, or to execute periodically. (Note | ||
| 221 | * however that if this single thread terminates due to a failure | ||
| 222 | * during execution prior to shutdown, a new one will take its | ||
| 223 | * place if needed to execute subsequent tasks.) Tasks are | ||
| 224 | * guaranteed to execute sequentially, and no more than one task | ||
| 225 | * will be active at any given time. Unlike the otherwise | ||
| 226 | * equivalent <tt>newScheduledThreadPool(1, threadFactory)</tt> | ||
| 227 | * the returned executor is guaranteed not to be reconfigurable to | ||
| 228 | * use additional threads. | ||
| 229 | * @param threadFactory the factory to use when creating new | ||
| 230 | * threads | ||
| 231 | * @return a newly created scheduled executor | ||
| 232 | * @throws NullPointerException if threadFactory is null | ||
| 233 | */ | ||
| 234 | public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) { | ||
| 235 | return new DelegatedScheduledExecutorService | ||
| 236 | (new ScheduledThreadPoolExecutor(1, threadFactory)); | ||
| 237 | } | ||
| 238 | |||
| 239 | /** | ||
| 240 | * Creates a thread pool that can schedule commands to run after a | ||
| 241 | * given delay, or to execute periodically. | ||
| 242 | * @param corePoolSize the number of threads to keep in the pool, | ||
| 243 | * even if they are idle. | ||
| 244 | * @return a newly created scheduled thread pool | ||
| 245 | * @throws IllegalArgumentException if {@code corePoolSize < 0} | ||
| 246 | */ | ||
| 247 | public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { | ||
| 248 | return new ScheduledThreadPoolExecutor(corePoolSize); | ||
| 249 | } | ||
| 250 | |||
| 251 | /** | ||
| 252 | * Creates a thread pool that can schedule commands to run after a | ||
| 253 | * given delay, or to execute periodically. | ||
| 254 | * @param corePoolSize the number of threads to keep in the pool, | ||
| 255 | * even if they are idle. | ||
| 256 | * @param threadFactory the factory to use when the executor | ||
| 257 | * creates a new thread. | ||
| 258 | * @return a newly created scheduled thread pool | ||
| 259 | * @throws IllegalArgumentException if {@code corePoolSize < 0} | ||
| 260 | * @throws NullPointerException if threadFactory is null | ||
| 261 | */ | ||
| 262 | public static ScheduledExecutorService newScheduledThreadPool( | ||
| 263 | int corePoolSize, ThreadFactory threadFactory) { | ||
| 264 | return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory); | ||
| 265 | } | ||
| 266 | |||
| 267 | |||
| 268 | /** | ||
| 269 | * Returns an object that delegates all defined {@link | ||
| 270 | * ExecutorService} methods to the given executor, but not any | ||
| 271 | * other methods that might otherwise be accessible using | ||
| 272 | * casts. This provides a way to safely "freeze" configuration and | ||
| 273 | * disallow tuning of a given concrete implementation. | ||
| 274 | * @param executor the underlying implementation | ||
| 275 | * @return an <tt>ExecutorService</tt> instance | ||
| 276 | * @throws NullPointerException if executor null | ||
| 277 | */ | ||
| 278 | public static ExecutorService unconfigurableExecutorService(ExecutorService executor) { | ||
| 279 | if (executor == null) | ||
| 280 | throw new NullPointerException(); | ||
| 281 | return new DelegatedExecutorService(executor); | ||
| 282 | } | ||
| 283 | |||
| 284 | /** | ||
| 285 | * Returns an object that delegates all defined {@link | ||
| 286 | * ScheduledExecutorService} methods to the given executor, but | ||
| 287 | * not any other methods that might otherwise be accessible using | ||
| 288 | * casts. This provides a way to safely "freeze" configuration and | ||
| 289 | * disallow tuning of a given concrete implementation. | ||
| 290 | * @param executor the underlying implementation | ||
| 291 | * @return a <tt>ScheduledExecutorService</tt> instance | ||
| 292 | * @throws NullPointerException if executor null | ||
| 293 | */ | ||
| 294 | public static ScheduledExecutorService unconfigurableScheduledExecutorService(ScheduledExecutorService executor) { | ||
| 295 | if (executor == null) | ||
| 296 | throw new NullPointerException(); | ||
| 297 | return new DelegatedScheduledExecutorService(executor); | ||
| 298 | } | ||
| 299 | |||
| 300 | /** | ||
| 301 | * Returns a default thread factory used to create new threads. | ||
| 302 | * This factory creates all new threads used by an Executor in the | ||
| 303 | * same {@link ThreadGroup}. If there is a {@link | ||
| 304 | * java.lang.SecurityManager}, it uses the group of {@link | ||
| 305 | * System#getSecurityManager}, else the group of the thread | ||
| 306 | * invoking this <tt>defaultThreadFactory</tt> method. Each new | ||
| 307 | * thread is created as a non-daemon thread with priority set to | ||
| 308 | * the smaller of <tt>Thread.NORM_PRIORITY</tt> and the maximum | ||
| 309 | * priority permitted in the thread group. New threads have names | ||
| 310 | * accessible via {@link Thread#getName} of | ||
| 311 | * <em>pool-N-thread-M</em>, where <em>N</em> is the sequence | ||
| 312 | * number of this factory, and <em>M</em> is the sequence number | ||
| 313 | * of the thread created by this factory. | ||
| 314 | * @return a thread factory | ||
| 315 | */ | ||
| 316 | public static ThreadFactory defaultThreadFactory() { | ||
| 317 | return new DefaultThreadFactory(); | ||
| 318 | } | ||
| 319 | |||
| 320 | /** | ||
| 321 | * Returns a thread factory used to create new threads that | ||
| 322 | * have the same permissions as the current thread. | ||
| 323 | * This factory creates threads with the same settings as {@link | ||
| 324 | * Executors#defaultThreadFactory}, additionally setting the | ||
| 325 | * AccessControlContext and contextClassLoader of new threads to | ||
| 326 | * be the same as the thread invoking this | ||
| 327 | * <tt>privilegedThreadFactory</tt> method. A new | ||
| 328 | * <tt>privilegedThreadFactory</tt> can be created within an | ||
| 329 | * {@link AccessController#doPrivileged} action setting the | ||
| 330 | * current thread's access control context to create threads with | ||
| 331 | * the selected permission settings holding within that action. | ||
| 332 | * | ||
| 333 | * <p> Note that while tasks running within such threads will have | ||
| 334 | * the same access control and class loader settings as the | ||
| 335 | * current thread, they need not have the same {@link | ||
| 336 | * java.lang.ThreadLocal} or {@link | ||
| 337 | * java.lang.InheritableThreadLocal} values. If necessary, | ||
| 338 | * particular values of thread locals can be set or reset before | ||
| 339 | * any task runs in {@link ThreadPoolExecutor} subclasses using | ||
| 340 | * {@link ThreadPoolExecutor#beforeExecute}. Also, if it is | ||
| 341 | * necessary to initialize worker threads to have the same | ||
| 342 | * InheritableThreadLocal settings as some other designated | ||
| 343 | * thread, you can create a custom ThreadFactory in which that | ||
| 344 | * thread waits for and services requests to create others that | ||
| 345 | * will inherit its values. | ||
| 346 | * | ||
| 347 | * @return a thread factory | ||
| 348 | * @throws AccessControlException if the current access control | ||
| 349 | * context does not have permission to both get and set context | ||
| 350 | * class loader. | ||
| 351 | */ | ||
| 352 | public static ThreadFactory privilegedThreadFactory() { | ||
| 353 | return new PrivilegedThreadFactory(); | ||
| 354 | } | ||
| 355 | |||
| 356 | /** | ||
| 357 | * Returns a {@link Callable} object that, when | ||
| 358 | * called, runs the given task and returns the given result. This | ||
| 359 | * can be useful when applying methods requiring a | ||
| 360 | * <tt>Callable</tt> to an otherwise resultless action. | ||
| 361 | * @param task the task to run | ||
| 362 | * @param result the result to return | ||
| 363 | * @return a callable object | ||
| 364 | * @throws NullPointerException if task null | ||
| 365 | */ | ||
| 366 | public static <T> Callable<T> callable(Runnable task, T result) { | ||
| 367 | if (task == null) | ||
| 368 | throw new NullPointerException(); | ||
| 369 | return new RunnableAdapter<T>(task, result); | ||
| 370 | } | ||
| 371 | |||
| 372 | /** | ||
| 373 | * Returns a {@link Callable} object that, when | ||
| 374 | * called, runs the given task and returns <tt>null</tt>. | ||
| 375 | * @param task the task to run | ||
| 376 | * @return a callable object | ||
| 377 | * @throws NullPointerException if task null | ||
| 378 | */ | ||
| 379 | public static Callable<Object> callable(Runnable task) { | ||
| 380 | if (task == null) | ||
| 381 | throw new NullPointerException(); | ||
| 382 | return new RunnableAdapter<Object>(task, null); | ||
| 383 | } | ||
| 384 | |||
| 385 | /** | ||
| 386 | * Returns a {@link Callable} object that, when | ||
| 387 | * called, runs the given privileged action and returns its result. | ||
| 388 | * @param action the privileged action to run | ||
| 389 | * @return a callable object | ||
| 390 | * @throws NullPointerException if action null | ||
| 391 | */ | ||
| 392 | public static Callable<Object> callable(final PrivilegedAction<?> action) { | ||
| 393 | if (action == null) | ||
| 394 | throw new NullPointerException(); | ||
| 395 | return new Callable<Object>() { | ||
| 396 | public Object call() { return action.run(); }}; | ||
| 397 | } | ||
| 398 | |||
| 399 | /** | ||
| 400 | * Returns a {@link Callable} object that, when | ||
| 401 | * called, runs the given privileged exception action and returns | ||
| 402 | * its result. | ||
| 403 | * @param action the privileged exception action to run | ||
| 404 | * @return a callable object | ||
| 405 | * @throws NullPointerException if action null | ||
| 406 | */ | ||
| 407 | public static Callable<Object> callable(final PrivilegedExceptionAction<?> action) { | ||
| 408 | if (action == null) | ||
| 409 | throw new NullPointerException(); | ||
| 410 | return new Callable<Object>() { | ||
| 411 | public Object call() throws Exception { return action.run(); }}; | ||
| 412 | } | ||
| 413 | |||
| 414 | /** | ||
| 415 | * Returns a {@link Callable} object that will, when | ||
| 416 | * called, execute the given <tt>callable</tt> under the current | ||
| 417 | * access control context. This method should normally be | ||
| 418 | * invoked within an {@link AccessController#doPrivileged} action | ||
| 419 | * to create callables that will, if possible, execute under the | ||
| 420 | * selected permission settings holding within that action; or if | ||
| 421 | * not possible, throw an associated {@link | ||
| 422 | * AccessControlException}. | ||
| 423 | * @param callable the underlying task | ||
| 424 | * @return a callable object | ||
| 425 | * @throws NullPointerException if callable null | ||
| 426 | * | ||
| 427 | */ | ||
| 428 | public static <T> Callable<T> privilegedCallable(Callable<T> callable) { | ||
| 429 | if (callable == null) | ||
| 430 | throw new NullPointerException(); | ||
| 431 | return new PrivilegedCallable<T>(callable); | ||
| 432 | } | ||
| 433 | |||
| 434 | /** | ||
| 435 | * Returns a {@link Callable} object that will, when | ||
| 436 | * called, execute the given <tt>callable</tt> under the current | ||
| 437 | * access control context, with the current context class loader | ||
| 438 | * as the context class loader. This method should normally be | ||
| 439 | * invoked within an {@link AccessController#doPrivileged} action | ||
| 440 | * to create callables that will, if possible, execute under the | ||
| 441 | * selected permission settings holding within that action; or if | ||
| 442 | * not possible, throw an associated {@link | ||
| 443 | * AccessControlException}. | ||
| 444 | * @param callable the underlying task | ||
| 445 | * | ||
| 446 | * @return a callable object | ||
| 447 | * @throws NullPointerException if callable null | ||
| 448 | * @throws AccessControlException if the current access control | ||
| 449 | * context does not have permission to both set and get context | ||
| 450 | * class loader. | ||
| 451 | */ | ||
| 452 | public static <T> Callable<T> privilegedCallableUsingCurrentClassLoader(Callable<T> callable) { | ||
| 453 | if (callable == null) | ||
| 454 | throw new NullPointerException(); | ||
| 455 | return new PrivilegedCallableUsingCurrentClassLoader<T>(callable); | ||
| 456 | } | ||
| 457 | |||
| 458 | // Non-public classes supporting the public methods | ||
| 459 | |||
| 460 | /** | ||
| 461 | * A callable that runs given task and returns given result | ||
| 462 | */ | ||
| 463 | static final class RunnableAdapter<T> implements Callable<T> { | ||
| 464 | final Runnable task; | ||
| 465 | final T result; | ||
| 466 | RunnableAdapter(Runnable task, T result) { | ||
| 467 | this.task = task; | ||
| 468 | this.result = result; | ||
| 469 | } | ||
| 470 | public T call() { | ||
| 471 | task.run(); | ||
| 472 | return result; | ||
| 473 | } | ||
| 474 | } | ||
| 475 | |||
| 476 | /** | ||
| 477 | * A callable that runs under established access control settings | ||
| 478 | */ | ||
| 479 | static final class PrivilegedCallable<T> implements Callable<T> { | ||
| 480 | private final Callable<T> task; | ||
| 481 | private final AccessControlContext acc; | ||
| 482 | |||
| 483 | PrivilegedCallable(Callable<T> task) { | ||
| 484 | this.task = task; | ||
| 485 | this.acc = AccessController.getContext(); | ||
| 486 | } | ||
| 487 | |||
| 488 | public T call() throws Exception { | ||
| 489 | try { | ||
| 490 | return AccessController.doPrivileged( | ||
| 491 | new PrivilegedExceptionAction<T>() { | ||
| 492 | public T run() throws Exception { | ||
| 493 | return task.call(); | ||
| 494 | } | ||
| 495 | }, acc); | ||
| 496 | } catch (PrivilegedActionException e) { | ||
| 497 | throw e.getException(); | ||
| 498 | } | ||
| 499 | } | ||
| 500 | } | ||
| 501 | |||
| 502 | /** | ||
| 503 | * A callable that runs under established access control settings and | ||
| 504 | * current ClassLoader | ||
| 505 | */ | ||
| 506 | static final class PrivilegedCallableUsingCurrentClassLoader<T> implements Callable<T> { | ||
| 507 | private final Callable<T> task; | ||
| 508 | private final AccessControlContext acc; | ||
| 509 | private final ClassLoader ccl; | ||
| 510 | |||
| 511 | PrivilegedCallableUsingCurrentClassLoader(Callable<T> task) { | ||
| 512 | SecurityManager sm = System.getSecurityManager(); | ||
| 513 | if (sm != null) { | ||
| 514 | // Calls to getContextClassLoader from this class | ||
| 515 | // never trigger a security check, but we check | ||
| 516 | // whether our callers have this permission anyways. | ||
| 517 | sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); | ||
| 518 | |||
| 519 | // Whether setContextClassLoader turns out to be necessary | ||
| 520 | // or not, we fail fast if permission is not available. | ||
| 521 | sm.checkPermission(new RuntimePermission("setContextClassLoader")); | ||
| 522 | } | ||
| 523 | this.task = task; | ||
| 524 | this.acc = AccessController.getContext(); | ||
| 525 | this.ccl = Thread.currentThread().getContextClassLoader(); | ||
| 526 | } | ||
| 527 | |||
| 528 | public T call() throws Exception { | ||
| 529 | try { | ||
| 530 | return AccessController.doPrivileged( | ||
| 531 | new PrivilegedExceptionAction<T>() { | ||
| 532 | public T run() throws Exception { | ||
| 533 | ClassLoader savedcl = null; | ||
| 534 | Thread t = Thread.currentThread(); | ||
| 535 | try { | ||
| 536 | ClassLoader cl = t.getContextClassLoader(); | ||
| 537 | if (ccl != cl) { | ||
| 538 | t.setContextClassLoader(ccl); | ||
| 539 | savedcl = cl; | ||
| 540 | } | ||
| 541 | return task.call(); | ||
| 542 | } finally { | ||
| 543 | if (savedcl != null) | ||
| 544 | t.setContextClassLoader(savedcl); | ||
| 545 | } | ||
| 546 | } | ||
| 547 | }, acc); | ||
| 548 | } catch (PrivilegedActionException e) { | ||
| 549 | throw e.getException(); | ||
| 550 | } | ||
| 551 | } | ||
| 552 | } | ||
| 553 | |||
| 554 | /** | ||
| 555 | * The default thread factory | ||
| 556 | */ | ||
| 557 | static class DefaultThreadFactory implements ThreadFactory { | ||
| 558 | private static final AtomicInteger poolNumber = new AtomicInteger(1); | ||
| 559 | private final ThreadGroup group; | ||
| 560 | private final AtomicInteger threadNumber = new AtomicInteger(1); | ||
| 561 | private final String namePrefix; | ||
| 562 | |||
| 563 | DefaultThreadFactory() { | ||
| 564 | SecurityManager s = System.getSecurityManager(); | ||
| 565 | group = (s != null) ? s.getThreadGroup() : | ||
| 566 | Thread.currentThread().getThreadGroup(); | ||
| 567 | namePrefix = "pool-" + | ||
| 568 | poolNumber.getAndIncrement() + | ||
| 569 | "-thread-"; | ||
| 570 | } | ||
| 571 | |||
| 572 | public Thread newThread(Runnable r) { | ||
| 573 | Thread t = new Thread(group, r, | ||
| 574 | namePrefix + threadNumber.getAndIncrement(), | ||
| 575 | 0); | ||
| 576 | if (t.isDaemon()) | ||
| 577 | t.setDaemon(false); | ||
| 578 | if (t.getPriority() != Thread.NORM_PRIORITY) | ||
| 579 | t.setPriority(Thread.NORM_PRIORITY); | ||
| 580 | return t; | ||
| 581 | } | ||
| 582 | } | ||
| 583 | |||
| 584 | /** | ||
| 585 | * Thread factory capturing access control context and class loader | ||
| 586 | */ | ||
| 587 | static class PrivilegedThreadFactory extends DefaultThreadFactory { | ||
| 588 | private final AccessControlContext acc; | ||
| 589 | private final ClassLoader ccl; | ||
| 590 | |||
| 591 | PrivilegedThreadFactory() { | ||
| 592 | super(); | ||
| 593 | SecurityManager sm = System.getSecurityManager(); | ||
| 594 | if (sm != null) { | ||
| 595 | // Calls to getContextClassLoader from this class | ||
| 596 | // never trigger a security check, but we check | ||
| 597 | // whether our callers have this permission anyways. | ||
| 598 | sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); | ||
| 599 | |||
| 600 | // Fail fast | ||
| 601 | sm.checkPermission(new RuntimePermission("setContextClassLoader")); | ||
| 602 | } | ||
| 603 | this.acc = AccessController.getContext(); | ||
| 604 | this.ccl = Thread.currentThread().getContextClassLoader(); | ||
| 605 | } | ||
| 606 | |||
| 607 | public Thread newThread(final Runnable r) { | ||
| 608 | return super.newThread(new Runnable() { | ||
| 609 | public void run() { | ||
| 610 | AccessController.doPrivileged(new PrivilegedAction<Void>() { | ||
| 611 | public Void run() { | ||
| 612 | Thread.currentThread().setContextClassLoader(ccl); | ||
| 613 | r.run(); | ||
| 614 | return null; | ||
| 615 | } | ||
| 616 | }, acc); | ||
| 617 | } | ||
| 618 | }); | ||
| 619 | } | ||
| 620 | } | ||
| 621 | |||
| 622 | /** | ||
| 623 | * A wrapper class that exposes only the ExecutorService methods | ||
| 624 | * of an ExecutorService implementation. | ||
| 625 | */ | ||
| 626 | static class DelegatedExecutorService extends AbstractExecutorService { | ||
| 627 | private final ExecutorService e; | ||
| 628 | DelegatedExecutorService(ExecutorService executor) { e = executor; } | ||
| 629 | public void execute(Runnable command) { e.execute(command); } | ||
| 630 | public void shutdown() { e.shutdown(); } | ||
| 631 | public List<Runnable> shutdownNow() { return e.shutdownNow(); } | ||
| 632 | public boolean isShutdown() { return e.isShutdown(); } | ||
| 633 | public boolean isTerminated() { return e.isTerminated(); } | ||
| 634 | public boolean awaitTermination(long timeout, TimeUnit unit) | ||
| 635 | throws InterruptedException { | ||
| 636 | return e.awaitTermination(timeout, unit); | ||
| 637 | } | ||
| 638 | public Future<?> submit(Runnable task) { | ||
| 639 | return e.submit(task); | ||
| 640 | } | ||
| 641 | public <T> Future<T> submit(Callable<T> task) { | ||
| 642 | return e.submit(task); | ||
| 643 | } | ||
| 644 | public <T> Future<T> submit(Runnable task, T result) { | ||
| 645 | return e.submit(task, result); | ||
| 646 | } | ||
| 647 | public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) | ||
| 648 | throws InterruptedException { | ||
| 649 | return e.invokeAll(tasks); | ||
| 650 | } | ||
| 651 | public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, | ||
| 652 | long timeout, TimeUnit unit) | ||
| 653 | throws InterruptedException { | ||
| 654 | return e.invokeAll(tasks, timeout, unit); | ||
| 655 | } | ||
| 656 | public <T> T invokeAny(Collection<? extends Callable<T>> tasks) | ||
| 657 | throws InterruptedException, ExecutionException { | ||
| 658 | return e.invokeAny(tasks); | ||
| 659 | } | ||
| 660 | public <T> T invokeAny(Collection<? extends Callable<T>> tasks, | ||
| 661 | long timeout, TimeUnit unit) | ||
| 662 | throws InterruptedException, ExecutionException, TimeoutException { | ||
| 663 | return e.invokeAny(tasks, timeout, unit); | ||
| 664 | } | ||
| 665 | } | ||
| 666 | |||
| 667 | static class FinalizableDelegatedExecutorService | ||
| 668 | extends DelegatedExecutorService { | ||
| 669 | FinalizableDelegatedExecutorService(ExecutorService executor) { | ||
| 670 | super(executor); | ||
| 671 | } | ||
| 672 | protected void finalize() { | ||
| 673 | super.shutdown(); | ||
| 674 | } | ||
| 675 | } | ||
| 676 | |||
| 677 | /** | ||
| 678 | * A wrapper class that exposes only the ScheduledExecutorService | ||
| 679 | * methods of a ScheduledExecutorService implementation. | ||
| 680 | */ | ||
| 681 | static class DelegatedScheduledExecutorService | ||
| 682 | extends DelegatedExecutorService | ||
| 683 | implements ScheduledExecutorService { | ||
| 684 | private final ScheduledExecutorService e; | ||
| 685 | DelegatedScheduledExecutorService(ScheduledExecutorService executor) { | ||
| 686 | super(executor); | ||
| 687 | e = executor; | ||
| 688 | } | ||
| 689 | public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) { | ||
| 690 | return e.schedule(command, delay, unit); | ||
| 691 | } | ||
| 692 | public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) { | ||
| 693 | return e.schedule(callable, delay, unit); | ||
| 694 | } | ||
| 695 | public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) { | ||
| 696 | return e.scheduleAtFixedRate(command, initialDelay, period, unit); | ||
| 697 | } | ||
| 698 | public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) { | ||
| 699 | return e.scheduleWithFixedDelay(command, initialDelay, delay, unit); | ||
| 700 | } | ||
| 701 | } | ||
| 702 | |||
| 703 | |||
| 704 | /** Cannot instantiate. */ | ||
| 705 | private Executors() {} | ||
| 706 | } | ||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,2177 @@ | |||
| 1 | /* | ||
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 3 | * | ||
| 4 | * This code is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License version 2 only, as | ||
| 6 | * published by the Free Software Foundation. Oracle designates this | ||
| 7 | * particular file as subject to the "Classpath" exception as provided | ||
| 8 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 9 | * | ||
| 10 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 13 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 14 | * accompanied this code). | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License version | ||
| 17 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | * | ||
| 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 21 | * or visit www.oracle.com if you need additional information or have any | ||
| 22 | * questions. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * This file is available under and governed by the GNU General Public | ||
| 27 | * License version 2 only, as published by the Free Software Foundation. | ||
| 28 | * However, the following notice accompanied the original version of this | ||
| 29 | * file: | ||
| 30 | * | ||
| 31 | * Written by Doug Lea with assistance from members of JCP JSR-166 | ||
| 32 | * Expert Group and released to the public domain, as explained at | ||
| 33 | * http://creativecommons.org/publicdomain/zero/1.0/ | ||
| 34 | */ | ||
| 35 | |||
| 36 | package java.util.concurrent; | ||
| 37 | |||
| 38 | import java.util.ArrayList; | ||
| 39 | import java.util.Arrays; | ||
| 40 | import java.util.Collection; | ||
| 41 | import java.util.Collections; | ||
| 42 | import java.util.List; | ||
| 43 | import java.util.Random; | ||
| 44 | import java.util.concurrent.AbstractExecutorService; | ||
| 45 | import java.util.concurrent.Callable; | ||
| 46 | import java.util.concurrent.ExecutorService; | ||
| 47 | import java.util.concurrent.Future; | ||
| 48 | import java.util.concurrent.RejectedExecutionException; | ||
| 49 | import java.util.concurrent.RunnableFuture; | ||
| 50 | import java.util.concurrent.TimeUnit; | ||
| 51 | import java.util.concurrent.TimeoutException; | ||
| 52 | import java.util.concurrent.atomic.AtomicInteger; | ||
| 53 | import java.util.concurrent.locks.LockSupport; | ||
| 54 | import java.util.concurrent.locks.ReentrantLock; | ||
| 55 | import java.util.concurrent.locks.Condition; | ||
| 56 | |||
| 57 | /** | ||
| 58 | * An {@link ExecutorService} for running {@link ForkJoinTask}s. | ||
| 59 | * A {@code ForkJoinPool} provides the entry point for submissions | ||
| 60 | * from non-{@code ForkJoinTask} clients, as well as management and | ||
| 61 | * monitoring operations. | ||
| 62 | * | ||
| 63 | * <p>A {@code ForkJoinPool} differs from other kinds of {@link | ||
| 64 | * ExecutorService} mainly by virtue of employing | ||
| 65 | * <em>work-stealing</em>: all threads in the pool attempt to find and | ||
| 66 | * execute subtasks created by other active tasks (eventually blocking | ||
| 67 | * waiting for work if none exist). This enables efficient processing | ||
| 68 | * when most tasks spawn other subtasks (as do most {@code | ||
| 69 | * ForkJoinTask}s). When setting <em>asyncMode</em> to true in | ||
| 70 | * constructors, {@code ForkJoinPool}s may also be appropriate for use | ||
| 71 | * with event-style tasks that are never joined. | ||
| 72 | * | ||
| 73 | * <p>A {@code ForkJoinPool} is constructed with a given target | ||
| 74 | * parallelism level; by default, equal to the number of available | ||
| 75 | * processors. The pool attempts to maintain enough active (or | ||
| 76 | * available) threads by dynamically adding, suspending, or resuming | ||
| 77 | * internal worker threads, even if some tasks are stalled waiting to | ||
| 78 | * join others. However, no such adjustments are guaranteed in the | ||
| 79 | * face of blocked IO or other unmanaged synchronization. The nested | ||
| 80 | * {@link ManagedBlocker} interface enables extension of the kinds of | ||
| 81 | * synchronization accommodated. | ||
| 82 | * | ||
| 83 | * <p>In addition to execution and lifecycle control methods, this | ||
| 84 | * class provides status check methods (for example | ||
| 85 | * {@link #getStealCount}) that are intended to aid in developing, | ||
| 86 | * tuning, and monitoring fork/join applications. Also, method | ||
| 87 | * {@link #toString} returns indications of pool state in a | ||
| 88 | * convenient form for informal monitoring. | ||
| 89 | * | ||
| 90 | * <p> As is the case with other ExecutorServices, there are three | ||
| 91 | * main task execution methods summarized in the following | ||
| 92 | * table. These are designed to be used by clients not already engaged | ||
| 93 | * in fork/join computations in the current pool. The main forms of | ||
| 94 | * these methods accept instances of {@code ForkJoinTask}, but | ||
| 95 | * overloaded forms also allow mixed execution of plain {@code | ||
| 96 | * Runnable}- or {@code Callable}- based activities as well. However, | ||
| 97 | * tasks that are already executing in a pool should normally | ||
| 98 | * <em>NOT</em> use these pool execution methods, but instead use the | ||
| 99 | * within-computation forms listed in the table. | ||
| 100 | * | ||
| 101 | * <table BORDER CELLPADDING=3 CELLSPACING=1> | ||
| 102 | * <tr> | ||
| 103 | * <td></td> | ||
| 104 | * <td ALIGN=CENTER> <b>Call from non-fork/join clients</b></td> | ||
| 105 | * <td ALIGN=CENTER> <b>Call from within fork/join computations</b></td> | ||
| 106 | * </tr> | ||
| 107 | * <tr> | ||
| 108 | * <td> <b>Arrange async execution</td> | ||
| 109 | * <td> {@link #execute(ForkJoinTask)}</td> | ||
| 110 | * <td> {@link ForkJoinTask#fork}</td> | ||
| 111 | * </tr> | ||
| 112 | * <tr> | ||
| 113 | * <td> <b>Await and obtain result</td> | ||
| 114 | * <td> {@link #invoke(ForkJoinTask)}</td> | ||
| 115 | * <td> {@link ForkJoinTask#invoke}</td> | ||
| 116 | * </tr> | ||
| 117 | * <tr> | ||
| 118 | * <td> <b>Arrange exec and obtain Future</td> | ||
| 119 | * <td> {@link #submit(ForkJoinTask)}</td> | ||
| 120 | * <td> {@link ForkJoinTask#fork} (ForkJoinTasks <em>are</em> Futures)</td> | ||
| 121 | * </tr> | ||
| 122 | * </table> | ||
| 123 | * | ||
| 124 | * <p><b>Sample Usage.</b> Normally a single {@code ForkJoinPool} is | ||
| 125 | * used for all parallel task execution in a program or subsystem. | ||
| 126 | * Otherwise, use would not usually outweigh the construction and | ||
| 127 | * bookkeeping overhead of creating a large set of threads. For | ||
| 128 | * example, a common pool could be used for the {@code SortTasks} | ||
| 129 | * illustrated in {@link RecursiveAction}. Because {@code | ||
| 130 | * ForkJoinPool} uses threads in {@linkplain java.lang.Thread#isDaemon | ||
| 131 | * daemon} mode, there is typically no need to explicitly {@link | ||
| 132 | * #shutdown} such a pool upon program exit. | ||
| 133 | * | ||
| 134 | * <pre> | ||
| 135 | * static final ForkJoinPool mainPool = new ForkJoinPool(); | ||
| 136 | * ... | ||
| 137 | * public void sort(long[] array) { | ||
| 138 | * mainPool.invoke(new SortTask(array, 0, array.length)); | ||
| 139 | * } | ||
| 140 | * </pre> | ||
| 141 | * | ||
| 142 | * <p><b>Implementation notes</b>: This implementation restricts the | ||
| 143 | * maximum number of running threads to 32767. Attempts to create | ||
| 144 | * pools with greater than the maximum number result in | ||
| 145 | * {@code IllegalArgumentException}. | ||
| 146 | * | ||
| 147 | * <p>This implementation rejects submitted tasks (that is, by throwing | ||
| 148 | * {@link RejectedExecutionException}) only when the pool is shut down | ||
| 149 | * or internal resources have been exhausted. | ||
| 150 | * | ||
| 151 | * @since 1.7 | ||
| 152 | * @author Doug Lea | ||
| 153 | */ | ||
| 154 | public class ForkJoinPool extends AbstractExecutorService { | ||
| 155 | |||
| 156 | /* | ||
| 157 | * Implementation Overview | ||
| 158 | * | ||
| 159 | * This class provides the central bookkeeping and control for a | ||
| 160 | * set of worker threads: Submissions from non-FJ threads enter | ||
| 161 | * into a submission queue. Workers take these tasks and typically | ||
| 162 | * split them into subtasks that may be stolen by other workers. | ||
| 163 | * Preference rules give first priority to processing tasks from | ||
| 164 | * their own queues (LIFO or FIFO, depending on mode), then to | ||
| 165 | * randomized FIFO steals of tasks in other worker queues, and | ||
| 166 | * lastly to new submissions. | ||
| 167 | * | ||
| 168 | * The main throughput advantages of work-stealing stem from | ||
| 169 | * decentralized control -- workers mostly take tasks from | ||
| 170 | * themselves or each other. We cannot negate this in the | ||
| 171 | * implementation of other management responsibilities. The main | ||
| 172 | * tactic for avoiding bottlenecks is packing nearly all | ||
| 173 | * essentially atomic control state into a single 64bit volatile | ||
| 174 | * variable ("ctl"). This variable is read on the order of 10-100 | ||
| 175 | * times as often as it is modified (always via CAS). (There is | ||
| 176 | * some additional control state, for example variable "shutdown" | ||
| 177 | * for which we can cope with uncoordinated updates.) This | ||
| 178 | * streamlines synchronization and control at the expense of messy | ||
| 179 | * constructions needed to repack status bits upon updates. | ||
| 180 | * Updates tend not to contend with each other except during | ||
| 181 | * bursts while submitted tasks begin or end. In some cases when | ||
| 182 | * they do contend, threads can instead do something else | ||
| 183 | * (usually, scan for tasks) until contention subsides. | ||
| 184 | * | ||
| 185 | * To enable packing, we restrict maximum parallelism to (1<<15)-1 | ||
| 186 | * (which is far in excess of normal operating range) to allow | ||
| 187 | * ids, counts, and their negations (used for thresholding) to fit | ||
| 188 | * into 16bit fields. | ||
| 189 | * | ||
| 190 | * Recording Workers. Workers are recorded in the "workers" array | ||
| 191 | * that is created upon pool construction and expanded if (rarely) | ||
| 192 | * necessary. This is an array as opposed to some other data | ||
| 193 | * structure to support index-based random steals by workers. | ||
| 194 | * Updates to the array recording new workers and unrecording | ||
| 195 | * terminated ones are protected from each other by a seqLock | ||
| 196 | * (scanGuard) but the array is otherwise concurrently readable, | ||
| 197 | * and accessed directly by workers. To simplify index-based | ||
| 198 | * operations, the array size is always a power of two, and all | ||
| 199 | * readers must tolerate null slots. To avoid flailing during | ||
| 200 | * start-up, the array is presized to hold twice #parallelism | ||
| 201 | * workers (which is unlikely to need further resizing during | ||
| 202 | * execution). But to avoid dealing with so many null slots, | ||
| 203 | * variable scanGuard includes a mask for the nearest power of two | ||
| 204 | * that contains all current workers. All worker thread creation | ||
| 205 | * is on-demand, triggered by task submissions, replacement of | ||
| 206 | * terminated workers, and/or compensation for blocked | ||
| 207 | * workers. However, all other support code is set up to work with | ||
| 208 | * other policies. To ensure that we do not hold on to worker | ||
| 209 | * references that would prevent GC, ALL accesses to workers are | ||
| 210 | * via indices into the workers array (which is one source of some | ||
| 211 | * of the messy code constructions here). In essence, the workers | ||
| 212 | * array serves as a weak reference mechanism. Thus for example | ||
| 213 | * the wait queue field of ctl stores worker indices, not worker | ||
| 214 | * references. Access to the workers in associated methods (for | ||
| 215 | * example signalWork) must both index-check and null-check the | ||
| 216 | * IDs. All such accesses ignore bad IDs by returning out early | ||
| 217 | * from what they are doing, since this can only be associated | ||
| 218 | * with termination, in which case it is OK to give up. | ||
| 219 | * | ||
| 220 | * All uses of the workers array, as well as queue arrays, check | ||
| 221 | * that the array is non-null (even if previously non-null). This | ||
| 222 | * allows nulling during termination, which is currently not | ||
| 223 | * necessary, but remains an option for resource-revocation-based | ||
| 224 | * shutdown schemes. | ||
| 225 | * | ||
| 226 | * Wait Queuing. Unlike HPC work-stealing frameworks, we cannot | ||
| 227 | * let workers spin indefinitely scanning for tasks when none can | ||
| 228 | * be found immediately, and we cannot start/resume workers unless | ||
| 229 | * there appear to be tasks available. On the other hand, we must | ||
| 230 | * quickly prod them into action when new tasks are submitted or | ||
| 231 | * generated. We park/unpark workers after placing in an event | ||
| 232 | * wait queue when they cannot find work. This "queue" is actually | ||
| 233 | * a simple Treiber stack, headed by the "id" field of ctl, plus a | ||
| 234 | * 15bit counter value to both wake up waiters (by advancing their | ||
| 235 | * count) and avoid ABA effects. Successors are held in worker | ||
| 236 | * field "nextWait". Queuing deals with several intrinsic races, | ||
| 237 | * mainly that a task-producing thread can miss seeing (and | ||
| 238 | * signalling) another thread that gave up looking for work but | ||
| 239 | * has not yet entered the wait queue. We solve this by requiring | ||
| 240 | * a full sweep of all workers both before (in scan()) and after | ||
| 241 | * (in tryAwaitWork()) a newly waiting worker is added to the wait | ||
| 242 | * queue. During a rescan, the worker might release some other | ||
| 243 | * queued worker rather than itself, which has the same net | ||
| 244 | * effect. Because enqueued workers may actually be rescanning | ||
| 245 | * rather than waiting, we set and clear the "parked" field of | ||
| 246 | * ForkJoinWorkerThread to reduce unnecessary calls to unpark. | ||
| 247 | * (Use of the parked field requires a secondary recheck to avoid | ||
| 248 | * missed signals.) | ||
| 249 | * | ||
| 250 | * Signalling. We create or wake up workers only when there | ||
| 251 | * appears to be at least one task they might be able to find and | ||
| 252 | * execute. When a submission is added or another worker adds a | ||
| 253 | * task to a queue that previously had two or fewer tasks, they | ||
| 254 | * signal waiting workers (or trigger creation of new ones if | ||
| 255 | * fewer than the given parallelism level -- see signalWork). | ||
| 256 | * These primary signals are buttressed by signals during rescans | ||
| 257 | * as well as those performed when a worker steals a task and | ||
| 258 | * notices that there are more tasks too; together these cover the | ||
| 259 | * signals needed in cases when more than two tasks are pushed | ||
| 260 | * but untaken. | ||
| 261 | * | ||
| 262 | * Trimming workers. To release resources after periods of lack of | ||
| 263 | * use, a worker starting to wait when the pool is quiescent will | ||
| 264 | * time out and terminate if the pool has remained quiescent for | ||
| 265 | * SHRINK_RATE nanosecs. This will slowly propagate, eventually | ||
| 266 | * terminating all workers after long periods of non-use. | ||
| 267 | * | ||
| 268 | * Submissions. External submissions are maintained in an | ||
| 269 | * array-based queue that is structured identically to | ||
| 270 | * ForkJoinWorkerThread queues except for the use of | ||
| 271 | * submissionLock in method addSubmission. Unlike the case for | ||
| 272 | * worker queues, multiple external threads can add new | ||
| 273 | * submissions, so adding requires a lock. | ||
| 274 | * | ||
| 275 | * Compensation. Beyond work-stealing support and lifecycle | ||
| 276 | * control, the main responsibility of this framework is to take | ||
| 277 | * actions when one worker is waiting to join a task stolen (or | ||
| 278 | * always held by) another. Because we are multiplexing many | ||
| 279 | * tasks on to a pool of workers, we can't just let them block (as | ||
| 280 | * in Thread.join). We also cannot just reassign the joiner's | ||
| 281 | * run-time stack with another and replace it later, which would | ||
| 282 | * be a form of "continuation", that even if possible is not | ||
| 283 | * necessarily a good idea since we sometimes need both an | ||
| 284 | * unblocked task and its continuation to progress. Instead we | ||
| 285 | * combine two tactics: | ||
| 286 | * | ||
| 287 | * Helping: Arranging for the joiner to execute some task that it | ||
| 288 | * would be running if the steal had not occurred. Method | ||
| 289 | * ForkJoinWorkerThread.joinTask tracks joining->stealing | ||
| 290 | * links to try to find such a task. | ||
| 291 | * | ||
| 292 | * Compensating: Unless there are already enough live threads, | ||
| 293 | * method tryPreBlock() may create or re-activate a spare | ||
| 294 | * thread to compensate for blocked joiners until they | ||
| 295 | * unblock. | ||
| 296 | * | ||
| 297 | * The ManagedBlocker extension API can't use helping so relies | ||
| 298 | * only on compensation in method awaitBlocker. | ||
| 299 | * | ||
| 300 | * It is impossible to keep exactly the target parallelism number | ||
| 301 | * of threads running at any given time. Determining the | ||
| 302 | * existence of conservatively safe helping targets, the | ||
| 303 | * availability of already-created spares, and the apparent need | ||
| 304 | * to create new spares are all racy and require heuristic | ||
| 305 | * guidance, so we rely on multiple retries of each. Currently, | ||
| 306 | * in keeping with on-demand signalling policy, we compensate only | ||
| 307 | * if blocking would leave less than one active (non-waiting, | ||
| 308 | * non-blocked) worker. Additionally, to avoid some false alarms | ||
| 309 | * due to GC, lagging counters, system activity, etc, compensated | ||
| 310 | * blocking for joins is only attempted after rechecks stabilize | ||
| 311 | * (retries are interspersed with Thread.yield, for good | ||
| 312 | * citizenship). The variable blockedCount, incremented before | ||
| 313 | * blocking and decremented after, is sometimes needed to | ||
| 314 | * distinguish cases of waiting for work vs blocking on joins or | ||
| 315 | * other managed sync. Both cases are equivalent for most pool | ||
| 316 | * control, so we can update non-atomically. (Additionally, | ||
| 317 | * contention on blockedCount alleviates some contention on ctl). | ||
| 318 | * | ||
| 319 | * Shutdown and Termination. A call to shutdownNow atomically sets | ||
| 320 | * the ctl stop bit and then (non-atomically) sets each workers | ||
| 321 | * "terminate" status, cancels all unprocessed tasks, and wakes up | ||
| 322 | * all waiting workers. Detecting whether termination should | ||
| 323 | * commence after a non-abrupt shutdown() call requires more work | ||
| 324 | * and bookkeeping. We need consensus about quiesence (i.e., that | ||
| 325 | * there is no more work) which is reflected in active counts so | ||
| 326 | * long as there are no current blockers, as well as possible | ||
| 327 | * re-evaluations during independent changes in blocking or | ||
| 328 | * quiescing workers. | ||
| 329 | * | ||
| 330 | * Style notes: There is a lot of representation-level coupling | ||
| 331 | * among classes ForkJoinPool, ForkJoinWorkerThread, and | ||
| 332 | * ForkJoinTask. Most fields of ForkJoinWorkerThread maintain | ||
| 333 | * data structures managed by ForkJoinPool, so are directly | ||
| 334 | * accessed. Conversely we allow access to "workers" array by | ||
| 335 | * workers, and direct access to ForkJoinTask.status by both | ||
| 336 | * ForkJoinPool and ForkJoinWorkerThread. There is little point | ||
| 337 | * trying to reduce this, since any associated future changes in | ||
| 338 | * representations will need to be accompanied by algorithmic | ||
| 339 | * changes anyway. All together, these low-level implementation | ||
| 340 | * choices produce as much as a factor of 4 performance | ||
| 341 | * improvement compared to naive implementations, and enable the | ||
| 342 | * processing of billions of tasks per second, at the expense of | ||
| 343 | * some ugliness. | ||
| 344 | * | ||
| 345 | * Methods signalWork() and scan() are the main bottlenecks so are | ||
| 346 | * especially heavily micro-optimized/mangled. There are lots of | ||
| 347 | * inline assignments (of form "while ((local = field) != 0)") | ||
| 348 | * which are usually the simplest way to ensure the required read | ||
| 349 | * orderings (which are sometimes critical). This leads to a | ||
| 350 | * "C"-like style of listing declarations of these locals at the | ||
| 351 | * heads of methods or blocks. There are several occurrences of | ||
| 352 | * the unusual "do {} while (!cas...)" which is the simplest way | ||
| 353 | * to force an update of a CAS'ed variable. There are also other | ||
| 354 | * coding oddities that help some methods perform reasonably even | ||
| 355 | * when interpreted (not compiled). | ||
| 356 | * | ||
| 357 | * The order of declarations in this file is: (1) declarations of | ||
| 358 | * statics (2) fields (along with constants used when unpacking | ||
| 359 | * some of them), listed in an order that tends to reduce | ||
| 360 | * contention among them a bit under most JVMs. (3) internal | ||
| 361 | * control methods (4) callbacks and other support for | ||
| 362 | * ForkJoinTask and ForkJoinWorkerThread classes, (5) exported | ||
| 363 | * methods (plus a few little helpers). (6) static block | ||
| 364 | * initializing all statics in a minimally dependent order. | ||
| 365 | */ | ||
| 366 | |||
| 367 | /** | ||
| 368 | * Factory for creating new {@link ForkJoinWorkerThread}s. | ||
| 369 | * A {@code ForkJoinWorkerThreadFactory} must be defined and used | ||
| 370 | * for {@code ForkJoinWorkerThread} subclasses that extend base | ||
| 371 | * functionality or initialize threads with different contexts. | ||
| 372 | */ | ||
| 373 | public static interface ForkJoinWorkerThreadFactory { | ||
| 374 | /** | ||
| 375 | * Returns a new worker thread operating in the given pool. | ||
| 376 | * | ||
| 377 | * @param pool the pool this thread works in | ||
| 378 | * @throws NullPointerException if the pool is null | ||
| 379 | */ | ||
| 380 | public ForkJoinWorkerThread newThread(ForkJoinPool pool); | ||
| 381 | } | ||
| 382 | |||
| 383 | /** | ||
| 384 | * Default ForkJoinWorkerThreadFactory implementation; creates a | ||
| 385 | * new ForkJoinWorkerThread. | ||
| 386 | */ | ||
| 387 | static class DefaultForkJoinWorkerThreadFactory | ||
| 388 | implements ForkJoinWorkerThreadFactory { | ||
| 389 | public ForkJoinWorkerThread newThread(ForkJoinPool pool) { | ||
| 390 | return new ForkJoinWorkerThread(pool); | ||
| 391 | } | ||
| 392 | } | ||
| 393 | |||
| 394 | /** | ||
| 395 | * Creates a new ForkJoinWorkerThread. This factory is used unless | ||
| 396 | * overridden in ForkJoinPool constructors. | ||
| 397 | */ | ||
| 398 | public static final ForkJoinWorkerThreadFactory | ||
| 399 | defaultForkJoinWorkerThreadFactory; | ||
| 400 | |||
| 401 | /** | ||
| 402 | * Permission required for callers of methods that may start or | ||
| 403 | * kill threads. | ||
| 404 | */ | ||
| 405 | private static final RuntimePermission modifyThreadPermission; | ||
| 406 | |||
| 407 | /** | ||
| 408 | * If there is a security manager, makes sure caller has | ||
| 409 | * permission to modify threads. | ||
| 410 | */ | ||
| 411 | private static void checkPermission() { | ||
| 412 | SecurityManager security = System.getSecurityManager(); | ||
| 413 | if (security != null) | ||
| 414 | security.checkPermission(modifyThreadPermission); | ||
| 415 | } | ||
| 416 | |||
| 417 | /** | ||
| 418 | * Generator for assigning sequence numbers as pool names. | ||
| 419 | */ | ||
| 420 | private static final AtomicInteger poolNumberGenerator; | ||
| 421 | |||
| 422 | /** | ||
| 423 | * Generator for initial random seeds for worker victim | ||
| 424 | * selection. This is used only to create initial seeds. Random | ||
| 425 | * steals use a cheaper xorshift generator per steal attempt. We | ||
| 426 | * don't expect much contention on seedGenerator, so just use a | ||
| 427 | * plain Random. | ||
| 428 | */ | ||
| 429 | static final Random workerSeedGenerator; | ||
| 430 | |||
| 431 | /** | ||
| 432 | * Array holding all worker threads in the pool. Initialized upon | ||
| 433 | * construction. Array size must be a power of two. Updates and | ||
| 434 | * replacements are protected by scanGuard, but the array is | ||
| 435 | * always kept in a consistent enough state to be randomly | ||
| 436 | * accessed without locking by workers performing work-stealing, | ||
| 437 | * as well as other traversal-based methods in this class, so long | ||
| 438 | * as reads memory-acquire by first reading ctl. All readers must | ||
| 439 | * tolerate that some array slots may be null. | ||
| 440 | */ | ||
| 441 | ForkJoinWorkerThread[] workers; | ||
| 442 | |||
| 443 | /** | ||
| 444 | * Initial size for submission queue array. Must be a power of | ||
| 445 | * two. In many applications, these always stay small so we use a | ||
| 446 | * small initial cap. | ||
| 447 | */ | ||
| 448 | private static final int INITIAL_QUEUE_CAPACITY = 8; | ||
| 449 | |||
| 450 | /** | ||
| 451 | * Maximum size for submission queue array. Must be a power of two | ||
| 452 | * less than or equal to 1 << (31 - width of array entry) to | ||
| 453 | * ensure lack of index wraparound, but is capped at a lower | ||
| 454 | * value to help users trap runaway computations. | ||
| 455 | */ | ||
| 456 | private static final int MAXIMUM_QUEUE_CAPACITY = 1 << 24; // 16M | ||
| 457 | |||
| 458 | /** | ||
| 459 | * Array serving as submission queue. Initialized upon construction. | ||
| 460 | */ | ||
| 461 | private ForkJoinTask<?>[] submissionQueue; | ||
| 462 | |||
| 463 | /** | ||
| 464 | * Lock protecting submissions array for addSubmission | ||
| 465 | */ | ||
| 466 | private final ReentrantLock submissionLock; | ||
| 467 | |||
| 468 | /** | ||
| 469 | * Condition for awaitTermination, using submissionLock for | ||
| 470 | * convenience. | ||
| 471 | */ | ||
| 472 | private final Condition termination; | ||
| 473 | |||
| 474 | /** | ||
| 475 | * Creation factory for worker threads. | ||
| 476 | */ | ||
| 477 | private final ForkJoinWorkerThreadFactory factory; | ||
| 478 | |||
| 479 | /** | ||
| 480 | * The uncaught exception handler used when any worker abruptly | ||
| 481 | * terminates. | ||
| 482 | */ | ||
| 483 | final Thread.UncaughtExceptionHandler ueh; | ||
| 484 | |||
| 485 | /** | ||
| 486 | * Prefix for assigning names to worker threads | ||
| 487 | */ | ||
| 488 | private final String workerNamePrefix; | ||
| 489 | |||
| 490 | /** | ||
| 491 | * Sum of per-thread steal counts, updated only when threads are | ||
| 492 | * idle or terminating. | ||
| 493 | */ | ||
| 494 | private volatile long stealCount; | ||
| 495 | |||
| 496 | /** | ||
| 497 | * Main pool control -- a long packed with: | ||
| 498 | * AC: Number of active running workers minus target parallelism (16 bits) | ||
| 499 | * TC: Number of total workers minus target parallelism (16bits) | ||
| 500 | * ST: true if pool is terminating (1 bit) | ||
| 501 | * EC: the wait count of top waiting thread (15 bits) | ||
| 502 | * ID: ~poolIndex of top of Treiber stack of waiting threads (16 bits) | ||
| 503 | * | ||
| 504 | * When convenient, we can extract the upper 32 bits of counts and | ||
| 505 | * the lower 32 bits of queue state, u = (int)(ctl >>> 32) and e = | ||
| 506 | * (int)ctl. The ec field is never accessed alone, but always | ||
| 507 | * together with id and st. The offsets of counts by the target | ||
| 508 | * parallelism and the positionings of fields makes it possible to | ||
| 509 | * perform the most common checks via sign tests of fields: When | ||
| 510 | * ac is negative, there are not enough active workers, when tc is | ||
| 511 | * negative, there are not enough total workers, when id is | ||
| 512 | * negative, there is at least one waiting worker, and when e is | ||
| 513 | * negative, the pool is terminating. To deal with these possibly | ||
| 514 | * negative fields, we use casts in and out of "short" and/or | ||
| 515 | * signed shifts to maintain signedness. | ||
| 516 | */ | ||
| 517 | volatile long ctl; | ||
| 518 | |||
| 519 | // bit positions/shifts for fields | ||
| 520 | private static final int AC_SHIFT = 48; | ||
| 521 | private static final int TC_SHIFT = 32; | ||
| 522 | private static final int ST_SHIFT = 31; | ||
| 523 | private static final int EC_SHIFT = 16; | ||
| 524 | |||
| 525 | // bounds | ||
| 526 | private static final int MAX_ID = 0x7fff; // max poolIndex | ||
| 527 | private static final int SMASK = 0xffff; // mask short bits | ||
| 528 | private static final int SHORT_SIGN = 1 << 15; | ||
| 529 | private static final int INT_SIGN = 1 << 31; | ||
| 530 | |||
| 531 | // masks | ||
| 532 | private static final long STOP_BIT = 0x0001L << ST_SHIFT; | ||
| 533 | private static final long AC_MASK = ((long)SMASK) << AC_SHIFT; | ||
| 534 | private static final long TC_MASK = ((long)SMASK) << TC_SHIFT; | ||
| 535 | |||
| 536 | // units for incrementing and decrementing | ||
| 537 | private static final long TC_UNIT = 1L << TC_SHIFT; | ||
| 538 | private static final long AC_UNIT = 1L << AC_SHIFT; | ||
| 539 | |||
| 540 | // masks and units for dealing with u = (int)(ctl >>> 32) | ||
| 541 | private static final int UAC_SHIFT = AC_SHIFT - 32; | ||
| 542 | private static final int UTC_SHIFT = TC_SHIFT - 32; | ||
| 543 | private static final int UAC_MASK = SMASK << UAC_SHIFT; | ||
| 544 | private static final int UTC_MASK = SMASK << UTC_SHIFT; | ||
| 545 | private static final int UAC_UNIT = 1 << UAC_SHIFT; | ||
| 546 | private static final int UTC_UNIT = 1 << UTC_SHIFT; | ||
| 547 | |||
| 548 | // masks and units for dealing with e = (int)ctl | ||
| 549 | private static final int E_MASK = 0x7fffffff; // no STOP_BIT | ||
| 550 | private static final int EC_UNIT = 1 << EC_SHIFT; | ||
| 551 | |||
| 552 | /** | ||
| 553 | * The target parallelism level. | ||
| 554 | */ | ||
| 555 | final int parallelism; | ||
| 556 | |||
| 557 | /** | ||
| 558 | * Index (mod submission queue length) of next element to take | ||
| 559 | * from submission queue. Usage is identical to that for | ||
| 560 | * per-worker queues -- see ForkJoinWorkerThread internal | ||
| 561 | * documentation. | ||
| 562 | */ | ||
| 563 | volatile int queueBase; | ||
| 564 | |||
| 565 | /** | ||
| 566 | * Index (mod submission queue length) of next element to add | ||
| 567 | * in submission queue. Usage is identical to that for | ||
| 568 | * per-worker queues -- see ForkJoinWorkerThread internal | ||
| 569 | * documentation. | ||
| 570 | */ | ||
| 571 | int queueTop; | ||
| 572 | |||
| 573 | /** | ||
| 574 | * True when shutdown() has been called. | ||
| 575 | */ | ||
| 576 | volatile boolean shutdown; | ||
| 577 | |||
| 578 | /** | ||
| 579 | * True if use local fifo, not default lifo, for local polling | ||
| 580 | * Read by, and replicated by ForkJoinWorkerThreads | ||
| 581 | */ | ||
| 582 | final boolean locallyFifo; | ||
| 583 | |||
| 584 | /** | ||
| 585 | * The number of threads in ForkJoinWorkerThreads.helpQuiescePool. | ||
| 586 | * When non-zero, suppresses automatic shutdown when active | ||
| 587 | * counts become zero. | ||
| 588 | */ | ||
| 589 | volatile int quiescerCount; | ||
| 590 | |||
| 591 | /** | ||
| 592 | * The number of threads blocked in join. | ||
| 593 | */ | ||
| 594 | volatile int blockedCount; | ||
| 595 | |||
| 596 | /** | ||
| 597 | * Counter for worker Thread names (unrelated to their poolIndex) | ||
| 598 | */ | ||
| 599 | private volatile int nextWorkerNumber; | ||
| 600 | |||
| 601 | /** | ||
| 602 | * The index for the next created worker. Accessed under scanGuard. | ||
| 603 | */ | ||
| 604 | private int nextWorkerIndex; | ||
| 605 | |||
| 606 | /** | ||
| 607 | * SeqLock and index masking for updates to workers array. Locked | ||
| 608 | * when SG_UNIT is set. Unlocking clears bit by adding | ||
| 609 | * SG_UNIT. Staleness of read-only operations can be checked by | ||
| 610 | * comparing scanGuard to value before the reads. The low 16 bits | ||
| 611 | * (i.e, anding with SMASK) hold (the smallest power of two | ||
| 612 | * covering all worker indices, minus one, and is used to avoid | ||
| 613 | * dealing with large numbers of null slots when the workers array | ||
| 614 | * is overallocated. | ||
| 615 | */ | ||
| 616 | volatile int scanGuard; | ||
| 617 | |||
| 618 | private static final int SG_UNIT = 1 << 16; | ||
| 619 | |||
| 620 | /** | ||
| 621 | * The wakeup interval (in nanoseconds) for a worker waiting for a | ||
| 622 | * task when the pool is quiescent to instead try to shrink the | ||
| 623 | * number of workers. The exact value does not matter too | ||
| 624 | * much. It must be short enough to release resources during | ||
| 625 | * sustained periods of idleness, but not so short that threads | ||
| 626 | * are continually re-created. | ||
| 627 | */ | ||
| 628 | private static final long SHRINK_RATE = | ||
| 629 | 4L * 1000L * 1000L * 1000L; // 4 seconds | ||
| 630 | |||
| 631 | /** | ||
| 632 | * Top-level loop for worker threads: On each step: if the | ||
| 633 | * previous step swept through all queues and found no tasks, or | ||
| 634 | * there are excess threads, then possibly blocks. Otherwise, | ||
| 635 | * scans for and, if found, executes a task. Returns when pool | ||
| 636 | * and/or worker terminate. | ||
| 637 | * | ||
| 638 | * @param w the worker | ||
| 639 | */ | ||
| 640 | final void work(ForkJoinWorkerThread w) { | ||
| 641 | boolean swept = false; // true on empty scans | ||
| 642 | long c; | ||
| 643 | while (!w.terminate && (int)(c = ctl) >= 0) { | ||
| 644 | int a; // active count | ||
| 645 | if (!swept && (a = (int)(c >> AC_SHIFT)) <= 0) | ||
| 646 | swept = scan(w, a); | ||
| 647 | else if (tryAwaitWork(w, c)) | ||
| 648 | swept = false; | ||
| 649 | } | ||
| 650 | } | ||
| 651 | |||
| 652 | // Signalling | ||
| 653 | |||
| 654 | /** | ||
| 655 | * Wakes up or creates a worker. | ||
| 656 | */ | ||
| 657 | final void signalWork() { | ||
| 658 | /* | ||
| 659 | * The while condition is true if: (there is are too few total | ||
| 660 | * workers OR there is at least one waiter) AND (there are too | ||
| 661 | * few active workers OR the pool is terminating). The value | ||
| 662 | * of e distinguishes the remaining cases: zero (no waiters) | ||
| 663 | * for create, negative if terminating (in which case do | ||
| 664 | * nothing), else release a waiter. The secondary checks for | ||
| 665 | * release (non-null array etc) can fail if the pool begins | ||
| 666 | * terminating after the test, and don't impose any added cost | ||
| 667 | * because JVMs must perform null and bounds checks anyway. | ||
| 668 | */ | ||
| 669 | long c; int e, u; | ||
| 670 | while ((((e = (int)(c = ctl)) | (u = (int)(c >>> 32))) & | ||
| 671 | (INT_SIGN|SHORT_SIGN)) == (INT_SIGN|SHORT_SIGN) && e >= 0) { | ||
| 672 | if (e > 0) { // release a waiting worker | ||
| 673 | int i; ForkJoinWorkerThread w; ForkJoinWorkerThread[] ws; | ||
| 674 | if ((ws = workers) == null || | ||
| 675 | (i = ~e & SMASK) >= ws.length || | ||
| 676 | (w = ws[i]) == null) | ||
| 677 | break; | ||
| 678 | long nc = (((long)(w.nextWait & E_MASK)) | | ||
| 679 | ((long)(u + UAC_UNIT) << 32)); | ||
| 680 | if (w.eventCount == e && | ||
| 681 | UNSAFE.compareAndSwapLong(this, ctlOffset, c, nc)) { | ||
| 682 | w.eventCount = (e + EC_UNIT) & E_MASK; | ||
| 683 | if (w.parked) | ||
| 684 | UNSAFE.unpark(w); | ||
| 685 | break; | ||
| 686 | } | ||
| 687 | } | ||
| 688 | else if (UNSAFE.compareAndSwapLong | ||
| 689 | (this, ctlOffset, c, | ||
| 690 | (long)(((u + UTC_UNIT) & UTC_MASK) | | ||
| 691 | ((u + UAC_UNIT) & UAC_MASK)) << 32)) { | ||
| 692 | addWorker(); | ||
| 693 | break; | ||
| 694 | } | ||
| 695 | } | ||
| 696 | } | ||
| 697 | |||
| 698 | /** | ||
| 699 | * Variant of signalWork to help release waiters on rescans. | ||
| 700 | * Tries once to release a waiter if active count < 0. | ||
| 701 | * | ||
| 702 | * @return false if failed due to contention, else true | ||
| 703 | */ | ||
| 704 | private boolean tryReleaseWaiter() { | ||
| 705 | long c; int e, i; ForkJoinWorkerThread w; ForkJoinWorkerThread[] ws; | ||
| 706 | if ((e = (int)(c = ctl)) > 0 && | ||
| 707 | (int)(c >> AC_SHIFT) < 0 && | ||
| 708 | (ws = workers) != null && | ||
| 709 | (i = ~e & SMASK) < ws.length && | ||
| 710 | (w = ws[i]) != null) { | ||
| 711 | long nc = ((long)(w.nextWait & E_MASK) | | ||
| 712 | ((c + AC_UNIT) & (AC_MASK|TC_MASK))); | ||
| 713 | if (w.eventCount != e || | ||
| 714 | !UNSAFE.compareAndSwapLong(this, ctlOffset, c, nc)) | ||
| 715 | return false; | ||
| 716 | w.eventCount = (e + EC_UNIT) & E_MASK; | ||
| 717 | if (w.parked) | ||
| 718 | UNSAFE.unpark(w); | ||
| 719 | } | ||
| 720 | return true; | ||
| 721 | } | ||
| 722 | |||
| 723 | // Scanning for tasks | ||
| 724 | |||
| 725 | /** | ||
| 726 | * Scans for and, if found, executes one task. Scans start at a | ||
| 727 | * random index of workers array, and randomly select the first | ||
| 728 | * (2*#workers)-1 probes, and then, if all empty, resort to 2 | ||
| 729 | * circular sweeps, which is necessary to check quiescence. and | ||
| 730 | * taking a submission only if no stealable tasks were found. The | ||
| 731 | * steal code inside the loop is a specialized form of | ||
| 732 | * ForkJoinWorkerThread.deqTask, followed bookkeeping to support | ||
| 733 | * helpJoinTask and signal propagation. The code for submission | ||
| 734 | * queues is almost identical. On each steal, the worker completes | ||
| 735 | * not only the task, but also all local tasks that this task may | ||
| 736 | * have generated. On detecting staleness or contention when | ||
| 737 | * trying to take a task, this method returns without finishing | ||
| 738 | * sweep, which allows global state rechecks before retry. | ||
| 739 | * | ||
| 740 | * @param w the worker | ||
| 741 | * @param a the number of active workers | ||
| 742 | * @return true if swept all queues without finding a task | ||
| 743 | */ | ||
| 744 | private boolean scan(ForkJoinWorkerThread w, int a) { | ||
| 745 | int g = scanGuard; // mask 0 avoids useless scans if only one active | ||
| 746 | int m = (parallelism == 1 - a && blockedCount == 0) ? 0 : g & SMASK; | ||
| 747 | ForkJoinWorkerThread[] ws = workers; | ||
| 748 | if (ws == null || ws.length <= m) // staleness check | ||
| 749 | return false; | ||
| 750 | for (int r = w.seed, k = r, j = -(m + m); j <= m + m; ++j) { | ||
| 751 | ForkJoinTask<?> t; ForkJoinTask<?>[] q; int b, i; | ||
| 752 | ForkJoinWorkerThread v = ws[k & m]; | ||
| 753 | if (v != null && (b = v.queueBase) != v.queueTop && | ||
| 754 | (q = v.queue) != null && (i = (q.length - 1) & b) >= 0) { | ||
| 755 | long u = (i << ASHIFT) + ABASE; | ||
| 756 | if ((t = q[i]) != null && v.queueBase == b && | ||
| 757 | UNSAFE.compareAndSwapObject(q, u, t, null)) { | ||
| 758 | int d = (v.queueBase = b + 1) - v.queueTop; | ||
| 759 | v.stealHint = w.poolIndex; | ||
| 760 | if (d != 0) | ||
| 761 | signalWork(); // propagate if nonempty | ||
| 762 | w.execTask(t); | ||
| 763 | } | ||
| 764 | r ^= r << 13; r ^= r >>> 17; w.seed = r ^ (r << 5); | ||
| 765 | return false; // store next seed | ||
| 766 | } | ||
| 767 | else if (j < 0) { // xorshift | ||
| 768 | r ^= r << 13; r ^= r >>> 17; k = r ^= r << 5; | ||
| 769 | } | ||
| 770 | else | ||
| 771 | ++k; | ||
| 772 | } | ||
| 773 | if (scanGuard != g) // staleness check | ||
| 774 | return false; | ||
| 775 | else { // try to take submission | ||
| 776 | ForkJoinTask<?> t; ForkJoinTask<?>[] q; int b, i; | ||
| 777 | if ((b = queueBase) != queueTop && | ||
| 778 | (q = submissionQueue) != null && | ||
| 779 | (i = (q.length - 1) & b) >= 0) { | ||
| 780 | long u = (i << ASHIFT) + ABASE; | ||
| 781 | if ((t = q[i]) != null && queueBase == b && | ||
| 782 | UNSAFE.compareAndSwapObject(q, u, t, null)) { | ||
| 783 | queueBase = b + 1; | ||
| 784 | w.execTask(t); | ||
| 785 | } | ||
| 786 | return false; | ||
| 787 | } | ||
| 788 | return true; // all queues empty | ||
| 789 | } | ||
| 790 | } | ||
| 791 | |||
| 792 | /** | ||
| 793 | * Tries to enqueue worker w in wait queue and await change in | ||
| 794 | * worker's eventCount. If the pool is quiescent and there is | ||
| 795 | * more than one worker, possibly terminates worker upon exit. | ||
| 796 | * Otherwise, before blocking, rescans queues to avoid missed | ||
| 797 | * signals. Upon finding work, releases at least one worker | ||
| 798 | * (which may be the current worker). Rescans restart upon | ||
| 799 | * detected staleness or failure to release due to | ||
| 800 | * contention. Note the unusual conventions about Thread.interrupt | ||
| 801 | * here and elsewhere: Because interrupts are used solely to alert | ||
| 802 | * threads to check termination, which is checked here anyway, we | ||
| 803 | * clear status (using Thread.interrupted) before any call to | ||
| 804 | * park, so that park does not immediately return due to status | ||
| 805 | * being set via some other unrelated call to interrupt in user | ||
| 806 | * code. | ||
| 807 | * | ||
| 808 | * @param w the calling worker | ||
| 809 | * @param c the ctl value on entry | ||
| 810 | * @return true if waited or another thread was released upon enq | ||
| 811 | */ | ||
| 812 | private boolean tryAwaitWork(ForkJoinWorkerThread w, long c) { | ||
| 813 | int v = w.eventCount; | ||
| 814 | w.nextWait = (int)c; // w's successor record | ||
| 815 | long nc = (long)(v & E_MASK) | ((c - AC_UNIT) & (AC_MASK|TC_MASK)); | ||
| 816 | if (ctl != c || !UNSAFE.compareAndSwapLong(this, ctlOffset, c, nc)) { | ||
| 817 | long d = ctl; // return true if lost to a deq, to force scan | ||
| 818 | return (int)d != (int)c && ((d - c) & AC_MASK) >= 0L; | ||
| 819 | } | ||
| 820 | for (int sc = w.stealCount; sc != 0;) { // accumulate stealCount | ||
| 821 | long s = stealCount; | ||
| 822 | if (UNSAFE.compareAndSwapLong(this, stealCountOffset, s, s + sc)) | ||
| 823 | sc = w.stealCount = 0; | ||
| 824 | else if (w.eventCount != v) | ||
| 825 | return true; // update next time | ||
| 826 | } | ||
| 827 | if ((!shutdown || !tryTerminate(false)) && | ||
| 828 | (int)c != 0 && parallelism + (int)(nc >> AC_SHIFT) == 0 && | ||
| 829 | blockedCount == 0 && quiescerCount == 0) | ||
| 830 | idleAwaitWork(w, nc, c, v); // quiescent | ||
| 831 | for (boolean rescanned = false;;) { | ||
| 832 | if (w.eventCount != v) | ||
| 833 | return true; | ||
| 834 | if (!rescanned) { | ||
| 835 | int g = scanGuard, m = g & SMASK; | ||
| 836 | ForkJoinWorkerThread[] ws = workers; | ||
| 837 | if (ws != null && m < ws.length) { | ||
| 838 | rescanned = true; | ||
| 839 | for (int i = 0; i <= m; ++i) { | ||
| 840 | ForkJoinWorkerThread u = ws[i]; | ||
| 841 | if (u != null) { | ||
| 842 | if (u.queueBase != u.queueTop && | ||
| 843 | !tryReleaseWaiter()) | ||
| 844 | rescanned = false; // contended | ||
| 845 | if (w.eventCount != v) | ||
| 846 | return true; | ||
| 847 | } | ||
| 848 | } | ||
| 849 | } | ||
| 850 | if (scanGuard != g || // stale | ||
| 851 | (queueBase != queueTop && !tryReleaseWaiter())) | ||
| 852 | rescanned = false; | ||
| 853 | if (!rescanned) | ||
| 854 | Thread.yield(); // reduce contention | ||
| 855 | else | ||
| 856 | Thread.interrupted(); // clear before park | ||
| 857 | } | ||
| 858 | else { | ||
| 859 | w.parked = true; // must recheck | ||
| 860 | if (w.eventCount != v) { | ||
| 861 | w.parked = false; | ||
| 862 | return true; | ||
| 863 | } | ||
| 864 | LockSupport.park(this); | ||
| 865 | rescanned = w.parked = false; | ||
| 866 | } | ||
| 867 | } | ||
| 868 | } | ||
| 869 | |||
| 870 | /** | ||
| 871 | * If inactivating worker w has caused pool to become | ||
| 872 | * quiescent, check for pool termination, and wait for event | ||
| 873 | * for up to SHRINK_RATE nanosecs (rescans are unnecessary in | ||
| 874 | * this case because quiescence reflects consensus about lack | ||
| 875 | * of work). On timeout, if ctl has not changed, terminate the | ||
| 876 | * worker. Upon its termination (see deregisterWorker), it may | ||
| 877 | * wake up another worker to possibly repeat this process. | ||
| 878 | * | ||
| 879 | * @param w the calling worker | ||
| 880 | * @param currentCtl the ctl value after enqueuing w | ||
| 881 | * @param prevCtl the ctl value if w terminated | ||
| 882 | * @param v the eventCount w awaits change | ||
| 883 | */ | ||
| 884 | private void idleAwaitWork(ForkJoinWorkerThread w, long currentCtl, | ||
| 885 | long prevCtl, int v) { | ||
| 886 | if (w.eventCount == v) { | ||
| 887 | if (shutdown) | ||
| 888 | tryTerminate(false); | ||
| 889 | ForkJoinTask.helpExpungeStaleExceptions(); // help clean weak refs | ||
| 890 | while (ctl == currentCtl) { | ||
| 891 | long startTime = System.nanoTime(); | ||
| 892 | w.parked = true; | ||
| 893 | if (w.eventCount == v) // must recheck | ||
| 894 | LockSupport.parkNanos(this, SHRINK_RATE); | ||
| 895 | w.parked = false; | ||
| 896 | if (w.eventCount != v) | ||
| 897 | break; | ||
| 898 | else if (System.nanoTime() - startTime < | ||
| 899 | SHRINK_RATE - (SHRINK_RATE / 10)) // timing slop | ||
| 900 | Thread.interrupted(); // spurious wakeup | ||
| 901 | else if (UNSAFE.compareAndSwapLong(this, ctlOffset, | ||
| 902 | currentCtl, prevCtl)) { | ||
| 903 | w.terminate = true; // restore previous | ||
| 904 | w.eventCount = ((int)currentCtl + EC_UNIT) & E_MASK; | ||
| 905 | break; | ||
| 906 | } | ||
| 907 | } | ||
| 908 | } | ||
| 909 | } | ||
| 910 | |||
| 911 | // Submissions | ||
| 912 | |||
| 913 | /** | ||
| 914 | * Enqueues the given task in the submissionQueue. Same idea as | ||
| 915 | * ForkJoinWorkerThread.pushTask except for use of submissionLock. | ||
| 916 | * | ||
| 917 | * @param t the task | ||
| 918 | */ | ||
| 919 | private void addSubmission(ForkJoinTask<?> t) { | ||
| 920 | final ReentrantLock lock = this.submissionLock; | ||
| 921 | lock.lock(); | ||
| 922 | try { | ||
| 923 | ForkJoinTask<?>[] q; int s, m; | ||
| 924 | if ((q = submissionQueue) != null) { // ignore if queue removed | ||
| 925 | long u = (((s = queueTop) & (m = q.length-1)) << ASHIFT)+ABASE; | ||
| 926 | UNSAFE.putOrderedObject(q, u, t); | ||
| 927 | queueTop = s + 1; | ||
| 928 | if (s - queueBase == m) | ||
| 929 | growSubmissionQueue(); | ||
| 930 | } | ||
| 931 | } finally { | ||
| 932 | lock.unlock(); | ||
| 933 | } | ||
| 934 | signalWork(); | ||
| 935 | } | ||
| 936 | |||
| 937 | // (pollSubmission is defined below with exported methods) | ||
| 938 | |||
| 939 | /** | ||
| 940 | * Creates or doubles submissionQueue array. | ||
| 941 | * Basically identical to ForkJoinWorkerThread version. | ||
| 942 | */ | ||
| 943 | private void growSubmissionQueue() { | ||
| 944 | ForkJoinTask<?>[] oldQ = submissionQueue; | ||
| 945 | int size = oldQ != null ? oldQ.length << 1 : INITIAL_QUEUE_CAPACITY; | ||
| 946 | if (size > MAXIMUM_QUEUE_CAPACITY) | ||
| 947 | throw new RejectedExecutionException("Queue capacity exceeded"); | ||
| 948 | if (size < INITIAL_QUEUE_CAPACITY) | ||
| 949 | size = INITIAL_QUEUE_CAPACITY; | ||
| 950 | ForkJoinTask<?>[] q = submissionQueue = new ForkJoinTask<?>[size]; | ||
| 951 | int mask = size - 1; | ||
| 952 | int top = queueTop; | ||
| 953 | int oldMask; | ||
| 954 | if (oldQ != null && (oldMask = oldQ.length - 1) >= 0) { | ||
| 955 | for (int b = queueBase; b != top; ++b) { | ||
| 956 | long u = ((b & oldMask) << ASHIFT) + ABASE; | ||
| 957 | Object x = UNSAFE.getObjectVolatile(oldQ, u); | ||
| 958 | if (x != null && UNSAFE.compareAndSwapObject(oldQ, u, x, null)) | ||
| 959 | UNSAFE.putObjectVolatile | ||
| 960 | (q, ((b & mask) << ASHIFT) + ABASE, x); | ||
| 961 | } | ||
| 962 | } | ||
| 963 | } | ||
| 964 | |||
| 965 | // Blocking support | ||
| 966 | |||
| 967 | /** | ||
| 968 | * Tries to increment blockedCount, decrement active count | ||
| 969 | * (sometimes implicitly) and possibly release or create a | ||
| 970 | * compensating worker in preparation for blocking. Fails | ||
| 971 | * on contention or termination. | ||
| 972 | * | ||
| 973 | * @return true if the caller can block, else should recheck and retry | ||
| 974 | */ | ||
| 975 | private boolean tryPreBlock() { | ||
| 976 | int b = blockedCount; | ||
| 977 | if (UNSAFE.compareAndSwapInt(this, blockedCountOffset, b, b + 1)) { | ||
| 978 | int pc = parallelism; | ||
| 979 | do { | ||
| 980 | ForkJoinWorkerThread[] ws; ForkJoinWorkerThread w; | ||
| 981 | int e, ac, tc, rc, i; | ||
| 982 | long c = ctl; | ||
| 983 | int u = (int)(c >>> 32); | ||
| 984 | if ((e = (int)c) < 0) { | ||
| 985 | // skip -- terminating | ||
| 986 | } | ||
| 987 | else if ((ac = (u >> UAC_SHIFT)) <= 0 && e != 0 && | ||
| 988 | (ws = workers) != null && | ||
| 989 | (i = ~e & SMASK) < ws.length && | ||
| 990 | (w = ws[i]) != null) { | ||
| 991 | long nc = ((long)(w.nextWait & E_MASK) | | ||
| 992 | (c & (AC_MASK|TC_MASK))); | ||
| 993 | if (w.eventCount == e && | ||
| 994 | UNSAFE.compareAndSwapLong(this, ctlOffset, c, nc)) { | ||
| 995 | w.eventCount = (e + EC_UNIT) & E_MASK; | ||
| 996 | if (w.parked) | ||
| 997 | UNSAFE.unpark(w); | ||
| 998 | return true; // release an idle worker | ||
| 999 | } | ||
| 1000 | } | ||
| 1001 | else if ((tc = (short)(u >>> UTC_SHIFT)) >= 0 && ac + pc > 1) { | ||
| 1002 | long nc = ((c - AC_UNIT) & AC_MASK) | (c & ~AC_MASK); | ||
| 1003 | if (UNSAFE.compareAndSwapLong(this, ctlOffset, c, nc)) | ||
| 1004 | return true; // no compensation needed | ||
| 1005 | } | ||
| 1006 | else if (tc + pc < MAX_ID) { | ||
| 1007 | long nc = ((c + TC_UNIT) & TC_MASK) | (c & ~TC_MASK); | ||
| 1008 | if (UNSAFE.compareAndSwapLong(this, ctlOffset, c, nc)) { | ||
| 1009 | addWorker(); | ||
| 1010 | return true; // create a replacement | ||
| 1011 | } | ||
| 1012 | } | ||
| 1013 | // try to back out on any failure and let caller retry | ||
| 1014 | } while (!UNSAFE.compareAndSwapInt(this, blockedCountOffset, | ||
| 1015 | b = blockedCount, b - 1)); | ||
| 1016 | } | ||
| 1017 | return false; | ||
| 1018 | } | ||
| 1019 | |||
| 1020 | /** | ||
| 1021 | * Decrements blockedCount and increments active count | ||
| 1022 | */ | ||
| 1023 | private void postBlock() { | ||
| 1024 | long c; | ||
| 1025 | do {} while (!UNSAFE.compareAndSwapLong(this, ctlOffset, // no mask | ||
| 1026 | c = ctl, c + AC_UNIT)); | ||
| 1027 | int b; | ||
| 1028 | do {} while (!UNSAFE.compareAndSwapInt(this, blockedCountOffset, | ||
| 1029 | b = blockedCount, b - 1)); | ||
| 1030 | } | ||
| 1031 | |||
| 1032 | /** | ||
| 1033 | * Possibly blocks waiting for the given task to complete, or | ||
| 1034 | * cancels the task if terminating. Fails to wait if contended. | ||
| 1035 | * | ||
| 1036 | * @param joinMe the task | ||
| 1037 | */ | ||
| 1038 | final void tryAwaitJoin(ForkJoinTask<?> joinMe) { | ||
| 1039 | int s; | ||
| 1040 | Thread.interrupted(); // clear interrupts before checking termination | ||
| 1041 | if (joinMe.status >= 0) { | ||
| 1042 | if (tryPreBlock()) { | ||
| 1043 | joinMe.tryAwaitDone(0L); | ||
| 1044 | postBlock(); | ||
| 1045 | } | ||
| 1046 | else if ((ctl & STOP_BIT) != 0L) | ||
| 1047 | joinMe.cancelIgnoringExceptions(); | ||
| 1048 | } | ||
| 1049 | } | ||
| 1050 | |||
| 1051 | /** | ||
| 1052 | * Possibly blocks the given worker waiting for joinMe to | ||
| 1053 | * complete or timeout | ||
| 1054 | * | ||
| 1055 | * @param joinMe the task | ||
| 1056 | * @param millis the wait time for underlying Object.wait | ||
| 1057 | */ | ||
| 1058 | final void timedAwaitJoin(ForkJoinTask<?> joinMe, long nanos) { | ||
| 1059 | while (joinMe.status >= 0) { | ||
| 1060 | Thread.interrupted(); | ||
| 1061 | if ((ctl & STOP_BIT) != 0L) { | ||
| 1062 | joinMe.cancelIgnoringExceptions(); | ||
| 1063 | break; | ||
| 1064 | } | ||
| 1065 | if (tryPreBlock()) { | ||
| 1066 | long last = System.nanoTime(); | ||
| 1067 | while (joinMe.status >= 0) { | ||
| 1068 | long millis = TimeUnit.NANOSECONDS.toMillis(nanos); | ||
| 1069 | if (millis <= 0) | ||
| 1070 | break; | ||
| 1071 | joinMe.tryAwaitDone(millis); | ||
| 1072 | if (joinMe.status < 0) | ||
| 1073 | break; | ||
| 1074 | if ((ctl & STOP_BIT) != 0L) { | ||
| 1075 | joinMe.cancelIgnoringExceptions(); | ||
| 1076 | break; | ||
| 1077 | } | ||
| 1078 | long now = System.nanoTime(); | ||
| 1079 | nanos -= now - last; | ||
| 1080 | last = now; | ||
| 1081 | } | ||
| 1082 | postBlock(); | ||
| 1083 | break; | ||
| 1084 | } | ||
| 1085 | } | ||
| 1086 | } | ||
| 1087 | |||
| 1088 | /** | ||
| 1089 | * If necessary, compensates for blocker, and blocks | ||
| 1090 | */ | ||
| 1091 | private void awaitBlocker(ManagedBlocker blocker) | ||
| 1092 | throws InterruptedException { | ||
| 1093 | while (!blocker.isReleasable()) { | ||
| 1094 | if (tryPreBlock()) { | ||
| 1095 | try { | ||
| 1096 | do {} while (!blocker.isReleasable() && !blocker.block()); | ||
| 1097 | } finally { | ||
| 1098 | postBlock(); | ||
| 1099 | } | ||
| 1100 | break; | ||
| 1101 | } | ||
| 1102 | } | ||
| 1103 | } | ||
| 1104 | |||
| 1105 | // Creating, registering and deregistring workers | ||
| 1106 | |||
| 1107 | /** | ||
| 1108 | * Tries to create and start a worker; minimally rolls back counts | ||
| 1109 | * on failure. | ||
| 1110 | */ | ||
| 1111 | private void addWorker() { | ||
| 1112 | Throwable ex = null; | ||
| 1113 | ForkJoinWorkerThread t = null; | ||
| 1114 | try { | ||
| 1115 | t = factory.newThread(this); | ||
| 1116 | } catch (Throwable e) { | ||
| 1117 | ex = e; | ||
| 1118 | } | ||
| 1119 | if (t == null) { // null or exceptional factory return | ||
| 1120 | long c; // adjust counts | ||
| 1121 | do {} while (!UNSAFE.compareAndSwapLong | ||
| 1122 | (this, ctlOffset, c = ctl, | ||
| 1123 | (((c - AC_UNIT) & AC_MASK) | | ||
| 1124 | ((c - TC_UNIT) & TC_MASK) | | ||
| 1125 | (c & ~(AC_MASK|TC_MASK))))); | ||
| 1126 | // Propagate exception if originating from an external caller | ||
| 1127 | if (!tryTerminate(false) && ex != null && | ||
| 1128 | !(Thread.currentThread() instanceof ForkJoinWorkerThread)) | ||
| 1129 | UNSAFE.throwException(ex); | ||
| 1130 | } | ||
| 1131 | else | ||
| 1132 | t.start(); | ||
| 1133 | } | ||
| 1134 | |||
| 1135 | /** | ||
| 1136 | * Callback from ForkJoinWorkerThread constructor to assign a | ||
| 1137 | * public name | ||
| 1138 | */ | ||
| 1139 | final String nextWorkerName() { | ||
| 1140 | for (int n;;) { | ||
| 1141 | if (UNSAFE.compareAndSwapInt(this, nextWorkerNumberOffset, | ||
| 1142 | n = nextWorkerNumber, ++n)) | ||
| 1143 | return workerNamePrefix + n; | ||
| 1144 | } | ||
| 1145 | } | ||
| 1146 | |||
| 1147 | /** | ||
| 1148 | * Callback from ForkJoinWorkerThread constructor to | ||
| 1149 | * determine its poolIndex and record in workers array. | ||
| 1150 | * | ||
| 1151 | * @param w the worker | ||
| 1152 | * @return the worker's pool index | ||
| 1153 | */ | ||
| 1154 | final int registerWorker(ForkJoinWorkerThread w) { | ||
| 1155 | /* | ||
| 1156 | * In the typical case, a new worker acquires the lock, uses | ||
| 1157 | * next available index and returns quickly. Since we should | ||
| 1158 | * not block callers (ultimately from signalWork or | ||
| 1159 | * tryPreBlock) waiting for the lock needed to do this, we | ||
| 1160 | * instead help release other workers while waiting for the | ||
| 1161 | * lock. | ||
| 1162 | */ | ||
| 1163 | for (int g;;) { | ||
| 1164 | ForkJoinWorkerThread[] ws; | ||
| 1165 | if (((g = scanGuard) & SG_UNIT) == 0 && | ||
| 1166 | UNSAFE.compareAndSwapInt(this, scanGuardOffset, | ||
| 1167 | g, g | SG_UNIT)) { | ||
| 1168 | int k = nextWorkerIndex; | ||
| 1169 | try { | ||
| 1170 | if ((ws = workers) != null) { // ignore on shutdown | ||
| 1171 | int n = ws.length; | ||
| 1172 | if (k < 0 || k >= n || ws[k] != null) { | ||
| 1173 | for (k = 0; k < n && ws[k] != null; ++k) | ||
| 1174 | ; | ||
| 1175 | if (k == n) | ||
| 1176 | ws = workers = Arrays.copyOf(ws, n << 1); | ||
| 1177 | } | ||
| 1178 | ws[k] = w; | ||
| 1179 | nextWorkerIndex = k + 1; | ||
| 1180 | int m = g & SMASK; | ||
| 1181 | g = (k > m) ? ((m << 1) + 1) & SMASK : g + (SG_UNIT<<1); | ||
| 1182 | } | ||
| 1183 | } finally { | ||
| 1184 | scanGuard = g; | ||
| 1185 | } | ||
| 1186 | return k; | ||
| 1187 | } | ||
| 1188 | else if ((ws = workers) != null) { // help release others | ||
| 1189 | for (ForkJoinWorkerThread u : ws) { | ||
| 1190 | if (u != null && u.queueBase != u.queueTop) { | ||
| 1191 | if (tryReleaseWaiter()) | ||
| 1192 | break; | ||
| 1193 | } | ||
| 1194 | } | ||
| 1195 | } | ||
| 1196 | } | ||
| 1197 | } | ||
| 1198 | |||
| 1199 | /** | ||
| 1200 | * Final callback from terminating worker. Removes record of | ||
| 1201 | * worker from array, and adjusts counts. If pool is shutting | ||
| 1202 | * down, tries to complete termination. | ||
| 1203 | * | ||
| 1204 | * @param w the worker | ||
| 1205 | */ | ||
| 1206 | final void deregisterWorker(ForkJoinWorkerThread w, Throwable ex) { | ||
| 1207 | int idx = w.poolIndex; | ||
| 1208 | int sc = w.stealCount; | ||
| 1209 | int steps = 0; | ||
| 1210 | // Remove from array, adjust worker counts and collect steal count. | ||
| 1211 | // We can intermix failed removes or adjusts with steal updates | ||
| 1212 | do { | ||
| 1213 | long s, c; | ||
| 1214 | int g; | ||
| 1215 | if (steps == 0 && ((g = scanGuard) & SG_UNIT) == 0 && | ||
| 1216 | UNSAFE.compareAndSwapInt(this, scanGuardOffset, | ||
| 1217 | g, g |= SG_UNIT)) { | ||
| 1218 | ForkJoinWorkerThread[] ws = workers; | ||
| 1219 | if (ws != null && idx >= 0 && | ||
| 1220 | idx < ws.length && ws[idx] == w) | ||
| 1221 | ws[idx] = null; // verify | ||
| 1222 | nextWorkerIndex = idx; | ||
| 1223 | scanGuard = g + SG_UNIT; | ||
| 1224 | steps = 1; | ||
| 1225 | } | ||
| 1226 | if (steps == 1 && | ||
| 1227 | UNSAFE.compareAndSwapLong(this, ctlOffset, c = ctl, | ||
| 1228 | (((c - AC_UNIT) & AC_MASK) | | ||
| 1229 | ((c - TC_UNIT) & TC_MASK) | | ||
| 1230 | (c & ~(AC_MASK|TC_MASK))))) | ||
| 1231 | steps = 2; | ||
| 1232 | if (sc != 0 && | ||
| 1233 | UNSAFE.compareAndSwapLong(this, stealCountOffset, | ||
| 1234 | s = stealCount, s + sc)) | ||
| 1235 | sc = 0; | ||
| 1236 | } while (steps != 2 || sc != 0); | ||
| 1237 | if (!tryTerminate(false)) { | ||
| 1238 | if (ex != null) // possibly replace if died abnormally | ||
| 1239 | signalWork(); | ||
| 1240 | else | ||
| 1241 | tryReleaseWaiter(); | ||
| 1242 | } | ||
| 1243 | } | ||
| 1244 | |||
| 1245 | // Shutdown and termination | ||
| 1246 | |||
| 1247 | /** | ||
| 1248 | * Possibly initiates and/or completes termination. | ||
| 1249 | * | ||
| 1250 | * @param now if true, unconditionally terminate, else only | ||
| 1251 | * if shutdown and empty queue and no active workers | ||
| 1252 | * @return true if now terminating or terminated | ||
| 1253 | */ | ||
| 1254 | private boolean tryTerminate(boolean now) { | ||
| 1255 | long c; | ||
| 1256 | while (((c = ctl) & STOP_BIT) == 0) { | ||
| 1257 | if (!now) { | ||
| 1258 | if ((int)(c >> AC_SHIFT) != -parallelism) | ||
| 1259 | return false; | ||
| 1260 | if (!shutdown || blockedCount != 0 || quiescerCount != 0 || | ||
| 1261 | queueBase != queueTop) { | ||
| 1262 | if (ctl == c) // staleness check | ||
| 1263 | return false; | ||
| 1264 | continue; | ||
| 1265 | } | ||
| 1266 | } | ||
| 1267 | if (UNSAFE.compareAndSwapLong(this, ctlOffset, c, c | STOP_BIT)) | ||
| 1268 | startTerminating(); | ||
| 1269 | } | ||
| 1270 | if ((short)(c >>> TC_SHIFT) == -parallelism) { // signal when 0 workers | ||
| 1271 | final ReentrantLock lock = this.submissionLock; | ||
| 1272 | lock.lock(); | ||
| 1273 | try { | ||
| 1274 | termination.signalAll(); | ||
| 1275 | } finally { | ||
| 1276 | lock.unlock(); | ||
| 1277 | } | ||
| 1278 | } | ||
| 1279 | return true; | ||
| 1280 | } | ||
| 1281 | |||
| 1282 | /** | ||
| 1283 | * Runs up to three passes through workers: (0) Setting | ||
| 1284 | * termination status for each worker, followed by wakeups up to | ||
| 1285 | * queued workers; (1) helping cancel tasks; (2) interrupting | ||
| 1286 | * lagging threads (likely in external tasks, but possibly also | ||
| 1287 | * blocked in joins). Each pass repeats previous steps because of | ||
| 1288 | * potential lagging thread creation. | ||
| 1289 | */ | ||
| 1290 | private void startTerminating() { | ||
| 1291 | cancelSubmissions(); | ||
| 1292 | for (int pass = 0; pass < 3; ++pass) { | ||
| 1293 | ForkJoinWorkerThread[] ws = workers; | ||
| 1294 | if (ws != null) { | ||
| 1295 | for (ForkJoinWorkerThread w : ws) { | ||
| 1296 | if (w != null) { | ||
| 1297 | w.terminate = true; | ||
| 1298 | if (pass > 0) { | ||
| 1299 | w.cancelTasks(); | ||
| 1300 | if (pass > 1 && !w.isInterrupted()) { | ||
| 1301 | try { | ||
| 1302 | w.interrupt(); | ||
| 1303 | } catch (SecurityException ignore) { | ||
| 1304 | } | ||
| 1305 | } | ||
| 1306 | } | ||
| 1307 | } | ||
| 1308 | } | ||
| 1309 | terminateWaiters(); | ||
| 1310 | } | ||
| 1311 | } | ||
| 1312 | } | ||
| 1313 | |||
| 1314 | /** | ||
| 1315 | * Polls and cancels all submissions. Called only during termination. | ||
| 1316 | */ | ||
| 1317 | private void cancelSubmissions() { | ||
| 1318 | while (queueBase != queueTop) { | ||
| 1319 | ForkJoinTask<?> task = pollSubmission(); | ||
| 1320 | if (task != null) { | ||
| 1321 | try { | ||
| 1322 | task.cancel(false); | ||
| 1323 | } catch (Throwable ignore) { | ||
| 1324 | } | ||
| 1325 | } | ||
| 1326 | } | ||
| 1327 | } | ||
| 1328 | |||
| 1329 | /** | ||
| 1330 | * Tries to set the termination status of waiting workers, and | ||
| 1331 | * then wakes them up (after which they will terminate). | ||
| 1332 | */ | ||
| 1333 | private void terminateWaiters() { | ||
| 1334 | ForkJoinWorkerThread[] ws = workers; | ||
| 1335 | if (ws != null) { | ||
| 1336 | ForkJoinWorkerThread w; long c; int i, e; | ||
| 1337 | int n = ws.length; | ||
| 1338 | while ((i = ~(e = (int)(c = ctl)) & SMASK) < n && | ||
| 1339 | (w = ws[i]) != null && w.eventCount == (e & E_MASK)) { | ||
| 1340 | if (UNSAFE.compareAndSwapLong(this, ctlOffset, c, | ||
| 1341 | (long)(w.nextWait & E_MASK) | | ||
| 1342 | ((c + AC_UNIT) & AC_MASK) | | ||
| 1343 | (c & (TC_MASK|STOP_BIT)))) { | ||
| 1344 | w.terminate = true; | ||
| 1345 | w.eventCount = e + EC_UNIT; | ||
| 1346 | if (w.parked) | ||
| 1347 | UNSAFE.unpark(w); | ||
| 1348 | } | ||
| 1349 | } | ||
| 1350 | } | ||
| 1351 | } | ||
| 1352 | |||
| 1353 | // misc ForkJoinWorkerThread support | ||
| 1354 | |||
| 1355 | /** | ||
| 1356 | * Increment or decrement quiescerCount. Needed only to prevent | ||
| 1357 | * triggering shutdown if a worker is transiently inactive while | ||
| 1358 | * checking quiescence. | ||
| 1359 | * | ||
| 1360 | * @param delta 1 for increment, -1 for decrement | ||
| 1361 | */ | ||
| 1362 | final void addQuiescerCount(int delta) { | ||
| 1363 | int c; | ||
| 1364 | do {} while (!UNSAFE.compareAndSwapInt(this, quiescerCountOffset, | ||
| 1365 | c = quiescerCount, c + delta)); | ||
| 1366 | } | ||
| 1367 | |||
| 1368 | /** | ||
| 1369 | * Directly increment or decrement active count without | ||
| 1370 | * queuing. This method is used to transiently assert inactivation | ||
| 1371 | * while checking quiescence. | ||
| 1372 | * | ||
| 1373 | * @param delta 1 for increment, -1 for decrement | ||
| 1374 | */ | ||
| 1375 | final void addActiveCount(int delta) { | ||
| 1376 | long d = delta < 0 ? -AC_UNIT : AC_UNIT; | ||
| 1377 | long c; | ||
| 1378 | do {} while (!UNSAFE.compareAndSwapLong(this, ctlOffset, c = ctl, | ||
| 1379 | ((c + d) & AC_MASK) | | ||
| 1380 | (c & ~AC_MASK))); | ||
| 1381 | } | ||
| 1382 | |||
| 1383 | /** | ||
| 1384 | * Returns the approximate (non-atomic) number of idle threads per | ||
| 1385 | * active thread. | ||
| 1386 | */ | ||
| 1387 | final int idlePerActive() { | ||
| 1388 | // Approximate at powers of two for small values, saturate past 4 | ||
| 1389 | int p = parallelism; | ||
| 1390 | int a = p + (int)(ctl >> AC_SHIFT); | ||
| 1391 | return (a > (p >>>= 1) ? 0 : | ||
| 1392 | a > (p >>>= 1) ? 1 : | ||
| 1393 | a > (p >>>= 1) ? 2 : | ||
| 1394 | a > (p >>>= 1) ? 4 : | ||
| 1395 | 8); | ||
| 1396 | } | ||
| 1397 | |||
| 1398 | // Exported methods | ||
| 1399 | |||
| 1400 | // Constructors | ||
| 1401 | |||
| 1402 | /** | ||
| 1403 | * Creates a {@code ForkJoinPool} with parallelism equal to {@link | ||
| 1404 | * java.lang.Runtime#availableProcessors}, using the {@linkplain | ||
| 1405 | * #defaultForkJoinWorkerThreadFactory default thread factory}, | ||
| 1406 | * no UncaughtExceptionHandler, and non-async LIFO processing mode. | ||
| 1407 | * | ||
| 1408 | * @throws SecurityException if a security manager exists and | ||
| 1409 | * the caller is not permitted to modify threads | ||
| 1410 | * because it does not hold {@link | ||
| 1411 | * java.lang.RuntimePermission}{@code ("modifyThread")} | ||
| 1412 | */ | ||
| 1413 | public ForkJoinPool() { | ||
| 1414 | this(Runtime.getRuntime().availableProcessors(), | ||
| 1415 | defaultForkJoinWorkerThreadFactory, null, false); | ||
| 1416 | } | ||
| 1417 | |||
| 1418 | /** | ||
| 1419 | * Creates a {@code ForkJoinPool} with the indicated parallelism | ||
| 1420 | * level, the {@linkplain | ||
| 1421 | * #defaultForkJoinWorkerThreadFactory default thread factory}, | ||
| 1422 | * no UncaughtExceptionHandler, and non-async LIFO processing mode. | ||
| 1423 | * | ||
| 1424 | * @param parallelism the parallelism level | ||
| 1425 | * @throws IllegalArgumentException if parallelism less than or | ||
| 1426 | * equal to zero, or greater than implementation limit | ||
| 1427 | * @throws SecurityException if a security manager exists and | ||
| 1428 | * the caller is not permitted to modify threads | ||
| 1429 | * because it does not hold {@link | ||
| 1430 | * java.lang.RuntimePermission}{@code ("modifyThread")} | ||
| 1431 | */ | ||
| 1432 | public ForkJoinPool(int parallelism) { | ||
| 1433 | this(parallelism, defaultForkJoinWorkerThreadFactory, null, false); | ||
| 1434 | } | ||
| 1435 | |||
| 1436 | /** | ||
| 1437 | * Creates a {@code ForkJoinPool} with the given parameters. | ||
| 1438 | * | ||
| 1439 | * @param parallelism the parallelism level. For default value, | ||
| 1440 | * use {@link java.lang.Runtime#availableProcessors}. | ||
| 1441 | * @param factory the factory for creating new threads. For default value, | ||
| 1442 | * use {@link #defaultForkJoinWorkerThreadFactory}. | ||
| 1443 | * @param handler the handler for internal worker threads that | ||
| 1444 | * terminate due to unrecoverable errors encountered while executing | ||
| 1445 | * tasks. For default value, use {@code null}. | ||
| 1446 | * @param asyncMode if true, | ||
| 1447 | * establishes local first-in-first-out scheduling mode for forked | ||
| 1448 | * tasks that are never joined. This mode may be more appropriate | ||
| 1449 | * than default locally stack-based mode in applications in which | ||
| 1450 | * worker threads only process event-style asynchronous tasks. | ||
| 1451 | * For default value, use {@code false}. | ||
| 1452 | * @throws IllegalArgumentException if parallelism less than or | ||
| 1453 | * equal to zero, or greater than implementation limit | ||
| 1454 | * @throws NullPointerException if the factory is null | ||
| 1455 | * @throws SecurityException if a security manager exists and | ||
| 1456 | * the caller is not permitted to modify threads | ||
| 1457 | * because it does not hold {@link | ||
| 1458 | * java.lang.RuntimePermission}{@code ("modifyThread")} | ||
| 1459 | */ | ||
| 1460 | public ForkJoinPool(int parallelism, | ||
| 1461 | ForkJoinWorkerThreadFactory factory, | ||
| 1462 | Thread.UncaughtExceptionHandler handler, | ||
| 1463 | boolean asyncMode) { | ||
| 1464 | checkPermission(); | ||
| 1465 | if (factory == null) | ||
| 1466 | throw new NullPointerException(); | ||
| 1467 | if (parallelism <= 0 || parallelism > MAX_ID) | ||
| 1468 | throw new IllegalArgumentException(); | ||
| 1469 | this.parallelism = parallelism; | ||
| 1470 | this.factory = factory; | ||
| 1471 | this.ueh = handler; | ||
| 1472 | this.locallyFifo = asyncMode; | ||
| 1473 | long np = (long)(-parallelism); // offset ctl counts | ||
| 1474 | this.ctl = ((np << AC_SHIFT) & AC_MASK) | ((np << TC_SHIFT) & TC_MASK); | ||
| 1475 | this.submissionQueue = new ForkJoinTask<?>[INITIAL_QUEUE_CAPACITY]; | ||
| 1476 | // initialize workers array with room for 2*parallelism if possible | ||
| 1477 | int n = parallelism << 1; | ||
| 1478 | if (n >= MAX_ID) | ||
| 1479 | n = MAX_ID; | ||
| 1480 | else { // See Hackers Delight, sec 3.2, where n < (1 << 16) | ||
| 1481 | n |= n >>> 1; n |= n >>> 2; n |= n >>> 4; n |= n >>> 8; | ||
| 1482 | } | ||
| 1483 | workers = new ForkJoinWorkerThread[n + 1]; | ||
| 1484 | this.submissionLock = new ReentrantLock(); | ||
| 1485 | this.termination = submissionLock.newCondition(); | ||
| 1486 | StringBuilder sb = new StringBuilder("ForkJoinPool-"); | ||
| 1487 | sb.append(poolNumberGenerator.incrementAndGet()); | ||
| 1488 | sb.append("-worker-"); | ||
| 1489 | this.workerNamePrefix = sb.toString(); | ||
| 1490 | } | ||
| 1491 | |||
| 1492 | // Execution methods | ||
| 1493 | |||
| 1494 | /** | ||
| 1495 | * Performs the given task, returning its result upon completion. | ||
| 1496 | * If the computation encounters an unchecked Exception or Error, | ||
| 1497 | * it is rethrown as the outcome of this invocation. Rethrown | ||
| 1498 | * exceptions behave in the same way as regular exceptions, but, | ||
| 1499 | * when possible, contain stack traces (as displayed for example | ||
| 1500 | * using {@code ex.printStackTrace()}) of both the current thread | ||
| 1501 | * as well as the thread actually encountering the exception; | ||
| 1502 | * minimally only the latter. | ||
| 1503 | * | ||
| 1504 | * @param task the task | ||
| 1505 | * @return the task's result | ||
| 1506 | * @throws NullPointerException if the task is null | ||
| 1507 | * @throws RejectedExecutionException if the task cannot be | ||
| 1508 | * scheduled for execution | ||
| 1509 | */ | ||
| 1510 | public <T> T invoke(ForkJoinTask<T> task) { | ||
| 1511 | Thread t = Thread.currentThread(); | ||
| 1512 | if (task == null) | ||
| 1513 | throw new NullPointerException(); | ||
| 1514 | if (shutdown) | ||
| 1515 | throw new RejectedExecutionException(); | ||
| 1516 | if ((t instanceof ForkJoinWorkerThread) && | ||
| 1517 | ((ForkJoinWorkerThread)t).pool == this) | ||
| 1518 | return task.invoke(); // bypass submit if in same pool | ||
| 1519 | else { | ||
| 1520 | addSubmission(task); | ||
| 1521 | return task.join(); | ||
| 1522 | } | ||
| 1523 | } | ||
| 1524 | |||
| 1525 | /** | ||
| 1526 | * Unless terminating, forks task if within an ongoing FJ | ||
| 1527 | * computation in the current pool, else submits as external task. | ||
| 1528 | */ | ||
| 1529 | private <T> void forkOrSubmit(ForkJoinTask<T> task) { | ||
| 1530 | ForkJoinWorkerThread w; | ||
| 1531 | Thread t = Thread.currentThread(); | ||
| 1532 | if (shutdown) | ||
| 1533 | throw new RejectedExecutionException(); | ||
| 1534 | if ((t instanceof ForkJoinWorkerThread) && | ||
| 1535 | (w = (ForkJoinWorkerThread)t).pool == this) | ||
| 1536 | w.pushTask(task); | ||
| 1537 | else | ||
| 1538 | addSubmission(task); | ||
| 1539 | } | ||
| 1540 | |||
| 1541 | /** | ||
| 1542 | * Arranges for (asynchronous) execution of the given task. | ||
| 1543 | * | ||
| 1544 | * @param task the task | ||
| 1545 | * @throws NullPointerException if the task is null | ||
| 1546 | * @throws RejectedExecutionException if the task cannot be | ||
| 1547 | * scheduled for execution | ||
| 1548 | */ | ||
| 1549 | public void execute(ForkJoinTask<?> task) { | ||
| 1550 | if (task == null) | ||
| 1551 | throw new NullPointerException(); | ||
| 1552 | forkOrSubmit(task); | ||
| 1553 | } | ||
| 1554 | |||
| 1555 | // AbstractExecutorService methods | ||
| 1556 | |||
| 1557 | /** | ||
| 1558 | * @throws NullPointerException if the task is null | ||
| 1559 | * @throws RejectedExecutionException if the task cannot be | ||
| 1560 | * scheduled for execution | ||
| 1561 | */ | ||
| 1562 | public void execute(Runnable task) { | ||
| 1563 | if (task == null) | ||
| 1564 | throw new NullPointerException(); | ||
| 1565 | ForkJoinTask<?> job; | ||
| 1566 | if (task instanceof ForkJoinTask<?>) // avoid re-wrap | ||
| 1567 | job = (ForkJoinTask<?>) task; | ||
| 1568 | else | ||
| 1569 | job = ForkJoinTask.adapt(task, null); | ||
| 1570 | forkOrSubmit(job); | ||
| 1571 | } | ||
| 1572 | |||
| 1573 | /** | ||
| 1574 | * Submits a ForkJoinTask for execution. | ||
| 1575 | * | ||
| 1576 | * @param task the task to submit | ||
| 1577 | * @return the task | ||
| 1578 | * @throws NullPointerException if the task is null | ||
| 1579 | * @throws RejectedExecutionException if the task cannot be | ||
| 1580 | * scheduled for execution | ||
| 1581 | */ | ||
| 1582 | public <T> ForkJoinTask<T> submit(ForkJoinTask<T> task) { | ||
| 1583 | if (task == null) | ||
| 1584 | throw new NullPointerException(); | ||
| 1585 | forkOrSubmit(task); | ||
| 1586 | return task; | ||
| 1587 | } | ||
| 1588 | |||
| 1589 | /** | ||
| 1590 | * @throws NullPointerException if the task is null | ||
| 1591 | * @throws RejectedExecutionException if the task cannot be | ||
| 1592 | * scheduled for execution | ||
| 1593 | */ | ||
| 1594 | public <T> ForkJoinTask<T> submit(Callable<T> task) { | ||
| 1595 | if (task == null) | ||
| 1596 | throw new NullPointerException(); | ||
| 1597 | ForkJoinTask<T> job = ForkJoinTask.adapt(task); | ||
| 1598 | forkOrSubmit(job); | ||
| 1599 | return job; | ||
| 1600 | } | ||
| 1601 | |||
| 1602 | /** | ||
| 1603 | * @throws NullPointerException if the task is null | ||
| 1604 | * @throws RejectedExecutionException if the task cannot be | ||
| 1605 | * scheduled for execution | ||
| 1606 | */ | ||
| 1607 | public <T> ForkJoinTask<T> submit(Runnable task, T result) { | ||
| 1608 | if (task == null) | ||
| 1609 | throw new NullPointerException(); | ||
| 1610 | ForkJoinTask<T> job = ForkJoinTask.adapt(task, result); | ||
| 1611 | forkOrSubmit(job); | ||
| 1612 | return job; | ||
| 1613 | } | ||
| 1614 | |||
| 1615 | /** | ||
| 1616 | * @throws NullPointerException if the task is null | ||
| 1617 | * @throws RejectedExecutionException if the task cannot be | ||
| 1618 | * scheduled for execution | ||
| 1619 | */ | ||
| 1620 | public ForkJoinTask<?> submit(Runnable task) { | ||
| 1621 | if (task == null) | ||
| 1622 | throw new NullPointerException(); | ||
| 1623 | ForkJoinTask<?> job; | ||
| 1624 | if (task instanceof ForkJoinTask<?>) // avoid re-wrap | ||
| 1625 | job = (ForkJoinTask<?>) task; | ||
| 1626 | else | ||
| 1627 | job = ForkJoinTask.adapt(task, null); | ||
| 1628 | forkOrSubmit(job); | ||
| 1629 | return job; | ||
| 1630 | } | ||
| 1631 | |||
| 1632 | /** | ||
| 1633 | * @throws NullPointerException {@inheritDoc} | ||
| 1634 | * @throws RejectedExecutionException {@inheritDoc} | ||
| 1635 | */ | ||
| 1636 | public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) { | ||
| 1637 | ArrayList<ForkJoinTask<T>> forkJoinTasks = | ||
| 1638 | new ArrayList<ForkJoinTask<T>>(tasks.size()); | ||
| 1639 | for (Callable<T> task : tasks) | ||
| 1640 | forkJoinTasks.add(ForkJoinTask.adapt(task)); | ||
| 1641 | invoke(new InvokeAll<T>(forkJoinTasks)); | ||
| 1642 | |||
| 1643 | @SuppressWarnings({"unchecked", "rawtypes"}) | ||
| 1644 | List<Future<T>> futures = (List<Future<T>>) (List) forkJoinTasks; | ||
| 1645 | return futures; | ||
| 1646 | } | ||
| 1647 | |||
| 1648 | static final class InvokeAll<T> extends RecursiveAction { | ||
| 1649 | final ArrayList<ForkJoinTask<T>> tasks; | ||
| 1650 | InvokeAll(ArrayList<ForkJoinTask<T>> tasks) { this.tasks = tasks; } | ||
| 1651 | public void compute() { | ||
| 1652 | try { invokeAll(tasks); } | ||
| 1653 | catch (Exception ignore) {} | ||
| 1654 | } | ||
| 1655 | private static final long serialVersionUID = -7914297376763021607L; | ||
| 1656 | } | ||
| 1657 | |||
| 1658 | /** | ||
| 1659 | * Returns the factory used for constructing new workers. | ||
| 1660 | * | ||
| 1661 | * @return the factory used for constructing new workers | ||
| 1662 | */ | ||
| 1663 | public ForkJoinWorkerThreadFactory getFactory() { | ||
| 1664 | return factory; | ||
| 1665 | } | ||
| 1666 | |||
| 1667 | /** | ||
| 1668 | * Returns the handler for internal worker threads that terminate | ||
| 1669 | * due to unrecoverable errors encountered while executing tasks. | ||
| 1670 | * | ||
| 1671 | * @return the handler, or {@code null} if none | ||
| 1672 | */ | ||
| 1673 | public Thread.UncaughtExceptionHandler getUncaughtExceptionHandler() { | ||
| 1674 | return ueh; | ||
| 1675 | } | ||
| 1676 | |||
| 1677 | /** | ||
| 1678 | * Returns the targeted parallelism level of this pool. | ||
| 1679 | * | ||
| 1680 | * @return the targeted parallelism level of this pool | ||
| 1681 | */ | ||
| 1682 | public int getParallelism() { | ||
| 1683 | return parallelism; | ||
| 1684 | } | ||
| 1685 | |||
| 1686 | /** | ||
| 1687 | * Returns the number of worker threads that have started but not | ||
| 1688 | * yet terminated. The result returned by this method may differ | ||
| 1689 | * from {@link #getParallelism} when threads are created to | ||
| 1690 | * maintain parallelism when others are cooperatively blocked. | ||
| 1691 | * | ||
| 1692 | * @return the number of worker threads | ||
| 1693 | */ | ||
| 1694 | public int getPoolSize() { | ||
| 1695 | return parallelism + (short)(ctl >>> TC_SHIFT); | ||
| 1696 | } | ||
| 1697 | |||
| 1698 | /** | ||
| 1699 | * Returns {@code true} if this pool uses local first-in-first-out | ||
| 1700 | * scheduling mode for forked tasks that are never joined. | ||
| 1701 | * | ||
| 1702 | * @return {@code true} if this pool uses async mode | ||
| 1703 | */ | ||
| 1704 | public boolean getAsyncMode() { | ||
| 1705 | return locallyFifo; | ||
| 1706 | } | ||
| 1707 | |||
| 1708 | /** | ||
| 1709 | * Returns an estimate of the number of worker threads that are | ||
| 1710 | * not blocked waiting to join tasks or for other managed | ||
| 1711 | * synchronization. This method may overestimate the | ||
| 1712 | * number of running threads. | ||
| 1713 | * | ||
| 1714 | * @return the number of worker threads | ||
| 1715 | */ | ||
| 1716 | public int getRunningThreadCount() { | ||
| 1717 | int r = parallelism + (int)(ctl >> AC_SHIFT); | ||
| 1718 | return (r <= 0) ? 0 : r; // suppress momentarily negative values | ||
| 1719 | } | ||
| 1720 | |||
| 1721 | /** | ||
| 1722 | * Returns an estimate of the number of threads that are currently | ||
| 1723 | * stealing or executing tasks. This method may overestimate the | ||
| 1724 | * number of active threads. | ||
| 1725 | * | ||
| 1726 | * @return the number of active threads | ||
| 1727 | */ | ||
| 1728 | public int getActiveThreadCount() { | ||
| 1729 | int r = parallelism + (int)(ctl >> AC_SHIFT) + blockedCount; | ||
| 1730 | return (r <= 0) ? 0 : r; // suppress momentarily negative values | ||
| 1731 | } | ||
| 1732 | |||
| 1733 | /** | ||
| 1734 | * Returns {@code true} if all worker threads are currently idle. | ||
| 1735 | * An idle worker is one that cannot obtain a task to execute | ||
| 1736 | * because none are available to steal from other threads, and | ||
| 1737 | * there are no pending submissions to the pool. This method is | ||
| 1738 | * conservative; it might not return {@code true} immediately upon | ||
| 1739 | * idleness of all threads, but will eventually become true if | ||
| 1740 | * threads remain inactive. | ||
| 1741 | * | ||
| 1742 | * @return {@code true} if all threads are currently idle | ||
| 1743 | */ | ||
| 1744 | public boolean isQuiescent() { | ||
| 1745 | return parallelism + (int)(ctl >> AC_SHIFT) + blockedCount == 0; | ||
| 1746 | } | ||
| 1747 | |||
| 1748 | /** | ||
| 1749 | * Returns an estimate of the total number of tasks stolen from | ||
| 1750 | * one thread's work queue by another. The reported value | ||
| 1751 | * underestimates the actual total number of steals when the pool | ||
| 1752 | * is not quiescent. This value may be useful for monitoring and | ||
| 1753 | * tuning fork/join programs: in general, steal counts should be | ||
| 1754 | * high enough to keep threads busy, but low enough to avoid | ||
| 1755 | * overhead and contention across threads. | ||
| 1756 | * | ||
| 1757 | * @return the number of steals | ||
| 1758 | */ | ||
| 1759 | public long getStealCount() { | ||
| 1760 | return stealCount; | ||
| 1761 | } | ||
| 1762 | |||
| 1763 | /** | ||
| 1764 | * Returns an estimate of the total number of tasks currently held | ||
| 1765 | * in queues by worker threads (but not including tasks submitted | ||
| 1766 | * to the pool that have not begun executing). This value is only | ||
| 1767 | * an approximation, obtained by iterating across all threads in | ||
| 1768 | * the pool. This method may be useful for tuning task | ||
| 1769 | * granularities. | ||
| 1770 | * | ||
| 1771 | * @return the number of queued tasks | ||
| 1772 | */ | ||
| 1773 | public long getQueuedTaskCount() { | ||
| 1774 | long count = 0; | ||
| 1775 | ForkJoinWorkerThread[] ws; | ||
| 1776 | if ((short)(ctl >>> TC_SHIFT) > -parallelism && | ||
| 1777 | (ws = workers) != null) { | ||
| 1778 | for (ForkJoinWorkerThread w : ws) | ||
| 1779 | if (w != null) | ||
| 1780 | count -= w.queueBase - w.queueTop; // must read base first | ||
| 1781 | } | ||
| 1782 | return count; | ||
| 1783 | } | ||
| 1784 | |||
| 1785 | /** | ||
| 1786 | * Returns an estimate of the number of tasks submitted to this | ||
| 1787 | * pool that have not yet begun executing. This method may take | ||
| 1788 | * time proportional to the number of submissions. | ||
| 1789 | * | ||
| 1790 | * @return the number of queued submissions | ||
| 1791 | */ | ||
| 1792 | public int getQueuedSubmissionCount() { | ||
| 1793 | return -queueBase + queueTop; | ||
| 1794 | } | ||
| 1795 | |||
| 1796 | /** | ||
| 1797 | * Returns {@code true} if there are any tasks submitted to this | ||
| 1798 | * pool that have not yet begun executing. | ||
| 1799 | * | ||
| 1800 | * @return {@code true} if there are any queued submissions | ||
| 1801 | */ | ||
| 1802 | public boolean hasQueuedSubmissions() { | ||
| 1803 | return queueBase != queueTop; | ||
| 1804 | } | ||
| 1805 | |||
| 1806 | /** | ||
| 1807 | * Removes and returns the next unexecuted submission if one is | ||
| 1808 | * available. This method may be useful in extensions to this | ||
| 1809 | * class that re-assign work in systems with multiple pools. | ||
| 1810 | * | ||
| 1811 | * @return the next submission, or {@code null} if none | ||
| 1812 | */ | ||
| 1813 | protected ForkJoinTask<?> pollSubmission() { | ||
| 1814 | ForkJoinTask<?> t; ForkJoinTask<?>[] q; int b, i; | ||
| 1815 | while ((b = queueBase) != queueTop && | ||
| 1816 | (q = submissionQueue) != null && | ||
| 1817 | (i = (q.length - 1) & b) >= 0) { | ||
| 1818 | long u = (i << ASHIFT) + ABASE; | ||
| 1819 | if ((t = q[i]) != null && | ||
| 1820 | queueBase == b && | ||
| 1821 | UNSAFE.compareAndSwapObject(q, u, t, null)) { | ||
| 1822 | queueBase = b + 1; | ||
| 1823 | return t; | ||
| 1824 | } | ||
| 1825 | } | ||
| 1826 | return null; | ||
| 1827 | } | ||
| 1828 | |||
| 1829 | /** | ||
| 1830 | * Removes all available unexecuted submitted and forked tasks | ||
| 1831 | * from scheduling queues and adds them to the given collection, | ||
| 1832 | * without altering their execution status. These may include | ||
| 1833 | * artificially generated or wrapped tasks. This method is | ||
| 1834 | * designed to be invoked only when the pool is known to be | ||
| 1835 | * quiescent. Invocations at other times may not remove all | ||
| 1836 | * tasks. A failure encountered while attempting to add elements | ||
| 1837 | * to collection {@code c} may result in elements being in | ||
| 1838 | * neither, either or both collections when the associated | ||
| 1839 | * exception is thrown. The behavior of this operation is | ||
| 1840 | * undefined if the specified collection is modified while the | ||
| 1841 | * operation is in progress. | ||
| 1842 | * | ||
| 1843 | * @param c the collection to transfer elements into | ||
| 1844 | * @return the number of elements transferred | ||
| 1845 | */ | ||
| 1846 | protected int drainTasksTo(Collection<? super ForkJoinTask<?>> c) { | ||
| 1847 | int count = 0; | ||
| 1848 | while (queueBase != queueTop) { | ||
| 1849 | ForkJoinTask<?> t = pollSubmission(); | ||
| 1850 | if (t != null) { | ||
| 1851 | c.add(t); | ||
| 1852 | ++count; | ||
| 1853 | } | ||
| 1854 | } | ||
| 1855 | ForkJoinWorkerThread[] ws; | ||
| 1856 | if ((short)(ctl >>> TC_SHIFT) > -parallelism && | ||
| 1857 | (ws = workers) != null) { | ||
| 1858 | for (ForkJoinWorkerThread w : ws) | ||
| 1859 | if (w != null) | ||
| 1860 | count += w.drainTasksTo(c); | ||
| 1861 | } | ||
| 1862 | return count; | ||
| 1863 | } | ||
| 1864 | |||
| 1865 | /** | ||
| 1866 | * Returns a string identifying this pool, as well as its state, | ||
| 1867 | * including indications of run state, parallelism level, and | ||
| 1868 | * worker and task counts. | ||
| 1869 | * | ||
| 1870 | * @return a string identifying this pool, as well as its state | ||
| 1871 | */ | ||
| 1872 | public String toString() { | ||
| 1873 | long st = getStealCount(); | ||
| 1874 | long qt = getQueuedTaskCount(); | ||
| 1875 | long qs = getQueuedSubmissionCount(); | ||
| 1876 | int pc = parallelism; | ||
| 1877 | long c = ctl; | ||
| 1878 | int tc = pc + (short)(c >>> TC_SHIFT); | ||
| 1879 | int rc = pc + (int)(c >> AC_SHIFT); | ||
| 1880 | if (rc < 0) // ignore transient negative | ||
| 1881 | rc = 0; | ||
| 1882 | int ac = rc + blockedCount; | ||
| 1883 | String level; | ||
| 1884 | if ((c & STOP_BIT) != 0) | ||
| 1885 | level = (tc == 0) ? "Terminated" : "Terminating"; | ||
| 1886 | else | ||
| 1887 | level = shutdown ? "Shutting down" : "Running"; | ||
| 1888 | return super.toString() + | ||
| 1889 | "[" + level + | ||
| 1890 | ", parallelism = " + pc + | ||
| 1891 | ", size = " + tc + | ||
| 1892 | ", active = " + ac + | ||
| 1893 | ", running = " + rc + | ||
| 1894 | ", steals = " + st + | ||
| 1895 | ", tasks = " + qt + | ||
| 1896 | ", submissions = " + qs + | ||
| 1897 | "]"; | ||
| 1898 | } | ||
| 1899 | |||
| 1900 | /** | ||
| 1901 | * Initiates an orderly shutdown in which previously submitted | ||
| 1902 | * tasks are executed, but no new tasks will be accepted. | ||
| 1903 | * Invocation has no additional effect if already shut down. | ||
| 1904 | * Tasks that are in the process of being submitted concurrently | ||
| 1905 | * during the course of this method may or may not be rejected. | ||
| 1906 | * | ||
| 1907 | * @throws SecurityException if a security manager exists and | ||
| 1908 | * the caller is not permitted to modify threads | ||
| 1909 | * because it does not hold {@link | ||
| 1910 | * java.lang.RuntimePermission}{@code ("modifyThread")} | ||
| 1911 | */ | ||
| 1912 | public void shutdown() { | ||
| 1913 | checkPermission(); | ||
| 1914 | shutdown = true; | ||
| 1915 | tryTerminate(false); | ||
| 1916 | } | ||
| 1917 | |||
| 1918 | /** | ||
| 1919 | * Attempts to cancel and/or stop all tasks, and reject all | ||
| 1920 | * subsequently submitted tasks. Tasks that are in the process of | ||
| 1921 | * being submitted or executed concurrently during the course of | ||
| 1922 | * this method may or may not be rejected. This method cancels | ||
| 1923 | * both existing and unexecuted tasks, in order to permit | ||
| 1924 | * termination in the presence of task dependencies. So the method | ||
| 1925 | * always returns an empty list (unlike the case for some other | ||
| 1926 | * Executors). | ||
| 1927 | * | ||
| 1928 | * @return an empty list | ||
| 1929 | * @throws SecurityException if a security manager exists and | ||
| 1930 | * the caller is not permitted to modify threads | ||
| 1931 | * because it does not hold {@link | ||
| 1932 | * java.lang.RuntimePermission}{@code ("modifyThread")} | ||
| 1933 | */ | ||
| 1934 | public List<Runnable> shutdownNow() { | ||
| 1935 | checkPermission(); | ||
| 1936 | shutdown = true; | ||
| 1937 | tryTerminate(true); | ||
| 1938 | return Collections.emptyList(); | ||
| 1939 | } | ||
| 1940 | |||
| 1941 | /** | ||
| 1942 | * Returns {@code true} if all tasks have completed following shut down. | ||
| 1943 | * | ||
| 1944 | * @return {@code true} if all tasks have completed following shut down | ||
| 1945 | */ | ||
| 1946 | public boolean isTerminated() { | ||
| 1947 | long c = ctl; | ||
| 1948 | return ((c & STOP_BIT) != 0L && | ||
| 1949 | (short)(c >>> TC_SHIFT) == -parallelism); | ||
| 1950 | } | ||
| 1951 | |||
| 1952 | /** | ||
| 1953 | * Returns {@code true} if the process of termination has | ||
| 1954 | * commenced but not yet completed. This method may be useful for | ||
| 1955 | * debugging. A return of {@code true} reported a sufficient | ||
| 1956 | * period after shutdown may indicate that submitted tasks have | ||
| 1957 | * ignored or suppressed interruption, or are waiting for IO, | ||
| 1958 | * causing this executor not to properly terminate. (See the | ||
| 1959 | * advisory notes for class {@link ForkJoinTask} stating that | ||
| 1960 | * tasks should not normally entail blocking operations. But if | ||
| 1961 | * they do, they must abort them on interrupt.) | ||
| 1962 | * | ||
| 1963 | * @return {@code true} if terminating but not yet terminated | ||
| 1964 | */ | ||
| 1965 | public boolean isTerminating() { | ||
| 1966 | long c = ctl; | ||
| 1967 | return ((c & STOP_BIT) != 0L && | ||
| 1968 | (short)(c >>> TC_SHIFT) != -parallelism); | ||
| 1969 | } | ||
| 1970 | |||
| 1971 | /** | ||
| 1972 | * Returns true if terminating or terminated. Used by ForkJoinWorkerThread. | ||
| 1973 | */ | ||
| 1974 | final boolean isAtLeastTerminating() { | ||
| 1975 | return (ctl & STOP_BIT) != 0L; | ||
| 1976 | } | ||
| 1977 | |||
| 1978 | /** | ||
| 1979 | * Returns {@code true} if this pool has been shut down. | ||
| 1980 | * | ||
| 1981 | * @return {@code true} if this pool has been shut down | ||
| 1982 | */ | ||
| 1983 | public boolean isShutdown() { | ||
| 1984 | return shutdown; | ||
| 1985 | } | ||
| 1986 | |||
| 1987 | /** | ||
| 1988 | * Blocks until all tasks have completed execution after a shutdown | ||
| 1989 | * request, or the timeout occurs, or the current thread is | ||
| 1990 | * interrupted, whichever happens first. | ||
| 1991 | * | ||
| 1992 | * @param timeout the maximum time to wait | ||
| 1993 | * @param unit the time unit of the timeout argument | ||
| 1994 | * @return {@code true} if this executor terminated and | ||
| 1995 | * {@code false} if the timeout elapsed before termination | ||
| 1996 | * @throws InterruptedException if interrupted while waiting | ||
| 1997 | */ | ||
| 1998 | public boolean awaitTermination(long timeout, TimeUnit unit) | ||
| 1999 | throws InterruptedException { | ||
| 2000 | long nanos = unit.toNanos(timeout); | ||
| 2001 | final ReentrantLock lock = this.submissionLock; | ||
| 2002 | lock.lock(); | ||
| 2003 | try { | ||
| 2004 | for (;;) { | ||
| 2005 | if (isTerminated()) | ||
| 2006 | return true; | ||
| 2007 | if (nanos <= 0) | ||
| 2008 | return false; | ||
| 2009 | nanos = termination.awaitNanos(nanos); | ||
| 2010 | } | ||
| 2011 | } finally { | ||
| 2012 | lock.unlock(); | ||
| 2013 | } | ||
| 2014 | } | ||
| 2015 | |||
| 2016 | /** | ||
| 2017 | * Interface for extending managed parallelism for tasks running | ||
| 2018 | * in {@link ForkJoinPool}s. | ||
| 2019 | * | ||
| 2020 | * <p>A {@code ManagedBlocker} provides two methods. Method | ||
| 2021 | * {@code isReleasable} must return {@code true} if blocking is | ||
| 2022 | * not necessary. Method {@code block} blocks the current thread | ||
| 2023 | * if necessary (perhaps internally invoking {@code isReleasable} | ||
| 2024 | * before actually blocking). These actions are performed by any | ||
| 2025 | * thread invoking {@link ForkJoinPool#managedBlock}. The | ||
| 2026 | * unusual methods in this API accommodate synchronizers that may, | ||
| 2027 | * but don't usually, block for long periods. Similarly, they | ||
| 2028 | * allow more efficient internal handling of cases in which | ||
| 2029 | * additional workers may be, but usually are not, needed to | ||
| 2030 | * ensure sufficient parallelism. Toward this end, | ||
| 2031 | * implementations of method {@code isReleasable} must be amenable | ||
| 2032 | * to repeated invocation. | ||
| 2033 | * | ||
| 2034 | * <p>For example, here is a ManagedBlocker based on a | ||
| 2035 | * ReentrantLock: | ||
| 2036 | * <pre> {@code | ||
| 2037 | * class ManagedLocker implements ManagedBlocker { | ||
| 2038 | * final ReentrantLock lock; | ||
| 2039 | * boolean hasLock = false; | ||
| 2040 | * ManagedLocker(ReentrantLock lock) { this.lock = lock; } | ||
| 2041 | * public boolean block() { | ||
| 2042 | * if (!hasLock) | ||
| 2043 | * lock.lock(); | ||
| 2044 | * return true; | ||
| 2045 | * } | ||
| 2046 | * public boolean isReleasable() { | ||
| 2047 | * return hasLock || (hasLock = lock.tryLock()); | ||
| 2048 | * } | ||
| 2049 | * }}</pre> | ||
| 2050 | * | ||
| 2051 | * <p>Here is a class that possibly blocks waiting for an | ||
| 2052 | * item on a given queue: | ||
| 2053 | * <pre> {@code | ||
| 2054 | * class QueueTaker<E> implements ManagedBlocker { | ||
| 2055 | * final BlockingQueue<E> queue; | ||
| 2056 | * volatile E item = null; | ||
| 2057 | * QueueTaker(BlockingQueue<E> q) { this.queue = q; } | ||
| 2058 | * public boolean block() throws InterruptedException { | ||
| 2059 | * if (item == null) | ||
| 2060 | * item = queue.take(); | ||
| 2061 | * return true; | ||
| 2062 | * } | ||
| 2063 | * public boolean isReleasable() { | ||
| 2064 | * return item != null || (item = queue.poll()) != null; | ||
| 2065 | * } | ||
| 2066 | * public E getItem() { // call after pool.managedBlock completes | ||
| 2067 | * return item; | ||
| 2068 | * } | ||
| 2069 | * }}</pre> | ||
| 2070 | */ | ||
| 2071 | public static interface ManagedBlocker { | ||
| 2072 | /** | ||
| 2073 | * Possibly blocks the current thread, for example waiting for | ||
| 2074 | * a lock or condition. | ||
| 2075 | * | ||
| 2076 | * @return {@code true} if no additional blocking is necessary | ||
| 2077 | * (i.e., if isReleasable would return true) | ||
| 2078 | * @throws InterruptedException if interrupted while waiting | ||
| 2079 | * (the method is not required to do so, but is allowed to) | ||
| 2080 | */ | ||
| 2081 | boolean block() throws InterruptedException; | ||
| 2082 | |||
| 2083 | /** | ||
| 2084 | * Returns {@code true} if blocking is unnecessary. | ||
| 2085 | */ | ||
| 2086 | boolean isReleasable(); | ||
| 2087 | } | ||
| 2088 | |||
| 2089 | /** | ||
| 2090 | * Blocks in accord with the given blocker. If the current thread | ||
| 2091 | * is a {@link ForkJoinWorkerThread}, this method possibly | ||
| 2092 | * arranges for a spare thread to be activated if necessary to | ||
| 2093 | * ensure sufficient parallelism while the current thread is blocked. | ||
| 2094 | * | ||
| 2095 | * <p>If the caller is not a {@link ForkJoinTask}, this method is | ||
| 2096 | * behaviorally equivalent to | ||
| 2097 | * <pre> {@code | ||
| 2098 | * while (!blocker.isReleasable()) | ||
| 2099 | * if (blocker.block()) | ||
| 2100 | * return; | ||
| 2101 | * }</pre> | ||
| 2102 | * | ||
| 2103 | * If the caller is a {@code ForkJoinTask}, then the pool may | ||
| 2104 | * first be expanded to ensure parallelism, and later adjusted. | ||
| 2105 | * | ||
| 2106 | * @param blocker the blocker | ||
| 2107 | * @throws InterruptedException if blocker.block did so | ||
| 2108 | */ | ||
| 2109 | public static void managedBlock(ManagedBlocker blocker) | ||
| 2110 | throws InterruptedException { | ||
| 2111 | Thread t = Thread.currentThread(); | ||
| 2112 | if (t instanceof ForkJoinWorkerThread) { | ||
| 2113 | ForkJoinWorkerThread w = (ForkJoinWorkerThread) t; | ||
| 2114 | w.pool.awaitBlocker(blocker); | ||
| 2115 | } | ||
| 2116 | else { | ||
| 2117 | do {} while (!blocker.isReleasable() && !blocker.block()); | ||
| 2118 | } | ||
| 2119 | } | ||
| 2120 | |||
| 2121 | // AbstractExecutorService overrides. These rely on undocumented | ||
| 2122 | // fact that ForkJoinTask.adapt returns ForkJoinTasks that also | ||
| 2123 | // implement RunnableFuture. | ||
| 2124 | |||
| 2125 | protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) { | ||
| 2126 | return (RunnableFuture<T>) ForkJoinTask.adapt(runnable, value); | ||
| 2127 | } | ||
| 2128 | |||
| 2129 | protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) { | ||
| 2130 | return (RunnableFuture<T>) ForkJoinTask.adapt(callable); | ||
| 2131 | } | ||
| 2132 | |||
| 2133 | // Unsafe mechanics | ||
| 2134 | private static final sun.misc.Unsafe UNSAFE; | ||
| 2135 | private static final long ctlOffset; | ||
| 2136 | private static final long stealCountOffset; | ||
| 2137 | private static final long blockedCountOffset; | ||
| 2138 | private static final long quiescerCountOffset; | ||
| 2139 | private static final long scanGuardOffset; | ||
| 2140 | private static final long nextWorkerNumberOffset; | ||
| 2141 | private static final long ABASE; | ||
| 2142 | private static final int ASHIFT; | ||
| 2143 | |||
| 2144 | static { | ||
| 2145 | poolNumberGenerator = new AtomicInteger(); | ||
| 2146 | workerSeedGenerator = new Random(); | ||
| 2147 | modifyThreadPermission = new RuntimePermission("modifyThread"); | ||
| 2148 | defaultForkJoinWorkerThreadFactory = | ||
| 2149 | new DefaultForkJoinWorkerThreadFactory(); | ||
| 2150 | int s; | ||
| 2151 | try { | ||
| 2152 | UNSAFE = sun.misc.Unsafe.getUnsafe(); | ||
| 2153 | Class k = ForkJoinPool.class; | ||
| 2154 | ctlOffset = UNSAFE.objectFieldOffset | ||
| 2155 | (k.getDeclaredField("ctl")); | ||
| 2156 | stealCountOffset = UNSAFE.objectFieldOffset | ||
| 2157 | (k.getDeclaredField("stealCount")); | ||
| 2158 | blockedCountOffset = UNSAFE.objectFieldOffset | ||
| 2159 | (k.getDeclaredField("blockedCount")); | ||
| 2160 | quiescerCountOffset = UNSAFE.objectFieldOffset | ||
| 2161 | (k.getDeclaredField("quiescerCount")); | ||
| 2162 | scanGuardOffset = UNSAFE.objectFieldOffset | ||
| 2163 | (k.getDeclaredField("scanGuard")); | ||
| 2164 | nextWorkerNumberOffset = UNSAFE.objectFieldOffset | ||
| 2165 | (k.getDeclaredField("nextWorkerNumber")); | ||
| 2166 | Class a = ForkJoinTask[].class; | ||
| 2167 | ABASE = UNSAFE.arrayBaseOffset(a); | ||
| 2168 | s = UNSAFE.arrayIndexScale(a); | ||
| 2169 | } catch (Exception e) { | ||
| 2170 | throw new Error(e); | ||
| 2171 | } | ||
| 2172 | if ((s & (s-1)) != 0) | ||
| 2173 | throw new Error("data type scale not a power of two"); | ||
| 2174 | ASHIFT = 31 - Integer.numberOfLeadingZeros(s); | ||
| 2175 | } | ||
| 2176 | |||
| 2177 | } | ||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,1386 @@ | |||
| 1 | /* | ||
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 3 | * | ||
| 4 | * This code is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License version 2 only, as | ||
| 6 | * published by the Free Software Foundation. Oracle designates this | ||
| 7 | * particular file as subject to the "Classpath" exception as provided | ||
| 8 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 9 | * | ||
| 10 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 13 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 14 | * accompanied this code). | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License version | ||
| 17 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | * | ||
| 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 21 | * or visit www.oracle.com if you need additional information or have any | ||
| 22 | * questions. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * This file is available under and governed by the GNU General Public | ||
| 27 | * License version 2 only, as published by the Free Software Foundation. | ||
| 28 | * However, the following notice accompanied the original version of this | ||
| 29 | * file: | ||
| 30 | * | ||
| 31 | * Written by Doug Lea with assistance from members of JCP JSR-166 | ||
| 32 | * Expert Group and released to the public domain, as explained at | ||
| 33 | * http://creativecommons.org/publicdomain/zero/1.0/ | ||
| 34 | */ | ||
| 35 | |||
| 36 | package java.util.concurrent; | ||
| 37 | |||
| 38 | import java.io.Serializable; | ||
| 39 | import java.util.Collection; | ||
| 40 | import java.util.Collections; | ||
| 41 | import java.util.List; | ||
| 42 | import java.util.RandomAccess; | ||
| 43 | import java.util.Map; | ||
| 44 | import java.lang.ref.WeakReference; | ||
| 45 | import java.lang.ref.ReferenceQueue; | ||
| 46 | import java.util.concurrent.Callable; | ||
| 47 | import java.util.concurrent.CancellationException; | ||
| 48 | import java.util.concurrent.ExecutionException; | ||
| 49 | import java.util.concurrent.Executor; | ||
| 50 | import java.util.concurrent.ExecutorService; | ||
| 51 | import java.util.concurrent.Future; | ||
| 52 | import java.util.concurrent.RejectedExecutionException; | ||
| 53 | import java.util.concurrent.RunnableFuture; | ||
| 54 | import java.util.concurrent.TimeUnit; | ||
| 55 | import java.util.concurrent.TimeoutException; | ||
| 56 | import java.util.concurrent.locks.ReentrantLock; | ||
| 57 | import java.lang.reflect.Constructor; | ||
| 58 | |||
| 59 | /** | ||
| 60 | * Abstract base class for tasks that run within a {@link ForkJoinPool}. | ||
| 61 | * A {@code ForkJoinTask} is a thread-like entity that is much | ||
| 62 | * lighter weight than a normal thread. Huge numbers of tasks and | ||
| 63 | * subtasks may be hosted by a small number of actual threads in a | ||
| 64 | * ForkJoinPool, at the price of some usage limitations. | ||
| 65 | * | ||
| 66 | * <p>A "main" {@code ForkJoinTask} begins execution when submitted | ||
| 67 | * to a {@link ForkJoinPool}. Once started, it will usually in turn | ||
| 68 | * start other subtasks. As indicated by the name of this class, | ||
| 69 | * many programs using {@code ForkJoinTask} employ only methods | ||
| 70 | * {@link #fork} and {@link #join}, or derivatives such as {@link | ||
| 71 | * #invokeAll(ForkJoinTask...) invokeAll}. However, this class also | ||
| 72 | * provides a number of other methods that can come into play in | ||
| 73 | * advanced usages, as well as extension mechanics that allow | ||
| 74 | * support of new forms of fork/join processing. | ||
| 75 | * | ||
| 76 | * <p>A {@code ForkJoinTask} is a lightweight form of {@link Future}. | ||
| 77 | * The efficiency of {@code ForkJoinTask}s stems from a set of | ||
| 78 | * restrictions (that are only partially statically enforceable) | ||
| 79 | * reflecting their intended use as computational tasks calculating | ||
| 80 | * pure functions or operating on purely isolated objects. The | ||
| 81 | * primary coordination mechanisms are {@link #fork}, that arranges | ||
| 82 | * asynchronous execution, and {@link #join}, that doesn't proceed | ||
| 83 | * until the task's result has been computed. Computations should | ||
| 84 | * avoid {@code synchronized} methods or blocks, and should minimize | ||
| 85 | * other blocking synchronization apart from joining other tasks or | ||
| 86 | * using synchronizers such as Phasers that are advertised to | ||
| 87 | * cooperate with fork/join scheduling. Tasks should also not perform | ||
| 88 | * blocking IO, and should ideally access variables that are | ||
| 89 | * completely independent of those accessed by other running | ||
| 90 | * tasks. Minor breaches of these restrictions, for example using | ||
| 91 | * shared output streams, may be tolerable in practice, but frequent | ||
| 92 | * use may result in poor performance, and the potential to | ||
| 93 | * indefinitely stall if the number of threads not waiting for IO or | ||
| 94 | * other external synchronization becomes exhausted. This usage | ||
| 95 | * restriction is in part enforced by not permitting checked | ||
| 96 | * exceptions such as {@code IOExceptions} to be thrown. However, | ||
| 97 | * computations may still encounter unchecked exceptions, that are | ||
| 98 | * rethrown to callers attempting to join them. These exceptions may | ||
| 99 | * additionally include {@link RejectedExecutionException} stemming | ||
| 100 | * from internal resource exhaustion, such as failure to allocate | ||
| 101 | * internal task queues. Rethrown exceptions behave in the same way as | ||
| 102 | * regular exceptions, but, when possible, contain stack traces (as | ||
| 103 | * displayed for example using {@code ex.printStackTrace()}) of both | ||
| 104 | * the thread that initiated the computation as well as the thread | ||
| 105 | * actually encountering the exception; minimally only the latter. | ||
| 106 | * | ||
| 107 | * <p>The primary method for awaiting completion and extracting | ||
| 108 | * results of a task is {@link #join}, but there are several variants: | ||
| 109 | * The {@link Future#get} methods support interruptible and/or timed | ||
| 110 | * waits for completion and report results using {@code Future} | ||
| 111 | * conventions. Method {@link #invoke} is semantically | ||
| 112 | * equivalent to {@code fork(); join()} but always attempts to begin | ||
| 113 | * execution in the current thread. The "<em>quiet</em>" forms of | ||
| 114 | * these methods do not extract results or report exceptions. These | ||
| 115 | * may be useful when a set of tasks are being executed, and you need | ||
| 116 | * to delay processing of results or exceptions until all complete. | ||
| 117 | * Method {@code invokeAll} (available in multiple versions) | ||
| 118 | * performs the most common form of parallel invocation: forking a set | ||
| 119 | * of tasks and joining them all. | ||
| 120 | * | ||
| 121 | * <p>The execution status of tasks may be queried at several levels | ||
| 122 | * of detail: {@link #isDone} is true if a task completed in any way | ||
| 123 | * (including the case where a task was cancelled without executing); | ||
| 124 | * {@link #isCompletedNormally} is true if a task completed without | ||
| 125 | * cancellation or encountering an exception; {@link #isCancelled} is | ||
| 126 | * true if the task was cancelled (in which case {@link #getException} | ||
| 127 | * returns a {@link java.util.concurrent.CancellationException}); and | ||
| 128 | * {@link #isCompletedAbnormally} is true if a task was either | ||
| 129 | * cancelled or encountered an exception, in which case {@link | ||
| 130 | * #getException} will return either the encountered exception or | ||
| 131 | * {@link java.util.concurrent.CancellationException}. | ||
| 132 | * | ||
| 133 | * <p>The ForkJoinTask class is not usually directly subclassed. | ||
| 134 | * Instead, you subclass one of the abstract classes that support a | ||
| 135 | * particular style of fork/join processing, typically {@link | ||
| 136 | * RecursiveAction} for computations that do not return results, or | ||
| 137 | * {@link RecursiveTask} for those that do. Normally, a concrete | ||
| 138 | * ForkJoinTask subclass declares fields comprising its parameters, | ||
| 139 | * established in a constructor, and then defines a {@code compute} | ||
| 140 | * method that somehow uses the control methods supplied by this base | ||
| 141 | * class. While these methods have {@code public} access (to allow | ||
| 142 | * instances of different task subclasses to call each other's | ||
| 143 | * methods), some of them may only be called from within other | ||
| 144 | * ForkJoinTasks (as may be determined using method {@link | ||
| 145 | * #inForkJoinPool}). Attempts to invoke them in other contexts | ||
| 146 | * result in exceptions or errors, possibly including | ||
| 147 | * {@code ClassCastException}. | ||
| 148 | * | ||
| 149 | * <p>Method {@link #join} and its variants are appropriate for use | ||
| 150 | * only when completion dependencies are acyclic; that is, the | ||
| 151 | * parallel computation can be described as a directed acyclic graph | ||
| 152 | * (DAG). Otherwise, executions may encounter a form of deadlock as | ||
| 153 | * tasks cyclically wait for each other. However, this framework | ||
| 154 | * supports other methods and techniques (for example the use of | ||
| 155 | * {@link Phaser}, {@link #helpQuiesce}, and {@link #complete}) that | ||
| 156 | * may be of use in constructing custom subclasses for problems that | ||
| 157 | * are not statically structured as DAGs. | ||
| 158 | * | ||
| 159 | * <p>Most base support methods are {@code final}, to prevent | ||
| 160 | * overriding of implementations that are intrinsically tied to the | ||
| 161 | * underlying lightweight task scheduling framework. Developers | ||
| 162 | * creating new basic styles of fork/join processing should minimally | ||
| 163 | * implement {@code protected} methods {@link #exec}, {@link | ||
| 164 | * #setRawResult}, and {@link #getRawResult}, while also introducing | ||
| 165 | * an abstract computational method that can be implemented in its | ||
| 166 | * subclasses, possibly relying on other {@code protected} methods | ||
| 167 | * provided by this class. | ||
| 168 | * | ||
| 169 | * <p>ForkJoinTasks should perform relatively small amounts of | ||
| 170 | * computation. Large tasks should be split into smaller subtasks, | ||
| 171 | * usually via recursive decomposition. As a very rough rule of thumb, | ||
| 172 | * a task should perform more than 100 and less than 10000 basic | ||
| 173 | * computational steps, and should avoid indefinite looping. If tasks | ||
| 174 | * are too big, then parallelism cannot improve throughput. If too | ||
| 175 | * small, then memory and internal task maintenance overhead may | ||
| 176 | * overwhelm processing. | ||
| 177 | * | ||
| 178 | * <p>This class provides {@code adapt} methods for {@link Runnable} | ||
| 179 | * and {@link Callable}, that may be of use when mixing execution of | ||
| 180 | * {@code ForkJoinTasks} with other kinds of tasks. When all tasks are | ||
| 181 | * of this form, consider using a pool constructed in <em>asyncMode</em>. | ||
| 182 | * | ||
| 183 | * <p>ForkJoinTasks are {@code Serializable}, which enables them to be | ||
| 184 | * used in extensions such as remote execution frameworks. It is | ||
| 185 | * sensible to serialize tasks only before or after, but not during, | ||
| 186 | * execution. Serialization is not relied on during execution itself. | ||
| 187 | * | ||
| 188 | * @since 1.7 | ||
| 189 | * @author Doug Lea | ||
| 190 | */ | ||
| 191 | public abstract class ForkJoinTask<V> implements Future<V>, Serializable { | ||
| 192 | |||
| 193 | /* | ||
| 194 | * See the internal documentation of class ForkJoinPool for a | ||
| 195 | * general implementation overview. ForkJoinTasks are mainly | ||
| 196 | * responsible for maintaining their "status" field amidst relays | ||
| 197 | * to methods in ForkJoinWorkerThread and ForkJoinPool. The | ||
| 198 | * methods of this class are more-or-less layered into (1) basic | ||
| 199 | * status maintenance (2) execution and awaiting completion (3) | ||
| 200 | * user-level methods that additionally report results. This is | ||
| 201 | * sometimes hard to see because this file orders exported methods | ||
| 202 | * in a way that flows well in javadocs. | ||
| 203 | */ | ||
| 204 | |||
| 205 | /* | ||
| 206 | * The status field holds run control status bits packed into a | ||
| 207 | * single int to minimize footprint and to ensure atomicity (via | ||
| 208 | * CAS). Status is initially zero, and takes on nonnegative | ||
| 209 | * values until completed, upon which status holds value | ||
| 210 | * NORMAL, CANCELLED, or EXCEPTIONAL. Tasks undergoing blocking | ||
| 211 | * waits by other threads have the SIGNAL bit set. Completion of | ||
| 212 | * a stolen task with SIGNAL set awakens any waiters via | ||
| 213 | * notifyAll. Even though suboptimal for some purposes, we use | ||
| 214 | * basic builtin wait/notify to take advantage of "monitor | ||
| 215 | * inflation" in JVMs that we would otherwise need to emulate to | ||
| 216 | * avoid adding further per-task bookkeeping overhead. We want | ||
| 217 | * these monitors to be "fat", i.e., not use biasing or thin-lock | ||
| 218 | * techniques, so use some odd coding idioms that tend to avoid | ||
| 219 | * them. | ||
| 220 | */ | ||
| 221 | |||
| 222 | /** The run status of this task */ | ||
| 223 | volatile int status; // accessed directly by pool and workers | ||
| 224 | private static final int NORMAL = -1; | ||
| 225 | private static final int CANCELLED = -2; | ||
| 226 | private static final int EXCEPTIONAL = -3; | ||
| 227 | private static final int SIGNAL = 1; | ||
| 228 | |||
| 229 | /** | ||
| 230 | * Marks completion and wakes up threads waiting to join this task, | ||
| 231 | * also clearing signal request bits. | ||
| 232 | * | ||
| 233 | * @param completion one of NORMAL, CANCELLED, EXCEPTIONAL | ||
| 234 | * @return completion status on exit | ||
| 235 | */ | ||
| 236 | private int setCompletion(int completion) { | ||
| 237 | for (int s;;) { | ||
| 238 | if ((s = status) < 0) | ||
| 239 | return s; | ||
| 240 | if (UNSAFE.compareAndSwapInt(this, statusOffset, s, completion)) { | ||
| 241 | if (s != 0) | ||
| 242 | synchronized (this) { notifyAll(); } | ||
| 243 | return completion; | ||
| 244 | } | ||
| 245 | } | ||
| 246 | } | ||
| 247 | |||
| 248 | /** | ||
| 249 | * Tries to block a worker thread until completed or timed out. | ||
| 250 | * Uses Object.wait time argument conventions. | ||
| 251 | * May fail on contention or interrupt. | ||
| 252 | * | ||
| 253 | * @param millis if > 0, wait time. | ||
| 254 | */ | ||
| 255 | final void tryAwaitDone(long millis) { | ||
| 256 | int s; | ||
| 257 | try { | ||
| 258 | if (((s = status) > 0 || | ||
| 259 | (s == 0 && | ||
| 260 | UNSAFE.compareAndSwapInt(this, statusOffset, 0, SIGNAL))) && | ||
| 261 | status > 0) { | ||
| 262 | synchronized (this) { | ||
| 263 | if (status > 0) | ||
| 264 | wait(millis); | ||
| 265 | } | ||
| 266 | } | ||
| 267 | } catch (InterruptedException ie) { | ||
| 268 | // caller must check termination | ||
| 269 | } | ||
| 270 | } | ||
| 271 | |||
| 272 | /** | ||
| 273 | * Blocks a non-worker-thread until completion. | ||
| 274 | * @return status upon completion | ||
| 275 | */ | ||
| 276 | private int externalAwaitDone() { | ||
| 277 | int s; | ||
| 278 | if ((s = status) >= 0) { | ||
| 279 | boolean interrupted = false; | ||
| 280 | synchronized (this) { | ||
| 281 | while ((s = status) >= 0) { | ||
| 282 | if (s == 0) | ||
| 283 | UNSAFE.compareAndSwapInt(this, statusOffset, | ||
| 284 | 0, SIGNAL); | ||
| 285 | else { | ||
| 286 | try { | ||
| 287 | wait(); | ||
| 288 | } catch (InterruptedException ie) { | ||
| 289 | interrupted = true; | ||
| 290 | } | ||
| 291 | } | ||
| 292 | } | ||
| 293 | } | ||
| 294 | if (interrupted) | ||
| 295 | Thread.currentThread().interrupt(); | ||
| 296 | } | ||
| 297 | return s; | ||
| 298 | } | ||
| 299 | |||
| 300 | /** | ||
| 301 | * Blocks a non-worker-thread until completion or interruption or timeout. | ||
| 302 | */ | ||
| 303 | private int externalInterruptibleAwaitDone(long millis) | ||
| 304 | throws InterruptedException { | ||
| 305 | int s; | ||
| 306 | if (Thread.interrupted()) | ||
| 307 | throw new InterruptedException(); | ||
| 308 | if ((s = status) >= 0) { | ||
| 309 | synchronized (this) { | ||
| 310 | while ((s = status) >= 0) { | ||
| 311 | if (s == 0) | ||
| 312 | UNSAFE.compareAndSwapInt(this, statusOffset, | ||
| 313 | 0, SIGNAL); | ||
| 314 | else { | ||
| 315 | wait(millis); | ||
| 316 | if (millis > 0L) | ||
| 317 | break; | ||
| 318 | } | ||
| 319 | } | ||
| 320 | } | ||
| 321 | } | ||
| 322 | return s; | ||
| 323 | } | ||
| 324 | |||
| 325 | /** | ||
| 326 | * Primary execution method for stolen tasks. Unless done, calls | ||
| 327 | * exec and records status if completed, but doesn't wait for | ||
| 328 | * completion otherwise. | ||
| 329 | */ | ||
| 330 | final void doExec() { | ||
| 331 | if (status >= 0) { | ||
| 332 | boolean completed; | ||
| 333 | try { | ||
| 334 | completed = exec(); | ||
| 335 | } catch (Throwable rex) { | ||
| 336 | setExceptionalCompletion(rex); | ||
| 337 | return; | ||
| 338 | } | ||
| 339 | if (completed) | ||
| 340 | setCompletion(NORMAL); // must be outside try block | ||
| 341 | } | ||
| 342 | } | ||
| 343 | |||
| 344 | /** | ||
| 345 | * Primary mechanics for join, get, quietlyJoin. | ||
| 346 | * @return status upon completion | ||
| 347 | */ | ||
| 348 | private int doJoin() { | ||
| 349 | Thread t; ForkJoinWorkerThread w; int s; boolean completed; | ||
| 350 | if ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) { | ||
| 351 | if ((s = status) < 0) | ||
| 352 | return s; | ||
| 353 | if ((w = (ForkJoinWorkerThread)t).unpushTask(this)) { | ||
| 354 | try { | ||
| 355 | completed = exec(); | ||
| 356 | } catch (Throwable rex) { | ||
| 357 | return setExceptionalCompletion(rex); | ||
| 358 | } | ||
| 359 | if (completed) | ||
| 360 | return setCompletion(NORMAL); | ||
| 361 | } | ||
| 362 | return w.joinTask(this); | ||
| 363 | } | ||
| 364 | else | ||
| 365 | return externalAwaitDone(); | ||
| 366 | } | ||
| 367 | |||
| 368 | /** | ||
| 369 | * Primary mechanics for invoke, quietlyInvoke. | ||
| 370 | * @return status upon completion | ||
| 371 | */ | ||
| 372 | private int doInvoke() { | ||
| 373 | int s; boolean completed; | ||
| 374 | if ((s = status) < 0) | ||
| 375 | return s; | ||
| 376 | try { | ||
| 377 | completed = exec(); | ||
| 378 | } catch (Throwable rex) { | ||
| 379 | return setExceptionalCompletion(rex); | ||
| 380 | } | ||
| 381 | if (completed) | ||
| 382 | return setCompletion(NORMAL); | ||
| 383 | else | ||
| 384 | return doJoin(); | ||
| 385 | } | ||
| 386 | |||
| 387 | // Exception table support | ||
| 388 | |||
| 389 | /** | ||
| 390 | * Table of exceptions thrown by tasks, to enable reporting by | ||
| 391 | * callers. Because exceptions are rare, we don't directly keep | ||
| 392 | * them with task objects, but instead use a weak ref table. Note | ||
| 393 | * that cancellation exceptions don't appear in the table, but are | ||
| 394 | * instead recorded as status values. | ||
| 395 | * | ||
| 396 | * Note: These statics are initialized below in static block. | ||
| 397 | */ | ||
| 398 | private static final ExceptionNode[] exceptionTable; | ||
| 399 | private static final ReentrantLock exceptionTableLock; | ||
| 400 | private static final ReferenceQueue<Object> exceptionTableRefQueue; | ||
| 401 | |||
| 402 | /** | ||
| 403 | * Fixed capacity for exceptionTable. | ||
| 404 | */ | ||
| 405 | private static final int EXCEPTION_MAP_CAPACITY = 32; | ||
| 406 | |||
| 407 | /** | ||
| 408 | * Key-value nodes for exception table. The chained hash table | ||
| 409 | * uses identity comparisons, full locking, and weak references | ||
| 410 | * for keys. The table has a fixed capacity because it only | ||
| 411 | * maintains task exceptions long enough for joiners to access | ||
| 412 | * them, so should never become very large for sustained | ||
| 413 | * periods. However, since we do not know when the last joiner | ||
| 414 | * completes, we must use weak references and expunge them. We do | ||
| 415 | * so on each operation (hence full locking). Also, some thread in | ||
| 416 | * any ForkJoinPool will call helpExpungeStaleExceptions when its | ||
| 417 | * pool becomes isQuiescent. | ||
| 418 | */ | ||
| 419 | static final class ExceptionNode extends WeakReference<ForkJoinTask<?>>{ | ||
| 420 | final Throwable ex; | ||
| 421 | ExceptionNode next; | ||
| 422 | final long thrower; // use id not ref to avoid weak cycles | ||
| 423 | ExceptionNode(ForkJoinTask<?> task, Throwable ex, ExceptionNode next) { | ||
| 424 | super(task, exceptionTableRefQueue); | ||
| 425 | this.ex = ex; | ||
| 426 | this.next = next; | ||
| 427 | this.thrower = Thread.currentThread().getId(); | ||
| 428 | } | ||
| 429 | } | ||
| 430 | |||
| 431 | /** | ||
| 432 | * Records exception and sets exceptional completion. | ||
| 433 | * | ||
| 434 | * @return status on exit | ||
| 435 | */ | ||
| 436 | private int setExceptionalCompletion(Throwable ex) { | ||
| 437 | int h = System.identityHashCode(this); | ||
| 438 | final ReentrantLock lock = exceptionTableLock; | ||
| 439 | lock.lock(); | ||
| 440 | try { | ||
| 441 | expungeStaleExceptions(); | ||
| 442 | ExceptionNode[] t = exceptionTable; | ||
| 443 | int i = h & (t.length - 1); | ||
| 444 | for (ExceptionNode e = t[i]; ; e = e.next) { | ||
| 445 | if (e == null) { | ||
| 446 | t[i] = new ExceptionNode(this, ex, t[i]); | ||
| 447 | break; | ||
| 448 | } | ||
| 449 | if (e.get() == this) // already present | ||
| 450 | break; | ||
| 451 | } | ||
| 452 | } finally { | ||
| 453 | lock.unlock(); | ||
| 454 | } | ||
| 455 | return setCompletion(EXCEPTIONAL); | ||
| 456 | } | ||
| 457 | |||
| 458 | /** | ||
| 459 | * Removes exception node and clears status | ||
| 460 | */ | ||
| 461 | private void clearExceptionalCompletion() { | ||
| 462 | int h = System.identityHashCode(this); | ||
| 463 | final ReentrantLock lock = exceptionTableLock; | ||
| 464 | lock.lock(); | ||
| 465 | try { | ||
| 466 | ExceptionNode[] t = exceptionTable; | ||
| 467 | int i = h & (t.length - 1); | ||
| 468 | ExceptionNode e = t[i]; | ||
| 469 | ExceptionNode pred = null; | ||
| 470 | while (e != null) { | ||
| 471 | ExceptionNode next = e.next; | ||
| 472 | if (e.get() == this) { | ||
| 473 | if (pred == null) | ||
| 474 | t[i] = next; | ||
| 475 | else | ||
| 476 | pred.next = next; | ||
| 477 | break; | ||
| 478 | } | ||
| 479 | pred = e; | ||
| 480 | e = next; | ||
| 481 | } | ||
| 482 | expungeStaleExceptions(); | ||
| 483 | status = 0; | ||
| 484 | } finally { | ||
| 485 | lock.unlock(); | ||
| 486 | } | ||
| 487 | } | ||
| 488 | |||
| 489 | /** | ||
| 490 | * Returns a rethrowable exception for the given task, if | ||
| 491 | * available. To provide accurate stack traces, if the exception | ||
| 492 | * was not thrown by the current thread, we try to create a new | ||
| 493 | * exception of the same type as the one thrown, but with the | ||
| 494 | * recorded exception as its cause. If there is no such | ||
| 495 | * constructor, we instead try to use a no-arg constructor, | ||
| 496 | * followed by initCause, to the same effect. If none of these | ||
| 497 | * apply, or any fail due to other exceptions, we return the | ||
| 498 | * recorded exception, which is still correct, although it may | ||
| 499 | * contain a misleading stack trace. | ||
| 500 | * | ||
| 501 | * @return the exception, or null if none | ||
| 502 | */ | ||
| 503 | private Throwable getThrowableException() { | ||
| 504 | if (status != EXCEPTIONAL) | ||
| 505 | return null; | ||
| 506 | int h = System.identityHashCode(this); | ||
| 507 | ExceptionNode e; | ||
| 508 | final ReentrantLock lock = exceptionTableLock; | ||
| 509 | lock.lock(); | ||
| 510 | try { | ||
| 511 | expungeStaleExceptions(); | ||
| 512 | ExceptionNode[] t = exceptionTable; | ||
| 513 | e = t[h & (t.length - 1)]; | ||
| 514 | while (e != null && e.get() != this) | ||
| 515 | e = e.next; | ||
| 516 | } finally { | ||
| 517 | lock.unlock(); | ||
| 518 | } | ||
| 519 | Throwable ex; | ||
| 520 | if (e == null || (ex = e.ex) == null) | ||
| 521 | return null; | ||
| 522 | if (e.thrower != Thread.currentThread().getId()) { | ||
| 523 | Class ec = ex.getClass(); | ||
| 524 | try { | ||
| 525 | Constructor<?> noArgCtor = null; | ||
| 526 | Constructor<?>[] cs = ec.getConstructors();// public ctors only | ||
| 527 | for (int i = 0; i < cs.length; ++i) { | ||
| 528 | Constructor<?> c = cs[i]; | ||
| 529 | Class<?>[] ps = c.getParameterTypes(); | ||
| 530 | if (ps.length == 0) | ||
| 531 | noArgCtor = c; | ||
| 532 | else if (ps.length == 1 && ps[0] == Throwable.class) | ||
| 533 | return (Throwable)(c.newInstance(ex)); | ||
| 534 | } | ||
| 535 | if (noArgCtor != null) { | ||
| 536 | Throwable wx = (Throwable)(noArgCtor.newInstance()); | ||
| 537 | wx.initCause(ex); | ||
| 538 | return wx; | ||
| 539 | } | ||
| 540 | } catch (Exception ignore) { | ||
| 541 | } | ||
| 542 | } | ||
| 543 | return ex; | ||
| 544 | } | ||
| 545 | |||
| 546 | /** | ||
| 547 | * Poll stale refs and remove them. Call only while holding lock. | ||
| 548 | */ | ||
| 549 | private static void expungeStaleExceptions() { | ||
| 550 | for (Object x; (x = exceptionTableRefQueue.poll()) != null;) { | ||
| 551 | if (x instanceof ExceptionNode) { | ||
| 552 | ForkJoinTask<?> key = ((ExceptionNode)x).get(); | ||
| 553 | ExceptionNode[] t = exceptionTable; | ||
| 554 | int i = System.identityHashCode(key) & (t.length - 1); | ||
| 555 | ExceptionNode e = t[i]; | ||
| 556 | ExceptionNode pred = null; | ||
| 557 | while (e != null) { | ||
| 558 | ExceptionNode next = e.next; | ||
| 559 | if (e == x) { | ||
| 560 | if (pred == null) | ||
| 561 | t[i] = next; | ||
| 562 | else | ||
| 563 | pred.next = next; | ||
| 564 | break; | ||
| 565 | } | ||
| 566 | pred = e; | ||
| 567 | e = next; | ||
| 568 | } | ||
| 569 | } | ||
| 570 | } | ||
| 571 | } | ||
| 572 | |||
| 573 | /** | ||
| 574 | * If lock is available, poll stale refs and remove them. | ||
| 575 | * Called from ForkJoinPool when pools become quiescent. | ||
| 576 | */ | ||
| 577 | static final void helpExpungeStaleExceptions() { | ||
| 578 | final ReentrantLock lock = exceptionTableLock; | ||
| 579 | if (lock.tryLock()) { | ||
| 580 | try { | ||
| 581 | expungeStaleExceptions(); | ||
| 582 | } finally { | ||
| 583 | lock.unlock(); | ||
| 584 | } | ||
| 585 | } | ||
| 586 | } | ||
| 587 | |||
| 588 | /** | ||
| 589 | * Report the result of invoke or join; called only upon | ||
| 590 | * non-normal return of internal versions. | ||
| 591 | */ | ||
| 592 | private V reportResult() { | ||
| 593 | int s; Throwable ex; | ||
| 594 | if ((s = status) == CANCELLED) | ||
| 595 | throw new CancellationException(); | ||
| 596 | if (s == EXCEPTIONAL && (ex = getThrowableException()) != null) | ||
| 597 | UNSAFE.throwException(ex); | ||
| 598 | return getRawResult(); | ||
| 599 | } | ||
| 600 | |||
| 601 | // public methods | ||
| 602 | |||
| 603 | /** | ||
| 604 | * Arranges to asynchronously execute this task. While it is not | ||
| 605 | * necessarily enforced, it is a usage error to fork a task more | ||
| 606 | * than once unless it has completed and been reinitialized. | ||
| 607 | * Subsequent modifications to the state of this task or any data | ||
| 608 | * it operates on are not necessarily consistently observable by | ||
| 609 | * any thread other than the one executing it unless preceded by a | ||
| 610 | * call to {@link #join} or related methods, or a call to {@link | ||
| 611 | * #isDone} returning {@code true}. | ||
| 612 | * | ||
| 613 | * <p>This method may be invoked only from within {@code | ||
| 614 | * ForkJoinPool} computations (as may be determined using method | ||
| 615 | * {@link #inForkJoinPool}). Attempts to invoke in other contexts | ||
| 616 | * result in exceptions or errors, possibly including {@code | ||
| 617 | * ClassCastException}. | ||
| 618 | * | ||
| 619 | * @return {@code this}, to simplify usage | ||
| 620 | */ | ||
| 621 | public final ForkJoinTask<V> fork() { | ||
| 622 | ((ForkJoinWorkerThread) Thread.currentThread()) | ||
| 623 | .pushTask(this); | ||
| 624 | return this; | ||
| 625 | } | ||
| 626 | |||
| 627 | /** | ||
| 628 | * Returns the result of the computation when it {@link #isDone is | ||
| 629 | * done}. This method differs from {@link #get()} in that | ||
| 630 | * abnormal completion results in {@code RuntimeException} or | ||
| 631 | * {@code Error}, not {@code ExecutionException}, and that | ||
| 632 | * interrupts of the calling thread do <em>not</em> cause the | ||
| 633 | * method to abruptly return by throwing {@code | ||
| 634 | * InterruptedException}. | ||
| 635 | * | ||
| 636 | * @return the computed result | ||
| 637 | */ | ||
| 638 | public final V join() { | ||
| 639 | if (doJoin() != NORMAL) | ||
| 640 | return reportResult(); | ||
| 641 | else | ||
| 642 | return getRawResult(); | ||
| 643 | } | ||
| 644 | |||
| 645 | /** | ||
| 646 | * Commences performing this task, awaits its completion if | ||
| 647 | * necessary, and returns its result, or throws an (unchecked) | ||
| 648 | * {@code RuntimeException} or {@code Error} if the underlying | ||
| 649 | * computation did so. | ||
| 650 | * | ||
| 651 | * @return the computed result | ||
| 652 | */ | ||
| 653 | public final V invoke() { | ||
| 654 | if (doInvoke() != NORMAL) | ||
| 655 | return reportResult(); | ||
| 656 | else | ||
| 657 | return getRawResult(); | ||
| 658 | } | ||
| 659 | |||
| 660 | /** | ||
| 661 | * Forks the given tasks, returning when {@code isDone} holds for | ||
| 662 | * each task or an (unchecked) exception is encountered, in which | ||
| 663 | * case the exception is rethrown. If more than one task | ||
| 664 | * encounters an exception, then this method throws any one of | ||
| 665 | * these exceptions. If any task encounters an exception, the | ||
| 666 | * other may be cancelled. However, the execution status of | ||
| 667 | * individual tasks is not guaranteed upon exceptional return. The | ||
| 668 | * status of each task may be obtained using {@link | ||
| 669 | * #getException()} and related methods to check if they have been | ||
| 670 | * cancelled, completed normally or exceptionally, or left | ||
| 671 | * unprocessed. | ||
| 672 | * | ||
| 673 | * <p>This method may be invoked only from within {@code | ||
| 674 | * ForkJoinPool} computations (as may be determined using method | ||
| 675 | * {@link #inForkJoinPool}). Attempts to invoke in other contexts | ||
| 676 | * result in exceptions or errors, possibly including {@code | ||
| 677 | * ClassCastException}. | ||
| 678 | * | ||
| 679 | * @param t1 the first task | ||
| 680 | * @param t2 the second task | ||
| 681 | * @throws NullPointerException if any task is null | ||
| 682 | */ | ||
| 683 | public static void invokeAll(ForkJoinTask<?> t1, ForkJoinTask<?> t2) { | ||
| 684 | t2.fork(); | ||
| 685 | t1.invoke(); | ||
| 686 | t2.join(); | ||
| 687 | } | ||
| 688 | |||
| 689 | /** | ||
| 690 | * Forks the given tasks, returning when {@code isDone} holds for | ||
| 691 | * each task or an (unchecked) exception is encountered, in which | ||
| 692 | * case the exception is rethrown. If more than one task | ||
| 693 | * encounters an exception, then this method throws any one of | ||
| 694 | * these exceptions. If any task encounters an exception, others | ||
| 695 | * may be cancelled. However, the execution status of individual | ||
| 696 | * tasks is not guaranteed upon exceptional return. The status of | ||
| 697 | * each task may be obtained using {@link #getException()} and | ||
| 698 | * related methods to check if they have been cancelled, completed | ||
| 699 | * normally or exceptionally, or left unprocessed. | ||
| 700 | * | ||
| 701 | * <p>This method may be invoked only from within {@code | ||
| 702 | * ForkJoinPool} computations (as may be determined using method | ||
| 703 | * {@link #inForkJoinPool}). Attempts to invoke in other contexts | ||
| 704 | * result in exceptions or errors, possibly including {@code | ||
| 705 | * ClassCastException}. | ||
| 706 | * | ||
| 707 | * @param tasks the tasks | ||
| 708 | * @throws NullPointerException if any task is null | ||
| 709 | */ | ||
| 710 | public static void invokeAll(ForkJoinTask<?>... tasks) { | ||
| 711 | Throwable ex = null; | ||
| 712 | int last = tasks.length - 1; | ||
| 713 | for (int i = last; i >= 0; --i) { | ||
| 714 | ForkJoinTask<?> t = tasks[i]; | ||
| 715 | if (t == null) { | ||
| 716 | if (ex == null) | ||
| 717 | ex = new NullPointerException(); | ||
| 718 | } | ||
| 719 | else if (i != 0) | ||
| 720 | t.fork(); | ||
| 721 | else if (t.doInvoke() < NORMAL && ex == null) | ||
| 722 | ex = t.getException(); | ||
| 723 | } | ||
| 724 | for (int i = 1; i <= last; ++i) { | ||
| 725 | ForkJoinTask<?> t = tasks[i]; | ||
| 726 | if (t != null) { | ||
| 727 | if (ex != null) | ||
| 728 | t.cancel(false); | ||
| 729 | else if (t.doJoin() < NORMAL && ex == null) | ||
| 730 | ex = t.getException(); | ||
| 731 | } | ||
| 732 | } | ||
| 733 | if (ex != null) | ||
| 734 | UNSAFE.throwException(ex); | ||
| 735 | } | ||
| 736 | |||
| 737 | /** | ||
| 738 | * Forks all tasks in the specified collection, returning when | ||
| 739 | * {@code isDone} holds for each task or an (unchecked) exception | ||
| 740 | * is encountered, in which case the exception is rethrown. If | ||
| 741 | * more than one task encounters an exception, then this method | ||
| 742 | * throws any one of these exceptions. If any task encounters an | ||
| 743 | * exception, others may be cancelled. However, the execution | ||
| 744 | * status of individual tasks is not guaranteed upon exceptional | ||
| 745 | * return. The status of each task may be obtained using {@link | ||
| 746 | * #getException()} and related methods to check if they have been | ||
| 747 | * cancelled, completed normally or exceptionally, or left | ||
| 748 | * unprocessed. | ||
| 749 | * | ||
| 750 | * <p>This method may be invoked only from within {@code | ||
| 751 | * ForkJoinPool} computations (as may be determined using method | ||
| 752 | * {@link #inForkJoinPool}). Attempts to invoke in other contexts | ||
| 753 | * result in exceptions or errors, possibly including {@code | ||
| 754 | * ClassCastException}. | ||
| 755 | * | ||
| 756 | * @param tasks the collection of tasks | ||
| 757 | * @return the tasks argument, to simplify usage | ||
| 758 | * @throws NullPointerException if tasks or any element are null | ||
| 759 | */ | ||
| 760 | public static <T extends ForkJoinTask<?>> Collection<T> invokeAll(Collection<T> tasks) { | ||
| 761 | if (!(tasks instanceof RandomAccess) || !(tasks instanceof List<?>)) { | ||
| 762 | invokeAll(tasks.toArray(new ForkJoinTask<?>[tasks.size()])); | ||
| 763 | return tasks; | ||
| 764 | } | ||
| 765 | @SuppressWarnings("unchecked") | ||
| 766 | List<? extends ForkJoinTask<?>> ts = | ||
| 767 | (List<? extends ForkJoinTask<?>>) tasks; | ||
| 768 | Throwable ex = null; | ||
| 769 | int last = ts.size() - 1; | ||
| 770 | for (int i = last; i >= 0; --i) { | ||
| 771 | ForkJoinTask<?> t = ts.get(i); | ||
| 772 | if (t == null) { | ||
| 773 | if (ex == null) | ||
| 774 | ex = new NullPointerException(); | ||
| 775 | } | ||
| 776 | else if (i != 0) | ||
| 777 | t.fork(); | ||
| 778 | else if (t.doInvoke() < NORMAL && ex == null) | ||
| 779 | ex = t.getException(); | ||
| 780 | } | ||
| 781 | for (int i = 1; i <= last; ++i) { | ||
| 782 | ForkJoinTask<?> t = ts.get(i); | ||
| 783 | if (t != null) { | ||
| 784 | if (ex != null) | ||
| 785 | t.cancel(false); | ||
| 786 | else if (t.doJoin() < NORMAL && ex == null) | ||
| 787 | ex = t.getException(); | ||
| 788 | } | ||
| 789 | } | ||
| 790 | if (ex != null) | ||
| 791 | UNSAFE.throwException(ex); | ||
| 792 | return tasks; | ||
| 793 | } | ||
| 794 | |||
| 795 | /** | ||
| 796 | * Attempts to cancel execution of this task. This attempt will | ||
| 797 | * fail if the task has already completed or could not be | ||
| 798 | * cancelled for some other reason. If successful, and this task | ||
| 799 | * has not started when {@code cancel} is called, execution of | ||
| 800 | * this task is suppressed. After this method returns | ||
| 801 | * successfully, unless there is an intervening call to {@link | ||
| 802 | * #reinitialize}, subsequent calls to {@link #isCancelled}, | ||
| 803 | * {@link #isDone}, and {@code cancel} will return {@code true} | ||
| 804 | * and calls to {@link #join} and related methods will result in | ||
| 805 | * {@code CancellationException}. | ||
| 806 | * | ||
| 807 | * <p>This method may be overridden in subclasses, but if so, must | ||
| 808 | * still ensure that these properties hold. In particular, the | ||
| 809 | * {@code cancel} method itself must not throw exceptions. | ||
| 810 | * | ||
| 811 | * <p>This method is designed to be invoked by <em>other</em> | ||
| 812 | * tasks. To terminate the current task, you can just return or | ||
| 813 | * throw an unchecked exception from its computation method, or | ||
| 814 | * invoke {@link #completeExceptionally}. | ||
| 815 | * | ||
| 816 | * @param mayInterruptIfRunning this value has no effect in the | ||
| 817 | * default implementation because interrupts are not used to | ||
| 818 | * control cancellation. | ||
| 819 | * | ||
| 820 | * @return {@code true} if this task is now cancelled | ||
| 821 | */ | ||
| 822 | public boolean cancel(boolean mayInterruptIfRunning) { | ||
| 823 | return setCompletion(CANCELLED) == CANCELLED; | ||
| 824 | } | ||
| 825 | |||
| 826 | /** | ||
| 827 | * Cancels, ignoring any exceptions thrown by cancel. Used during | ||
| 828 | * worker and pool shutdown. Cancel is spec'ed not to throw any | ||
| 829 | * exceptions, but if it does anyway, we have no recourse during | ||
| 830 | * shutdown, so guard against this case. | ||
| 831 | */ | ||
| 832 | final void cancelIgnoringExceptions() { | ||
| 833 | try { | ||
| 834 | cancel(false); | ||
| 835 | } catch (Throwable ignore) { | ||
| 836 | } | ||
| 837 | } | ||
| 838 | |||
| 839 | public final boolean isDone() { | ||
| 840 | return status < 0; | ||
| 841 | } | ||
| 842 | |||
| 843 | public final boolean isCancelled() { | ||
| 844 | return status == CANCELLED; | ||
| 845 | } | ||
| 846 | |||
| 847 | /** | ||
| 848 | * Returns {@code true} if this task threw an exception or was cancelled. | ||
| 849 | * | ||
| 850 | * @return {@code true} if this task threw an exception or was cancelled | ||
| 851 | */ | ||
| 852 | public final boolean isCompletedAbnormally() { | ||
| 853 | return status < NORMAL; | ||
| 854 | } | ||
| 855 | |||
| 856 | /** | ||
| 857 | * Returns {@code true} if this task completed without throwing an | ||
| 858 | * exception and was not cancelled. | ||
| 859 | * | ||
| 860 | * @return {@code true} if this task completed without throwing an | ||
| 861 | * exception and was not cancelled | ||
| 862 | */ | ||
| 863 | public final boolean isCompletedNormally() { | ||
| 864 | return status == NORMAL; | ||
| 865 | } | ||
| 866 | |||
| 867 | /** | ||
| 868 | * Returns the exception thrown by the base computation, or a | ||
| 869 | * {@code CancellationException} if cancelled, or {@code null} if | ||
| 870 | * none or if the method has not yet completed. | ||
| 871 | * | ||
| 872 | * @return the exception, or {@code null} if none | ||
| 873 | */ | ||
| 874 | public final Throwable getException() { | ||
| 875 | int s = status; | ||
| 876 | return ((s >= NORMAL) ? null : | ||
| 877 | (s == CANCELLED) ? new CancellationException() : | ||
| 878 | getThrowableException()); | ||
| 879 | } | ||
| 880 | |||
| 881 | /** | ||
| 882 | * Completes this task abnormally, and if not already aborted or | ||
| 883 | * cancelled, causes it to throw the given exception upon | ||
| 884 | * {@code join} and related operations. This method may be used | ||
| 885 | * to induce exceptions in asynchronous tasks, or to force | ||
| 886 | * completion of tasks that would not otherwise complete. Its use | ||
| 887 | * in other situations is discouraged. This method is | ||
| 888 | * overridable, but overridden versions must invoke {@code super} | ||
| 889 | * implementation to maintain guarantees. | ||
| 890 | * | ||
| 891 | * @param ex the exception to throw. If this exception is not a | ||
| 892 | * {@code RuntimeException} or {@code Error}, the actual exception | ||
| 893 | * thrown will be a {@code RuntimeException} with cause {@code ex}. | ||
| 894 | */ | ||
| 895 | public void completeExceptionally(Throwable ex) { | ||
| 896 | setExceptionalCompletion((ex instanceof RuntimeException) || | ||
| 897 | (ex instanceof Error) ? ex : | ||
| 898 | new RuntimeException(ex)); | ||
| 899 | } | ||
| 900 | |||
| 901 | /** | ||
| 902 | * Completes this task, and if not already aborted or cancelled, | ||
| 903 | * returning the given value as the result of subsequent | ||
| 904 | * invocations of {@code join} and related operations. This method | ||
| 905 | * may be used to provide results for asynchronous tasks, or to | ||
| 906 | * provide alternative handling for tasks that would not otherwise | ||
| 907 | * complete normally. Its use in other situations is | ||
| 908 | * discouraged. This method is overridable, but overridden | ||
| 909 | * versions must invoke {@code super} implementation to maintain | ||
| 910 | * guarantees. | ||
| 911 | * | ||
| 912 | * @param value the result value for this task | ||
| 913 | */ | ||
| 914 | public void complete(V value) { | ||
| 915 | try { | ||
| 916 | setRawResult(value); | ||
| 917 | } catch (Throwable rex) { | ||
| 918 | setExceptionalCompletion(rex); | ||
| 919 | return; | ||
| 920 | } | ||
| 921 | setCompletion(NORMAL); | ||
| 922 | } | ||
| 923 | |||
| 924 | /** | ||
| 925 | * Waits if necessary for the computation to complete, and then | ||
| 926 | * retrieves its result. | ||
| 927 | * | ||
| 928 | * @return the computed result | ||
| 929 | * @throws CancellationException if the computation was cancelled | ||
| 930 | * @throws ExecutionException if the computation threw an | ||
| 931 | * exception | ||
| 932 | * @throws InterruptedException if the current thread is not a | ||
| 933 | * member of a ForkJoinPool and was interrupted while waiting | ||
| 934 | */ | ||
| 935 | public final V get() throws InterruptedException, ExecutionException { | ||
| 936 | int s = (Thread.currentThread() instanceof ForkJoinWorkerThread) ? | ||
| 937 | doJoin() : externalInterruptibleAwaitDone(0L); | ||
| 938 | Throwable ex; | ||
| 939 | if (s == CANCELLED) | ||
| 940 | throw new CancellationException(); | ||
| 941 | if (s == EXCEPTIONAL && (ex = getThrowableException()) != null) | ||
| 942 | throw new ExecutionException(ex); | ||
| 943 | return getRawResult(); | ||
| 944 | } | ||
| 945 | |||
| 946 | /** | ||
| 947 | * Waits if necessary for at most the given time for the computation | ||
| 948 | * to complete, and then retrieves its result, if available. | ||
| 949 | * | ||
| 950 | * @param timeout the maximum time to wait | ||
| 951 | * @param unit the time unit of the timeout argument | ||
| 952 | * @return the computed result | ||
| 953 | * @throws CancellationException if the computation was cancelled | ||
| 954 | * @throws ExecutionException if the computation threw an | ||
| 955 | * exception | ||
| 956 | * @throws InterruptedException if the current thread is not a | ||
| 957 | * member of a ForkJoinPool and was interrupted while waiting | ||
| 958 | * @throws TimeoutException if the wait timed out | ||
| 959 | */ | ||
| 960 | public final V get(long timeout, TimeUnit unit) | ||
| 961 | throws InterruptedException, ExecutionException, TimeoutException { | ||
| 962 | Thread t = Thread.currentThread(); | ||
| 963 | if (t instanceof ForkJoinWorkerThread) { | ||
| 964 | ForkJoinWorkerThread w = (ForkJoinWorkerThread) t; | ||
| 965 | long nanos = unit.toNanos(timeout); | ||
| 966 | if (status >= 0) { | ||
| 967 | boolean completed = false; | ||
| 968 | if (w.unpushTask(this)) { | ||
| 969 | try { | ||
| 970 | completed = exec(); | ||
| 971 | } catch (Throwable rex) { | ||
| 972 | setExceptionalCompletion(rex); | ||
| 973 | } | ||
| 974 | } | ||
| 975 | if (completed) | ||
| 976 | setCompletion(NORMAL); | ||
| 977 | else if (status >= 0 && nanos > 0) | ||
| 978 | w.pool.timedAwaitJoin(this, nanos); | ||
| 979 | } | ||
| 980 | } | ||
| 981 | else { | ||
| 982 | long millis = unit.toMillis(timeout); | ||
| 983 | if (millis > 0) | ||
| 984 | externalInterruptibleAwaitDone(millis); | ||
| 985 | } | ||
| 986 | int s = status; | ||
| 987 | if (s != NORMAL) { | ||
| 988 | Throwable ex; | ||
| 989 | if (s == CANCELLED) | ||
| 990 | throw new CancellationException(); | ||
| 991 | if (s != EXCEPTIONAL) | ||
| 992 | throw new TimeoutException(); | ||
| 993 | if ((ex = getThrowableException()) != null) | ||
| 994 | throw new ExecutionException(ex); | ||
| 995 | } | ||
| 996 | return getRawResult(); | ||
| 997 | } | ||
| 998 | |||
| 999 | /** | ||
| 1000 | * Joins this task, without returning its result or throwing its | ||
| 1001 | * exception. This method may be useful when processing | ||
| 1002 | * collections of tasks when some have been cancelled or otherwise | ||
| 1003 | * known to have aborted. | ||
| 1004 | */ | ||
| 1005 | public final void quietlyJoin() { | ||
| 1006 | doJoin(); | ||
| 1007 | } | ||
| 1008 | |||
| 1009 | /** | ||
| 1010 | * Commences performing this task and awaits its completion if | ||
| 1011 | * necessary, without returning its result or throwing its | ||
| 1012 | * exception. | ||
| 1013 | */ | ||
| 1014 | public final void quietlyInvoke() { | ||
| 1015 | doInvoke(); | ||
| 1016 | } | ||
| 1017 | |||
| 1018 | /** | ||
| 1019 | * Possibly executes tasks until the pool hosting the current task | ||
| 1020 | * {@link ForkJoinPool#isQuiescent is quiescent}. This method may | ||
| 1021 | * be of use in designs in which many tasks are forked, but none | ||
| 1022 | * are explicitly joined, instead executing them until all are | ||
| 1023 | * processed. | ||
| 1024 | * | ||
| 1025 | * <p>This method may be invoked only from within {@code | ||
| 1026 | * ForkJoinPool} computations (as may be determined using method | ||
| 1027 | * {@link #inForkJoinPool}). Attempts to invoke in other contexts | ||
| 1028 | * result in exceptions or errors, possibly including {@code | ||
| 1029 | * ClassCastException}. | ||
| 1030 | */ | ||
| 1031 | public static void helpQuiesce() { | ||
| 1032 | ((ForkJoinWorkerThread) Thread.currentThread()) | ||
| 1033 | .helpQuiescePool(); | ||
| 1034 | } | ||
| 1035 | |||
| 1036 | /** | ||
| 1037 | * Resets the internal bookkeeping state of this task, allowing a | ||
| 1038 | * subsequent {@code fork}. This method allows repeated reuse of | ||
| 1039 | * this task, but only if reuse occurs when this task has either | ||
| 1040 | * never been forked, or has been forked, then completed and all | ||
| 1041 | * outstanding joins of this task have also completed. Effects | ||
| 1042 | * under any other usage conditions are not guaranteed. | ||
| 1043 | * This method may be useful when executing | ||
| 1044 | * pre-constructed trees of subtasks in loops. | ||
| 1045 | * | ||
| 1046 | * <p>Upon completion of this method, {@code isDone()} reports | ||
| 1047 | * {@code false}, and {@code getException()} reports {@code | ||
| 1048 | * null}. However, the value returned by {@code getRawResult} is | ||
| 1049 | * unaffected. To clear this value, you can invoke {@code | ||
| 1050 | * setRawResult(null)}. | ||
| 1051 | */ | ||
| 1052 | public void reinitialize() { | ||
| 1053 | if (status == EXCEPTIONAL) | ||
| 1054 | clearExceptionalCompletion(); | ||
| 1055 | else | ||
| 1056 | status = 0; | ||
| 1057 | } | ||
| 1058 | |||
| 1059 | /** | ||
| 1060 | * Returns the pool hosting the current task execution, or null | ||
| 1061 | * if this task is executing outside of any ForkJoinPool. | ||
| 1062 | * | ||
| 1063 | * @see #inForkJoinPool | ||
| 1064 | * @return the pool, or {@code null} if none | ||
| 1065 | */ | ||
| 1066 | public static ForkJoinPool getPool() { | ||
| 1067 | Thread t = Thread.currentThread(); | ||
| 1068 | return (t instanceof ForkJoinWorkerThread) ? | ||
| 1069 | ((ForkJoinWorkerThread) t).pool : null; | ||
| 1070 | } | ||
| 1071 | |||
| 1072 | /** | ||
| 1073 | * Returns {@code true} if the current thread is a {@link | ||
| 1074 | * ForkJoinWorkerThread} executing as a ForkJoinPool computation. | ||
| 1075 | * | ||
| 1076 | * @return {@code true} if the current thread is a {@link | ||
| 1077 | * ForkJoinWorkerThread} executing as a ForkJoinPool computation, | ||
| 1078 | * or {@code false} otherwise | ||
| 1079 | */ | ||
| 1080 | public static boolean inForkJoinPool() { | ||
| 1081 | return Thread.currentThread() instanceof ForkJoinWorkerThread; | ||
| 1082 | } | ||
| 1083 | |||
| 1084 | /** | ||
| 1085 | * Tries to unschedule this task for execution. This method will | ||
| 1086 | * typically succeed if this task is the most recently forked task | ||
| 1087 | * by the current thread, and has not commenced executing in | ||
| 1088 | * another thread. This method may be useful when arranging | ||
| 1089 | * alternative local processing of tasks that could have been, but | ||
| 1090 | * were not, stolen. | ||
| 1091 | * | ||
| 1092 | * <p>This method may be invoked only from within {@code | ||
| 1093 | * ForkJoinPool} computations (as may be determined using method | ||
| 1094 | * {@link #inForkJoinPool}). Attempts to invoke in other contexts | ||
| 1095 | * result in exceptions or errors, possibly including {@code | ||
| 1096 | * ClassCastException}. | ||
| 1097 | * | ||
| 1098 | * @return {@code true} if unforked | ||
| 1099 | */ | ||
| 1100 | public boolean tryUnfork() { | ||
| 1101 | return ((ForkJoinWorkerThread) Thread.currentThread()) | ||
| 1102 | .unpushTask(this); | ||
| 1103 | } | ||
| 1104 | |||
| 1105 | /** | ||
| 1106 | * Returns an estimate of the number of tasks that have been | ||
| 1107 | * forked by the current worker thread but not yet executed. This | ||
| 1108 | * value may be useful for heuristic decisions about whether to | ||
| 1109 | * fork other tasks. | ||
| 1110 | * | ||
| 1111 | * <p>This method may be invoked only from within {@code | ||
| 1112 | * ForkJoinPool} computations (as may be determined using method | ||
| 1113 | * {@link #inForkJoinPool}). Attempts to invoke in other contexts | ||
| 1114 | * result in exceptions or errors, possibly including {@code | ||
| 1115 | * ClassCastException}. | ||
| 1116 | * | ||
| 1117 | * @return the number of tasks | ||
| 1118 | */ | ||
| 1119 | public static int getQueuedTaskCount() { | ||
| 1120 | return ((ForkJoinWorkerThread) Thread.currentThread()) | ||
| 1121 | .getQueueSize(); | ||
| 1122 | } | ||
| 1123 | |||
| 1124 | /** | ||
| 1125 | * Returns an estimate of how many more locally queued tasks are | ||
| 1126 | * held by the current worker thread than there are other worker | ||
| 1127 | * threads that might steal them. This value may be useful for | ||
| 1128 | * heuristic decisions about whether to fork other tasks. In many | ||
| 1129 | * usages of ForkJoinTasks, at steady state, each worker should | ||
| 1130 | * aim to maintain a small constant surplus (for example, 3) of | ||
| 1131 | * tasks, and to process computations locally if this threshold is | ||
| 1132 | * exceeded. | ||
| 1133 | * | ||
| 1134 | * <p>This method may be invoked only from within {@code | ||
| 1135 | * ForkJoinPool} computations (as may be determined using method | ||
| 1136 | * {@link #inForkJoinPool}). Attempts to invoke in other contexts | ||
| 1137 | * result in exceptions or errors, possibly including {@code | ||
| 1138 | * ClassCastException}. | ||
| 1139 | * | ||
| 1140 | * @return the surplus number of tasks, which may be negative | ||
| 1141 | */ | ||
| 1142 | public static int getSurplusQueuedTaskCount() { | ||
| 1143 | return ((ForkJoinWorkerThread) Thread.currentThread()) | ||
| 1144 | .getEstimatedSurplusTaskCount(); | ||
| 1145 | } | ||
| 1146 | |||
| 1147 | // Extension methods | ||
| 1148 | |||
| 1149 | /** | ||
| 1150 | * Returns the result that would be returned by {@link #join}, even | ||
| 1151 | * if this task completed abnormally, or {@code null} if this task | ||
| 1152 | * is not known to have been completed. This method is designed | ||
| 1153 | * to aid debugging, as well as to support extensions. Its use in | ||
| 1154 | * any other context is discouraged. | ||
| 1155 | * | ||
| 1156 | * @return the result, or {@code null} if not completed | ||
| 1157 | */ | ||
| 1158 | public abstract V getRawResult(); | ||
| 1159 | |||
| 1160 | /** | ||
| 1161 | * Forces the given value to be returned as a result. This method | ||
| 1162 | * is designed to support extensions, and should not in general be | ||
| 1163 | * called otherwise. | ||
| 1164 | * | ||
| 1165 | * @param value the value | ||
| 1166 | */ | ||
| 1167 | protected abstract void setRawResult(V value); | ||
| 1168 | |||
| 1169 | /** | ||
| 1170 | * Immediately performs the base action of this task. This method | ||
| 1171 | * is designed to support extensions, and should not in general be | ||
| 1172 | * called otherwise. The return value controls whether this task | ||
| 1173 | * is considered to be done normally. It may return false in | ||
| 1174 | * asynchronous actions that require explicit invocations of | ||
| 1175 | * {@link #complete} to become joinable. It may also throw an | ||
| 1176 | * (unchecked) exception to indicate abnormal exit. | ||
| 1177 | * | ||
| 1178 | * @return {@code true} if completed normally | ||
| 1179 | */ | ||
| 1180 | protected abstract boolean exec(); | ||
| 1181 | |||
| 1182 | /** | ||
| 1183 | * Returns, but does not unschedule or execute, a task queued by | ||
| 1184 | * the current thread but not yet executed, if one is immediately | ||
| 1185 | * available. There is no guarantee that this task will actually | ||
| 1186 | * be polled or executed next. Conversely, this method may return | ||
| 1187 | * null even if a task exists but cannot be accessed without | ||
| 1188 | * contention with other threads. This method is designed | ||
| 1189 | * primarily to support extensions, and is unlikely to be useful | ||
| 1190 | * otherwise. | ||
| 1191 | * | ||
| 1192 | * <p>This method may be invoked only from within {@code | ||
| 1193 | * ForkJoinPool} computations (as may be determined using method | ||
| 1194 | * {@link #inForkJoinPool}). Attempts to invoke in other contexts | ||
| 1195 | * result in exceptions or errors, possibly including {@code | ||
| 1196 | * ClassCastException}. | ||
| 1197 | * | ||
| 1198 | * @return the next task, or {@code null} if none are available | ||
| 1199 | */ | ||
| 1200 | protected static ForkJoinTask<?> peekNextLocalTask() { | ||
| 1201 | return ((ForkJoinWorkerThread) Thread.currentThread()) | ||
| 1202 | .peekTask(); | ||
| 1203 | } | ||
| 1204 | |||
| 1205 | /** | ||
| 1206 | * Unschedules and returns, without executing, the next task | ||
| 1207 | * queued by the current thread but not yet executed. This method | ||
| 1208 | * is designed primarily to support extensions, and is unlikely to | ||
| 1209 | * be useful otherwise. | ||
| 1210 | * | ||
| 1211 | * <p>This method may be invoked only from within {@code | ||
| 1212 | * ForkJoinPool} computations (as may be determined using method | ||
| 1213 | * {@link #inForkJoinPool}). Attempts to invoke in other contexts | ||
| 1214 | * result in exceptions or errors, possibly including {@code | ||
| 1215 | * ClassCastException}. | ||
| 1216 | * | ||
| 1217 | * @return the next task, or {@code null} if none are available | ||
| 1218 | */ | ||
| 1219 | protected static ForkJoinTask<?> pollNextLocalTask() { | ||
| 1220 | return ((ForkJoinWorkerThread) Thread.currentThread()) | ||
| 1221 | .pollLocalTask(); | ||
| 1222 | } | ||
| 1223 | |||
| 1224 | /** | ||
| 1225 | * Unschedules and returns, without executing, the next task | ||
| 1226 | * queued by the current thread but not yet executed, if one is | ||
| 1227 | * available, or if not available, a task that was forked by some | ||
| 1228 | * other thread, if available. Availability may be transient, so a | ||
| 1229 | * {@code null} result does not necessarily imply quiescence | ||
| 1230 | * of the pool this task is operating in. This method is designed | ||
| 1231 | * primarily to support extensions, and is unlikely to be useful | ||
| 1232 | * otherwise. | ||
| 1233 | * | ||
| 1234 | * <p>This method may be invoked only from within {@code | ||
| 1235 | * ForkJoinPool} computations (as may be determined using method | ||
| 1236 | * {@link #inForkJoinPool}). Attempts to invoke in other contexts | ||
| 1237 | * result in exceptions or errors, possibly including {@code | ||
| 1238 | * ClassCastException}. | ||
| 1239 | * | ||
| 1240 | * @return a task, or {@code null} if none are available | ||
| 1241 | */ | ||
| 1242 | protected static ForkJoinTask<?> pollTask() { | ||
| 1243 | return ((ForkJoinWorkerThread) Thread.currentThread()) | ||
| 1244 | .pollTask(); | ||
| 1245 | } | ||
| 1246 | |||
| 1247 | /** | ||
| 1248 | * Adaptor for Runnables. This implements RunnableFuture | ||
| 1249 | * to be compliant with AbstractExecutorService constraints | ||
| 1250 | * when used in ForkJoinPool. | ||
| 1251 | */ | ||
| 1252 | static final class AdaptedRunnable<T> extends ForkJoinTask<T> | ||
| 1253 | implements RunnableFuture<T> { | ||
| 1254 | final Runnable runnable; | ||
| 1255 | final T resultOnCompletion; | ||
| 1256 | T result; | ||
| 1257 | AdaptedRunnable(Runnable runnable, T result) { | ||
| 1258 | if (runnable == null) throw new NullPointerException(); | ||
| 1259 | this.runnable = runnable; | ||
| 1260 | this.resultOnCompletion = result; | ||
| 1261 | } | ||
| 1262 | public T getRawResult() { return result; } | ||
| 1263 | public void setRawResult(T v) { result = v; } | ||
| 1264 | public boolean exec() { | ||
| 1265 | runnable.run(); | ||
| 1266 | result = resultOnCompletion; | ||
| 1267 | return true; | ||
| 1268 | } | ||
| 1269 | public void run() { invoke(); } | ||
| 1270 | private static final long serialVersionUID = 5232453952276885070L; | ||
| 1271 | } | ||
| 1272 | |||
| 1273 | /** | ||
| 1274 | * Adaptor for Callables | ||
| 1275 | */ | ||
| 1276 | static final class AdaptedCallable<T> extends ForkJoinTask<T> | ||
| 1277 | implements RunnableFuture<T> { | ||
| 1278 | final Callable<? extends T> callable; | ||
| 1279 | T result; | ||
| 1280 | AdaptedCallable(Callable<? extends T> callable) { | ||
| 1281 | if (callable == null) throw new NullPointerException(); | ||
| 1282 | this.callable = callable; | ||
| 1283 | } | ||
| 1284 | public T getRawResult() { return result; } | ||
| 1285 | public void setRawResult(T v) { result = v; } | ||
| 1286 | public boolean exec() { | ||
| 1287 | try { | ||
| 1288 | result = callable.call(); | ||
| 1289 | return true; | ||
| 1290 | } catch (Error err) { | ||
| 1291 | throw err; | ||
| 1292 | } catch (RuntimeException rex) { | ||
| 1293 | throw rex; | ||
| 1294 | } catch (Exception ex) { | ||
| 1295 | throw new RuntimeException(ex); | ||
| 1296 | } | ||
| 1297 | } | ||
| 1298 | public void run() { invoke(); } | ||
| 1299 | private static final long serialVersionUID = 2838392045355241008L; | ||
| 1300 | } | ||
| 1301 | |||
| 1302 | /** | ||
| 1303 | * Returns a new {@code ForkJoinTask} that performs the {@code run} | ||
| 1304 | * method of the given {@code Runnable} as its action, and returns | ||
| 1305 | * a null result upon {@link #join}. | ||
| 1306 | * | ||
| 1307 | * @param runnable the runnable action | ||
| 1308 | * @return the task | ||
| 1309 | */ | ||
| 1310 | public static ForkJoinTask<?> adapt(Runnable runnable) { | ||
| 1311 | return new AdaptedRunnable<Void>(runnable, null); | ||
| 1312 | } | ||
| 1313 | |||
| 1314 | /** | ||
| 1315 | * Returns a new {@code ForkJoinTask} that performs the {@code run} | ||
| 1316 | * method of the given {@code Runnable} as its action, and returns | ||
| 1317 | * the given result upon {@link #join}. | ||
| 1318 | * | ||
| 1319 | * @param runnable the runnable action | ||
| 1320 | * @param result the result upon completion | ||
| 1321 | * @return the task | ||
| 1322 | */ | ||
| 1323 | public static <T> ForkJoinTask<T> adapt(Runnable runnable, T result) { | ||
| 1324 | return new AdaptedRunnable<T>(runnable, result); | ||
| 1325 | } | ||
| 1326 | |||
| 1327 | /** | ||
| 1328 | * Returns a new {@code ForkJoinTask} that performs the {@code call} | ||
| 1329 | * method of the given {@code Callable} as its action, and returns | ||
| 1330 | * its result upon {@link #join}, translating any checked exceptions | ||
| 1331 | * encountered into {@code RuntimeException}. | ||
| 1332 | * | ||
| 1333 | * @param callable the callable action | ||
| 1334 | * @return the task | ||
| 1335 | */ | ||
| 1336 | public static <T> ForkJoinTask<T> adapt(Callable<? extends T> callable) { | ||
| 1337 | return new AdaptedCallable<T>(callable); | ||
| 1338 | } | ||
| 1339 | |||
| 1340 | // Serialization support | ||
| 1341 | |||
| 1342 | private static final long serialVersionUID = -7721805057305804111L; | ||
| 1343 | |||
| 1344 | /** | ||
| 1345 | * Saves the state to a stream (that is, serializes it). | ||
| 1346 | * | ||
| 1347 | * @serialData the current run status and the exception thrown | ||
| 1348 | * during execution, or {@code null} if none | ||
| 1349 | * @param s the stream | ||
| 1350 | */ | ||
| 1351 | private void writeObject(java.io.ObjectOutputStream s) | ||
| 1352 | throws java.io.IOException { | ||
| 1353 | s.defaultWriteObject(); | ||
| 1354 | s.writeObject(getException()); | ||
| 1355 | } | ||
| 1356 | |||
| 1357 | /** | ||
| 1358 | * Reconstitutes the instance from a stream (that is, deserializes it). | ||
| 1359 | * | ||
| 1360 | * @param s the stream | ||
| 1361 | */ | ||
| 1362 | private void readObject(java.io.ObjectInputStream s) | ||
| 1363 | throws java.io.IOException, ClassNotFoundException { | ||
| 1364 | s.defaultReadObject(); | ||
| 1365 | Object ex = s.readObject(); | ||
| 1366 | if (ex != null) | ||
| 1367 | setExceptionalCompletion((Throwable)ex); | ||
| 1368 | } | ||
| 1369 | |||
| 1370 | // Unsafe mechanics | ||
| 1371 | private static final sun.misc.Unsafe UNSAFE; | ||
| 1372 | private static final long statusOffset; | ||
| 1373 | static { | ||
| 1374 | exceptionTableLock = new ReentrantLock(); | ||
| 1375 | exceptionTableRefQueue = new ReferenceQueue<Object>(); | ||
| 1376 | exceptionTable = new ExceptionNode[EXCEPTION_MAP_CAPACITY]; | ||
| 1377 | try { | ||
| 1378 | UNSAFE = sun.misc.Unsafe.getUnsafe(); | ||
| 1379 | statusOffset = UNSAFE.objectFieldOffset | ||
| 1380 | (ForkJoinTask.class.getDeclaredField("status")); | ||
| 1381 | } catch (Exception e) { | ||
| 1382 | throw new Error(e); | ||
| 1383 | } | ||
| 1384 | } | ||
| 1385 | |||
| 1386 | } | ||
Binary file not shown.
| @@ -0,0 +1,998 @@ | |||
| 1 | /* | ||
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 3 | * | ||
| 4 | * This code is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License version 2 only, as | ||
| 6 | * published by the Free Software Foundation. Oracle designates this | ||
| 7 | * particular file as subject to the "Classpath" exception as provided | ||
| 8 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 9 | * | ||
| 10 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 13 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 14 | * accompanied this code). | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License version | ||
| 17 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | * | ||
| 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 21 | * or visit www.oracle.com if you need additional information or have any | ||
| 22 | * questions. | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * This file is available under and governed by the GNU General Public | ||
| 27 | * License version 2 only, as published by the Free Software Foundation. | ||
| 28 | * However, the following notice accompanied the original version of this | ||
| 29 | * file: | ||
| 30 | * | ||
| 31 | * Written by Doug Lea with assistance from members of JCP JSR-166 | ||
| 32 | * Expert Group and released to the public domain, as explained at | ||
| 33 | * http://creativecommons.org/publicdomain/zero/1.0/ | ||
| 34 | */ | ||
| 35 | |||
| 36 | package java.util.concurrent; | ||
| 37 | |||
| 38 | import java.util.Collection; | ||
| 39 | import java.util.concurrent.RejectedExecutionException; | ||
| 40 | |||
| 41 | /** | ||
| 42 | * A thread managed by a {@link ForkJoinPool}, which executes | ||
| 43 | * {@link ForkJoinTask}s. | ||
| 44 | * This class is subclassable solely for the sake of adding | ||
| 45 | * functionality -- there are no overridable methods dealing with | ||
| 46 | * scheduling or execution. However, you can override initialization | ||
| 47 | * and termination methods surrounding the main task processing loop. | ||
| 48 | * If you do create such a subclass, you will also need to supply a | ||
| 49 | * custom {@link ForkJoinPool.ForkJoinWorkerThreadFactory} to use it | ||
| 50 | * in a {@code ForkJoinPool}. | ||
| 51 | * | ||
| 52 | * @since 1.7 | ||
| 53 | * @author Doug Lea | ||
| 54 | */ | ||
| 55 | public class ForkJoinWorkerThread extends Thread { | ||
| 56 | /* | ||
| 57 | * Overview: | ||
| 58 | * | ||
| 59 | * ForkJoinWorkerThreads are managed by ForkJoinPools and perform | ||
| 60 | * ForkJoinTasks. This class includes bookkeeping in support of | ||
| 61 | * worker activation, suspension, and lifecycle control described | ||
| 62 | * in more detail in the internal documentation of class | ||
| 63 | * ForkJoinPool. And as described further below, this class also | ||
| 64 | * includes special-cased support for some ForkJoinTask | ||
| 65 | * methods. But the main mechanics involve work-stealing: | ||
| 66 | * | ||
| 67 | * Work-stealing queues are special forms of Deques that support | ||
| 68 | * only three of the four possible end-operations -- push, pop, | ||
| 69 | * and deq (aka steal), under the further constraints that push | ||
| 70 | * and pop are called only from the owning thread, while deq may | ||
| 71 | * be called from other threads. (If you are unfamiliar with | ||
| 72 | * them, you probably want to read Herlihy and Shavit's book "The | ||
| 73 | * Art of Multiprocessor programming", chapter 16 describing these | ||
| 74 | * in more detail before proceeding.) The main work-stealing | ||
| 75 | * queue design is roughly similar to those in the papers "Dynamic | ||
| 76 | * Circular Work-Stealing Deque" by Chase and Lev, SPAA 2005 | ||
| 77 | * (http://research.sun.com/scalable/pubs/index.html) and | ||
| 78 | * "Idempotent work stealing" by Michael, Saraswat, and Vechev, | ||
| 79 | * PPoPP 2009 (http://portal.acm.org/citation.cfm?id=1504186). | ||
| 80 | * The main differences ultimately stem from gc requirements that | ||
| 81 | * we null out taken slots as soon as we can, to maintain as small | ||
| 82 | * a footprint as possible even in programs generating huge | ||
| 83 | * numbers of tasks. To accomplish this, we shift the CAS | ||
| 84 | * arbitrating pop vs deq (steal) from being on the indices | ||
| 85 | * ("queueBase" and "queueTop") to the slots themselves (mainly | ||
| 86 | * via method "casSlotNull()"). So, both a successful pop and deq | ||
| 87 | * mainly entail a CAS of a slot from non-null to null. Because | ||
| 88 | * we rely on CASes of references, we do not need tag bits on | ||
| 89 | * queueBase or queueTop. They are simple ints as used in any | ||
| 90 | * circular array-based queue (see for example ArrayDeque). | ||
| 91 | * Updates to the indices must still be ordered in a way that | ||
| 92 | * guarantees that queueTop == queueBase means the queue is empty, | ||
| 93 | * but otherwise may err on the side of possibly making the queue | ||
| 94 | * appear nonempty when a push, pop, or deq have not fully | ||
| 95 | * committed. Note that this means that the deq operation, | ||
| 96 | * considered individually, is not wait-free. One thief cannot | ||
| 97 | * successfully continue until another in-progress one (or, if | ||
| 98 | * previously empty, a push) completes. However, in the | ||
| 99 | * aggregate, we ensure at least probabilistic non-blockingness. | ||
| 100 | * If an attempted steal fails, a thief always chooses a different | ||
| 101 | * random victim target to try next. So, in order for one thief to | ||
| 102 | * progress, it suffices for any in-progress deq or new push on | ||
| 103 | * any empty queue to complete. | ||
| 104 | * | ||
| 105 | * This approach also enables support for "async mode" where local | ||
| 106 | * task processing is in FIFO, not LIFO order; simply by using a | ||
| 107 | * version of deq rather than pop when locallyFifo is true (as set | ||
| 108 | * by the ForkJoinPool). This allows use in message-passing | ||
| 109 | * frameworks in which tasks are never joined. However neither | ||
| 110 | * mode considers affinities, loads, cache localities, etc, so | ||
| 111 | * rarely provide the best possible performance on a given | ||
| 112 | * machine, but portably provide good throughput by averaging over | ||
| 113 | * these factors. (Further, even if we did try to use such | ||
| 114 | * information, we do not usually have a basis for exploiting | ||
| 115 | * it. For example, some sets of tasks profit from cache | ||
| 116 | * affinities, but others are harmed by cache pollution effects.) | ||
| 117 | * | ||
| 118 | * When a worker would otherwise be blocked waiting to join a | ||
| 119 | * task, it first tries a form of linear helping: Each worker | ||
| 120 | * records (in field currentSteal) the most recent task it stole | ||
| 121 | * from some other worker. Plus, it records (in field currentJoin) | ||
| 122 | * the task it is currently actively joining. Method joinTask uses | ||
| 123 | * these markers to try to find a worker to help (i.e., steal back | ||
| 124 | * a task from and execute it) that could hasten completion of the | ||
| 125 | * actively joined task. In essence, the joiner executes a task | ||
| 126 | * that would be on its own local deque had the to-be-joined task | ||
| 127 | * not been stolen. This may be seen as a conservative variant of | ||
| 128 | * the approach in Wagner & Calder "Leapfrogging: a portable | ||
| 129 | * technique for implementing efficient futures" SIGPLAN Notices, | ||
| 130 | * 1993 (http://portal.acm.org/citation.cfm?id=155354). It differs | ||
| 131 | * in that: (1) We only maintain dependency links across workers | ||
| 132 | * upon steals, rather than use per-task bookkeeping. This may | ||
| 133 | * require a linear scan of workers array to locate stealers, but | ||
| 134 | * usually doesn't because stealers leave hints (that may become | ||
| 135 | * stale/wrong) of where to locate them. This isolates cost to | ||
| 136 | * when it is needed, rather than adding to per-task overhead. | ||
| 137 | * (2) It is "shallow", ignoring nesting and potentially cyclic | ||
| 138 | * mutual steals. (3) It is intentionally racy: field currentJoin | ||
| 139 | * is updated only while actively joining, which means that we | ||
| 140 | * miss links in the chain during long-lived tasks, GC stalls etc | ||
| 141 | * (which is OK since blocking in such cases is usually a good | ||
| 142 | * idea). (4) We bound the number of attempts to find work (see | ||
| 143 | * MAX_HELP) and fall back to suspending the worker and if | ||
| 144 | * necessary replacing it with another. | ||
| 145 | * | ||
| 146 | * Efficient implementation of these algorithms currently relies | ||
| 147 | * on an uncomfortable amount of "Unsafe" mechanics. To maintain | ||
| 148 | * correct orderings, reads and writes of variable queueBase | ||
| 149 | * require volatile ordering. Variable queueTop need not be | ||
| 150 | * volatile because non-local reads always follow those of | ||
| 151 | * queueBase. Similarly, because they are protected by volatile | ||
| 152 | * queueBase reads, reads of the queue array and its slots by | ||
| 153 | * other threads do not need volatile load semantics, but writes | ||
| 154 | * (in push) require store order and CASes (in pop and deq) | ||
| 155 | * require (volatile) CAS semantics. (Michael, Saraswat, and | ||
| 156 | * Vechev's algorithm has similar properties, but without support | ||
| 157 | * for nulling slots.) Since these combinations aren't supported | ||
| 158 | * using ordinary volatiles, the only way to accomplish these | ||
| 159 | * efficiently is to use direct Unsafe calls. (Using external | ||
| 160 | * AtomicIntegers and AtomicReferenceArrays for the indices and | ||
| 161 | * array is significantly slower because of memory locality and | ||
| 162 | * indirection effects.) | ||
| 163 | * | ||
| 164 | * Further, performance on most platforms is very sensitive to | ||
| 165 | * placement and sizing of the (resizable) queue array. Even | ||
| 166 | * though these queues don't usually become all that big, the | ||
| 167 | * initial size must be large enough to counteract cache | ||
| 168 | * contention effects across multiple queues (especially in the | ||
| 169 | * presence of GC cardmarking). Also, to improve thread-locality, | ||
| 170 | * queues are initialized after starting. | ||
| 171 | */ | ||
| 172 | |||
| 173 | /** | ||
| 174 | * Mask for pool indices encoded as shorts | ||
| 175 | */ | ||
| 176 | private static final int SMASK = 0xffff; | ||
| 177 | |||
| 178 | /** | ||
| 179 | * Capacity of work-stealing queue array upon initialization. | ||
| 180 | * Must be a power of two. Initial size must be at least 4, but is | ||
| 181 | * padded to minimize cache effects. | ||
| 182 | */ | ||
| 183 | private static final int INITIAL_QUEUE_CAPACITY = 1 << 13; | ||
| 184 | |||
| 185 | /** | ||
| 186 | * Maximum size for queue array. Must be a power of two | ||
| 187 | * less than or equal to 1 << (31 - width of array entry) to | ||
| 188 | * ensure lack of index wraparound, but is capped at a lower | ||
| 189 | * value to help users trap runaway computations. | ||
| 190 | */ | ||
| 191 | private static final int MAXIMUM_QUEUE_CAPACITY = 1 << 24; // 16M | ||
| 192 | |||
| 193 | /** | ||
| 194 | * The work-stealing queue array. Size must be a power of two. | ||
| 195 | * Initialized when started (as oposed to when constructed), to | ||
| 196 | * improve memory locality. | ||
| 197 | */ | ||
| 198 | ForkJoinTask<?>[] queue; | ||
| 199 | |||
| 200 | /** | ||
| 201 | * The pool this thread works in. Accessed directly by ForkJoinTask. | ||
| 202 | */ | ||
| 203 | final ForkJoinPool pool; | ||
| 204 | |||
| 205 | /** | ||
| 206 | * Index (mod queue.length) of next queue slot to push to or pop | ||
| 207 | * from. It is written only by owner thread, and accessed by other | ||
| 208 | * threads only after reading (volatile) queueBase. Both queueTop | ||
| 209 | * and queueBase are allowed to wrap around on overflow, but | ||
| 210 | * (queueTop - queueBase) still estimates size. | ||
| 211 | */ | ||
| 212 | int queueTop; | ||
| 213 | |||
| 214 | /** | ||
| 215 | * Index (mod queue.length) of least valid queue slot, which is | ||
| 216 | * always the next position to steal from if nonempty. | ||
| 217 | */ | ||
| 218 | volatile int queueBase; | ||
| 219 | |||
| 220 | /** | ||
| 221 | * The index of most recent stealer, used as a hint to avoid | ||
| 222 | * traversal in method helpJoinTask. This is only a hint because a | ||
| 223 | * worker might have had multiple steals and this only holds one | ||
| 224 | * of them (usually the most current). Declared non-volatile, | ||
| 225 | * relying on other prevailing sync to keep reasonably current. | ||
| 226 | */ | ||
| 227 | int stealHint; | ||
| 228 | |||
| 229 | /** | ||
| 230 | * Index of this worker in pool array. Set once by pool before | ||
| 231 | * running, and accessed directly by pool to locate this worker in | ||
| 232 | * its workers array. | ||
| 233 | */ | ||
| 234 | final int poolIndex; | ||
| 235 | |||
| 236 | /** | ||
| 237 | * Encoded record for pool task waits. Usages are always | ||
| 238 | * surrounded by volatile reads/writes | ||
| 239 | */ | ||
| 240 | int nextWait; | ||
| 241 | |||
| 242 | /** | ||
| 243 | * Complement of poolIndex, offset by count of entries of task | ||
| 244 | * waits. Accessed by ForkJoinPool to manage event waiters. | ||
| 245 | */ | ||
| 246 | volatile int eventCount; | ||
| 247 | |||
| 248 | /** | ||
| 249 | * Seed for random number generator for choosing steal victims. | ||
| 250 | * Uses Marsaglia xorshift. Must be initialized as nonzero. | ||
| 251 | */ | ||
| 252 | int seed; | ||
| 253 | |||
| 254 | /** | ||
| 255 | * Number of steals. Directly accessed (and reset) by pool when | ||
| 256 | * idle. | ||
| 257 | */ | ||
| 258 | int stealCount; | ||
| 259 | |||
| 260 | /** | ||
| 261 | * True if this worker should or did terminate | ||
| 262 | */ | ||
| 263 | volatile boolean terminate; | ||
| 264 | |||
| 265 | /** | ||
| 266 | * Set to true before LockSupport.park; false on return | ||
| 267 | */ | ||
| 268 | volatile boolean parked; | ||
| 269 | |||
| 270 | /** | ||
| 271 | * True if use local fifo, not default lifo, for local polling. | ||
| 272 | * Shadows value from ForkJoinPool. | ||
| 273 | */ | ||
| 274 | final boolean locallyFifo; | ||
| 275 | |||
| 276 | /** | ||
| 277 | * The task most recently stolen from another worker (or | ||
| 278 | * submission queue). All uses are surrounded by enough volatile | ||
| 279 | * reads/writes to maintain as non-volatile. | ||
| 280 | */ | ||
| 281 | ForkJoinTask<?> currentSteal; | ||
| 282 | |||
| 283 | /** | ||
| 284 | * The task currently being joined, set only when actively trying | ||
| 285 | * to help other stealers in helpJoinTask. All uses are surrounded | ||
| 286 | * by enough volatile reads/writes to maintain as non-volatile. | ||
| 287 | */ | ||
| 288 | ForkJoinTask<?> currentJoin; | ||
| 289 | |||
| 290 | /** | ||
| 291 | * Creates a ForkJoinWorkerThread operating in the given pool. | ||
| 292 | * | ||
| 293 | * @param pool the pool this thread works in | ||
| 294 | * @throws NullPointerException if pool is null | ||
| 295 | */ | ||
| 296 | protected ForkJoinWorkerThread(ForkJoinPool pool) { | ||
| 297 | super(pool.nextWorkerName()); | ||
| 298 | this.pool = pool; | ||
| 299 | int k = pool.registerWorker(this); | ||
| 300 | poolIndex = k; | ||
| 301 | eventCount = ~k & SMASK; // clear wait count | ||
| 302 | locallyFifo = pool.locallyFifo; | ||
| 303 | Thread.UncaughtExceptionHandler ueh = pool.ueh; | ||
| 304 | if (ueh != null) | ||
| 305 | setUncaughtExceptionHandler(ueh); | ||
| 306 | setDaemon(true); | ||
| 307 | } | ||
| 308 | |||
| 309 | // Public methods | ||
| 310 | |||
| 311 | /** | ||
| 312 | * Returns the pool hosting this thread. | ||
| 313 | * | ||
| 314 | * @return the pool | ||
| 315 | */ | ||
| 316 | public ForkJoinPool getPool() { | ||
| 317 | return pool; | ||
| 318 | } | ||
| 319 | |||
| 320 | /** | ||
| 321 | * Returns the index number of this thread in its pool. The | ||
| 322 | * returned value ranges from zero to the maximum number of | ||
| 323 | * threads (minus one) that have ever been created in the pool. | ||
| 324 | * This method may be useful for applications that track status or | ||
| 325 | * collect results per-worker rather than per-task. | ||
| 326 | * | ||
| 327 | * @return the index number | ||
| 328 | */ | ||
| 329 | public int getPoolIndex() { | ||
| 330 | return poolIndex; | ||
| 331 | } | ||
| 332 | |||
| 333 | // Randomization | ||
| 334 | |||
| 335 | /** | ||
| 336 | * Computes next value for random victim probes and backoffs. | ||
| 337 | * Scans don't require a very high quality generator, but also not | ||
| 338 | * a crummy one. Marsaglia xor-shift is cheap and works well | ||
| 339 | * enough. Note: This is manually inlined in FJP.scan() to avoid | ||
| 340 | * writes inside busy loops. | ||
| 341 | */ | ||
| 342 | private int nextSeed() { | ||
| 343 | int r = seed; | ||
| 344 | r ^= r << 13; | ||
| 345 | r ^= r >>> 17; | ||
| 346 | r ^= r << 5; | ||
| 347 | return seed = r; | ||
| 348 | } | ||
| 349 | |||
| 350 | // Run State management | ||
| 351 | |||
| 352 | /** | ||
| 353 | * Initializes internal state after construction but before | ||
| 354 | * processing any tasks. If you override this method, you must | ||
| 355 | * invoke {@code super.onStart()} at the beginning of the method. | ||
| 356 | * Initialization requires care: Most fields must have legal | ||
| 357 | * default values, to ensure that attempted accesses from other | ||
| 358 | * threads work correctly even before this thread starts | ||
| 359 | * processing tasks. | ||
| 360 | */ | ||
| 361 | protected void onStart() { | ||
| 362 | queue = new ForkJoinTask<?>[INITIAL_QUEUE_CAPACITY]; | ||
| 363 | int r = pool.workerSeedGenerator.nextInt(); | ||
| 364 | seed = (r == 0) ? 1 : r; // must be nonzero | ||
| 365 | } | ||
| 366 | |||
| 367 | /** | ||
| 368 | * Performs cleanup associated with termination of this worker | ||
| 369 | * thread. If you override this method, you must invoke | ||
| 370 | * {@code super.onTermination} at the end of the overridden method. | ||
| 371 | * | ||
| 372 | * @param exception the exception causing this thread to abort due | ||
| 373 | * to an unrecoverable error, or {@code null} if completed normally | ||
| 374 | */ | ||
| 375 | protected void onTermination(Throwable exception) { | ||
| 376 | try { | ||
| 377 | terminate = true; | ||
| 378 | cancelTasks(); | ||
| 379 | pool.deregisterWorker(this, exception); | ||
| 380 | } catch (Throwable ex) { // Shouldn't ever happen | ||
| 381 | if (exception == null) // but if so, at least rethrown | ||
| 382 | exception = ex; | ||
| 383 | } finally { | ||
| 384 | if (exception != null) | ||
| 385 | UNSAFE.throwException(exception); | ||
| 386 | } | ||
| 387 | } | ||
| 388 | |||
| 389 | /** | ||
| 390 | * This method is required to be public, but should never be | ||
| 391 | * called explicitly. It performs the main run loop to execute | ||
| 392 | * {@link ForkJoinTask}s. | ||
| 393 | */ | ||
| 394 | public void run() { | ||
| 395 | Throwable exception = null; | ||
| 396 | try { | ||
| 397 | onStart(); | ||
| 398 | pool.work(this); | ||
| 399 | } catch (Throwable ex) { | ||
| 400 | exception = ex; | ||
| 401 | } finally { | ||
| 402 | onTermination(exception); | ||
| 403 | } | ||
| 404 | } | ||
| 405 | |||
| 406 | /* | ||
| 407 | * Intrinsics-based atomic writes for queue slots. These are | ||
| 408 | * basically the same as methods in AtomicReferenceArray, but | ||
| 409 | * specialized for (1) ForkJoinTask elements (2) requirement that | ||
| 410 | * nullness and bounds checks have already been performed by | ||
| 411 | * callers and (3) effective offsets are known not to overflow | ||
| 412 | * from int to long (because of MAXIMUM_QUEUE_CAPACITY). We don't | ||
| 413 | * need corresponding version for reads: plain array reads are OK | ||
| 414 | * because they are protected by other volatile reads and are | ||
| 415 | * confirmed by CASes. | ||
| 416 | * | ||
| 417 | * Most uses don't actually call these methods, but instead | ||
| 418 | * contain inlined forms that enable more predictable | ||
| 419 | * optimization. We don't define the version of write used in | ||
| 420 | * pushTask at all, but instead inline there a store-fenced array | ||
| 421 | * slot write. | ||
| 422 | * | ||
| 423 | * Also in most methods, as a performance (not correctness) issue, | ||
| 424 | * we'd like to encourage compilers not to arbitrarily postpone | ||
| 425 | * setting queueTop after writing slot. Currently there is no | ||
| 426 | * intrinsic for arranging this, but using Unsafe putOrderedInt | ||
| 427 | * may be a preferable strategy on some compilers even though its | ||
| 428 | * main effect is a pre-, not post- fence. To simplify possible | ||
| 429 | * changes, the option is left in comments next to the associated | ||
| 430 | * assignments. | ||
| 431 | */ | ||
| 432 | |||
| 433 | /** | ||
| 434 | * CASes slot i of array q from t to null. Caller must ensure q is | ||
| 435 | * non-null and index is in range. | ||
| 436 | */ | ||
| 437 | private static final boolean casSlotNull(ForkJoinTask<?>[] q, int i, | ||
| 438 | ForkJoinTask<?> t) { | ||
| 439 | return UNSAFE.compareAndSwapObject(q, (i << ASHIFT) + ABASE, t, null); | ||
| 440 | } | ||
| 441 | |||
| 442 | /** | ||
| 443 | * Performs a volatile write of the given task at given slot of | ||
| 444 | * array q. Caller must ensure q is non-null and index is in | ||
| 445 | * range. This method is used only during resets and backouts. | ||
| 446 | */ | ||
| 447 | private static final void writeSlot(ForkJoinTask<?>[] q, int i, | ||
| 448 | ForkJoinTask<?> t) { | ||
| 449 | UNSAFE.putObjectVolatile(q, (i << ASHIFT) + ABASE, t); | ||
| 450 | } | ||
| 451 | |||
| 452 | // queue methods | ||
| 453 | |||
| 454 | /** | ||
| 455 | * Pushes a task. Call only from this thread. | ||
| 456 | * | ||
| 457 | * @param t the task. Caller must ensure non-null. | ||
| 458 | */ | ||
| 459 | final void pushTask(ForkJoinTask<?> t) { | ||
| 460 | ForkJoinTask<?>[] q; int s, m; | ||
| 461 | if ((q = queue) != null) { // ignore if queue removed | ||
| 462 | long u = (((s = queueTop) & (m = q.length - 1)) << ASHIFT) + ABASE; | ||
| 463 | UNSAFE.putOrderedObject(q, u, t); | ||
| 464 | queueTop = s + 1; // or use putOrderedInt | ||
| 465 | if ((s -= queueBase) <= 2) | ||
| 466 | pool.signalWork(); | ||
| 467 | else if (s == m) | ||
| 468 | growQueue(); | ||
| 469 | } | ||
| 470 | } | ||
| 471 | |||
| 472 | /** | ||
| 473 | * Creates or doubles queue array. Transfers elements by | ||
| 474 | * emulating steals (deqs) from old array and placing, oldest | ||
| 475 | * first, into new array. | ||
| 476 | */ | ||
| 477 | private void growQueue() { | ||
| 478 | ForkJoinTask<?>[] oldQ = queue; | ||
| 479 | int size = oldQ != null ? oldQ.length << 1 : INITIAL_QUEUE_CAPACITY; | ||
| 480 | if (size > MAXIMUM_QUEUE_CAPACITY) | ||
| 481 | throw new RejectedExecutionException("Queue capacity exceeded"); | ||
| 482 | if (size < INITIAL_QUEUE_CAPACITY) | ||
| 483 | size = INITIAL_QUEUE_CAPACITY; | ||
| 484 | ForkJoinTask<?>[] q = queue = new ForkJoinTask<?>[size]; | ||
| 485 | int mask = size - 1; | ||
| 486 | int top = queueTop; | ||
| 487 | int oldMask; | ||
| 488 | if (oldQ != null && (oldMask = oldQ.length - 1) >= 0) { | ||
| 489 | for (int b = queueBase; b != top; ++b) { | ||
| 490 | long u = ((b & oldMask) << ASHIFT) + ABASE; | ||
| 491 | Object x = UNSAFE.getObjectVolatile(oldQ, u); | ||
| 492 | if (x != null && UNSAFE.compareAndSwapObject(oldQ, u, x, null)) | ||
| 493 | UNSAFE.putObjectVolatile | ||
| 494 | (q, ((b & mask) << ASHIFT) + ABASE, x); | ||
| 495 | } | ||
| 496 | } | ||
| 497 | } | ||
| 498 | |||
| 499 | /** | ||
| 500 | * Tries to take a task from the base of the queue, failing if | ||
| 501 | * empty or contended. Note: Specializations of this code appear | ||
| 502 | * in locallyDeqTask and elsewhere. | ||
| 503 | * | ||
| 504 | * @return a task, or null if none or contended | ||
| 505 | */ | ||
| 506 | final ForkJoinTask<?> deqTask() { | ||
| 507 | ForkJoinTask<?> t; ForkJoinTask<?>[] q; int b, i; | ||
| 508 | if (queueTop != (b = queueBase) && | ||
| 509 | (q = queue) != null && // must read q after b | ||
| 510 | (i = (q.length - 1) & b) >= 0 && | ||
| 511 | (t = q[i]) != null && queueBase == b && | ||
| 512 | UNSAFE.compareAndSwapObject(q, (i << ASHIFT) + ABASE, t, null)) { | ||
| 513 | queueBase = b + 1; | ||
| 514 | return t; | ||
| 515 | } | ||
| 516 | return null; | ||
| 517 | } | ||
| 518 | |||
| 519 | /** | ||
| 520 | * Tries to take a task from the base of own queue. Called only | ||
| 521 | * by this thread. | ||
| 522 | * | ||
| 523 | * @return a task, or null if none | ||
| 524 | */ | ||
| 525 | final ForkJoinTask<?> locallyDeqTask() { | ||
| 526 | ForkJoinTask<?> t; int m, b, i; | ||
| 527 | ForkJoinTask<?>[] q = queue; | ||
| 528 | if (q != null && (m = q.length - 1) >= 0) { | ||
| 529 | while (queueTop != (b = queueBase)) { | ||
| 530 | if ((t = q[i = m & b]) != null && | ||
| 531 | queueBase == b && | ||
| 532 | UNSAFE.compareAndSwapObject(q, (i << ASHIFT) + ABASE, | ||
| 533 | t, null)) { | ||
| 534 | queueBase = b + 1; | ||
| 535 | return t; | ||
| 536 | } | ||
| 537 | } | ||
| 538 | } | ||
| 539 | return null; | ||
| 540 | } | ||
| 541 | |||
| 542 | /** | ||
| 543 | * Returns a popped task, or null if empty. | ||
| 544 | * Called only by this thread. | ||
| 545 | */ | ||
| 546 | private ForkJoinTask<?> popTask() { | ||
| 547 | int m; | ||
| 548 | ForkJoinTask<?>[] q = queue; | ||
| 549 | if (q != null && (m = q.length - 1) >= 0) { | ||
| 550 | for (int s; (s = queueTop) != queueBase;) { | ||
| 551 | int i = m & --s; | ||
| 552 | long u = (i << ASHIFT) + ABASE; // raw offset | ||
| 553 | ForkJoinTask<?> t = q[i]; | ||
| 554 | if (t == null) // lost to stealer | ||
| 555 | break; | ||
| 556 | if (UNSAFE.compareAndSwapObject(q, u, t, null)) { | ||
| 557 | queueTop = s; // or putOrderedInt | ||
| 558 | return t; | ||
| 559 | } | ||
| 560 | } | ||
| 561 | } | ||
| 562 | return null; | ||
| 563 | } | ||
| 564 | |||
| 565 | /** | ||
| 566 | * Specialized version of popTask to pop only if topmost element | ||
| 567 | * is the given task. Called only by this thread. | ||
| 568 | * | ||
| 569 | * @param t the task. Caller must ensure non-null. | ||
| 570 | */ | ||
| 571 | final boolean unpushTask(ForkJoinTask<?> t) { | ||
| 572 | ForkJoinTask<?>[] q; | ||
| 573 | int s; | ||
| 574 | if ((q = queue) != null && (s = queueTop) != queueBase && | ||
| 575 | UNSAFE.compareAndSwapObject | ||
| 576 | (q, (((q.length - 1) & --s) << ASHIFT) + ABASE, t, null)) { | ||
| 577 | queueTop = s; // or putOrderedInt | ||
| 578 | return true; | ||
| 579 | } | ||
| 580 | return false; | ||
| 581 | } | ||
| 582 | |||
| 583 | /** | ||
| 584 | * Returns next task, or null if empty or contended. | ||
| 585 | */ | ||
| 586 | final ForkJoinTask<?> peekTask() { | ||
| 587 | int m; | ||
| 588 | ForkJoinTask<?>[] q = queue; | ||
| 589 | if (q == null || (m = q.length - 1) < 0) | ||
| 590 | return null; | ||
| 591 | int i = locallyFifo ? queueBase : (queueTop - 1); | ||
| 592 | return q[i & m]; | ||
| 593 | } | ||
| 594 | |||
| 595 | // Support methods for ForkJoinPool | ||
| 596 | |||
| 597 | /** | ||
| 598 | * Runs the given task, plus any local tasks until queue is empty | ||
| 599 | */ | ||
| 600 | final void execTask(ForkJoinTask<?> t) { | ||
| 601 | currentSteal = t; | ||
| 602 | for (;;) { | ||
| 603 | if (t != null) | ||
| 604 | t.doExec(); | ||
| 605 | if (queueTop == queueBase) | ||
| 606 | break; | ||
| 607 | t = locallyFifo ? locallyDeqTask() : popTask(); | ||
| 608 | } | ||
| 609 | ++stealCount; | ||
| 610 | currentSteal = null; | ||
| 611 | } | ||
| 612 | |||
| 613 | /** | ||
| 614 | * Removes and cancels all tasks in queue. Can be called from any | ||
| 615 | * thread. | ||
| 616 | */ | ||
| 617 | final void cancelTasks() { | ||
| 618 | ForkJoinTask<?> cj = currentJoin; // try to cancel ongoing tasks | ||
| 619 | if (cj != null && cj.status >= 0) | ||
| 620 | cj.cancelIgnoringExceptions(); | ||
| 621 | ForkJoinTask<?> cs = currentSteal; | ||
| 622 | if (cs != null && cs.status >= 0) | ||
| 623 | cs.cancelIgnoringExceptions(); | ||
| 624 | while (queueBase != queueTop) { | ||
| 625 | ForkJoinTask<?> t = deqTask(); | ||
| 626 | if (t != null) | ||
| 627 | t.cancelIgnoringExceptions(); | ||
| 628 | } | ||
| 629 | } | ||
| 630 | |||
| 631 | /** | ||
| 632 | * Drains tasks to given collection c. | ||
| 633 | * | ||
| 634 | * @return the number of tasks drained | ||
| 635 | */ | ||
| 636 | final int drainTasksTo(Collection<? super ForkJoinTask<?>> c) { | ||
| 637 | int n = 0; | ||
| 638 | while (queueBase != queueTop) { | ||
| 639 | ForkJoinTask<?> t = deqTask(); | ||
| 640 | if (t != null) { | ||
| 641 | c.add(t); | ||
| 642 | ++n; | ||
| 643 | } | ||
| 644 | } | ||
| 645 | return n; | ||
| 646 | } | ||
| 647 | |||
| 648 | // Support methods for ForkJoinTask | ||
| 649 | |||
| 650 | /** | ||
| 651 | * Returns an estimate of the number of tasks in the queue. | ||
| 652 | */ | ||
| 653 | final int getQueueSize() { | ||
| 654 | return queueTop - queueBase; | ||
| 655 | } | ||
| 656 | |||
| 657 | /** | ||
| 658 | * Gets and removes a local task. | ||
| 659 | * | ||
| 660 | * @return a task, if available | ||
| 661 | */ | ||
| 662 | final ForkJoinTask<?> pollLocalTask() { | ||
| 663 | return locallyFifo ? locallyDeqTask() : popTask(); | ||
| 664 | } | ||
| 665 | |||
| 666 | /** | ||
| 667 | * Gets and removes a local or stolen task. | ||
| 668 | * | ||
| 669 | * @return a task, if available | ||
| 670 | */ | ||
| 671 | final ForkJoinTask<?> pollTask() { | ||
| 672 | ForkJoinWorkerThread[] ws; | ||
| 673 | ForkJoinTask<?> t = pollLocalTask(); | ||
| 674 | if (t != null || (ws = pool.workers) == null) | ||
| 675 | return t; | ||
| 676 | int n = ws.length; // cheap version of FJP.scan | ||
| 677 | int steps = n << 1; | ||
| 678 | int r = nextSeed(); | ||
| 679 | int i = 0; | ||
| 680 | while (i < steps) { | ||
| 681 | ForkJoinWorkerThread w = ws[(i++ + r) & (n - 1)]; | ||
| 682 | if (w != null && w.queueBase != w.queueTop && w.queue != null) { | ||
| 683 | if ((t = w.deqTask()) != null) | ||
| 684 | return t; | ||
| 685 | i = 0; | ||
| 686 | } | ||
| 687 | } | ||
| 688 | return null; | ||
| 689 | } | ||
| 690 | |||
| 691 | /** | ||
| 692 | * The maximum stolen->joining link depth allowed in helpJoinTask, | ||
| 693 | * as well as the maximum number of retries (allowing on average | ||
| 694 | * one staleness retry per level) per attempt to instead try | ||
| 695 | * compensation. Depths for legitimate chains are unbounded, but | ||
| 696 | * we use a fixed constant to avoid (otherwise unchecked) cycles | ||
| 697 | * and bound staleness of traversal parameters at the expense of | ||
| 698 | * sometimes blocking when we could be helping. | ||
| 699 | */ | ||
| 700 | private static final int MAX_HELP = 16; | ||
| 701 | |||
| 702 | /** | ||
| 703 | * Possibly runs some tasks and/or blocks, until joinMe is done. | ||
| 704 | * | ||
| 705 | * @param joinMe the task to join | ||
| 706 | * @return completion status on exit | ||
| 707 | */ | ||
| 708 | final int joinTask(ForkJoinTask<?> joinMe) { | ||
| 709 | ForkJoinTask<?> prevJoin = currentJoin; | ||
| 710 | currentJoin = joinMe; | ||
| 711 | for (int s, retries = MAX_HELP;;) { | ||
| 712 | if ((s = joinMe.status) < 0) { | ||
| 713 | currentJoin = prevJoin; | ||
| 714 | return s; | ||
| 715 | } | ||
| 716 | if (retries > 0) { | ||
| 717 | if (queueTop != queueBase) { | ||
| 718 | if (!localHelpJoinTask(joinMe)) | ||
| 719 | retries = 0; // cannot help | ||
| 720 | } | ||
| 721 | else if (retries == MAX_HELP >>> 1) { | ||
| 722 | --retries; // check uncommon case | ||
| 723 | if (tryDeqAndExec(joinMe) >= 0) | ||
| 724 | Thread.yield(); // for politeness | ||
| 725 | } | ||
| 726 | else | ||
| 727 | retries = helpJoinTask(joinMe) ? MAX_HELP : retries - 1; | ||
| 728 | } | ||
| 729 | else { | ||
| 730 | retries = MAX_HELP; // restart if not done | ||
| 731 | pool.tryAwaitJoin(joinMe); | ||
| 732 | } | ||
| 733 | } | ||
| 734 | } | ||
| 735 | |||
| 736 | /** | ||
| 737 | * If present, pops and executes the given task, or any other | ||
| 738 | * cancelled task | ||
| 739 | * | ||
| 740 | * @return false if any other non-cancelled task exists in local queue | ||
| 741 | */ | ||
| 742 | private boolean localHelpJoinTask(ForkJoinTask<?> joinMe) { | ||
| 743 | int s, i; ForkJoinTask<?>[] q; ForkJoinTask<?> t; | ||
| 744 | if ((s = queueTop) != queueBase && (q = queue) != null && | ||
| 745 | (i = (q.length - 1) & --s) >= 0 && | ||
| 746 | (t = q[i]) != null) { | ||
| 747 | if (t != joinMe && t.status >= 0) | ||
| 748 | return false; | ||
| 749 | if (UNSAFE.compareAndSwapObject | ||
| 750 | (q, (i << ASHIFT) + ABASE, t, null)) { | ||
| 751 | queueTop = s; // or putOrderedInt | ||
| 752 | t.doExec(); | ||
| 753 | } | ||
| 754 | } | ||
| 755 | return true; | ||
| 756 | } | ||
| 757 | |||
| 758 | /** | ||
| 759 | * Tries to locate and execute tasks for a stealer of the given | ||
| 760 | * task, or in turn one of its stealers, Traces | ||
| 761 | * currentSteal->currentJoin links looking for a thread working on | ||
| 762 | * a descendant of the given task and with a non-empty queue to | ||
| 763 | * steal back and execute tasks from. The implementation is very | ||
| 764 | * branchy to cope with potential inconsistencies or loops | ||
| 765 | * encountering chains that are stale, unknown, or of length | ||
| 766 | * greater than MAX_HELP links. All of these cases are dealt with | ||
| 767 | * by just retrying by caller. | ||
| 768 | * | ||
| 769 | * @param joinMe the task to join | ||
| 770 | * @param canSteal true if local queue is empty | ||
| 771 | * @return true if ran a task | ||
| 772 | */ | ||
| 773 | private boolean helpJoinTask(ForkJoinTask<?> joinMe) { | ||
| 774 | boolean helped = false; | ||
| 775 | int m = pool.scanGuard & SMASK; | ||
| 776 | ForkJoinWorkerThread[] ws = pool.workers; | ||
| 777 | if (ws != null && ws.length > m && joinMe.status >= 0) { | ||
| 778 | int levels = MAX_HELP; // remaining chain length | ||
| 779 | ForkJoinTask<?> task = joinMe; // base of chain | ||
| 780 | outer:for (ForkJoinWorkerThread thread = this;;) { | ||
| 781 | // Try to find v, the stealer of task, by first using hint | ||
| 782 | ForkJoinWorkerThread v = ws[thread.stealHint & m]; | ||
| 783 | if (v == null || v.currentSteal != task) { | ||
| 784 | for (int j = 0; ;) { // search array | ||
| 785 | if ((v = ws[j]) != null && v.currentSteal == task) { | ||
| 786 | thread.stealHint = j; | ||
| 787 | break; // save hint for next time | ||
| 788 | } | ||
| 789 | if (++j > m) | ||
| 790 | break outer; // can't find stealer | ||
| 791 | } | ||
| 792 | } | ||
| 793 | // Try to help v, using specialized form of deqTask | ||
| 794 | for (;;) { | ||
| 795 | ForkJoinTask<?>[] q; int b, i; | ||
| 796 | if (joinMe.status < 0) | ||
| 797 | break outer; | ||
| 798 | if ((b = v.queueBase) == v.queueTop || | ||
| 799 | (q = v.queue) == null || | ||
| 800 | (i = (q.length-1) & b) < 0) | ||
| 801 | break; // empty | ||
| 802 | long u = (i << ASHIFT) + ABASE; | ||
| 803 | ForkJoinTask<?> t = q[i]; | ||
| 804 | if (task.status < 0) | ||
| 805 | break outer; // stale | ||
| 806 | if (t != null && v.queueBase == b && | ||
| 807 | UNSAFE.compareAndSwapObject(q, u, t, null)) { | ||
| 808 | v.queueBase = b + 1; | ||
| 809 | v.stealHint = poolIndex; | ||
| 810 | ForkJoinTask<?> ps = currentSteal; | ||
| 811 | currentSteal = t; | ||
| 812 | t.doExec(); | ||
| 813 | currentSteal = ps; | ||
| 814 | helped = true; | ||
| 815 | } | ||
| 816 | } | ||
| 817 | // Try to descend to find v's stealer | ||
| 818 | ForkJoinTask<?> next = v.currentJoin; | ||
| 819 | if (--levels > 0 && task.status >= 0 && | ||
| 820 | next != null && next != task) { | ||
| 821 | task = next; | ||
177 more lines aren’t shown here.
Binary file not shown.
This diff is large: its 170 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 361 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 1199 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 911 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 1352 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 1153 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 979 lines aren’t shown here.
Binary file not shown.
This diff is large: its 182 lines aren’t shown here.
Binary file not shown.
This diff is large: its 98 lines aren’t shown here.
Binary file not shown.
This diff is large: its 92 lines aren’t shown here.
Binary file not shown.
This diff is large: its 63 lines aren’t shown here.
Binary file not shown.
This diff is large: its 55 lines aren’t shown here.
Binary file not shown.
This diff is large: its 59 lines aren’t shown here.
Binary file not shown.
This diff is large: its 188 lines aren’t shown here.
Binary file not shown.
This diff is large: its 49 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 1278 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 714 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 1197 lines aren’t shown here.
Binary file not shown.
This diff is large: its 71 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 227 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 2055 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 365 lines aren’t shown here.
Binary file not shown.
This diff is large: its 68 lines aren’t shown here.
Binary file not shown.
This diff is large: its 162 lines aren’t shown here.
Binary file not shown.
This diff is large: its 165 lines aren’t shown here.
Binary file not shown.
This diff is large: its 266 lines aren’t shown here.
Binary file not shown.
This diff is large: its 285 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 347 lines aren’t shown here.
Binary file not shown.
This diff is large: its 280 lines aren’t shown here.
Binary file not shown.
This diff is large: its 285 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 437 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 213 lines aren’t shown here.
Binary file not shown.
This diff is large: its 156 lines aren’t shown here.
Binary file not shown.
This diff is large: its 214 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 305 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 214 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 200 lines aren’t shown here.
Binary file not shown.
This diff is large: its 87 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 2110 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 2331 lines aren’t shown here.
Binary file not shown.
This diff is large: its 489 lines aren’t shown here.
Binary file not shown.
This diff is large: its 357 lines aren’t shown here.
Binary file not shown.
This diff is large: its 386 lines aren’t shown here.
Binary file not shown.
This diff is large: its 134 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 771 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 1487 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 301 lines aren’t shown here.