# HG changeset patch # User valeriep # Date 1373408780 25200 # Node ID becb627a8655727a57f33e23164a527f4795151b # Parent 6a7dc4611ff2c49bbc502ef8353d78034e0d98c2# Parent 1973449fc9d9e36ad48348936b2108febc1cdfec Merge diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/io/DataInput.java --- a/jdk/src/share/classes/java/io/DataInput.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/io/DataInput.java Tue Jul 09 15:26:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -66,10 +66,10 @@ * summary="Bit values and bytes"> * * - * Bit Values + * Bit Values * * - * Byte 1 + * Byte 1 * * * @@ -92,10 +92,10 @@ * summary="Bit values and bytes"> * * - * + * * * - * + * *
Bit ValuesBit Values
Byte 1Byte 1 * * @@ -108,7 +108,7 @@ * * * - * + * *
Byte 2Byte 2 * * @@ -131,10 +131,10 @@ * summary="Bit values and bytes"> * * - * + * * * - * + * *
Bit ValuesBit Values
Byte 1Byte 1 * * @@ -148,7 +148,7 @@ * * * - * + * *
Byte 2Byte 2 * * diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/io/FileInputStream.java --- a/jdk/src/share/classes/java/io/FileInputStream.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/io/FileInputStream.java Tue Jul 09 15:26:20 2013 -0700 @@ -331,7 +331,7 @@ * object associated with this file input stream. * *

The initial {@link java.nio.channels.FileChannel#position() - * position} of the returned channel will be equal to the + * position} of the returned channel will be equal to the * number of bytes read from the file so far. Reading bytes from this * stream will increment the channel's position. Changing the channel's * position, either explicitly or by reading, will change this stream's diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/io/FileOutputStream.java --- a/jdk/src/share/classes/java/io/FileOutputStream.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/io/FileOutputStream.java Tue Jul 09 15:26:20 2013 -0700 @@ -358,10 +358,10 @@ /** * Returns the unique {@link java.nio.channels.FileChannel FileChannel} - * object associated with this file output stream.

+ * object associated with this file output stream. * *

The initial {@link java.nio.channels.FileChannel#position() - * position} of the returned channel will be equal to the + * position} of the returned channel will be equal to the * number of bytes written to the file so far unless this stream is in * append mode, in which case it will be equal to the size of the file. * Writing bytes to this stream will increment the channel's position diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/io/InputStreamReader.java --- a/jdk/src/share/classes/java/io/InputStreamReader.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/io/InputStreamReader.java Tue Jul 09 15:26:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ /** * An InputStreamReader is a bridge from byte streams to character streams: It * reads bytes and decodes them into characters using a specified {@link - * java.nio.charset.Charset charset}. The charset that it uses + * java.nio.charset.Charset charset}. The charset that it uses * may be specified by name or may be given explicitly, or the platform's * default charset may be accepted. * @@ -101,7 +101,7 @@ } /** - * Creates an InputStreamReader that uses the given charset.

+ * Creates an InputStreamReader that uses the given charset. * * @param in An InputStream * @param cs A charset @@ -117,7 +117,7 @@ } /** - * Creates an InputStreamReader that uses the given charset decoder.

+ * Creates an InputStreamReader that uses the given charset decoder. * * @param in An InputStream * @param dec A charset decoder diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/io/OutputStreamWriter.java --- a/jdk/src/share/classes/java/io/OutputStreamWriter.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/io/OutputStreamWriter.java Tue Jul 09 15:26:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ /** * An OutputStreamWriter is a bridge from character streams to byte streams: * Characters written to it are encoded into bytes using a specified {@link - * java.nio.charset.Charset charset}. The charset that it uses + * java.nio.charset.Charset charset}. The charset that it uses * may be specified by name or may be given explicitly, or the platform's * default charset may be accepted. * @@ -86,7 +86,7 @@ * * @param charsetName * The name of a supported - * {@link java.nio.charset.Charset
charset} + * {@link java.nio.charset.Charset charset} * * @exception UnsupportedEncodingException * If the named encoding is not supported @@ -115,7 +115,7 @@ } /** - * Creates an OutputStreamWriter that uses the given charset.

+ * Creates an OutputStreamWriter that uses the given charset. * * @param out * An OutputStream @@ -134,7 +134,7 @@ } /** - * Creates an OutputStreamWriter that uses the given charset encoder.

+ * Creates an OutputStreamWriter that uses the given charset encoder. * * @param out * An OutputStream diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/io/PipedInputStream.java --- a/jdk/src/share/classes/java/io/PipedInputStream.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/io/PipedInputStream.java Tue Jul 09 15:26:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ * The piped input stream contains a buffer, * decoupling read operations from write operations, * within limits. - * A pipe is said to be broken if a + * A pipe is said to be broken if a * thread that was providing data bytes to the connected * piped output stream is no longer alive. * @@ -193,7 +193,7 @@ * Receives a byte of data. This method will block if no input is * available. * @param b the byte being received - * @exception IOException If the pipe is broken, + * @exception IOException If the pipe is broken, * {@link #connect(java.io.PipedOutputStream) unconnected}, * closed, or if an I/O error occurs. * @since JDK1.1 @@ -219,7 +219,7 @@ * @param b the buffer into which the data is received * @param off the start offset of the data * @param len the maximum number of bytes received - * @exception IOException If the pipe is broken, + * @exception IOException If the pipe is broken, * {@link #connect(java.io.PipedOutputStream) unconnected}, * closed,or if an I/O error occurs. */ @@ -298,7 +298,7 @@ * stream is reached. * @exception IOException if the pipe is * {@link #connect(java.io.PipedOutputStream) unconnected}, - * broken, closed, + * broken, closed, * or if an I/O error occurs. */ public synchronized int read() throws IOException { @@ -361,7 +361,7 @@ * @exception IndexOutOfBoundsException If off is negative, * len is negative, or len is greater than * b.length - off - * @exception IOException if the pipe is broken, + * @exception IOException if the pipe is broken, * {@link #connect(java.io.PipedOutputStream) unconnected}, * closed, or if an I/O error occurs. */ @@ -419,7 +419,7 @@ * without blocking, or {@code 0} if this input stream has been * closed by invoking its {@link #close()} method, or if the pipe * is {@link #connect(java.io.PipedOutputStream) unconnected}, or - * broken. + * broken. * * @exception IOException if an I/O error occurs. * @since JDK1.0.2 diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/io/RandomAccessFile.java --- a/jdk/src/share/classes/java/io/RandomAccessFile.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/io/RandomAccessFile.java Tue Jul 09 15:26:20 2013 -0700 @@ -123,11 +123,11 @@ * write to, the file specified by the {@link File} argument. A new {@link * FileDescriptor} object is created to represent this file connection. * - *

The mode argument specifies the access mode + *

The mode argument specifies the access mode * in which the file is to be opened. The permitted values and their * meanings are: * - *

+ *
* * * - *

Value

Meaning

"r" Open for reading only. Invoking any of the write @@ -144,7 +144,7 @@ * Open for reading and writing, as with "rw", and also * require that every update to the file's content be written * synchronously to the underlying storage device.
+ *
* * The "rws" and "rwd" modes work much like the {@link * java.nio.channels.FileChannel#force(boolean) force(boolean)} method of @@ -158,13 +158,13 @@ * event of a system crash. If the file does not reside on a local device * then no such guarantee is made. * - *

The "rwd" mode can be used to reduce the number of I/O + *

The "rwd" mode can be used to reduce the number of I/O * operations performed. Using "rwd" only requires updates to the * file's content to be written to storage; using "rws" requires * updates to both the file's content and its metadata to be written, which * generally requires at least one more low-level I/O operation. * - *

If there is a security manager, its {@code checkRead} method is + *

If there is a security manager, its {@code checkRead} method is * called with the pathname of the {@code file} argument as its * argument to see if read access to the file is allowed. If the mode * allows writing, the security manager's {@code checkWrite} method is @@ -238,7 +238,7 @@ /** * Returns the opaque file descriptor object associated with this - * stream.

+ * stream. * * @return the file descriptor object associated with this stream. * @exception IOException if an I/O error occurs. diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/util/LinkedList.java --- a/jdk/src/share/classes/java/util/LinkedList.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/util/LinkedList.java Tue Jul 09 15:26:20 2013 -0700 @@ -1195,12 +1195,7 @@ n = s; if (n > MAX_BATCH) n = MAX_BATCH; - Object[] a; - try { - a = new Object[n]; - } catch (OutOfMemoryError oome) { - return null; - } + Object[] a = new Object[n]; int j = 0; do { a[j++] = p.item; } while ((p = p.next) != null && j < n); current = p; diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/util/Spliterators.java --- a/jdk/src/share/classes/java/util/Spliterators.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/util/Spliterators.java Tue Jul 09 15:26:20 2013 -0700 @@ -1314,12 +1314,7 @@ n = (int) s; if (n > MAX_BATCH) n = MAX_BATCH; - Object[] a; - try { - a = new Object[n]; - } catch (OutOfMemoryError oome) { - return null; - } + Object[] a = new Object[n]; int j = 0; do { a[j] = holder.value; } while (++j < n && tryAdvance(holder)); batch = j; @@ -1429,12 +1424,7 @@ n = (int) s; if (n > MAX_BATCH) n = MAX_BATCH; - int[] a; - try { - a = new int[n]; - } catch (OutOfMemoryError oome) { - return null; - } + int[] a = new int[n]; int j = 0; do { a[j] = holder.value; } while (++j < n && tryAdvance(holder)); batch = j; @@ -1544,12 +1534,7 @@ n = (int) s; if (n > MAX_BATCH) n = MAX_BATCH; - long[] a; - try { - a = new long[n]; - } catch (OutOfMemoryError oome) { - return null; - } + long[] a = new long[n]; int j = 0; do { a[j] = holder.value; } while (++j < n && tryAdvance(holder)); batch = j; @@ -1659,12 +1644,7 @@ n = (int) s; if (n > MAX_BATCH) n = MAX_BATCH; - double[] a; - try { - a = new double[n]; - } catch (OutOfMemoryError oome) { - return null; - } + double[] a = new double[n]; int j = 0; do { a[j] = holder.value; } while (++j < n && tryAdvance(holder)); batch = j; @@ -1795,12 +1775,7 @@ n = (int) s; if (n > MAX_BATCH) n = MAX_BATCH; - Object[] a; - try { - a = new Object[n]; - } catch (OutOfMemoryError oome) { - return null; - } + Object[] a = new Object[n]; int j = 0; do { a[j] = i.next(); } while (++j < n && i.hasNext()); batch = j; @@ -1910,12 +1885,7 @@ n = (int) s; if (n > MAX_BATCH) n = MAX_BATCH; - int[] a; - try { - a = new int[n]; - } catch (OutOfMemoryError oome) { - return null; - } + int[] a = new int[n]; int j = 0; do { a[j] = i.nextInt(); } while (++j < n && i.hasNext()); batch = j; @@ -2007,12 +1977,7 @@ n = (int) s; if (n > MAX_BATCH) n = MAX_BATCH; - long[] a; - try { - a = new long[n]; - } catch (OutOfMemoryError oome) { - return null; - } + long[] a = new long[n]; int j = 0; do { a[j] = i.nextLong(); } while (++j < n && i.hasNext()); batch = j; @@ -2104,12 +2069,7 @@ n = (int) s; if (n > MAX_BATCH) n = MAX_BATCH; - double[] a; - try { - a = new double[n]; - } catch (OutOfMemoryError oome) { - return null; - } + double[] a = new double[n]; int j = 0; do { a[j] = i.nextDouble(); } while (++j < n && i.hasNext()); batch = j; diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/util/concurrent/AbstractExecutorService.java --- a/jdk/src/share/classes/java/util/concurrent/AbstractExecutorService.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/util/concurrent/AbstractExecutorService.java Tue Jul 09 15:26:20 2013 -0700 @@ -38,19 +38,19 @@ /** * Provides default implementations of {@link ExecutorService} - * execution methods. This class implements the submit, - * invokeAny and invokeAll methods using a - * {@link RunnableFuture} returned by newTaskFor, which defaults + * execution methods. This class implements the {@code submit}, + * {@code invokeAny} and {@code invokeAll} methods using a + * {@link RunnableFuture} returned by {@code newTaskFor}, which defaults * to the {@link FutureTask} class provided in this package. For example, - * the implementation of submit(Runnable) creates an - * associated RunnableFuture that is executed and - * returned. Subclasses may override the newTaskFor methods - * to return RunnableFuture implementations other than - * FutureTask. + * the implementation of {@code submit(Runnable)} creates an + * associated {@code RunnableFuture} that is executed and + * returned. Subclasses may override the {@code newTaskFor} methods + * to return {@code RunnableFuture} implementations other than + * {@code FutureTask}. * - *

Extension example. Here is a sketch of a class + *

Extension example. Here is a sketch of a class * that customizes {@link ThreadPoolExecutor} to use - * a CustomTask class instead of the default FutureTask: + * a {@code CustomTask} class instead of the default {@code FutureTask}: *

 {@code
  * public class CustomThreadPoolExecutor extends ThreadPoolExecutor {
  *
@@ -71,15 +71,15 @@
 public abstract class AbstractExecutorService implements ExecutorService {
 
     /**
-     * Returns a RunnableFuture for the given runnable and default
+     * Returns a {@code RunnableFuture} for the given runnable and default
      * value.
      *
      * @param runnable the runnable task being wrapped
      * @param value the default value for the returned future
-     * @return a RunnableFuture which when run will run the
-     * underlying runnable and which, as a Future, will yield
+     * @return a {@code RunnableFuture} which, when run, will run the
+     * underlying runnable and which, as a {@code Future}, will yield
      * the given value as its result and provide for cancellation of
-     * the underlying task.
+     * the underlying task
      * @since 1.6
      */
     protected  RunnableFuture newTaskFor(Runnable runnable, T value) {
@@ -87,13 +87,13 @@
     }
 
     /**
-     * Returns a RunnableFuture for the given callable task.
+     * Returns a {@code RunnableFuture} for the given callable task.
      *
      * @param callable the callable task being wrapped
-     * @return a RunnableFuture which when run will call the
-     * underlying callable and which, as a Future, will yield
+     * @return a {@code RunnableFuture} which, when run, will call the
+     * underlying callable and which, as a {@code Future}, will yield
      * the callable's result as its result and provide for
-     * cancellation of the underlying task.
+     * cancellation of the underlying task
      * @since 1.6
      */
     protected  RunnableFuture newTaskFor(Callable callable) {
@@ -144,7 +144,7 @@
         int ntasks = tasks.size();
         if (ntasks == 0)
             throw new IllegalArgumentException();
-        List> futures= new ArrayList>(ntasks);
+        ArrayList> futures = new ArrayList>(ntasks);
         ExecutorCompletionService ecs =
             new ExecutorCompletionService(this);
 
@@ -202,8 +202,8 @@
             throw ee;
 
         } finally {
-            for (Future f : futures)
-                f.cancel(true);
+            for (int i = 0, size = futures.size(); i < size; i++)
+                futures.get(i).cancel(true);
         }
     }
 
@@ -227,7 +227,7 @@
         throws InterruptedException {
         if (tasks == null)
             throw new NullPointerException();
-        List> futures = new ArrayList>(tasks.size());
+        ArrayList> futures = new ArrayList>(tasks.size());
         boolean done = false;
         try {
             for (Callable t : tasks) {
@@ -235,7 +235,8 @@
                 futures.add(f);
                 execute(f);
             }
-            for (Future f : futures) {
+            for (int i = 0, size = futures.size(); i < size; i++) {
+                Future f = futures.get(i);
                 if (!f.isDone()) {
                     try {
                         f.get();
@@ -248,8 +249,8 @@
             return futures;
         } finally {
             if (!done)
-                for (Future f : futures)
-                    f.cancel(true);
+                for (int i = 0, size = futures.size(); i < size; i++)
+                    futures.get(i).cancel(true);
         }
     }
 
@@ -259,25 +260,26 @@
         if (tasks == null)
             throw new NullPointerException();
         long nanos = unit.toNanos(timeout);
-        List> futures = new ArrayList>(tasks.size());
+        ArrayList> futures = new ArrayList>(tasks.size());
         boolean done = false;
         try {
             for (Callable t : tasks)
                 futures.add(newTaskFor(t));
 
             final long deadline = System.nanoTime() + nanos;
+            final int size = futures.size();
 
             // Interleave time checks and calls to execute in case
             // executor doesn't have any/much parallelism.
-            Iterator> it = futures.iterator();
-            while (it.hasNext()) {
-                execute((Runnable)(it.next()));
+            for (int i = 0; i < size; i++) {
+                execute((Runnable)futures.get(i));
                 nanos = deadline - System.nanoTime();
                 if (nanos <= 0L)
                     return futures;
             }
 
-            for (Future f : futures) {
+            for (int i = 0; i < size; i++) {
+                Future f = futures.get(i);
                 if (!f.isDone()) {
                     if (nanos <= 0L)
                         return futures;
@@ -295,8 +297,8 @@
             return futures;
         } finally {
             if (!done)
-                for (Future f : futures)
-                    f.cancel(true);
+                for (int i = 0, size = futures.size(); i < size; i++)
+                    futures.get(i).cancel(true);
         }
     }
 
diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/util/concurrent/Callable.java
--- a/jdk/src/share/classes/java/util/concurrent/Callable.java	Mon Jul 08 11:11:07 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/Callable.java	Tue Jul 09 15:26:20 2013 -0700
@@ -38,21 +38,21 @@
 /**
  * A task that returns a result and may throw an exception.
  * Implementors define a single method with no arguments called
- * call.
+ * {@code call}.
  *
- * 

The Callable interface is similar to {@link + *

The {@code Callable} interface is similar to {@link * java.lang.Runnable}, in that both are designed for classes whose * instances are potentially executed by another thread. A - * Runnable, however, does not return a result and cannot + * {@code Runnable}, however, does not return a result and cannot * throw a checked exception. * - *

The {@link Executors} class contains utility methods to - * convert from other common forms to Callable classes. + *

The {@link Executors} class contains utility methods to + * convert from other common forms to {@code Callable} classes. * * @see Executor * @since 1.5 * @author Doug Lea - * @param the result type of method call + * @param the result type of method {@code call} */ public interface Callable { /** diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/util/concurrent/CancellationException.java --- a/jdk/src/share/classes/java/util/concurrent/CancellationException.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/util/concurrent/CancellationException.java Tue Jul 09 15:26:20 2013 -0700 @@ -47,12 +47,12 @@ private static final long serialVersionUID = -9202173006928992231L; /** - * Constructs a CancellationException with no detail message. + * Constructs a {@code CancellationException} with no detail message. */ public CancellationException() {} /** - * Constructs a CancellationException with the specified detail + * Constructs a {@code CancellationException} with the specified detail * message. * * @param message the detail message diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/util/concurrent/CompletableFuture.java --- a/jdk/src/share/classes/java/util/concurrent/CompletableFuture.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/util/concurrent/CompletableFuture.java Tue Jul 09 15:26:20 2013 -0700 @@ -1209,7 +1209,7 @@ (r = a.result) != null && compareAndSet(0, 1)) { if ((r instanceof AltResult) && - (ex = ((AltResult)r).ex) != null) { + (ex = ((AltResult)r).ex) != null) { try { t = fn.apply(ex); } catch (Throwable rex) { @@ -2892,7 +2892,7 @@ if (r != null && (d == null || d.compareAndSet(0, 1))) { T t = null; Throwable ex, dx = null; if (r instanceof AltResult) { - if ((ex = ((AltResult)r).ex) != null) { + if ((ex = ((AltResult)r).ex) != null) { try { t = fn.apply(ex); } catch (Throwable rex) { diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/util/concurrent/CompletionService.java --- a/jdk/src/share/classes/java/util/concurrent/CompletionService.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/util/concurrent/CompletionService.java Tue Jul 09 15:26:20 2013 -0700 @@ -38,17 +38,17 @@ /** * A service that decouples the production of new asynchronous tasks * from the consumption of the results of completed tasks. Producers - * submit tasks for execution. Consumers take + * {@code submit} tasks for execution. Consumers {@code take} * completed tasks and process their results in the order they - * complete. A CompletionService can for example be used to - * manage asynchronous IO, in which tasks that perform reads are + * complete. A {@code CompletionService} can for example be used to + * manage asynchronous I/O, in which tasks that perform reads are * submitted in one part of a program or system, and then acted upon * in a different part of the program when the reads complete, * possibly in a different order than they were requested. * - *

Typically, a CompletionService relies on a separate + *

Typically, a {@code CompletionService} relies on a separate * {@link Executor} to actually execute the tasks, in which case the - * CompletionService only manages an internal completion + * {@code CompletionService} only manages an internal completion * queue. The {@link ExecutorCompletionService} class provides an * implementation of this approach. * @@ -80,7 +80,7 @@ * @param task the task to submit * @param result the result to return upon successful completion * @return a Future representing pending completion of the task, - * and whose get() method will return the given + * and whose {@code get()} method will return the given * result value upon completion * @throws RejectedExecutionException if the task cannot be * scheduled for execution @@ -99,10 +99,10 @@ /** * Retrieves and removes the Future representing the next - * completed task or null if none are present. + * completed task, or {@code null} if none are present. * * @return the Future representing the next completed task, or - * null if none are present + * {@code null} if none are present */ Future poll(); @@ -112,11 +112,11 @@ * time if none are yet present. * * @param timeout how long to wait before giving up, in units of - * unit - * @param unit a TimeUnit determining how to interpret the - * timeout parameter + * {@code unit} + * @param unit a {@code TimeUnit} determining how to interpret the + * {@code timeout} parameter * @return the Future representing the next completed task or - * null if the specified waiting time elapses + * {@code null} if the specified waiting time elapses * before one is present * @throws InterruptedException if interrupted while waiting */ diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/util/concurrent/CountedCompleter.java --- a/jdk/src/share/classes/java/util/concurrent/CountedCompleter.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/util/concurrent/CountedCompleter.java Tue Jul 09 15:26:20 2013 -0700 @@ -37,14 +37,15 @@ /** * A {@link ForkJoinTask} with a completion action performed when - * triggered and there are no remaining pending - * actions. CountedCompleters are in general more robust in the + * triggered and there are no remaining pending actions. + * CountedCompleters are in general more robust in the * presence of subtask stalls and blockage than are other forms of * ForkJoinTasks, but are less intuitive to program. Uses of * CountedCompleter are similar to those of other completion based * components (such as {@link java.nio.channels.CompletionHandler}) * except that multiple pending completions may be necessary - * to trigger the completion action {@link #onCompletion}, not just one. + * to trigger the completion action {@link #onCompletion(CountedCompleter)}, + * not just one. * Unless initialized otherwise, the {@linkplain #getPendingCount pending * count} starts at zero, but may be (atomically) changed using * methods {@link #setPendingCount}, {@link #addToPendingCount}, and @@ -69,9 +70,10 @@ *

A concrete CountedCompleter class must define method {@link * #compute}, that should in most cases (as illustrated below), invoke * {@code tryComplete()} once before returning. The class may also - * optionally override method {@link #onCompletion} to perform an - * action upon normal completion, and method {@link - * #onExceptionalCompletion} to perform an action upon any exception. + * optionally override method {@link #onCompletion(CountedCompleter)} + * to perform an action upon normal completion, and method + * {@link #onExceptionalCompletion(Throwable, CountedCompleter)} to + * perform an action upon any exception. * *

CountedCompleters most often do not bear results, in which case * they are normally declared as {@code CountedCompleter}, and @@ -92,13 +94,14 @@ * only as an internal helper for other computations, so its own task * status (as reported in methods such as {@link ForkJoinTask#isDone}) * is arbitrary; this status changes only upon explicit invocations of - * {@link #complete}, {@link ForkJoinTask#cancel}, {@link - * ForkJoinTask#completeExceptionally} or upon exceptional completion - * of method {@code compute}. Upon any exceptional completion, the - * exception may be relayed to a task's completer (and its completer, - * and so on), if one exists and it has not otherwise already - * completed. Similarly, cancelling an internal CountedCompleter has - * only a local effect on that completer, so is not often useful. + * {@link #complete}, {@link ForkJoinTask#cancel}, + * {@link ForkJoinTask#completeExceptionally(Throwable)} or upon + * exceptional completion of method {@code compute}. Upon any + * exceptional completion, the exception may be relayed to a task's + * completer (and its completer, and so on), if one exists and it has + * not otherwise already completed. Similarly, cancelling an internal + * CountedCompleter has only a local effect on that completer, so is + * not often useful. * *

Sample Usages. * @@ -125,8 +128,8 @@ * improve load balancing. In the recursive case, the second of each * pair of subtasks to finish triggers completion of its parent * (because no result combination is performed, the default no-op - * implementation of method {@code onCompletion} is not overridden). A - * static utility method sets up the base task and invokes it + * implementation of method {@code onCompletion} is not overridden). + * A static utility method sets up the base task and invokes it * (here, implicitly using the {@link ForkJoinPool#commonPool()}). * *

 {@code
@@ -181,12 +184,11 @@
  *   }
  * }
* - * As a further improvement, notice that the left task need not even - * exist. Instead of creating a new one, we can iterate using the - * original task, and add a pending count for each fork. Additionally, - * because no task in this tree implements an {@link #onCompletion} - * method, {@code tryComplete()} can be replaced with {@link - * #propagateCompletion}. + * As a further improvement, notice that the left task need not even exist. + * Instead of creating a new one, we can iterate using the original task, + * and add a pending count for each fork. Additionally, because no task + * in this tree implements an {@link #onCompletion(CountedCompleter)} method, + * {@code tryComplete()} can be replaced with {@link #propagateCompletion}. * *
 {@code
  * class ForEach ...
@@ -253,7 +255,7 @@
  *   public static  E search(E[] array) {
  *       return new Searcher(null, array, new AtomicReference(), 0, array.length).invoke();
  *   }
- *}}
+ * }}
* * In this example, as well as others in which tasks have no other * effects except to compareAndSet a common result, the trailing @@ -264,7 +266,7 @@ * *

Recording subtasks. CountedCompleter tasks that combine * results of multiple subtasks usually need to access these results - * in method {@link #onCompletion}. As illustrated in the following + * in method {@link #onCompletion(CountedCompleter)}. As illustrated in the following * class (that performs a simplified form of map-reduce where mappings * and reductions are all of type {@code E}), one way to do this in * divide and conquer designs is to have each subtask record its @@ -365,7 +367,7 @@ * while (h - l >= 2) { * int mid = (l + h) >>> 1; * addToPendingCount(1); - * (forks = new MapReducer(this, array, mapper, reducer, mid, h, forks)).fork; + * (forks = new MapReducer(this, array, mapper, reducer, mid, h, forks)).fork(); * h = mid; * } * if (h > l) @@ -386,7 +388,7 @@ * *

Triggers. Some CountedCompleters are themselves never * forked, but instead serve as bits of plumbing in other designs; - * including those in which the completion of one of more async tasks + * including those in which the completion of one or more async tasks * triggers another async task. For example: * *

 {@code
@@ -460,27 +462,28 @@
      * (and/or links to other results) to combine.
      *
      * @param caller the task invoking this method (which may
-     * be this task itself).
+     * be this task itself)
      */
     public void onCompletion(CountedCompleter caller) {
     }
 
     /**
-     * Performs an action when method {@link #completeExceptionally}
-     * is invoked or method {@link #compute} throws an exception, and
-     * this task has not otherwise already completed normally. On
-     * entry to this method, this task {@link
-     * ForkJoinTask#isCompletedAbnormally}.  The return value of this
-     * method controls further propagation: If {@code true} and this
-     * task has a completer, then this completer is also completed
-     * exceptionally.  The default implementation of this method does
-     * nothing except return {@code true}.
+     * Performs an action when method {@link
+     * #completeExceptionally(Throwable)} is invoked or method {@link
+     * #compute} throws an exception, and this task has not already
+     * otherwise completed normally. On entry to this method, this task
+     * {@link ForkJoinTask#isCompletedAbnormally}.  The return value
+     * of this method controls further propagation: If {@code true}
+     * and this task has a completer that has not completed, then that
+     * completer is also completed exceptionally, with the same
+     * exception as this completer.  The default implementation of
+     * this method does nothing except return {@code true}.
      *
      * @param ex the exception
      * @param caller the task invoking this method (which may
-     * be this task itself).
-     * @return true if this exception should be propagated to this
-     * task's completer, if one exists.
+     * be this task itself)
+     * @return {@code true} if this exception should be propagated to this
+     * task's completer, if one exists
      */
     public boolean onExceptionalCompletion(Throwable ex, CountedCompleter caller) {
         return true;
@@ -520,8 +523,7 @@
      * @param delta the value to add
      */
     public final void addToPendingCount(int delta) {
-        int c; // note: can replace with intrinsic in jdk8
-        do {} while (!U.compareAndSwapInt(this, PENDING, c = pending, c+delta));
+        U.getAndAddInt(this, PENDING, delta);
     }
 
     /**
@@ -530,7 +532,7 @@
      *
      * @param expected the expected value
      * @param count the new value
-     * @return true if successful
+     * @return {@code true} if successful
      */
     public final boolean compareAndSetPendingCount(int expected, int count) {
         return U.compareAndSwapInt(this, PENDING, expected, count);
@@ -564,9 +566,9 @@
 
     /**
      * If the pending count is nonzero, decrements the count;
-     * otherwise invokes {@link #onCompletion} and then similarly
-     * tries to complete this task's completer, if one exists,
-     * else marks this task as complete.
+     * otherwise invokes {@link #onCompletion(CountedCompleter)}
+     * and then similarly tries to complete this task's completer,
+     * if one exists, else marks this task as complete.
      */
     public final void tryComplete() {
         CountedCompleter a = this, s = a;
@@ -585,12 +587,12 @@
 
     /**
      * Equivalent to {@link #tryComplete} but does not invoke {@link
-     * #onCompletion} along the completion path: If the pending count
-     * is nonzero, decrements the count; otherwise, similarly tries to
-     * complete this task's completer, if one exists, else marks this
-     * task as complete. This method may be useful in cases where
-     * {@code onCompletion} should not, or need not, be invoked for
-     * each completer in a computation.
+     * #onCompletion(CountedCompleter)} along the completion path:
+     * If the pending count is nonzero, decrements the count;
+     * otherwise, similarly tries to complete this task's completer, if
+     * one exists, else marks this task as complete. This method may be
+     * useful in cases where {@code onCompletion} should not, or need
+     * not, be invoked for each completer in a computation.
      */
     public final void propagateCompletion() {
         CountedCompleter a = this, s = a;
@@ -607,13 +609,15 @@
     }
 
     /**
-     * Regardless of pending count, invokes {@link #onCompletion},
-     * marks this task as complete and further triggers {@link
-     * #tryComplete} on this task's completer, if one exists.  The
-     * given rawResult is used as an argument to {@link #setRawResult}
-     * before invoking {@link #onCompletion} or marking this task as
-     * complete; its value is meaningful only for classes overriding
-     * {@code setRawResult}.
+     * Regardless of pending count, invokes
+     * {@link #onCompletion(CountedCompleter)}, marks this task as
+     * complete and further triggers {@link #tryComplete} on this
+     * task's completer, if one exists.  The given rawResult is
+     * used as an argument to {@link #setRawResult} before invoking
+     * {@link #onCompletion(CountedCompleter)} or marking this task
+     * as complete; its value is meaningful only for classes
+     * overriding {@code setRawResult}.  This method does not modify
+     * the pending count.
      *
      * 

This method may be useful when forcing completion as soon as * any one (versus all) of several subtask results are obtained. @@ -632,7 +636,6 @@ p.tryComplete(); } - /** * If this task's pending count is zero, returns this task; * otherwise decrements its pending count and returns {@code @@ -653,8 +656,8 @@ /** * If this task does not have a completer, invokes {@link * ForkJoinTask#quietlyComplete} and returns {@code null}. Or, if - * this task's pending count is non-zero, decrements its pending - * count and returns {@code null}. Otherwise, returns the + * the completer's pending count is non-zero, decrements that + * pending count and returns {@code null}. Otherwise, returns the * completer. This method can be used as part of a completion * traversal loop for homogeneous task hierarchies: * @@ -691,13 +694,34 @@ } /** + * If this task has not completed, attempts to process at most the + * given number of other unprocessed tasks for which this task is + * on the completion path, if any are known to exist. + * + * @param maxTasks the maximum number of tasks to process. If + * less than or equal to zero, then no tasks are + * processed. + */ + public final void helpComplete(int maxTasks) { + Thread t; ForkJoinWorkerThread wt; + if (maxTasks > 0 && status >= 0) { + if ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) + (wt = (ForkJoinWorkerThread)t).pool. + helpComplete(wt.workQueue, this, maxTasks); + else + ForkJoinPool.common.externalHelpComplete(this, maxTasks); + } + } + + /** * Supports ForkJoinTask exception propagation. */ void internalPropagateException(Throwable ex) { CountedCompleter a = this, s = a; while (a.onExceptionalCompletion(ex, s) && - (a = (s = a).completer) != null && a.status >= 0) - a.recordExceptionalCompletion(ex); + (a = (s = a).completer) != null && a.status >= 0 && + a.recordExceptionalCompletion(ex) == EXCEPTIONAL) + ; } /** diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/util/concurrent/ExecutionException.java --- a/jdk/src/share/classes/java/util/concurrent/ExecutionException.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/util/concurrent/ExecutionException.java Tue Jul 09 15:26:20 2013 -0700 @@ -48,14 +48,14 @@ private static final long serialVersionUID = 7830266012832686185L; /** - * Constructs an ExecutionException with no detail message. + * Constructs an {@code ExecutionException} with no detail message. * The cause is not initialized, and may subsequently be * initialized by a call to {@link #initCause(Throwable) initCause}. */ protected ExecutionException() { } /** - * Constructs an ExecutionException with the specified detail + * Constructs an {@code ExecutionException} with the specified detail * message. The cause is not initialized, and may subsequently be * initialized by a call to {@link #initCause(Throwable) initCause}. * @@ -66,7 +66,7 @@ } /** - * Constructs an ExecutionException with the specified detail + * Constructs an {@code ExecutionException} with the specified detail * message and cause. * * @param message the detail message @@ -78,7 +78,7 @@ } /** - * Constructs an ExecutionException with the specified cause. + * Constructs an {@code ExecutionException} with the specified cause. * The detail message is set to {@code (cause == null ? null : * cause.toString())} (which typically contains the class and * detail message of {@code cause}). diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/util/concurrent/Executor.java --- a/jdk/src/share/classes/java/util/concurrent/Executor.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/util/concurrent/Executor.java Tue Jul 09 15:26:20 2013 -0700 @@ -39,9 +39,9 @@ * An object that executes submitted {@link Runnable} tasks. This * interface provides a way of decoupling task submission from the * mechanics of how each task will be run, including details of thread - * use, scheduling, etc. An Executor is normally used + * use, scheduling, etc. An {@code Executor} is normally used * instead of explicitly creating threads. For example, rather than - * invoking new Thread(new(RunnableTask())).start() for each + * invoking {@code new Thread(new(RunnableTask())).start()} for each * of a set of tasks, you might use: * *

@@ -51,7 +51,7 @@
  * ...
  * 
* - * However, the Executor interface does not strictly + * However, the {@code Executor} interface does not strictly * require that execution be asynchronous. In the simplest case, an * executor can run the submitted task immediately in the caller's * thread: @@ -74,7 +74,7 @@ * } * }}
* - * Many Executor implementations impose some sort of + * Many {@code Executor} implementations impose some sort of * limitation on how and when tasks are scheduled. The executor below * serializes the submission of tasks to a second executor, * illustrating a composite executor. @@ -111,7 +111,7 @@ * } * }} * - * The Executor implementations provided in this package + * The {@code Executor} implementations provided in this package * implement {@link ExecutorService}, which is a more extensive * interface. The {@link ThreadPoolExecutor} class provides an * extensible thread pool implementation. The {@link Executors} class @@ -130,11 +130,11 @@ /** * Executes the given command at some time in the future. The command * may execute in a new thread, in a pooled thread, or in the calling - * thread, at the discretion of the Executor implementation. + * thread, at the discretion of the {@code Executor} implementation. * * @param command the runnable task * @throws RejectedExecutionException if this task cannot be - * accepted for execution. + * accepted for execution * @throws NullPointerException if command is null */ void execute(Runnable command); diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/util/concurrent/ExecutorService.java --- a/jdk/src/share/classes/java/util/concurrent/ExecutorService.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/util/concurrent/ExecutorService.java Tue Jul 09 15:26:20 2013 -0700 @@ -42,21 +42,21 @@ * methods that can produce a {@link Future} for tracking progress of * one or more asynchronous tasks. * - *

An ExecutorService can be shut down, which will cause + *

An {@code ExecutorService} can be shut down, which will cause * it to reject new tasks. Two different methods are provided for - * shutting down an ExecutorService. The {@link #shutdown} + * shutting down an {@code ExecutorService}. The {@link #shutdown} * method will allow previously submitted tasks to execute before * terminating, while the {@link #shutdownNow} method prevents waiting * tasks from starting and attempts to stop currently executing tasks. * Upon termination, an executor has no tasks actively executing, no * tasks awaiting execution, and no new tasks can be submitted. An - * unused ExecutorService should be shut down to allow + * unused {@code ExecutorService} should be shut down to allow * reclamation of its resources. * - *

Method submit extends base method {@link - * Executor#execute} by creating and returning a {@link Future} that - * can be used to cancel execution and/or wait for completion. - * Methods invokeAny and invokeAll perform the most + *

Method {@code submit} extends base method {@link + * Executor#execute(Runnable)} by creating and returning a {@link Future} + * that can be used to cancel execution and/or wait for completion. + * Methods {@code invokeAny} and {@code invokeAll} perform the most * commonly useful forms of bulk execution, executing a collection of * tasks and then waiting for at least one, or all, to * complete. (Class {@link ExecutorCompletionService} can be used to @@ -101,9 +101,9 @@ * } * }} * - * The following method shuts down an ExecutorService in two phases, - * first by calling shutdown to reject incoming tasks, and then - * calling shutdownNow, if necessary, to cancel any lingering tasks: + * The following method shuts down an {@code ExecutorService} in two phases, + * first by calling {@code shutdown} to reject incoming tasks, and then + * calling {@code shutdownNow}, if necessary, to cancel any lingering tasks: * *

 {@code
  * void shutdownAndAwaitTermination(ExecutorService pool) {
@@ -149,8 +149,8 @@
      *         shutting down this ExecutorService may manipulate
      *         threads that the caller is not permitted to modify
      *         because it does not hold {@link
-     *         java.lang.RuntimePermission}("modifyThread"),
-     *         or the security manager's checkAccess method
+     *         java.lang.RuntimePermission}{@code ("modifyThread")},
+     *         or the security manager's {@code checkAccess} method
      *         denies access.
      */
     void shutdown();
@@ -174,25 +174,25 @@
      *         shutting down this ExecutorService may manipulate
      *         threads that the caller is not permitted to modify
      *         because it does not hold {@link
-     *         java.lang.RuntimePermission}("modifyThread"),
-     *         or the security manager's checkAccess method
+     *         java.lang.RuntimePermission}{@code ("modifyThread")},
+     *         or the security manager's {@code checkAccess} method
      *         denies access.
      */
     List shutdownNow();
 
     /**
-     * Returns true if this executor has been shut down.
+     * Returns {@code true} if this executor has been shut down.
      *
-     * @return true if this executor has been shut down
+     * @return {@code true} if this executor has been shut down
      */
     boolean isShutdown();
 
     /**
-     * Returns true if all tasks have completed following shut down.
-     * Note that isTerminated is never true unless
-     * either shutdown or shutdownNow was called first.
+     * Returns {@code true} if all tasks have completed following shut down.
+     * Note that {@code isTerminated} is never {@code true} unless
+     * either {@code shutdown} or {@code shutdownNow} was called first.
      *
-     * @return true if all tasks have completed following shut down
+     * @return {@code true} if all tasks have completed following shut down
      */
     boolean isTerminated();
 
@@ -203,8 +203,8 @@
      *
      * @param timeout the maximum time to wait
      * @param unit the time unit of the timeout argument
-     * @return true if this executor terminated and
-     *         false if the timeout elapsed before termination
+     * @return {@code true} if this executor terminated and
+     *         {@code false} if the timeout elapsed before termination
      * @throws InterruptedException if interrupted while waiting
      */
     boolean awaitTermination(long timeout, TimeUnit unit)
@@ -213,15 +213,15 @@
     /**
      * Submits a value-returning task for execution and returns a
      * Future representing the pending results of the task. The
-     * Future's get method will return the task's result upon
+     * Future's {@code get} method will return the task's result upon
      * successful completion.
      *
      * 

* If you would like to immediately block waiting * for a task, you can use constructions of the form - * result = exec.submit(aCallable).get(); + * {@code result = exec.submit(aCallable).get();} * - *

Note: The {@link Executors} class includes a set of methods + *

Note: The {@link Executors} class includes a set of methods * that can convert some other common closure-like objects, * for example, {@link java.security.PrivilegedAction} to * {@link Callable} form so they can be submitted. @@ -236,7 +236,7 @@ /** * Submits a Runnable task for execution and returns a Future - * representing that task. The Future's get method will + * representing that task. The Future's {@code get} method will * return the given result upon successful completion. * * @param task the task to submit @@ -250,8 +250,8 @@ /** * Submits a Runnable task for execution and returns a Future - * representing that task. The Future's get method will - * return null upon successful completion. + * representing that task. The Future's {@code get} method will + * return {@code null} upon successful completion. * * @param task the task to submit * @return a Future representing pending completion of the task @@ -264,7 +264,7 @@ /** * Executes the given tasks, returning a list of Futures holding * their status and results when all complete. - * {@link Future#isDone} is true for each + * {@link Future#isDone} is {@code true} for each * element of the returned list. * Note that a completed task could have * terminated either normally or by throwing an exception. @@ -272,12 +272,12 @@ * collection is modified while this operation is in progress. * * @param tasks the collection of tasks - * @return A list of Futures representing the tasks, in the same + * @return a list of Futures representing the tasks, in the same * sequential order as produced by the iterator for the - * given task list, each of which has completed. + * given task list, each of which has completed * @throws InterruptedException if interrupted while waiting, in - * which case unfinished tasks are cancelled. - * @throws NullPointerException if tasks or any of its elements are null + * which case unfinished tasks are cancelled + * @throws NullPointerException if tasks or any of its elements are {@code null} * @throws RejectedExecutionException if any task cannot be * scheduled for execution */ @@ -288,7 +288,7 @@ * Executes the given tasks, returning a list of Futures holding * their status and results * when all complete or the timeout expires, whichever happens first. - * {@link Future#isDone} is true for each + * {@link Future#isDone} is {@code true} for each * element of the returned list. * Upon return, tasks that have not completed are cancelled. * Note that a completed task could have @@ -307,7 +307,7 @@ * @throws InterruptedException if interrupted while waiting, in * which case unfinished tasks are cancelled * @throws NullPointerException if tasks, any of its elements, or - * unit are null + * unit are {@code null} * @throws RejectedExecutionException if any task cannot be scheduled * for execution */ @@ -327,7 +327,7 @@ * @return the result returned by one of the tasks * @throws InterruptedException if interrupted while waiting * @throws NullPointerException if tasks or any element task - * subject to execution is null + * subject to execution is {@code null} * @throws IllegalArgumentException if tasks is empty * @throws ExecutionException if no task successfully completes * @throws RejectedExecutionException if tasks cannot be scheduled @@ -348,10 +348,10 @@ * @param tasks the collection of tasks * @param timeout the maximum time to wait * @param unit the time unit of the timeout argument - * @return the result returned by one of the tasks. + * @return the result returned by one of the tasks * @throws InterruptedException if interrupted while waiting * @throws NullPointerException if tasks, or unit, or any element - * task subject to execution is null + * task subject to execution is {@code null} * @throws TimeoutException if the given timeout elapses before * any task successfully completes * @throws ExecutionException if no task successfully completes diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/util/concurrent/Executors.java --- a/jdk/src/share/classes/java/util/concurrent/Executors.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/util/concurrent/Executors.java Tue Jul 09 15:26:20 2013 -0700 @@ -62,7 +62,7 @@ * that sets newly created threads to a known state. *

  • Methods that create and return a {@link Callable} * out of other closure-like forms, so they can be used - * in execution methods requiring Callable. + * in execution methods requiring {@code Callable}. * * * @since 1.5 @@ -73,7 +73,7 @@ /** * Creates a thread pool that reuses a fixed number of threads * operating off a shared unbounded queue. At any point, at most - * nThreads threads will be active processing tasks. + * {@code nThreads} threads will be active processing tasks. * If additional tasks are submitted when all threads are active, * they will wait in the queue until a thread is available. * If any thread terminates due to a failure during execution @@ -92,10 +92,47 @@ } /** + * Creates a thread pool that maintains enough threads to support + * the given parallelism level, and may use multiple queues to + * reduce contention. The parallelism level corresponds to the + * maximum number of threads actively engaged in, or available to + * engage in, task processing. The actual number of threads may + * grow and shrink dynamically. A work-stealing pool makes no + * guarantees about the order in which submitted tasks are + * executed. + * + * @param parallelism the targeted parallelism level + * @return the newly created thread pool + * @throws IllegalArgumentException if {@code parallelism <= 0} + * @since 1.8 + */ + public static ExecutorService newWorkStealingPool(int parallelism) { + return new ForkJoinPool + (parallelism, + ForkJoinPool.defaultForkJoinWorkerThreadFactory, + null, true); + } + + /** + * Creates a work-stealing thread pool using all + * {@link Runtime#availableProcessors available processors} + * as its target parallelism level. + * @return the newly created thread pool + * @see #newWorkStealingPool(int) + * @since 1.8 + */ + public static ExecutorService newWorkStealingPool() { + return new ForkJoinPool + (Runtime.getRuntime().availableProcessors(), + ForkJoinPool.defaultForkJoinWorkerThreadFactory, + null, true); + } + + /** * Creates a thread pool that reuses a fixed number of threads * operating off a shared unbounded queue, using the provided * ThreadFactory to create new threads when needed. At any point, - * at most nThreads threads will be active processing + * at most {@code nThreads} threads will be active processing * tasks. If additional tasks are submitted when all threads are * active, they will wait in the queue until a thread is * available. If any thread terminates due to a failure during @@ -125,7 +162,7 @@ * subsequent tasks.) Tasks are guaranteed to execute * sequentially, and no more than one task will be active at any * given time. Unlike the otherwise equivalent - * newFixedThreadPool(1) the returned executor is + * {@code newFixedThreadPool(1)} the returned executor is * guaranteed not to be reconfigurable to use additional threads. * * @return the newly created single-threaded Executor @@ -141,7 +178,7 @@ * Creates an Executor that uses a single worker thread operating * off an unbounded queue, and uses the provided ThreadFactory to * create a new thread when needed. Unlike the otherwise - * equivalent newFixedThreadPool(1, threadFactory) the + * equivalent {@code newFixedThreadPool(1, threadFactory)} the * returned executor is guaranteed not to be reconfigurable to use * additional threads. * @@ -164,7 +201,7 @@ * will reuse previously constructed threads when they are * available. These pools will typically improve the performance * of programs that execute many short-lived asynchronous tasks. - * Calls to execute will reuse previously constructed + * Calls to {@code execute} will reuse previously constructed * threads if available. If no existing thread is available, a new * thread will be created and added to the pool. Threads that have * not been used for sixty seconds are terminated and removed from @@ -206,7 +243,7 @@ * subsequent tasks.) Tasks are guaranteed to execute * sequentially, and no more than one task will be active at any * given time. Unlike the otherwise equivalent - * newScheduledThreadPool(1) the returned executor is + * {@code newScheduledThreadPool(1)} the returned executor is * guaranteed not to be reconfigurable to use additional threads. * @return the newly created scheduled executor */ @@ -223,7 +260,7 @@ * place if needed to execute subsequent tasks.) Tasks are * guaranteed to execute sequentially, and no more than one task * will be active at any given time. Unlike the otherwise - * equivalent newScheduledThreadPool(1, threadFactory) + * equivalent {@code newScheduledThreadPool(1, threadFactory)} * the returned executor is guaranteed not to be reconfigurable to * use additional threads. * @param threadFactory the factory to use when creating new @@ -240,7 +277,7 @@ * Creates a thread pool that can schedule commands to run after a * given delay, or to execute periodically. * @param corePoolSize the number of threads to keep in the pool, - * even if they are idle. + * even if they are idle * @return a newly created scheduled thread pool * @throws IllegalArgumentException if {@code corePoolSize < 0} */ @@ -252,9 +289,9 @@ * Creates a thread pool that can schedule commands to run after a * given delay, or to execute periodically. * @param corePoolSize the number of threads to keep in the pool, - * even if they are idle. + * even if they are idle * @param threadFactory the factory to use when the executor - * creates a new thread. + * creates a new thread * @return a newly created scheduled thread pool * @throws IllegalArgumentException if {@code corePoolSize < 0} * @throws NullPointerException if threadFactory is null @@ -264,7 +301,6 @@ return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory); } - /** * Returns an object that delegates all defined {@link * ExecutorService} methods to the given executor, but not any @@ -272,7 +308,7 @@ * casts. This provides a way to safely "freeze" configuration and * disallow tuning of a given concrete implementation. * @param executor the underlying implementation - * @return an ExecutorService instance + * @return an {@code ExecutorService} instance * @throws NullPointerException if executor null */ public static ExecutorService unconfigurableExecutorService(ExecutorService executor) { @@ -288,7 +324,7 @@ * casts. This provides a way to safely "freeze" configuration and * disallow tuning of a given concrete implementation. * @param executor the underlying implementation - * @return a ScheduledExecutorService instance + * @return a {@code ScheduledExecutorService} instance * @throws NullPointerException if executor null */ public static ScheduledExecutorService unconfigurableScheduledExecutorService(ScheduledExecutorService executor) { @@ -303,9 +339,9 @@ * same {@link ThreadGroup}. If there is a {@link * java.lang.SecurityManager}, it uses the group of {@link * System#getSecurityManager}, else the group of the thread - * invoking this defaultThreadFactory method. Each new + * invoking this {@code defaultThreadFactory} method. Each new * thread is created as a non-daemon thread with priority set to - * the smaller of Thread.NORM_PRIORITY and the maximum + * the smaller of {@code Thread.NORM_PRIORITY} and the maximum * priority permitted in the thread group. New threads have names * accessible via {@link Thread#getName} of * pool-N-thread-M, where N is the sequence @@ -324,30 +360,31 @@ * Executors#defaultThreadFactory}, additionally setting the * AccessControlContext and contextClassLoader of new threads to * be the same as the thread invoking this - * privilegedThreadFactory method. A new - * privilegedThreadFactory can be created within an - * {@link AccessController#doPrivileged} action setting the - * current thread's access control context to create threads with - * the selected permission settings holding within that action. + * {@code privilegedThreadFactory} method. A new + * {@code privilegedThreadFactory} can be created within an + * {@link AccessController#doPrivileged AccessController.doPrivileged} + * action setting the current thread's access control context to + * create threads with the selected permission settings holding + * within that action. * - *

    Note that while tasks running within such threads will have + *

    Note that while tasks running within such threads will have * the same access control and class loader settings as the * current thread, they need not have the same {@link * java.lang.ThreadLocal} or {@link * java.lang.InheritableThreadLocal} values. If necessary, * particular values of thread locals can be set or reset before * any task runs in {@link ThreadPoolExecutor} subclasses using - * {@link ThreadPoolExecutor#beforeExecute}. Also, if it is - * necessary to initialize worker threads to have the same - * InheritableThreadLocal settings as some other designated - * thread, you can create a custom ThreadFactory in which that - * thread waits for and services requests to create others that - * will inherit its values. + * {@link ThreadPoolExecutor#beforeExecute(Thread, Runnable)}. + * Also, if it is necessary to initialize worker threads to have + * the same InheritableThreadLocal settings as some other + * designated thread, you can create a custom ThreadFactory in + * which that thread waits for and services requests to create + * others that will inherit its values. * * @return a thread factory * @throws AccessControlException if the current access control * context does not have permission to both get and set context - * class loader. + * class loader */ public static ThreadFactory privilegedThreadFactory() { return new PrivilegedThreadFactory(); @@ -357,7 +394,7 @@ * Returns a {@link Callable} object that, when * called, runs the given task and returns the given result. This * can be useful when applying methods requiring a - * Callable to an otherwise resultless action. + * {@code Callable} to an otherwise resultless action. * @param task the task to run * @param result the result to return * @return a callable object @@ -371,7 +408,7 @@ /** * Returns a {@link Callable} object that, when - * called, runs the given task and returns null. + * called, runs the given task and returns {@code null}. * @param task the task to run * @return a callable object * @throws NullPointerException if task null @@ -412,18 +449,17 @@ } /** - * Returns a {@link Callable} object that will, when - * called, execute the given callable under the current - * access control context. This method should normally be - * invoked within an {@link AccessController#doPrivileged} action - * to create callables that will, if possible, execute under the - * selected permission settings holding within that action; or if - * not possible, throw an associated {@link + * Returns a {@link Callable} object that will, when called, + * execute the given {@code callable} under the current access + * control context. This method should normally be invoked within + * an {@link AccessController#doPrivileged AccessController.doPrivileged} + * action to create callables that will, if possible, execute + * under the selected permission settings holding within that + * action; or if not possible, throw an associated {@link * AccessControlException}. * @param callable the underlying task * @return a callable object * @throws NullPointerException if callable null - * */ public static Callable privilegedCallable(Callable callable) { if (callable == null) @@ -432,22 +468,23 @@ } /** - * Returns a {@link Callable} object that will, when - * called, execute the given callable under the current - * access control context, with the current context class loader - * as the context class loader. This method should normally be - * invoked within an {@link AccessController#doPrivileged} action - * to create callables that will, if possible, execute under the - * selected permission settings holding within that action; or if - * not possible, throw an associated {@link + * Returns a {@link Callable} object that will, when called, + * execute the given {@code callable} under the current access + * control context, with the current context class loader as the + * context class loader. This method should normally be invoked + * within an + * {@link AccessController#doPrivileged AccessController.doPrivileged} + * action to create callables that will, if possible, execute + * under the selected permission settings holding within that + * action; or if not possible, throw an associated {@link * AccessControlException}. + * * @param callable the underlying task - * * @return a callable object * @throws NullPointerException if callable null * @throws AccessControlException if the current access control * context does not have permission to both set and get context - * class loader. + * class loader */ public static Callable privilegedCallableUsingCurrentClassLoader(Callable callable) { if (callable == null) @@ -699,7 +736,6 @@ } } - /** Cannot instantiate. */ private Executors() {} } diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/util/concurrent/ForkJoinPool.java --- a/jdk/src/share/classes/java/util/concurrent/ForkJoinPool.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/util/concurrent/ForkJoinPool.java Tue Jul 09 15:26:20 2013 -0700 @@ -47,6 +47,7 @@ import java.util.concurrent.Future; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.RunnableFuture; +import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; /** @@ -79,9 +80,9 @@ * level; by default, equal to the number of available processors. The * pool attempts to maintain enough active (or available) threads by * dynamically adding, suspending, or resuming internal worker - * threads, even if some tasks are stalled waiting to join - * others. However, no such adjustments are guaranteed in the face of - * blocked I/O or other unmanaged synchronization. The nested {@link + * threads, even if some tasks are stalled waiting to join others. + * However, no such adjustments are guaranteed in the face of blocked + * I/O or other unmanaged synchronization. The nested {@link * ManagedBlocker} interface enables extension of the kinds of * synchronization accommodated. * @@ -157,6 +158,7 @@ * @since 1.7 * @author Doug Lea */ +@sun.misc.Contended public class ForkJoinPool extends AbstractExecutorService { /* @@ -189,32 +191,35 @@ * (http://research.sun.com/scalable/pubs/index.html) and * "Idempotent work stealing" by Michael, Saraswat, and Vechev, * PPoPP 2009 (http://portal.acm.org/citation.cfm?id=1504186). - * The main differences ultimately stem from GC requirements that - * we null out taken slots as soon as we can, to maintain as small - * a footprint as possible even in programs generating huge - * numbers of tasks. To accomplish this, we shift the CAS - * arbitrating pop vs poll (steal) from being on the indices - * ("base" and "top") to the slots themselves. So, both a - * successful pop and poll mainly entail a CAS of a slot from - * non-null to null. Because we rely on CASes of references, we - * do not need tag bits on base or top. They are simple ints as - * used in any circular array-based queue (see for example - * ArrayDeque). Updates to the indices must still be ordered in a - * way that guarantees that top == base means the queue is empty, - * but otherwise may err on the side of possibly making the queue - * appear nonempty when a push, pop, or poll have not fully - * committed. Note that this means that the poll operation, - * considered individually, is not wait-free. One thief cannot - * successfully continue until another in-progress one (or, if - * previously empty, a push) completes. However, in the - * aggregate, we ensure at least probabilistic non-blockingness. - * If an attempted steal fails, a thief always chooses a different - * random victim target to try next. So, in order for one thief to - * progress, it suffices for any in-progress poll or new push on - * any empty queue to complete. (This is why we normally use - * method pollAt and its variants that try once at the apparent - * base index, else consider alternative actions, rather than - * method poll.) + * See also "Correct and Efficient Work-Stealing for Weak Memory + * Models" by Le, Pop, Cohen, and Nardelli, PPoPP 2013 + * (http://www.di.ens.fr/~zappa/readings/ppopp13.pdf) for an + * analysis of memory ordering (atomic, volatile etc) issues. The + * main differences ultimately stem from GC requirements that we + * null out taken slots as soon as we can, to maintain as small a + * footprint as possible even in programs generating huge numbers + * of tasks. To accomplish this, we shift the CAS arbitrating pop + * vs poll (steal) from being on the indices ("base" and "top") to + * the slots themselves. So, both a successful pop and poll + * mainly entail a CAS of a slot from non-null to null. Because + * we rely on CASes of references, we do not need tag bits on base + * or top. They are simple ints as used in any circular + * array-based queue (see for example ArrayDeque). Updates to the + * indices must still be ordered in a way that guarantees that top + * == base means the queue is empty, but otherwise may err on the + * side of possibly making the queue appear nonempty when a push, + * pop, or poll have not fully committed. Note that this means + * that the poll operation, considered individually, is not + * wait-free. One thief cannot successfully continue until another + * in-progress one (or, if previously empty, a push) completes. + * However, in the aggregate, we ensure at least probabilistic + * non-blockingness. If an attempted steal fails, a thief always + * chooses a different random victim target to try next. So, in + * order for one thief to progress, it suffices for any + * in-progress poll or new push on any empty queue to + * complete. (This is why we normally use method pollAt and its + * variants that try once at the apparent base index, else + * consider alternative actions, rather than method poll.) * * This approach also enables support of a user mode in which local * task processing is in FIFO, not LIFO order, simply by using @@ -334,37 +339,35 @@ * has not yet entered the wait queue. We solve this by requiring * a full sweep of all workers (via repeated calls to method * scan()) both before and after a newly waiting worker is added - * to the wait queue. During a rescan, the worker might release - * some other queued worker rather than itself, which has the same - * net effect. Because enqueued workers may actually be rescanning - * rather than waiting, we set and clear the "parker" field of - * WorkQueues to reduce unnecessary calls to unpark. (This - * requires a secondary recheck to avoid missed signals.) Note - * the unusual conventions about Thread.interrupts surrounding - * parking and other blocking: Because interrupts are used solely - * to alert threads to check termination, which is checked anyway - * upon blocking, we clear status (using Thread.interrupted) - * before any call to park, so that park does not immediately - * return due to status being set via some other unrelated call to - * interrupt in user code. + * to the wait queue. Because enqueued workers may actually be + * rescanning rather than waiting, we set and clear the "parker" + * field of WorkQueues to reduce unnecessary calls to unpark. + * (This requires a secondary recheck to avoid missed signals.) + * Note the unusual conventions about Thread.interrupts + * surrounding parking and other blocking: Because interrupts are + * used solely to alert threads to check termination, which is + * checked anyway upon blocking, we clear status (using + * Thread.interrupted) before any call to park, so that park does + * not immediately return due to status being set via some other + * unrelated call to interrupt in user code. * * Signalling. We create or wake up workers only when there * appears to be at least one task they might be able to find and - * execute. However, many other threads may notice the same task - * and each signal to wake up a thread that might take it. So in - * general, pools will be over-signalled. When a submission is - * added or another worker adds a task to a queue that has fewer - * than two tasks, they signal waiting workers (or trigger - * creation of new ones if fewer than the given parallelism level - * -- signalWork), and may leave a hint to the unparked worker to - * help signal others upon wakeup). These primary signals are - * buttressed by others (see method helpSignal) whenever other - * threads scan for work or do not have a task to process. On - * most platforms, signalling (unpark) overhead time is noticeably + * execute. When a submission is added or another worker adds a + * task to a queue that has fewer than two tasks, they signal + * waiting workers (or trigger creation of new ones if fewer than + * the given parallelism level -- signalWork). These primary + * signals are buttressed by others whenever other threads remove + * a task from a queue and notice that there are other tasks there + * as well. So in general, pools will be over-signalled. On most + * platforms, signalling (unpark) overhead time is noticeably * long, and the time between signalling a thread and it actually * making progress can be very noticeably long, so it is worth * offloading these delays from critical paths as much as - * possible. + * possible. Additionally, workers spin-down gradually, by staying + * alive so long as they see the ctl state changing. Similar + * stability-sensing techniques are also used before blocking in + * awaitJoin and helpComplete. * * Trimming workers. To release resources after periods of lack of * use, a worker starting to wait when the pool is quiescent will @@ -477,7 +480,7 @@ * Common Pool * =========== * - * The static common Pool always exists after static + * The static common pool always exists after static * initialization. Since it (or any other created pool) need * never be used, we minimize initial construction overhead and * footprint to the setup of about a dozen fields, with no nested @@ -485,8 +488,11 @@ * fullExternalPush during the first submission to the pool. * * When external threads submit to the common pool, they can - * perform some subtask processing (see externalHelpJoin and - * related methods). We do not need to record whether these + * perform subtask processing (see externalHelpJoin and related + * methods). This caller-helps policy makes it sensible to set + * common pool parallelism level to one (or more) less than the + * total number of available cores, or even zero for pure + * caller-runs. We do not need to record whether external * submissions are to the common pool -- if not, externalHelpJoin * returns quickly (at the most helping to signal some common pool * workers). These submitters would otherwise be blocked waiting @@ -631,18 +637,10 @@ * do not want multiple WorkQueue instances or multiple queue * arrays sharing cache lines. (It would be best for queue objects * and their arrays to share, but there is nothing available to - * help arrange that). Unfortunately, because they are recorded - * in a common array, WorkQueue instances are often moved to be - * adjacent by garbage collectors. To reduce impact, we use field - * padding that works OK on common platforms; this effectively - * trades off slightly slower average field access for the sake of - * avoiding really bad worst-case access. (Until better JVM - * support is in place, this padding is dependent on transient - * properties of JVM field layout rules.) We also take care in - * allocating, sizing and resizing the array. Non-shared queue - * arrays are initialized by workers before use. Others are - * allocated on first use. + * help arrange that). The @Contended annotation alerts JVMs to + * try to keep instances apart. */ + @sun.misc.Contended static final class WorkQueue { /** * Capacity of work-stealing queue array upon initialization. @@ -664,16 +662,12 @@ */ static final int MAXIMUM_QUEUE_CAPACITY = 1 << 26; // 64M - // Heuristic padding to ameliorate unfortunate memory placements - volatile long pad00, pad01, pad02, pad03, pad04, pad05, pad06; - - int seed; // for random scanning; initialize nonzero volatile int eventCount; // encoded inactivation count; < 0 if inactive int nextWait; // encoded record of next event waiter - int hint; // steal or signal hint (index) - int poolIndex; // index of this queue in pool (or 0) - final int mode; // 0: lifo, > 0: fifo, < 0: shared int nsteals; // number of steals + int hint; // steal index hint + short poolIndex; // index of this queue in pool + final short mode; // 0: lifo, > 0: fifo, < 0: shared volatile int qlock; // 1: locked, -1: terminate; else 0 volatile int base; // index of next slot for poll int top; // index of next slot for push @@ -684,15 +678,12 @@ volatile ForkJoinTask currentJoin; // task being joined in awaitJoin ForkJoinTask currentSteal; // current non-local task being executed - volatile Object pad10, pad11, pad12, pad13, pad14, pad15, pad16, pad17; - volatile Object pad18, pad19, pad1a, pad1b, pad1c, pad1d; - WorkQueue(ForkJoinPool pool, ForkJoinWorkerThread owner, int mode, int seed) { this.pool = pool; this.owner = owner; - this.mode = mode; - this.seed = seed; + this.mode = (short)mode; + this.hint = seed; // store initial seed for runWorker // Place indices in the center of array (that is not yet allocated) base = top = INITIAL_QUEUE_CAPACITY >>> 1; } @@ -705,7 +696,7 @@ return (n >= 0) ? 0 : -n; // ignore transient negative } - /** + /** * Provides a more accurate estimate of whether this queue has * any tasks than does queueSize, by checking whether a * near-empty queue has at least one unclaimed task. @@ -730,20 +721,18 @@ */ final void push(ForkJoinTask task) { ForkJoinTask[] a; ForkJoinPool p; - int s = top, m, n; + int s = top, n; if ((a = array) != null) { // ignore if queue removed - int j = (((m = a.length - 1) & s) << ASHIFT) + ABASE; - U.putOrderedObject(a, j, task); - if ((n = (top = s + 1) - base) <= 2) { - if ((p = pool) != null) - p.signalWork(this); - } + int m = a.length - 1; + U.putOrderedObject(a, ((m & s) << ASHIFT) + ABASE, task); + if ((n = (top = s + 1) - base) <= 2) + (p = pool).signalWork(p.workQueues, this); else if (n >= m) growArray(); } } - /** + /** * Initializes or doubles the capacity of array. Call either * by owner or with lock held -- it is OK for base, but not * top, to move while resizings are in progress. @@ -801,9 +790,8 @@ if ((a = array) != null) { int j = (((a.length - 1) & b) << ASHIFT) + ABASE; if ((t = (ForkJoinTask)U.getObjectVolatile(a, j)) != null && - base == b && - U.compareAndSwapObject(a, j, t, null)) { - base = b + 1; + base == b && U.compareAndSwapObject(a, j, t, null)) { + U.putOrderedInt(this, QBASE, b + 1); return t; } } @@ -819,9 +807,8 @@ int j = (((a.length - 1) & b) << ASHIFT) + ABASE; t = (ForkJoinTask)U.getObjectVolatile(a, j); if (t != null) { - if (base == b && - U.compareAndSwapObject(a, j, t, null)) { - base = b + 1; + if (U.compareAndSwapObject(a, j, t, null)) { + U.putOrderedInt(this, QBASE, b + 1); return t; } } @@ -878,49 +865,43 @@ ForkJoinTask.cancelIgnoringExceptions(t); } - /** - * Computes next value for random probes. Scans don't require - * a very high quality generator, but also not a crummy one. - * Marsaglia xor-shift is cheap and works well enough. Note: - * This is manually inlined in its usages in ForkJoinPool to - * avoid writes inside busy scan loops. - */ - final int nextSeed() { - int r = seed; - r ^= r << 13; - r ^= r >>> 17; - return seed = r ^= r << 5; - } - // Specialized execution methods /** - * Pops and runs tasks until empty. - */ - private void popAndExecAll() { - // A bit faster than repeated pop calls - ForkJoinTask[] a; int m, s; long j; ForkJoinTask t; - while ((a = array) != null && (m = a.length - 1) >= 0 && - (s = top - 1) - base >= 0 && - (t = ((ForkJoinTask) - U.getObject(a, j = ((m & s) << ASHIFT) + ABASE))) - != null) { - if (U.compareAndSwapObject(a, j, t, null)) { - top = s; - t.doExec(); - } - } - } - - /** * Polls and runs tasks until empty. */ - private void pollAndExecAll() { + final void pollAndExecAll() { for (ForkJoinTask t; (t = poll()) != null;) t.doExec(); } /** + * Executes a top-level task and any local tasks remaining + * after execution. + */ + final void runTask(ForkJoinTask task) { + if ((currentSteal = task) != null) { + task.doExec(); + ForkJoinTask[] a = array; + int md = mode; + ++nsteals; + currentSteal = null; + if (md != 0) + pollAndExecAll(); + else if (a != null) { + int s, m = a.length - 1; + ForkJoinTask t; + while ((s = top - 1) - base >= 0 && + (t = (ForkJoinTask)U.getAndSetObject + (a, ((m & s) << ASHIFT) + ABASE, null)) != null) { + top = s; + t.doExec(); + } + } + } + } + + /** * If present, removes from queue and executes the given task, * or any other cancelled task. Returns (true) on any CAS * or consistency check failure so caller can retry. @@ -928,13 +909,15 @@ * @return false if no progress can be made, else true */ final boolean tryRemoveAndExec(ForkJoinTask task) { - boolean stat = true, removed = false, empty = true; + boolean stat; ForkJoinTask[] a; int m, s, b, n; - if ((a = array) != null && (m = a.length - 1) >= 0 && + if (task != null && (a = array) != null && (m = a.length - 1) >= 0 && (n = (s = top) - (b = base)) > 0) { + boolean removed = false, empty = true; + stat = true; for (ForkJoinTask t;;) { // traverse from s to b - int j = ((--s & m) << ASHIFT) + ABASE; - t = (ForkJoinTask)U.getObjectVolatile(a, j); + long j = ((--s & m) << ASHIFT) + ABASE; + t = (ForkJoinTask)U.getObject(a, j); if (t == null) // inconsistent length break; else if (t == task) { @@ -962,68 +945,95 @@ break; } } + if (removed) + task.doExec(); } - if (removed) - task.doExec(); + else + stat = false; return stat; } /** - * Polls for and executes the given task or any other task in - * its CountedCompleter computation. + * Tries to poll for and execute the given task or any other + * task in its CountedCompleter computation. */ - final boolean pollAndExecCC(ForkJoinTask root) { - ForkJoinTask[] a; int b; Object o; - outer: while ((b = base) - top < 0 && (a = array) != null) { + final boolean pollAndExecCC(CountedCompleter root) { + ForkJoinTask[] a; int b; Object o; CountedCompleter t, r; + if ((b = base) - top < 0 && (a = array) != null) { long j = (((a.length - 1) & b) << ASHIFT) + ABASE; - if ((o = U.getObject(a, j)) == null || - !(o instanceof CountedCompleter)) - break; - for (CountedCompleter t = (CountedCompleter)o, r = t;;) { - if (r == root) { - if (base == b && - U.compareAndSwapObject(a, j, t, null)) { - base = b + 1; - t.doExec(); + if ((o = U.getObjectVolatile(a, j)) == null) + return true; // retry + if (o instanceof CountedCompleter) { + for (t = (CountedCompleter)o, r = t;;) { + if (r == root) { + if (base == b && + U.compareAndSwapObject(a, j, t, null)) { + U.putOrderedInt(this, QBASE, b + 1); + t.doExec(); + } return true; } - else - break; // restart + else if ((r = r.completer) == null) + break; // not part of root computation } - if ((r = r.completer) == null) - break outer; // not part of root computation } } return false; } /** - * Executes a top-level task and any local tasks remaining - * after execution. + * Tries to pop and execute the given task or any other task + * in its CountedCompleter computation. */ - final void runTask(ForkJoinTask t) { - if (t != null) { - (currentSteal = t).doExec(); - currentSteal = null; - ++nsteals; - if (base - top < 0) { // process remaining local tasks - if (mode == 0) - popAndExecAll(); - else - pollAndExecAll(); + final boolean externalPopAndExecCC(CountedCompleter root) { + ForkJoinTask[] a; int s; Object o; CountedCompleter t, r; + if (base - (s = top) < 0 && (a = array) != null) { + long j = (((a.length - 1) & (s - 1)) << ASHIFT) + ABASE; + if ((o = U.getObject(a, j)) instanceof CountedCompleter) { + for (t = (CountedCompleter)o, r = t;;) { + if (r == root) { + if (U.compareAndSwapInt(this, QLOCK, 0, 1)) { + if (top == s && array == a && + U.compareAndSwapObject(a, j, t, null)) { + top = s - 1; + qlock = 0; + t.doExec(); + } + else + qlock = 0; + } + return true; + } + else if ((r = r.completer) == null) + break; + } } } + return false; } /** - * Executes a non-top-level (stolen) task. + * Internal version */ - final void runSubtask(ForkJoinTask t) { - if (t != null) { - ForkJoinTask ps = currentSteal; - (currentSteal = t).doExec(); - currentSteal = ps; + final boolean internalPopAndExecCC(CountedCompleter root) { + ForkJoinTask[] a; int s; Object o; CountedCompleter t, r; + if (base - (s = top) < 0 && (a = array) != null) { + long j = (((a.length - 1) & (s - 1)) << ASHIFT) + ABASE; + if ((o = U.getObject(a, j)) instanceof CountedCompleter) { + for (t = (CountedCompleter)o, r = t;;) { + if (r == root) { + if (U.compareAndSwapObject(a, j, t, null)) { + top = s - 1; + t.doExec(); + } + return true; + } + else if ((r = r.completer) == null) + break; + } + } } + return false; } /** @@ -1040,6 +1050,7 @@ // Unsafe mechanics private static final sun.misc.Unsafe U; + private static final long QBASE; private static final long QLOCK; private static final int ABASE; private static final int ASHIFT; @@ -1048,6 +1059,8 @@ U = sun.misc.Unsafe.getUnsafe(); Class k = WorkQueue.class; Class ak = ForkJoinTask[].class; + QBASE = U.objectFieldOffset + (k.getDeclaredField("base")); QLOCK = U.objectFieldOffset (k.getDeclaredField("qlock")); ABASE = U.arrayBaseOffset(ak); @@ -1087,7 +1100,7 @@ /** * Common pool parallelism. To allow simpler use and management * when common pool threads are disabled, we allow the underlying - * common.config field to be zero, but in that case still report + * common.parallelism field to be zero, but in that case still report * parallelism as 1 to reflect resulting caller-runs mechanics. */ static final int commonParallelism; @@ -1227,35 +1240,18 @@ static final int FIFO_QUEUE = 1; static final int SHARED_QUEUE = -1; - // bounds for #steps in scan loop -- must be power 2 minus 1 - private static final int MIN_SCAN = 0x1ff; // cover estimation slop - private static final int MAX_SCAN = 0x1ffff; // 4 * max workers - // Instance fields - - /* - * Field layout of this class tends to matter more than one would - * like. Runtime layout order is only loosely related to - * declaration order and may differ across JVMs, but the following - * empirically works OK on current JVMs. - */ - - // Heuristic padding to ameliorate unfortunate memory placements - volatile long pad00, pad01, pad02, pad03, pad04, pad05, pad06; - volatile long stealCount; // collects worker counts volatile long ctl; // main pool control volatile int plock; // shutdown status and seqLock volatile int indexSeed; // worker/submitter index seed - final int config; // mode and parallelism level + final short parallelism; // parallelism level + final short mode; // LIFO/FIFO WorkQueue[] workQueues; // main registry final ForkJoinWorkerThreadFactory factory; final UncaughtExceptionHandler ueh; // per-worker UEH final String workerNamePrefix; // to create worker name string - volatile Object pad10, pad11, pad12, pad13, pad14, pad15, pad16, pad17; - volatile Object pad18, pad19, pad1a, pad1b; - /** * Acquires the plock lock to protect worker array and related * updates. This method is called only if an initial CAS on plock @@ -1307,11 +1303,11 @@ * parallelism level exist. Adjusts counts etc on failure. */ private void tryAddWorker() { - long c; int u; + long c; int u, e; while ((u = (int)((c = ctl) >>> 32)) < 0 && - (u & SHORT_SIGN) != 0 && (int)c == 0) { - long nc = (long)(((u + UTC_UNIT) & UTC_MASK) | - ((u + UAC_UNIT) & UAC_MASK)) << 32; + (u & SHORT_SIGN) != 0 && (e = (int)c) >= 0) { + long nc = ((long)(((u + UTC_UNIT) & UTC_MASK) | + ((u + UAC_UNIT) & UAC_MASK)) << 32) | (long)e; if (U.compareAndSwapLong(this, CTL, c, nc)) { ForkJoinWorkerThreadFactory fac; Throwable ex = null; @@ -1322,8 +1318,8 @@ wt.start(); break; } - } catch (Throwable e) { - ex = e; + } catch (Throwable rex) { + ex = rex; } deregisterWorker(wt, ex); break; @@ -1351,7 +1347,7 @@ do {} while (!U.compareAndSwapInt(this, INDEXSEED, s = indexSeed, s += SEED_INCREMENT) || s == 0); // skip 0 - WorkQueue w = new WorkQueue(this, wt, config >>> 16, s); + WorkQueue w = new WorkQueue(this, wt, mode, s); if (((ps = plock) & PL_LOCK) != 0 || !U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK)) ps = acquirePlock(); @@ -1371,14 +1367,15 @@ } } } - w.eventCount = w.poolIndex = r; // volatile write orders + w.poolIndex = (short)r; + w.eventCount = r; // volatile write orders ws[r] = w; } } finally { if (!U.compareAndSwapInt(this, PLOCK, ps, nps)) releasePlock(nps); } - wt.setName(workerNamePrefix.concat(Integer.toString(w.poolIndex))); + wt.setName(workerNamePrefix.concat(Integer.toString(w.poolIndex >>> 1))); return w; } @@ -1396,9 +1393,7 @@ if (wt != null && (w = wt.workQueue) != null) { int ps; w.qlock = -1; // ensure set - long ns = w.nsteals, sc; // collect steal count - do {} while (!U.compareAndSwapLong(this, STEALCOUNT, - sc = stealCount, sc + ns)); + U.getAndAddLong(this, STEALCOUNT, w.nsteals); // collect steals if (((ps = plock) & PL_LOCK) != 0 || !U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK)) ps = acquirePlock(); @@ -1464,19 +1459,21 @@ * @param task the task. Caller must ensure non-null. */ final void externalPush(ForkJoinTask task) { - WorkQueue[] ws; WorkQueue q; int z, m; ForkJoinTask[] a; - if ((z = ThreadLocalRandom.getProbe()) != 0 && plock > 0 && - (ws = workQueues) != null && (m = (ws.length - 1)) >= 0 && - (q = ws[m & z & SQMASK]) != null && + WorkQueue q; int m, s, n, am; ForkJoinTask[] a; + int r = ThreadLocalRandom.getProbe(); + int ps = plock; + WorkQueue[] ws = workQueues; + if (ps > 0 && ws != null && (m = (ws.length - 1)) >= 0 && + (q = ws[m & r & SQMASK]) != null && r != 0 && U.compareAndSwapInt(q, QLOCK, 0, 1)) { // lock - int b = q.base, s = q.top, n, an; - if ((a = q.array) != null && (an = a.length) > (n = s + 1 - b)) { - int j = (((an - 1) & s) << ASHIFT) + ABASE; + if ((a = q.array) != null && + (am = a.length - 1) > (n = (s = q.top) - q.base)) { + int j = ((am & s) << ASHIFT) + ABASE; U.putOrderedObject(a, j, task); q.top = s + 1; // push on to deque q.qlock = 0; - if (n <= 2) - signalWork(q); + if (n <= 1) + signalWork(ws, q); return; } q.qlock = 0; @@ -1514,7 +1511,7 @@ throw new RejectedExecutionException(); else if (ps == 0 || (ws = workQueues) == null || (m = ws.length - 1) < 0) { // initialize workQueues - int p = config & SMASK; // find power of two table size + int p = parallelism; // find power of two table size int n = (p > 1) ? p - 1 : 1; // ensure at least 2 slots n |= n >>> 1; n |= n >>> 2; n |= n >>> 4; n |= n >>> 8; n |= n >>> 16; n = (n + 1) << 1; @@ -1546,7 +1543,7 @@ q.qlock = 0; // unlock } if (submitted) { - signalWork(q); + signalWork(ws, q); return; } } @@ -1554,6 +1551,7 @@ } else if (((ps = plock) & PL_LOCK) == 0) { // create new queue q = new WorkQueue(this, null, SHARED_QUEUE, r); + q.poolIndex = (short)k; if (((ps = plock) & PL_LOCK) != 0 || !U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK)) ps = acquirePlock(); @@ -1577,41 +1575,42 @@ */ final void incrementActiveCount() { long c; - do {} while (!U.compareAndSwapLong(this, CTL, c = ctl, c + AC_UNIT)); + do {} while (!U.compareAndSwapLong + (this, CTL, c = ctl, ((c & ~AC_MASK) | + ((c & AC_MASK) + AC_UNIT)))); } /** * Tries to create or activate a worker if too few are active. * - * @param q the (non-null) queue holding tasks to be signalled + * @param ws the worker array to use to find signallees + * @param q if non-null, the queue holding tasks to be processed */ - final void signalWork(WorkQueue q) { - int hint = q.poolIndex; - long c; int e, u, i, n; WorkQueue[] ws; WorkQueue w; Thread p; - while ((u = (int)((c = ctl) >>> 32)) < 0) { - if ((e = (int)c) > 0) { - if ((ws = workQueues) != null && ws.length > (i = e & SMASK) && - (w = ws[i]) != null && w.eventCount == (e | INT_SIGN)) { - long nc = (((long)(w.nextWait & E_MASK)) | - ((long)(u + UAC_UNIT) << 32)); - if (U.compareAndSwapLong(this, CTL, c, nc)) { - w.hint = hint; - w.eventCount = (e + E_SEQ) & E_MASK; - if ((p = w.parker) != null) - U.unpark(p); - break; - } - if (q.top - q.base <= 0) - break; - } - else - break; - } - else { + final void signalWork(WorkQueue[] ws, WorkQueue q) { + for (;;) { + long c; int e, u, i; WorkQueue w; Thread p; + if ((u = (int)((c = ctl) >>> 32)) >= 0) + break; + if ((e = (int)c) <= 0) { if ((short)u < 0) tryAddWorker(); break; } + if (ws == null || ws.length <= (i = e & SMASK) || + (w = ws[i]) == null) + break; + long nc = (((long)(w.nextWait & E_MASK)) | + ((long)(u + UAC_UNIT)) << 32); + int ne = (e + E_SEQ) & E_MASK; + if (w.eventCount == (e | INT_SIGN) && + U.compareAndSwapLong(this, CTL, c, nc)) { + w.eventCount = ne; + if ((p = w.parker) != null) + U.unpark(p); + break; + } + if (q != null && q.base >= q.top) + break; } } @@ -1622,215 +1621,152 @@ */ final void runWorker(WorkQueue w) { w.growArray(); // allocate queue - do { w.runTask(scan(w)); } while (w.qlock >= 0); + for (int r = w.hint; scan(w, r) == 0; ) { + r ^= r << 13; r ^= r >>> 17; r ^= r << 5; // xorshift + } } /** - * Scans for and, if found, returns one task, else possibly + * Scans for and, if found, runs one task, else possibly * inactivates the worker. This method operates on single reads of * volatile state and is designed to be re-invoked continuously, * in part because it returns upon detecting inconsistencies, * contention, or state changes that indicate possible success on * re-invocation. * - * The scan searches for tasks across queues (starting at a random - * index, and relying on registerWorker to irregularly scatter - * them within array to avoid bias), checking each at least twice. - * The scan terminates upon either finding a non-empty queue, or - * completing the sweep. If the worker is not inactivated, it - * takes and returns a task from this queue. Otherwise, if not - * activated, it signals workers (that may include itself) and - * returns so caller can retry. Also returns for true if the - * worker array may have changed during an empty scan. On failure - * to find a task, we take one of the following actions, after - * which the caller will retry calling this method unless - * terminated. - * - * * If pool is terminating, terminate the worker. - * - * * If not already enqueued, try to inactivate and enqueue the - * worker on wait queue. Or, if inactivating has caused the pool - * to be quiescent, relay to idleAwaitWork to possibly shrink - * pool. - * - * * If already enqueued and none of the above apply, possibly - * park awaiting signal, else lingering to help scan and signal. - * - * * If a non-empty queue discovered or left as a hint, - * help wake up other workers before return. + * The scan searches for tasks across queues starting at a random + * index, checking each at least twice. The scan terminates upon + * either finding a non-empty queue, or completing the sweep. If + * the worker is not inactivated, it takes and runs a task from + * this queue. Otherwise, if not activated, it tries to activate + * itself or some other worker by signalling. On failure to find a + * task, returns (for retry) if pool state may have changed during + * an empty scan, or tries to inactivate if active, else possibly + * blocks or terminates via method awaitWork. * * @param w the worker (via its WorkQueue) - * @return a task or null if none found + * @param r a random seed + * @return worker qlock status if would have waited, else 0 */ - private final ForkJoinTask scan(WorkQueue w) { + private final int scan(WorkQueue w, int r) { WorkQueue[] ws; int m; - int ps = plock; // read plock before ws - if (w != null && (ws = workQueues) != null && (m = ws.length - 1) >= 0) { - int ec = w.eventCount; // ec is negative if inactive - int r = w.seed; r ^= r << 13; r ^= r >>> 17; w.seed = r ^= r << 5; - w.hint = -1; // update seed and clear hint - int j = ((m + m + 1) | MIN_SCAN) & MAX_SCAN; - do { - WorkQueue q; ForkJoinTask[] a; int b; - if ((q = ws[(r + j) & m]) != null && (b = q.base) - q.top < 0 && - (a = q.array) != null) { // probably nonempty - int i = (((a.length - 1) & b) << ASHIFT) + ABASE; - ForkJoinTask t = (ForkJoinTask) - U.getObjectVolatile(a, i); - if (q.base == b && ec >= 0 && t != null && - U.compareAndSwapObject(a, i, t, null)) { - if ((q.base = b + 1) - q.top < 0) - signalWork(q); - return t; // taken - } - else if ((ec < 0 || j < m) && (int)(ctl >> AC_SHIFT) <= 0) { - w.hint = (r + j) & m; // help signal below - break; // cannot take + long c = ctl; // for consistency check + if ((ws = workQueues) != null && (m = ws.length - 1) >= 0 && w != null) { + for (int j = m + m + 1, ec = w.eventCount;;) { + WorkQueue q; int b, e; ForkJoinTask[] a; ForkJoinTask t; + if ((q = ws[(r - j) & m]) != null && + (b = q.base) - q.top < 0 && (a = q.array) != null) { + long i = (((a.length - 1) & b) << ASHIFT) + ABASE; + if ((t = ((ForkJoinTask) + U.getObjectVolatile(a, i))) != null) { + if (ec < 0) + helpRelease(c, ws, w, q, b); + else if (q.base == b && + U.compareAndSwapObject(a, i, t, null)) { + U.putOrderedInt(q, QBASE, b + 1); + if ((b + 1) - q.top < 0) + signalWork(ws, q); + w.runTask(t); + } } - } - } while (--j >= 0); - - int h, e, ns; long c, sc; WorkQueue q; - if ((ns = w.nsteals) != 0) { - if (U.compareAndSwapLong(this, STEALCOUNT, - sc = stealCount, sc + ns)) - w.nsteals = 0; // collect steals and rescan - } - else if (plock != ps) // consistency check - ; // skip - else if ((e = (int)(c = ctl)) < 0) - w.qlock = -1; // pool is terminating - else { - if ((h = w.hint) < 0) { - if (ec >= 0) { // try to enqueue/inactivate - long nc = (((long)ec | - ((c - AC_UNIT) & (AC_MASK|TC_MASK)))); - w.nextWait = e; // link and mark inactive - w.eventCount = ec | INT_SIGN; - if (ctl != c || !U.compareAndSwapLong(this, CTL, c, nc)) - w.eventCount = ec; // unmark on CAS failure - else if ((int)(c >> AC_SHIFT) == 1 - (config & SMASK)) - idleAwaitWork(w, nc, c); - } - else if (w.eventCount < 0 && ctl == c) { - Thread wt = Thread.currentThread(); - Thread.interrupted(); // clear status - U.putObject(wt, PARKBLOCKER, this); - w.parker = wt; // emulate LockSupport.park - if (w.eventCount < 0) // recheck - U.park(false, 0L); // block - w.parker = null; - U.putObject(wt, PARKBLOCKER, null); - } + break; } - if ((h >= 0 || (h = w.hint) >= 0) && - (ws = workQueues) != null && h < ws.length && - (q = ws[h]) != null) { // signal others before retry - WorkQueue v; Thread p; int u, i, s; - for (int n = (config & SMASK) - 1;;) { - int idleCount = (w.eventCount < 0) ? 0 : -1; - if (((s = idleCount - q.base + q.top) <= n && - (n = s) <= 0) || - (u = (int)((c = ctl) >>> 32)) >= 0 || - (e = (int)c) <= 0 || m < (i = e & SMASK) || - (v = ws[i]) == null) - break; - long nc = (((long)(v.nextWait & E_MASK)) | - ((long)(u + UAC_UNIT) << 32)); - if (v.eventCount != (e | INT_SIGN) || - !U.compareAndSwapLong(this, CTL, c, nc)) - break; - v.hint = h; - v.eventCount = (e + E_SEQ) & E_MASK; - if ((p = v.parker) != null) - U.unpark(p); - if (--n <= 0) - break; + else if (--j < 0) { + if ((ec | (e = (int)c)) < 0) // inactive or terminating + return awaitWork(w, c, ec); + else if (ctl == c) { // try to inactivate and enqueue + long nc = (long)ec | ((c - AC_UNIT) & (AC_MASK|TC_MASK)); + w.nextWait = e; + w.eventCount = ec | INT_SIGN; + if (!U.compareAndSwapLong(this, CTL, c, nc)) + w.eventCount = ec; // back out } - } - } - } - return null; - } - - /** - * If inactivating worker w has caused the pool to become - * quiescent, checks for pool termination, and, so long as this is - * not the only worker, waits for event for up to a given - * duration. On timeout, if ctl has not changed, terminates the - * worker, which will in turn wake up another worker to possibly - * repeat this process. - * - * @param w the calling worker - * @param currentCtl the ctl value triggering possible quiescence - * @param prevCtl the ctl value to restore if thread is terminated - */ - private void idleAwaitWork(WorkQueue w, long currentCtl, long prevCtl) { - if (w != null && w.eventCount < 0 && - !tryTerminate(false, false) && (int)prevCtl != 0 && - ctl == currentCtl) { - int dc = -(short)(currentCtl >>> TC_SHIFT); - long parkTime = dc < 0 ? FAST_IDLE_TIMEOUT: (dc + 1) * IDLE_TIMEOUT; - long deadline = System.nanoTime() + parkTime - TIMEOUT_SLOP; - Thread wt = Thread.currentThread(); - while (ctl == currentCtl) { - Thread.interrupted(); // timed variant of version in scan() - U.putObject(wt, PARKBLOCKER, this); - w.parker = wt; - if (ctl == currentCtl) - U.park(false, parkTime); - w.parker = null; - U.putObject(wt, PARKBLOCKER, null); - if (ctl != currentCtl) - break; - if (deadline - System.nanoTime() <= 0L && - U.compareAndSwapLong(this, CTL, currentCtl, prevCtl)) { - w.eventCount = (w.eventCount + E_SEQ) | E_MASK; - w.hint = -1; - w.qlock = -1; // shrink break; } } } + return 0; } /** - * Scans through queues looking for work while joining a task; if - * any present, signals. May return early if more signalling is - * detectably unneeded. + * A continuation of scan(), possibly blocking or terminating + * worker w. Returns without blocking if pool state has apparently + * changed since last invocation. Also, if inactivating w has + * caused the pool to become quiescent, checks for pool + * termination, and, so long as this is not the only worker, waits + * for event for up to a given duration. On timeout, if ctl has + * not changed, terminates the worker, which will in turn wake up + * another worker to possibly repeat this process. * - * @param task return early if done - * @param origin an index to start scan + * @param w the calling worker + * @param c the ctl value on entry to scan + * @param ec the worker's eventCount on entry to scan */ - private void helpSignal(ForkJoinTask task, int origin) { - WorkQueue[] ws; WorkQueue w; Thread p; long c; int m, u, e, i, s; - if (task != null && task.status >= 0 && - (u = (int)(ctl >>> 32)) < 0 && (u >> UAC_SHIFT) < 0 && - (ws = workQueues) != null && (m = ws.length - 1) >= 0) { - outer: for (int k = origin, j = m; j >= 0; --j) { - WorkQueue q = ws[k++ & m]; - for (int n = m;;) { // limit to at most m signals - if (task.status < 0) - break outer; - if (q == null || - ((s = -q.base + q.top) <= n && (n = s) <= 0)) - break; - if ((u = (int)((c = ctl) >>> 32)) >= 0 || - (e = (int)c) <= 0 || m < (i = e & SMASK) || - (w = ws[i]) == null) - break outer; - long nc = (((long)(w.nextWait & E_MASK)) | - ((long)(u + UAC_UNIT) << 32)); - if (w.eventCount != (e | INT_SIGN)) - break outer; - if (U.compareAndSwapLong(this, CTL, c, nc)) { - w.eventCount = (e + E_SEQ) & E_MASK; - if ((p = w.parker) != null) - U.unpark(p); - if (--n <= 0) - break; - } + private final int awaitWork(WorkQueue w, long c, int ec) { + int stat, ns; long parkTime, deadline; + if ((stat = w.qlock) >= 0 && w.eventCount == ec && ctl == c && + !Thread.interrupted()) { + int e = (int)c; + int u = (int)(c >>> 32); + int d = (u >> UAC_SHIFT) + parallelism; // active count + + if (e < 0 || (d <= 0 && tryTerminate(false, false))) + stat = w.qlock = -1; // pool is terminating + else if ((ns = w.nsteals) != 0) { // collect steals and retry + w.nsteals = 0; + U.getAndAddLong(this, STEALCOUNT, (long)ns); + } + else { + long pc = ((d > 0 || ec != (e | INT_SIGN)) ? 0L : + ((long)(w.nextWait & E_MASK)) | // ctl to restore + ((long)(u + UAC_UNIT)) << 32); + if (pc != 0L) { // timed wait if last waiter + int dc = -(short)(c >>> TC_SHIFT); + parkTime = (dc < 0 ? FAST_IDLE_TIMEOUT: + (dc + 1) * IDLE_TIMEOUT); + deadline = System.nanoTime() + parkTime - TIMEOUT_SLOP; } + else + parkTime = deadline = 0L; + if (w.eventCount == ec && ctl == c) { + Thread wt = Thread.currentThread(); + U.putObject(wt, PARKBLOCKER, this); + w.parker = wt; // emulate LockSupport.park + if (w.eventCount == ec && ctl == c) + U.park(false, parkTime); // must recheck before park + w.parker = null; + U.putObject(wt, PARKBLOCKER, null); + if (parkTime != 0L && ctl == c && + deadline - System.nanoTime() <= 0L && + U.compareAndSwapLong(this, CTL, c, pc)) + stat = w.qlock = -1; // shrink pool + } + } + } + return stat; + } + + /** + * Possibly releases (signals) a worker. Called only from scan() + * when a worker with apparently inactive status finds a non-empty + * queue. This requires revalidating all of the associated state + * from caller. + */ + private final void helpRelease(long c, WorkQueue[] ws, WorkQueue w, + WorkQueue q, int b) { + WorkQueue v; int e, i; Thread p; + if (w != null && w.eventCount < 0 && (e = (int)c) > 0 && + ws != null && ws.length > (i = e & SMASK) && + (v = ws[i]) != null && ctl == c) { + long nc = (((long)(v.nextWait & E_MASK)) | + ((long)((int)(c >>> 32) + UAC_UNIT)) << 32); + int ne = (e + E_SEQ) & E_MASK; + if (q != null && q.base == b && w.eventCount < 0 && + v.eventCount == (e | INT_SIGN) && + U.compareAndSwapLong(this, CTL, c, nc)) { + v.eventCount = ne; + if ((p = v.parker) != null) + U.unpark(p); } } } @@ -1855,7 +1791,8 @@ */ private int tryHelpStealer(WorkQueue joiner, ForkJoinTask task) { int stat = 0, steps = 0; // bound to avoid cycles - if (joiner != null && task != null) { // hoist null checks + if (task != null && joiner != null && + joiner.base - joiner.top >= 0) { // hoist checks restart: for (;;) { ForkJoinTask subtask = task; // current target for (WorkQueue j = joiner, v;;) { // v is stealer of subtask @@ -1882,7 +1819,7 @@ } } for (;;) { // help stealer or descend to its stealer - ForkJoinTask[] a; int b; + ForkJoinTask[] a; int b; if (subtask.status < 0) // surround probes with continue restart; // consistency checks if ((b = v.base) - v.top < 0 && (a = v.array) != null) { @@ -1893,13 +1830,23 @@ v.currentSteal != subtask) continue restart; // stale stat = 1; // apparent progress - if (t != null && v.base == b && - U.compareAndSwapObject(a, i, t, null)) { - v.base = b + 1; // help stealer - joiner.runSubtask(t); + if (v.base == b) { + if (t == null) + break restart; + if (U.compareAndSwapObject(a, i, t, null)) { + U.putOrderedInt(v, QBASE, b + 1); + ForkJoinTask ps = joiner.currentSteal; + int jt = joiner.top; + do { + joiner.currentSteal = t; + t.doExec(); // clear local tasks too + } while (task.status >= 0 && + joiner.top != jt && + (t = joiner.pop()) != null); + joiner.currentSteal = ps; + break restart; + } } - else if (v.base == b && ++steps == MAX_HELP) - break restart; // v apparently stalled } else { // empty -- try to descend ForkJoinTask next = v.currentJoin; @@ -1926,27 +1873,45 @@ * and run tasks within the target's computation. * * @param task the task to join - * @param mode if shared, exit upon completing any task - * if all workers are active + * @param maxTasks the maximum number of other tasks to run */ - private int helpComplete(ForkJoinTask task, int mode) { - WorkQueue[] ws; WorkQueue q; int m, n, s, u; - if (task != null && (ws = workQueues) != null && - (m = ws.length - 1) >= 0) { - for (int j = 1, origin = j;;) { + final int helpComplete(WorkQueue joiner, CountedCompleter task, + int maxTasks) { + WorkQueue[] ws; int m; + int s = 0; + if ((ws = workQueues) != null && (m = ws.length - 1) >= 0 && + joiner != null && task != null) { + int j = joiner.poolIndex; + int scans = m + m + 1; + long c = 0L; // for stability check + for (int k = scans; ; j += 2) { + WorkQueue q; if ((s = task.status) < 0) - return s; - if ((q = ws[j & m]) != null && q.pollAndExecCC(task)) { - origin = j; - if (mode == SHARED_QUEUE && - ((u = (int)(ctl >>> 32)) >= 0 || (u >> UAC_SHIFT) >= 0)) + break; + else if (joiner.internalPopAndExecCC(task)) { + if (--maxTasks <= 0) { + s = task.status; break; + } + k = scans; } - else if ((j = (j + 2) & m) == origin) + else if ((s = task.status) < 0) break; + else if ((q = ws[j & m]) != null && q.pollAndExecCC(task)) { + if (--maxTasks <= 0) { + s = task.status; + break; + } + k = scans; + } + else if (--k < 0) { + if (c == (c = ctl)) + break; + k = scans; + } } } - return 0; + return s; } /** @@ -1955,17 +1920,22 @@ * for blocking. Fails on contention or termination. Otherwise, * adds a new thread if no idle workers are available and pool * may become starved. + * + * @param c the assumed ctl value */ - final boolean tryCompensate() { - int pc = config & SMASK, e, i, tc; long c; - WorkQueue[] ws; WorkQueue w; Thread p; - if ((ws = workQueues) != null && (e = (int)(c = ctl)) >= 0) { - if (e != 0 && (i = e & SMASK) < ws.length && - (w = ws[i]) != null && w.eventCount == (e | INT_SIGN)) { + final boolean tryCompensate(long c) { + WorkQueue[] ws = workQueues; + int pc = parallelism, e = (int)c, m, tc; + if (ws != null && (m = ws.length - 1) >= 0 && e >= 0 && ctl == c) { + WorkQueue w = ws[e & m]; + if (e != 0 && w != null) { + Thread p; long nc = ((long)(w.nextWait & E_MASK) | (c & (AC_MASK|TC_MASK))); - if (U.compareAndSwapLong(this, CTL, c, nc)) { - w.eventCount = (e + E_SEQ) & E_MASK; + int ne = (e + E_SEQ) & E_MASK; + if (w.eventCount == (e | INT_SIGN) && + U.compareAndSwapLong(this, CTL, c, nc)) { + w.eventCount = ne; if ((p = w.parker) != null) U.unpark(p); return true; // replace with idle worker @@ -2008,23 +1978,20 @@ */ final int awaitJoin(WorkQueue joiner, ForkJoinTask task) { int s = 0; - if (joiner != null && task != null && (s = task.status) >= 0) { + if (task != null && (s = task.status) >= 0 && joiner != null) { ForkJoinTask prevJoin = joiner.currentJoin; joiner.currentJoin = task; - do {} while ((s = task.status) >= 0 && !joiner.isEmpty() && - joiner.tryRemoveAndExec(task)); // process local tasks - if (s >= 0 && (s = task.status) >= 0) { - helpSignal(task, joiner.poolIndex); - if ((s = task.status) >= 0 && - (task instanceof CountedCompleter)) - s = helpComplete(task, LIFO_QUEUE); - } + do {} while (joiner.tryRemoveAndExec(task) && // process local tasks + (s = task.status) >= 0); + if (s >= 0 && (task instanceof CountedCompleter)) + s = helpComplete(joiner, (CountedCompleter)task, Integer.MAX_VALUE); + long cc = 0; // for stability checks while (s >= 0 && (s = task.status) >= 0) { - if ((!joiner.isEmpty() || // try helping - (s = tryHelpStealer(joiner, task)) == 0) && + if ((s = tryHelpStealer(joiner, task)) == 0 && (s = task.status) >= 0) { - helpSignal(task, joiner.poolIndex); - if ((s = task.status) >= 0 && tryCompensate()) { + if (!tryCompensate(cc)) + cc = ctl; + else { if (task.trySetSignal() && (s = task.status) >= 0) { synchronized (task) { if (task.status >= 0) { @@ -2037,9 +2004,11 @@ task.notifyAll(); } } - long c; // re-activate + long c; // reactivate do {} while (!U.compareAndSwapLong - (this, CTL, c = ctl, c + AC_UNIT)); + (this, CTL, c = ctl, + ((c & ~AC_MASK) | + ((c & AC_MASK) + AC_UNIT)))); } } } @@ -2061,15 +2030,11 @@ if (joiner != null && task != null && (s = task.status) >= 0) { ForkJoinTask prevJoin = joiner.currentJoin; joiner.currentJoin = task; - do {} while ((s = task.status) >= 0 && !joiner.isEmpty() && - joiner.tryRemoveAndExec(task)); - if (s >= 0 && (s = task.status) >= 0) { - helpSignal(task, joiner.poolIndex); - if ((s = task.status) >= 0 && - (task instanceof CountedCompleter)) - s = helpComplete(task, LIFO_QUEUE); - } - if (s >= 0 && joiner.isEmpty()) { + do {} while (joiner.tryRemoveAndExec(task) && // process local tasks + (s = task.status) >= 0); + if (s >= 0) { + if (task instanceof CountedCompleter) + helpComplete(joiner, (CountedCompleter)task, Integer.MAX_VALUE); do {} while (task.status >= 0 && tryHelpStealer(joiner, task) > 0); } @@ -2081,14 +2046,14 @@ * Returns a (probably) non-empty steal queue, if one is found * during a scan, else null. This method must be retried by * caller if, by the time it tries to use the queue, it is empty. - * @param r a (random) seed for scanning */ - private WorkQueue findNonEmptyStealQueue(int r) { + private WorkQueue findNonEmptyStealQueue() { + int r = ThreadLocalRandom.nextSecondarySeed(); for (;;) { int ps = plock, m; WorkQueue[] ws; WorkQueue q; if ((ws = workQueues) != null && (m = ws.length - 1) >= 0) { for (int j = (m + 1) << 2; j >= 0; --j) { - if ((q = ws[(((r + j) << 1) | 1) & m]) != null && + if ((q = ws[(((r - j) << 1) | 1) & m]) != null && q.base - q.top < 0) return q; } @@ -2105,35 +2070,36 @@ * find tasks either. */ final void helpQuiescePool(WorkQueue w) { + ForkJoinTask ps = w.currentSteal; for (boolean active = true;;) { long c; WorkQueue q; ForkJoinTask t; int b; - while ((t = w.nextLocalTask()) != null) { - if (w.base - w.top < 0) - signalWork(w); + while ((t = w.nextLocalTask()) != null) t.doExec(); - } - if ((q = findNonEmptyStealQueue(w.nextSeed())) != null) { + if ((q = findNonEmptyStealQueue()) != null) { if (!active) { // re-establish active count active = true; do {} while (!U.compareAndSwapLong - (this, CTL, c = ctl, c + AC_UNIT)); + (this, CTL, c = ctl, + ((c & ~AC_MASK) | + ((c & AC_MASK) + AC_UNIT)))); } if ((b = q.base) - q.top < 0 && (t = q.pollAt(b)) != null) { - if (q.base - q.top < 0) - signalWork(q); - w.runSubtask(t); + (w.currentSteal = t).doExec(); + w.currentSteal = ps; } } else if (active) { // decrement active count without queuing - long nc = (c = ctl) - AC_UNIT; - if ((int)(nc >> AC_SHIFT) + (config & SMASK) == 0) - return; // bypass decrement-then-increment + long nc = ((c = ctl) & ~AC_MASK) | ((c & AC_MASK) - AC_UNIT); + if ((int)(nc >> AC_SHIFT) + parallelism == 0) + break; // bypass decrement-then-increment if (U.compareAndSwapLong(this, CTL, c, nc)) active = false; } - else if ((int)((c = ctl) >> AC_SHIFT) + (config & SMASK) == 0 && - U.compareAndSwapLong(this, CTL, c, c + AC_UNIT)) - return; + else if ((int)((c = ctl) >> AC_SHIFT) + parallelism <= 0 && + U.compareAndSwapLong + (this, CTL, c, ((c & ~AC_MASK) | + ((c & AC_MASK) + AC_UNIT)))) + break; } } @@ -2147,13 +2113,10 @@ WorkQueue q; int b; if ((t = w.nextLocalTask()) != null) return t; - if ((q = findNonEmptyStealQueue(w.nextSeed())) == null) + if ((q = findNonEmptyStealQueue()) == null) return null; - if ((b = q.base) - q.top < 0 && (t = q.pollAt(b)) != null) { - if (q.base - q.top < 0) - signalWork(q); + if ((b = q.base) - q.top < 0 && (t = q.pollAt(b)) != null) return t; - } } } @@ -2206,7 +2169,7 @@ static int getSurplusQueuedTaskCount() { Thread t; ForkJoinWorkerThread wt; ForkJoinPool pool; WorkQueue q; if (((t = Thread.currentThread()) instanceof ForkJoinWorkerThread)) { - int p = (pool = (wt = (ForkJoinWorkerThread)t).pool).config & SMASK; + int p = (pool = (wt = (ForkJoinWorkerThread)t).pool).parallelism; int n = (q = wt.workQueue).top - q.base; int a = (int)(pool.ctl >> AC_SHIFT) + p; return n - (a > (p >>>= 1) ? 0 : @@ -2236,7 +2199,7 @@ */ private boolean tryTerminate(boolean now, boolean enable) { int ps; - if (this == common) // cannot shut down + if (this == common) // cannot shut down return false; if ((ps = plock) >= 0) { // enable by setting plock if (!enable) @@ -2250,7 +2213,7 @@ } for (long c;;) { if (((c = ctl) & STOP_BIT) != 0) { // already terminating - if ((short)(c >>> TC_SHIFT) == -(config & SMASK)) { + if ((short)(c >>> TC_SHIFT) + parallelism <= 0) { synchronized (this) { notifyAll(); // signal when 0 workers } @@ -2259,17 +2222,15 @@ } if (!now) { // check if idle & no tasks WorkQueue[] ws; WorkQueue w; - if ((int)(c >> AC_SHIFT) != -(config & SMASK)) + if ((int)(c >> AC_SHIFT) + parallelism > 0) return false; if ((ws = workQueues) != null) { for (int i = 0; i < ws.length; ++i) { - if ((w = ws[i]) != null) { - if (!w.isEmpty()) { // signal unprocessed tasks - signalWork(w); - return false; - } - if ((i & 1) != 0 && w.eventCount >= 0) - return false; // unqueued inactive worker + if ((w = ws[i]) != null && + (!w.isEmpty() || + ((i & 1) != 0 && w.eventCount >= 0))) { + signalWork(ws, w); + return false; } } } @@ -2336,116 +2297,67 @@ /** * Tries to pop the given task from submitter's queue in common pool. */ - static boolean tryExternalUnpush(ForkJoinTask t) { - ForkJoinPool p; WorkQueue[] ws; WorkQueue q; - ForkJoinTask[] a; int m, s, z; - if (t != null && - (z = ThreadLocalRandom.getProbe()) != 0 && - (p = common) != null && - (ws = p.workQueues) != null && - (m = ws.length - 1) >= 0 && - (q = ws[m & z & SQMASK]) != null && - (s = q.top) != q.base && - (a = q.array) != null) { + final boolean tryExternalUnpush(ForkJoinTask task) { + WorkQueue joiner; ForkJoinTask[] a; int m, s; + WorkQueue[] ws = workQueues; + int z = ThreadLocalRandom.getProbe(); + boolean popped = false; + if (ws != null && (m = ws.length - 1) >= 0 && + (joiner = ws[z & m & SQMASK]) != null && + joiner.base != (s = joiner.top) && + (a = joiner.array) != null) { long j = (((a.length - 1) & (s - 1)) << ASHIFT) + ABASE; - if (U.getObject(a, j) == t && - U.compareAndSwapInt(q, QLOCK, 0, 1)) { - if (q.array == a && q.top == s && // recheck - U.compareAndSwapObject(a, j, t, null)) { - q.top = s - 1; - q.qlock = 0; - return true; + if (U.getObject(a, j) == task && + U.compareAndSwapInt(joiner, QLOCK, 0, 1)) { + if (joiner.top == s && joiner.array == a && + U.compareAndSwapObject(a, j, task, null)) { + joiner.top = s - 1; + popped = true; } - q.qlock = 0; + joiner.qlock = 0; } } - return false; + return popped; } - /** - * Tries to pop and run local tasks within the same computation - * as the given root. On failure, tries to help complete from - * other queues via helpComplete. - */ - private void externalHelpComplete(WorkQueue q, ForkJoinTask root) { - ForkJoinTask[] a; int m; - if (q != null && (a = q.array) != null && (m = (a.length - 1)) >= 0 && - root != null && root.status >= 0) { - for (;;) { - int s, u; Object o; CountedCompleter task = null; - if ((s = q.top) - q.base > 0) { - long j = ((m & (s - 1)) << ASHIFT) + ABASE; - if ((o = U.getObject(a, j)) != null && - (o instanceof CountedCompleter)) { - CountedCompleter t = (CountedCompleter)o, r = t; - do { - if (r == root) { - if (U.compareAndSwapInt(q, QLOCK, 0, 1)) { - if (q.array == a && q.top == s && - U.compareAndSwapObject(a, j, t, null)) { - q.top = s - 1; - task = t; - } - q.qlock = 0; - } - break; - } - } while ((r = r.completer) != null); + final int externalHelpComplete(CountedCompleter task, int maxTasks) { + WorkQueue joiner; int m; + WorkQueue[] ws = workQueues; + int j = ThreadLocalRandom.getProbe(); + int s = 0; + if (ws != null && (m = ws.length - 1) >= 0 && + (joiner = ws[j & m & SQMASK]) != null && task != null) { + int scans = m + m + 1; + long c = 0L; // for stability check + j |= 1; // poll odd queues + for (int k = scans; ; j += 2) { + WorkQueue q; + if ((s = task.status) < 0) + break; + else if (joiner.externalPopAndExecCC(task)) { + if (--maxTasks <= 0) { + s = task.status; + break; } + k = scans; } - if (task != null) - task.doExec(); - if (root.status < 0 || - (config != 0 && - ((u = (int)(ctl >>> 32)) >= 0 || (u >> UAC_SHIFT) >= 0))) + else if ((s = task.status) < 0) break; - if (task == null) { - helpSignal(root, q.poolIndex); - if (root.status >= 0) - helpComplete(root, SHARED_QUEUE); - break; + else if ((q = ws[j & m]) != null && q.pollAndExecCC(task)) { + if (--maxTasks <= 0) { + s = task.status; + break; + } + k = scans; + } + else if (--k < 0) { + if (c == (c = ctl)) + break; + k = scans; } } } - } - - /** - * Tries to help execute or signal availability of the given task - * from submitter's queue in common pool. - */ - static void externalHelpJoin(ForkJoinTask t) { - // Some hard-to-avoid overlap with tryExternalUnpush - ForkJoinPool p; WorkQueue[] ws; WorkQueue q, w; - ForkJoinTask[] a; int m, s, n, z; - if (t != null && - (z = ThreadLocalRandom.getProbe()) != 0 && - (p = common) != null && - (ws = p.workQueues) != null && - (m = ws.length - 1) >= 0 && - (q = ws[m & z & SQMASK]) != null && - (a = q.array) != null) { - int am = a.length - 1; - if ((s = q.top) != q.base) { - long j = ((am & (s - 1)) << ASHIFT) + ABASE; - if (U.getObject(a, j) == t && - U.compareAndSwapInt(q, QLOCK, 0, 1)) { - if (q.array == a && q.top == s && - U.compareAndSwapObject(a, j, t, null)) { - q.top = s - 1; - q.qlock = 0; - t.doExec(); - } - else - q.qlock = 0; - } - } - if (t.status >= 0) { - if (t instanceof CountedCompleter) - p.externalHelpComplete(q, t); - else - p.helpSignal(t, q.poolIndex); - } - } + return s; } // Exported methods @@ -2517,7 +2429,7 @@ this(checkParallelism(parallelism), checkFactory(factory), handler, - asyncMode, + (asyncMode ? FIFO_QUEUE : LIFO_QUEUE), "ForkJoinPool-" + nextPoolId() + "-worker-"); checkPermission(); } @@ -2543,12 +2455,13 @@ private ForkJoinPool(int parallelism, ForkJoinWorkerThreadFactory factory, UncaughtExceptionHandler handler, - boolean asyncMode, + int mode, String workerNamePrefix) { this.workerNamePrefix = workerNamePrefix; this.factory = factory; this.ueh = handler; - this.config = parallelism | (asyncMode ? (FIFO_QUEUE << 16) : 0); + this.mode = (short)mode; + this.parallelism = (short)parallelism; long np = (long)(-parallelism); // offset ctl counts this.ctl = ((np << AC_SHIFT) & AC_MASK) | ((np << TC_SHIFT) & TC_MASK); } @@ -2736,8 +2649,8 @@ * @return the targeted parallelism level of this pool */ public int getParallelism() { - int par = (config & SMASK); - return (par > 0) ? par : 1; + int par; + return ((par = parallelism) > 0) ? par : 1; } /** @@ -2759,7 +2672,7 @@ * @return the number of worker threads */ public int getPoolSize() { - return (config & SMASK) + (short)(ctl >>> TC_SHIFT); + return parallelism + (short)(ctl >>> TC_SHIFT); } /** @@ -2769,7 +2682,7 @@ * @return {@code true} if this pool uses async mode */ public boolean getAsyncMode() { - return (config >>> 16) == FIFO_QUEUE; + return mode == FIFO_QUEUE; } /** @@ -2800,7 +2713,7 @@ * @return the number of active threads */ public int getActiveThreadCount() { - int r = (config & SMASK) + (int)(ctl >> AC_SHIFT); + int r = parallelism + (int)(ctl >> AC_SHIFT); return (r <= 0) ? 0 : r; // suppress momentarily negative values } @@ -2816,7 +2729,7 @@ * @return {@code true} if all threads are currently idle */ public boolean isQuiescent() { - return (int)(ctl >> AC_SHIFT) + (config & SMASK) == 0; + return parallelism + (int)(ctl >> AC_SHIFT) <= 0; } /** @@ -2979,7 +2892,7 @@ } } } - int pc = (config & SMASK); + int pc = parallelism; int tc = pc + (short)(c >>> TC_SHIFT); int ac = pc + (int)(c >> AC_SHIFT); if (ac < 0) // ignore transient negative @@ -3052,7 +2965,7 @@ public boolean isTerminated() { long c = ctl; return ((c & STOP_BIT) != 0L && - (short)(c >>> TC_SHIFT) == -(config & SMASK)); + (short)(c >>> TC_SHIFT) + parallelism <= 0); } /** @@ -3071,7 +2984,7 @@ public boolean isTerminating() { long c = ctl; return ((c & STOP_BIT) != 0L && - (short)(c >>> TC_SHIFT) != -(config & SMASK)); + (short)(c >>> TC_SHIFT) + parallelism > 0); } /** @@ -3108,19 +3021,20 @@ long nanos = unit.toNanos(timeout); if (isTerminated()) return true; - long startTime = System.nanoTime(); - boolean terminated = false; + if (nanos <= 0L) + return false; + long deadline = System.nanoTime() + nanos; synchronized (this) { - for (long waitTime = nanos, millis = 0L;;) { - if (terminated = isTerminated() || - waitTime <= 0L || - (millis = unit.toMillis(waitTime)) <= 0L) - break; - wait(millis); - waitTime = nanos - (System.nanoTime() - startTime); + for (;;) { + if (isTerminated()) + return true; + if (nanos <= 0L) + return false; + long millis = TimeUnit.NANOSECONDS.toMillis(nanos); + wait(millis > 0L ? millis : 1L); + nanos = deadline - System.nanoTime(); } } - return terminated; } /** @@ -3159,11 +3073,8 @@ ForkJoinTask t; WorkQueue q; int b; if ((q = ws[r++ & m]) != null && (b = q.base) - q.top < 0) { found = true; - if ((t = q.pollAt(b)) != null) { - if (q.base - q.top < 0) - signalWork(q); + if ((t = q.pollAt(b)) != null) t.doExec(); - } break; } } @@ -3278,21 +3189,8 @@ Thread t = Thread.currentThread(); if (t instanceof ForkJoinWorkerThread) { ForkJoinPool p = ((ForkJoinWorkerThread)t).pool; - while (!blocker.isReleasable()) { // variant of helpSignal - WorkQueue[] ws; WorkQueue q; int m, u; - if ((ws = p.workQueues) != null && (m = ws.length - 1) >= 0) { - for (int i = 0; i <= m; ++i) { - if (blocker.isReleasable()) - return; - if ((q = ws[i]) != null && q.base - q.top < 0) { - p.signalWork(q); - if ((u = (int)(p.ctl >>> 32)) >= 0 || - (u >> UAC_SHIFT) >= 0) - break; - } - } - } - if (p.tryCompensate()) { + while (!blocker.isReleasable()) { + if (p.tryCompensate(p.ctl)) { try { do {} while (!blocker.isReleasable() && !blocker.block()); @@ -3330,6 +3228,7 @@ private static final long STEALCOUNT; private static final long PLOCK; private static final long INDEXSEED; + private static final long QBASE; private static final long QLOCK; static { @@ -3349,6 +3248,8 @@ PARKBLOCKER = U.objectFieldOffset (tk.getDeclaredField("parkBlocker")); Class wk = WorkQueue.class; + QBASE = U.objectFieldOffset + (wk.getDeclaredField("base")); QLOCK = U.objectFieldOffset (wk.getDeclaredField("qlock")); Class ak = ForkJoinTask[].class; @@ -3368,7 +3269,7 @@ common = java.security.AccessController.doPrivileged (new java.security.PrivilegedAction() { public ForkJoinPool run() { return makeCommonPool(); }}); - int par = common.config; // report 1 even if threads disabled + int par = common.parallelism; // report 1 even if threads disabled commonParallelism = par > 0 ? par : 1; } @@ -3381,7 +3282,7 @@ ForkJoinWorkerThreadFactory factory = defaultForkJoinWorkerThreadFactory; UncaughtExceptionHandler handler = null; - try { // ignore exceptions in accesing/parsing properties + try { // ignore exceptions in accessing/parsing properties String pp = System.getProperty ("java.util.concurrent.ForkJoinPool.common.parallelism"); String fp = System.getProperty @@ -3399,11 +3300,12 @@ } catch (Exception ignore) { } - if (parallelism < 0) - parallelism = Runtime.getRuntime().availableProcessors(); + if (parallelism < 0 && // default 1 less than #cores + (parallelism = Runtime.getRuntime().availableProcessors() - 1) < 0) + parallelism = 0; if (parallelism > MAX_CAP) parallelism = MAX_CAP; - return new ForkJoinPool(parallelism, factory, handler, false, + return new ForkJoinPool(parallelism, factory, handler, LIFO_QUEUE, "ForkJoinPool.commonPool-worker-"); } diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/util/concurrent/ForkJoinTask.java --- a/jdk/src/share/classes/java/util/concurrent/ForkJoinTask.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/util/concurrent/ForkJoinTask.java Tue Jul 09 15:26:20 2013 -0700 @@ -165,7 +165,7 @@ * supports other methods and techniques (for example the use of * {@link Phaser}, {@link #helpQuiesce}, and {@link #complete}) that * may be of use in constructing custom subclasses for problems that - * are not statically structured as DAGs. To support such usages a + * are not statically structured as DAGs. To support such usages, a * ForkJoinTask may be atomically tagged with a {@code short} * value using {@link #setForkJoinTaskTag} or {@link * #compareAndSetForkJoinTaskTag} and checked using {@link @@ -314,25 +314,35 @@ */ private int externalAwaitDone() { int s; - ForkJoinPool.externalHelpJoin(this); - boolean interrupted = false; - while ((s = status) >= 0) { - if (U.compareAndSwapInt(this, STATUS, s, s | SIGNAL)) { - synchronized (this) { - if (status >= 0) { - try { - wait(); - } catch (InterruptedException ie) { - interrupted = true; + ForkJoinPool cp = ForkJoinPool.common; + if ((s = status) >= 0) { + if (cp != null) { + if (this instanceof CountedCompleter) + s = cp.externalHelpComplete((CountedCompleter)this, Integer.MAX_VALUE); + else if (cp.tryExternalUnpush(this)) + s = doExec(); + } + if (s >= 0 && (s = status) >= 0) { + boolean interrupted = false; + do { + if (U.compareAndSwapInt(this, STATUS, s, s | SIGNAL)) { + synchronized (this) { + if (status >= 0) { + try { + wait(); + } catch (InterruptedException ie) { + interrupted = true; + } + } + else + notifyAll(); } } - else - notifyAll(); - } + } while ((s = status) >= 0); + if (interrupted) + Thread.currentThread().interrupt(); } } - if (interrupted) - Thread.currentThread().interrupt(); return s; } @@ -341,9 +351,15 @@ */ private int externalInterruptibleAwaitDone() throws InterruptedException { int s; + ForkJoinPool cp = ForkJoinPool.common; if (Thread.interrupted()) throw new InterruptedException(); - ForkJoinPool.externalHelpJoin(this); + if ((s = status) >= 0 && cp != null) { + if (this instanceof CountedCompleter) + cp.externalHelpComplete((CountedCompleter)this, Integer.MAX_VALUE); + else if (cp.tryExternalUnpush(this)) + doExec(); + } while ((s = status) >= 0) { if (U.compareAndSwapInt(this, STATUS, s, s | SIGNAL)) { synchronized (this) { @@ -357,7 +373,6 @@ return s; } - /** * Implementation for join, get, quietlyJoin. Directly handles * only cases of already-completed, external wait, and @@ -629,14 +644,9 @@ /** * A version of "sneaky throw" to relay exceptions */ - static void rethrow(final Throwable ex) { - if (ex != null) { - if (ex instanceof Error) - throw (Error)ex; - if (ex instanceof RuntimeException) - throw (RuntimeException)ex; + static void rethrow(Throwable ex) { + if (ex != null) ForkJoinTask.uncheckedThrow(ex); - } } /** @@ -646,8 +656,7 @@ */ @SuppressWarnings("unchecked") static void uncheckedThrow(Throwable t) throws T { - if (t != null) - throw (T)t; // rely on vacuous cast + throw (T)t; // rely on vacuous cast } /** @@ -1010,6 +1019,7 @@ // Messy in part because we measure in nanosecs, but wait in millisecs int s; long ms; long ns = unit.toNanos(timeout); + ForkJoinPool cp; if ((s = status) >= 0 && ns > 0L) { long deadline = System.nanoTime() + ns; ForkJoinPool p = null; @@ -1021,8 +1031,12 @@ w = wt.workQueue; p.helpJoinOnce(w, this); // no retries on failure } - else - ForkJoinPool.externalHelpJoin(this); + else if ((cp = ForkJoinPool.common) != null) { + if (this instanceof CountedCompleter) + cp.externalHelpComplete((CountedCompleter)this, Integer.MAX_VALUE); + else if (cp.tryExternalUnpush(this)) + doExec(); + } boolean canBlock = false; boolean interrupted = false; try { @@ -1030,7 +1044,7 @@ if (w != null && w.qlock < 0) cancelIgnoringExceptions(this); else if (!canBlock) { - if (p == null || p.tryCompensate()) + if (p == null || p.tryCompensate(p.ctl)) canBlock = true; } else { @@ -1171,7 +1185,7 @@ Thread t; return (((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) ? ((ForkJoinWorkerThread)t).workQueue.tryUnpush(this) : - ForkJoinPool.tryExternalUnpush(this)); + ForkJoinPool.common.tryExternalUnpush(this)); } /** @@ -1340,7 +1354,7 @@ * * @param e the expected tag value * @param tag the new tag value - * @return true if successful; i.e., the current value was + * @return {@code true} if successful; i.e., the current value was * equal to e and is now tag. * @since 1.8 */ diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java --- a/jdk/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java Tue Jul 09 15:26:20 2013 -0700 @@ -43,8 +43,8 @@ * scheduling or execution. However, you can override initialization * and termination methods surrounding the main task processing loop. * If you do create such a subclass, you will also need to supply a - * custom {@link ForkJoinPool.ForkJoinWorkerThreadFactory} to use it - * in a {@code ForkJoinPool}. + * custom {@link ForkJoinPool.ForkJoinWorkerThreadFactory} to + * {@linkplain ForkJoinPool#ForkJoinPool use it} in a {@code ForkJoinPool}. * * @since 1.7 * @author Doug Lea @@ -89,16 +89,17 @@ } /** - * Returns the index number of this thread in its pool. The - * returned value ranges from zero to the maximum number of - * threads (minus one) that have ever been created in the pool. - * This method may be useful for applications that track status or - * collect results per-worker rather than per-task. + * Returns the unique index number of this thread in its pool. + * The returned value ranges from zero to the maximum number of + * threads (minus one) that may exist in the pool, and does not + * change during the lifetime of the thread. This method may be + * useful for applications that track status or collect results + * per-worker-thread rather than per-task. * * @return the index number */ public int getPoolIndex() { - return workQueue.poolIndex; + return workQueue.poolIndex >>> 1; // ignore odd/even tag bit } /** diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/util/concurrent/Future.java --- a/jdk/src/share/classes/java/util/concurrent/Future.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/util/concurrent/Future.java Tue Jul 09 15:26:20 2013 -0700 @@ -36,19 +36,19 @@ package java.util.concurrent; /** - * A Future represents the result of an asynchronous + * A {@code Future} represents the result of an asynchronous * computation. Methods are provided to check if the computation is * complete, to wait for its completion, and to retrieve the result of * the computation. The result can only be retrieved using method - * get when the computation has completed, blocking if + * {@code get} when the computation has completed, blocking if * necessary until it is ready. Cancellation is performed by the - * cancel method. Additional methods are provided to + * {@code cancel} method. Additional methods are provided to * determine if the task completed normally or was cancelled. Once a * computation has completed, the computation cannot be cancelled. - * If you would like to use a Future for the sake + * If you would like to use a {@code Future} for the sake * of cancellability but not provide a usable result, you can * declare types of the form {@code Future} and - * return null as a result of the underlying task. + * return {@code null} as a result of the underlying task. * *

    * Sample Usage (Note that the following classes are all @@ -72,9 +72,9 @@ * } * }}

  • * - * The {@link FutureTask} class is an implementation of Future that - * implements Runnable, and so may be executed by an Executor. - * For example, the above construction with submit could be replaced by: + * The {@link FutureTask} class is an implementation of {@code Future} that + * implements {@code Runnable}, and so may be executed by an {@code Executor}. + * For example, the above construction with {@code submit} could be replaced by: *
     {@code
      * FutureTask future =
      *   new FutureTask(new Callable() {
    @@ -91,7 +91,7 @@
      * @see Executor
      * @since 1.5
      * @author Doug Lea
    - * @param  The result type returned by this Future's get method
    + * @param  The result type returned by this Future's {@code get} method
      */
     public interface Future {
     
    @@ -99,41 +99,41 @@
          * Attempts to cancel execution of this task.  This attempt will
          * fail if the task has already completed, has already been cancelled,
          * or could not be cancelled for some other reason. If successful,
    -     * and this task has not started when cancel is called,
    +     * and this task has not started when {@code cancel} is called,
          * this task should never run.  If the task has already started,
    -     * then the mayInterruptIfRunning parameter determines
    +     * then the {@code mayInterruptIfRunning} parameter determines
          * whether the thread executing this task should be interrupted in
          * an attempt to stop the task.
          *
          * 

    After this method returns, subsequent calls to {@link #isDone} will - * always return true. Subsequent calls to {@link #isCancelled} - * will always return true if this method returned true. + * always return {@code true}. Subsequent calls to {@link #isCancelled} + * will always return {@code true} if this method returned {@code true}. * - * @param mayInterruptIfRunning true if the thread executing this + * @param mayInterruptIfRunning {@code true} if the thread executing this * task should be interrupted; otherwise, in-progress tasks are allowed * to complete - * @return false if the task could not be cancelled, + * @return {@code false} if the task could not be cancelled, * typically because it has already completed normally; - * true otherwise + * {@code true} otherwise */ boolean cancel(boolean mayInterruptIfRunning); /** - * Returns true if this task was cancelled before it completed + * Returns {@code true} if this task was cancelled before it completed * normally. * - * @return true if this task was cancelled before it completed + * @return {@code true} if this task was cancelled before it completed */ boolean isCancelled(); /** - * Returns true if this task completed. + * Returns {@code true} if this task completed. * * Completion may be due to normal termination, an exception, or * cancellation -- in all of these cases, this method will return - * true. + * {@code true}. * - * @return true if this task completed + * @return {@code true} if this task completed */ boolean isDone(); diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/util/concurrent/FutureTask.java --- a/jdk/src/share/classes/java/util/concurrent/FutureTask.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/util/concurrent/FutureTask.java Tue Jul 09 15:26:20 2013 -0700 @@ -162,19 +162,23 @@ } public boolean cancel(boolean mayInterruptIfRunning) { - if (state != NEW) + if (!(state == NEW && + UNSAFE.compareAndSwapInt(this, stateOffset, NEW, + mayInterruptIfRunning ? INTERRUPTING : CANCELLED))) return false; - if (mayInterruptIfRunning) { - if (!UNSAFE.compareAndSwapInt(this, stateOffset, NEW, INTERRUPTING)) - return false; - Thread t = runner; - if (t != null) - t.interrupt(); - UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED); // final state + try { // in case call to interrupt throws exception + if (mayInterruptIfRunning) { + try { + Thread t = runner; + if (t != null) + t.interrupt(); + } finally { // final state + UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED); + } + } + } finally { + finishCompletion(); } - else if (!UNSAFE.compareAndSwapInt(this, stateOffset, NEW, CANCELLED)) - return false; - finishCompletion(); return true; } @@ -288,7 +292,7 @@ * designed for use with tasks that intrinsically execute more * than once. * - * @return true if successfully run and reset + * @return {@code true} if successfully run and reset */ protected boolean runAndReset() { if (state != NEW || diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/util/concurrent/RecursiveAction.java --- a/jdk/src/share/classes/java/util/concurrent/RecursiveAction.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/util/concurrent/RecursiveAction.java Tue Jul 09 15:26:20 2013 -0700 @@ -63,7 +63,7 @@ * } * } * // implementation details follow: - * final static int THRESHOLD = 1000; + * static final int THRESHOLD = 1000; * void sortSequentially(int lo, int hi) { * Arrays.sort(array, lo, hi); * } @@ -140,21 +140,21 @@ * int h = hi; * Applyer right = null; * while (h - l > 1 && getSurplusQueuedTaskCount() <= 3) { - * int mid = (l + h) >>> 1; - * right = new Applyer(array, mid, h, right); - * right.fork(); - * h = mid; + * int mid = (l + h) >>> 1; + * right = new Applyer(array, mid, h, right); + * right.fork(); + * h = mid; * } * double sum = atLeaf(l, h); * while (right != null) { - * if (right.tryUnfork()) // directly calculate if not stolen - * sum += right.atLeaf(right.lo, right.hi); + * if (right.tryUnfork()) // directly calculate if not stolen + * sum += right.atLeaf(right.lo, right.hi); * else { - * right.join(); - * sum += right.result; - * } - * right = right.next; - * } + * right.join(); + * sum += right.result; + * } + * right = right.next; + * } * result = sum; * } * }}

    diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/util/concurrent/RecursiveTask.java --- a/jdk/src/share/classes/java/util/concurrent/RecursiveTask.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/util/concurrent/RecursiveTask.java Tue Jul 09 15:26:20 2013 -0700 @@ -46,7 +46,7 @@ * Fibonacci(int n) { this.n = n; } * Integer compute() { * if (n <= 1) - * return n; + * return n; * Fibonacci f1 = new Fibonacci(n - 1); * f1.fork(); * Fibonacci f2 = new Fibonacci(n - 2); @@ -75,6 +75,7 @@ /** * The main computation performed by this task. + * @return the result of the computation */ protected abstract V compute(); diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/util/concurrent/RejectedExecutionException.java --- a/jdk/src/share/classes/java/util/concurrent/RejectedExecutionException.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/util/concurrent/RejectedExecutionException.java Tue Jul 09 15:26:20 2013 -0700 @@ -46,14 +46,14 @@ private static final long serialVersionUID = -375805702767069545L; /** - * Constructs a RejectedExecutionException with no detail message. + * Constructs a {@code RejectedExecutionException} with no detail message. * The cause is not initialized, and may subsequently be * initialized by a call to {@link #initCause(Throwable) initCause}. */ public RejectedExecutionException() { } /** - * Constructs a RejectedExecutionException with the + * Constructs a {@code RejectedExecutionException} with the * specified detail message. The cause is not initialized, and may * subsequently be initialized by a call to {@link * #initCause(Throwable) initCause}. @@ -65,7 +65,7 @@ } /** - * Constructs a RejectedExecutionException with the + * Constructs a {@code RejectedExecutionException} with the * specified detail message and cause. * * @param message the detail message @@ -77,10 +77,10 @@ } /** - * Constructs a RejectedExecutionException with the + * Constructs a {@code RejectedExecutionException} with the * specified cause. The detail message is set to {@code (cause == * null ? null : cause.toString())} (which typically contains - * the class and detail message of cause). + * the class and detail message of {@code cause}). * * @param cause the cause (which is saved for later retrieval by the * {@link #getCause()} method) diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/util/concurrent/RunnableFuture.java --- a/jdk/src/share/classes/java/util/concurrent/RunnableFuture.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/util/concurrent/RunnableFuture.java Tue Jul 09 15:26:20 2013 -0700 @@ -37,13 +37,13 @@ /** * A {@link Future} that is {@link Runnable}. Successful execution of - * the run method causes completion of the Future + * the {@code run} method causes completion of the {@code Future} * and allows access to its results. * @see FutureTask * @see Executor * @since 1.6 * @author Doug Lea - * @param The result type returned by this Future's get method + * @param The result type returned by this Future's {@code get} method */ public interface RunnableFuture extends Runnable, Future { /** diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/util/concurrent/RunnableScheduledFuture.java --- a/jdk/src/share/classes/java/util/concurrent/RunnableScheduledFuture.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/util/concurrent/RunnableScheduledFuture.java Tue Jul 09 15:26:20 2013 -0700 @@ -37,22 +37,22 @@ /** * A {@link ScheduledFuture} that is {@link Runnable}. Successful - * execution of the run method causes completion of the - * Future and allows access to its results. + * execution of the {@code run} method causes completion of the + * {@code Future} and allows access to its results. * @see FutureTask * @see Executor * @since 1.6 * @author Doug Lea - * @param The result type returned by this Future's get method + * @param The result type returned by this Future's {@code get} method */ public interface RunnableScheduledFuture extends RunnableFuture, ScheduledFuture { /** - * Returns true if this is a periodic task. A periodic task may + * Returns {@code true} if this task is periodic. A periodic task may * re-run according to some schedule. A non-periodic task can be * run only once. * - * @return true if this task is periodic + * @return {@code true} if this task is periodic */ boolean isPeriodic(); } diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/util/concurrent/ScheduledExecutorService.java --- a/jdk/src/share/classes/java/util/concurrent/ScheduledExecutorService.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/util/concurrent/ScheduledExecutorService.java Tue Jul 09 15:26:20 2013 -0700 @@ -39,30 +39,30 @@ * An {@link ExecutorService} that can schedule commands to run after a given * delay, or to execute periodically. * - *

    The schedule methods create tasks with various delays + *

    The {@code schedule} methods create tasks with various delays * and return a task object that can be used to cancel or check - * execution. The scheduleAtFixedRate and - * scheduleWithFixedDelay methods create and execute tasks + * execution. The {@code scheduleAtFixedRate} and + * {@code scheduleWithFixedDelay} methods create and execute tasks * that run periodically until cancelled. * - *

    Commands submitted using the {@link Executor#execute} and - * {@link ExecutorService} submit methods are scheduled with - * a requested delay of zero. Zero and negative delays (but not - * periods) are also allowed in schedule methods, and are + *

    Commands submitted using the {@link Executor#execute(Runnable)} + * and {@link ExecutorService} {@code submit} methods are scheduled + * with a requested delay of zero. Zero and negative delays (but not + * periods) are also allowed in {@code schedule} methods, and are * treated as requests for immediate execution. * - *

    All schedule methods accept relative delays and + *

    All {@code schedule} methods accept relative delays and * periods as arguments, not absolute times or dates. It is a simple * matter to transform an absolute time represented as a {@link * java.util.Date} to the required form. For example, to schedule at - * a certain future date, you can use: schedule(task, + * a certain future {@code date}, you can use: {@code schedule(task, * date.getTime() - System.currentTimeMillis(), - * TimeUnit.MILLISECONDS). Beware however that expiration of a - * relative delay need not coincide with the current Date at + * TimeUnit.MILLISECONDS)}. Beware however that expiration of a + * relative delay need not coincide with the current {@code Date} at * which the task is enabled due to network time synchronization * protocols, clock drift, or other factors. * - * The {@link Executors} class provides convenient factory methods for + *

    The {@link Executors} class provides convenient factory methods for * the ScheduledExecutorService implementations provided in this package. * *

    Usage Example

    @@ -101,8 +101,8 @@ * @param delay the time from now to delay execution * @param unit the time unit of the delay parameter * @return a ScheduledFuture representing pending completion of - * the task and whose get() method will return - * null upon completion + * the task and whose {@code get()} method will return + * {@code null} upon completion * @throws RejectedExecutionException if the task cannot be * scheduled for execution * @throws NullPointerException if command is null @@ -129,8 +129,8 @@ * Creates and executes a periodic action that becomes enabled first * after the given initial delay, and subsequently with the given * period; that is executions will commence after - * initialDelay then initialDelay+period, then - * initialDelay + 2 * period, and so on. + * {@code initialDelay} then {@code initialDelay+period}, then + * {@code initialDelay + 2 * period}, and so on. * If any execution of the task * encounters an exception, subsequent executions are suppressed. * Otherwise, the task will only terminate via cancellation or @@ -143,7 +143,7 @@ * @param period the period between successive executions * @param unit the time unit of the initialDelay and period parameters * @return a ScheduledFuture representing pending completion of - * the task, and whose get() method will throw an + * the task, and whose {@code get()} method will throw an * exception upon cancellation * @throws RejectedExecutionException if the task cannot be * scheduled for execution @@ -170,7 +170,7 @@ * execution and the commencement of the next * @param unit the time unit of the initialDelay and delay parameters * @return a ScheduledFuture representing pending completion of - * the task, and whose get() method will throw an + * the task, and whose {@code get()} method will throw an * exception upon cancellation * @throws RejectedExecutionException if the task cannot be * scheduled for execution diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java --- a/jdk/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java Tue Jul 09 15:26:20 2013 -0700 @@ -81,7 +81,7 @@ * without threads to handle tasks once they become eligible to run. * *

    Extension notes: This class overrides the - * {@link ThreadPoolExecutor#execute execute} and + * {@link ThreadPoolExecutor#execute(Runnable) execute} and * {@link AbstractExecutorService#submit(Runnable) submit} * methods to generate internal {@link ScheduledFuture} objects to * control per-task delays and scheduling. To preserve @@ -256,9 +256,9 @@ } /** - * Returns true if this is a periodic (not a one-shot) action. + * Returns {@code true} if this is a periodic (not a one-shot) action. * - * @return true if periodic + * @return {@code true} if periodic */ public boolean isPeriodic() { return period != 0; @@ -315,7 +315,7 @@ * is shut down, rejects the task. Otherwise adds task to queue * and starts a thread, if necessary, to run it. (We cannot * prestart the thread to run the task because the task (probably) - * shouldn't be run yet,) If the pool is shut down while the task + * shouldn't be run yet.) If the pool is shut down while the task * is being added, cancel and remove it if required by state and * run-after-shutdown parameters. * @@ -654,7 +654,7 @@ * {@code false} when already shutdown. * This value is by default {@code false}. * - * @param value if {@code true}, continue after shutdown, else don't. + * @param value if {@code true}, continue after shutdown, else don't * @see #getContinueExistingPeriodicTasksAfterShutdownPolicy */ public void setContinueExistingPeriodicTasksAfterShutdownPolicy(boolean value) { @@ -686,7 +686,7 @@ * {@code false} when already shutdown. * This value is by default {@code true}. * - * @param value if {@code true}, execute after shutdown, else don't. + * @param value if {@code true}, execute after shutdown, else don't * @see #getExecuteExistingDelayedTasksAfterShutdownPolicy */ public void setExecuteExistingDelayedTasksAfterShutdownPolicy(boolean value) { @@ -1081,7 +1081,8 @@ long delay = first.getDelay(NANOSECONDS); if (delay <= 0) return finishPoll(first); - else if (leader != null) + first = null; // don't retain ref while waiting + if (leader != null) available.await(); else { Thread thisThread = Thread.currentThread(); @@ -1121,6 +1122,7 @@ return finishPoll(first); if (nanos <= 0) return null; + first = null; // don't retain ref while waiting if (nanos < delay || leader != null) nanos = available.awaitNanos(nanos); else { diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java --- a/jdk/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java Tue Jul 09 15:26:20 2013 -0700 @@ -75,22 +75,23 @@ * corePoolSize (see {@link #getCorePoolSize}) and * maximumPoolSize (see {@link #getMaximumPoolSize}). * - * When a new task is submitted in method {@link #execute}, and fewer - * than corePoolSize threads are running, a new thread is created to - * handle the request, even if other worker threads are idle. If - * there are more than corePoolSize but less than maximumPoolSize - * threads running, a new thread will be created only if the queue is - * full. By setting corePoolSize and maximumPoolSize the same, you - * create a fixed-size thread pool. By setting maximumPoolSize to an - * essentially unbounded value such as {@code Integer.MAX_VALUE}, you - * allow the pool to accommodate an arbitrary number of concurrent - * tasks. Most typically, core and maximum pool sizes are set only - * upon construction, but they may also be changed dynamically using - * {@link #setCorePoolSize} and {@link #setMaximumPoolSize}. + * When a new task is submitted in method {@link #execute(Runnable)}, + * and fewer than corePoolSize threads are running, a new thread is + * created to handle the request, even if other worker threads are + * idle. If there are more than corePoolSize but less than + * maximumPoolSize threads running, a new thread will be created only + * if the queue is full. By setting corePoolSize and maximumPoolSize + * the same, you create a fixed-size thread pool. By setting + * maximumPoolSize to an essentially unbounded value such as {@code + * Integer.MAX_VALUE}, you allow the pool to accommodate an arbitrary + * number of concurrent tasks. Most typically, core and maximum pool + * sizes are set only upon construction, but they may also be changed + * dynamically using {@link #setCorePoolSize} and {@link + * #setMaximumPoolSize}. * *

    On-demand construction
    * - *
    By default, even core threads are initially created and + *
    By default, even core threads are initially created and * started only when new tasks arrive, but this can be overridden * dynamically using method {@link #prestartCoreThread} or {@link * #prestartAllCoreThreads}. You probably want to prestart threads if @@ -117,17 +118,17 @@ * *
    If the pool currently has more than corePoolSize threads, * excess threads will be terminated if they have been idle for more - * than the keepAliveTime (see {@link #getKeepAliveTime}). This - * provides a means of reducing resource consumption when the pool is - * not being actively used. If the pool becomes more active later, new - * threads will be constructed. This parameter can also be changed - * dynamically using method {@link #setKeepAliveTime}. Using a value - * of {@code Long.MAX_VALUE} {@link TimeUnit#NANOSECONDS} effectively - * disables idle threads from ever terminating prior to shut down. By - * default, the keep-alive policy applies only when there are more - * than corePoolSizeThreads. But method {@link - * #allowCoreThreadTimeOut(boolean)} can be used to apply this - * time-out policy to core threads as well, so long as the + * than the keepAliveTime (see {@link #getKeepAliveTime(TimeUnit)}). + * This provides a means of reducing resource consumption when the + * pool is not being actively used. If the pool becomes more active + * later, new threads will be constructed. This parameter can also be + * changed dynamically using method {@link #setKeepAliveTime(long, + * TimeUnit)}. Using a value of {@code Long.MAX_VALUE} {@link + * TimeUnit#NANOSECONDS} effectively disables idle threads from ever + * terminating prior to shut down. By default, the keep-alive policy + * applies only when there are more than corePoolSize threads. But + * method {@link #allowCoreThreadTimeOut(boolean)} can be used to + * apply this time-out policy to core threads as well, so long as the * keepAliveTime value is non-zero.
    * *
    Queuing
    @@ -197,14 +198,14 @@ * *
    Rejected tasks
    * - *
    New tasks submitted in method {@link #execute} will be - * rejected when the Executor has been shut down, and also - * when the Executor uses finite bounds for both maximum threads and - * work queue capacity, and is saturated. In either case, the {@code - * execute} method invokes the {@link - * RejectedExecutionHandler#rejectedExecution} method of its {@link - * RejectedExecutionHandler}. Four predefined handler policies are - * provided: + *
    New tasks submitted in method {@link #execute(Runnable)} will be + * rejected when the Executor has been shut down, and also when + * the Executor uses finite bounds for both maximum threads and work queue + * capacity, and is saturated. In either case, the {@code execute} method + * invokes the {@link + * RejectedExecutionHandler#rejectedExecution(Runnable, ThreadPoolExecutor)} + * method of its {@link RejectedExecutionHandler}. Four predefined handler + * policies are provided: * *
      * @@ -234,30 +235,31 @@ * *
      Hook methods
      * - *
      This class provides {@code protected} overridable {@link - * #beforeExecute} and {@link #afterExecute} methods that are called + *
      This class provides {@code protected} overridable + * {@link #beforeExecute(Thread, Runnable)} and + * {@link #afterExecute(Runnable, Throwable)} methods that are called * before and after execution of each task. These can be used to * manipulate the execution environment; for example, reinitializing - * ThreadLocals, gathering statistics, or adding log - * entries. Additionally, method {@link #terminated} can be overridden - * to perform any special processing that needs to be done once the - * Executor has fully terminated. + * ThreadLocals, gathering statistics, or adding log entries. + * Additionally, method {@link #terminated} can be overridden to perform + * any special processing that needs to be done once the Executor has + * fully terminated. * *

      If hook or callback methods throw exceptions, internal worker * threads may in turn fail and abruptly terminate.

      * *
      Queue maintenance
      * - *
      Method {@link #getQueue} allows access to the work queue for - * purposes of monitoring and debugging. Use of this method for any - * other purpose is strongly discouraged. Two supplied methods, - * {@link #remove} and {@link #purge} are available to assist in - * storage reclamation when large numbers of queued tasks become - * cancelled.
      + *
      Method {@link #getQueue()} allows access to the work queue + * for purposes of monitoring and debugging. Use of this method for + * any other purpose is strongly discouraged. Two supplied methods, + * {@link #remove(Runnable)} and {@link #purge} are available to + * assist in storage reclamation when large numbers of queued tasks + * become cancelled.
      * *
      Finalization
      * - *
      A pool that is no longer referenced in a program AND + *
      A pool that is no longer referenced in a program AND * has no remaining threads will be {@code shutdown} automatically. If * you would like to ensure that unreferenced pools are reclaimed even * if users forget to call {@link #shutdown}, then you must arrange @@ -267,7 +269,7 @@ * * * - *

      Extension example. Most extensions of this class + *

      Extension example. Most extensions of this class * override one or more of the protected hook methods. For example, * here is a subclass that adds a simple pause/resume feature: * @@ -336,7 +338,7 @@ * bookkeeping before terminating. The user-visible pool size is * reported as the current size of the workers set. * - * The runState provides the main lifecyle control, taking on values: + * The runState provides the main lifecycle control, taking on values: * * RUNNING: Accept new tasks and process queued tasks * SHUTDOWN: Don't accept new tasks, but process queued tasks @@ -406,14 +408,14 @@ } /** - * Attempt to CAS-increment the workerCount field of ctl. + * Attempts to CAS-increment the workerCount field of ctl. */ private boolean compareAndIncrementWorkerCount(int expect) { return ctl.compareAndSet(expect, expect + 1); } /** - * Attempt to CAS-decrement the workerCount field of ctl. + * Attempts to CAS-decrement the workerCount field of ctl. */ private boolean compareAndDecrementWorkerCount(int expect) { return ctl.compareAndSet(expect, expect - 1); @@ -498,7 +500,7 @@ * We go further and preserve pool invariants even in the face of * errors such as OutOfMemoryError, that might be thrown while * trying to create threads. Such errors are rather common due to - * the need to allocate a native stack in Thread#start, and users + * the need to allocate a native stack in Thread.start, and users * will want to perform clean pool shutdown to clean up. There * will likely be enough memory available for the cleanup code to * complete without encountering yet another OutOfMemoryError. @@ -848,7 +850,7 @@ */ private List drainQueue() { BlockingQueue q = workQueue; - List taskList = new ArrayList(); + ArrayList taskList = new ArrayList(); q.drainTo(taskList); if (!q.isEmpty()) { for (Runnable r : q.toArray(new Runnable[0])) { @@ -873,7 +875,7 @@ * factory fails to create a thread when asked. If the thread * creation fails, either due to the thread factory returning * null, or due to an exception (typically OutOfMemoryError in - * Thread#start), we roll back cleanly. + * Thread.start()), we roll back cleanly. * * @param firstTask the task the new thread should run first (or * null if none). Workers are created with an initial first task @@ -920,17 +922,16 @@ boolean workerAdded = false; Worker w = null; try { - final ReentrantLock mainLock = this.mainLock; w = new Worker(firstTask); final Thread t = w.thread; if (t != null) { + final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { // Recheck while holding lock. // Back out on ThreadFactory failure or if // shut down before lock acquired. - int c = ctl.get(); - int rs = runStateOf(c); + int rs = runStateOf(ctl.get()); if (rs < SHUTDOWN || (rs == SHUTDOWN && firstTask == null)) { @@ -1029,7 +1030,8 @@ * 4. This worker timed out waiting for a task, and timed-out * workers are subject to termination (that is, * {@code allowCoreThreadTimeOut || workerCount > corePoolSize}) - * both before and after the timed wait. + * both before and after the timed wait, and if the queue is + * non-empty, this worker is not the last thread in the pool. * * @return task, or null if the worker must exit, in which case * workerCount is decremented @@ -1037,7 +1039,6 @@ private Runnable getTask() { boolean timedOut = false; // Did the last poll() time out? - retry: for (;;) { int c = ctl.get(); int rs = runStateOf(c); @@ -1048,20 +1049,16 @@ return null; } - boolean timed; // Are workers subject to culling? + int wc = workerCountOf(c); - for (;;) { - int wc = workerCountOf(c); - timed = allowCoreThreadTimeOut || wc > corePoolSize; + // Are workers subject to culling? + boolean timed = allowCoreThreadTimeOut || wc > corePoolSize; - if (wc <= maximumPoolSize && ! (timedOut && timed)) - break; + if ((wc > maximumPoolSize || (timed && timedOut)) + && (wc > 1 || workQueue.isEmpty())) { if (compareAndDecrementWorkerCount(c)) return null; - c = ctl.get(); // Re-read ctl - if (runStateOf(c) != rs) - continue retry; - // else CAS failed due to workerCount change; retry inner loop + continue; } try { @@ -1090,9 +1087,9 @@ * usually leads processWorkerExit to replace this thread. * * 2. Before running any task, the lock is acquired to prevent - * other pool interrupts while the task is executing, and - * clearInterruptsForTaskRun called to ensure that unless pool is - * stopping, this thread does not have its interrupt set. + * other pool interrupts while the task is executing, and then we + * ensure that unless pool is stopping, this thread does not have + * its interrupt set. * * 3. Each task run is preceded by a call to beforeExecute, which * might throw an exception, in which case we cause thread to die @@ -1100,12 +1097,12 @@ * the task. * * 4. Assuming beforeExecute completes normally, we run the task, - * gathering any of its thrown exceptions to send to - * afterExecute. We separately handle RuntimeException, Error - * (both of which the specs guarantee that we trap) and arbitrary - * Throwables. Because we cannot rethrow Throwables within - * Runnable.run, we wrap them within Errors on the way out (to the - * thread's UncaughtExceptionHandler). Any thrown exception also + * gathering any of its thrown exceptions to send to afterExecute. + * We separately handle RuntimeException, Error (both of which the + * specs guarantee that we trap) and arbitrary Throwables. + * Because we cannot rethrow Throwables within Runnable.run, we + * wrap them within Errors on the way out (to the thread's + * UncaughtExceptionHandler). Any thrown exception also * conservatively causes thread to die. * * 5. After task.run completes, we call afterExecute, which may @@ -1443,7 +1440,7 @@ * ignored or suppressed interruption, causing this executor not * to properly terminate. * - * @return true if terminating but not yet terminated + * @return {@code true} if terminating but not yet terminated */ public boolean isTerminating() { int c = ctl.get(); @@ -1497,7 +1494,7 @@ * Returns the thread factory used to create new threads. * * @return the current thread factory - * @see #setThreadFactory + * @see #setThreadFactory(ThreadFactory) */ public ThreadFactory getThreadFactory() { return threadFactory; @@ -1520,7 +1517,7 @@ * Returns the current handler for unexecutable tasks. * * @return the current handler - * @see #setRejectedExecutionHandler + * @see #setRejectedExecutionHandler(RejectedExecutionHandler) */ public RejectedExecutionHandler getRejectedExecutionHandler() { return handler; @@ -1692,7 +1689,7 @@ * @param unit the time unit of the {@code time} argument * @throws IllegalArgumentException if {@code time} less than zero or * if {@code time} is zero and {@code allowsCoreThreadTimeOut} - * @see #getKeepAliveTime + * @see #getKeepAliveTime(TimeUnit) */ public void setKeepAliveTime(long time, TimeUnit unit) { if (time < 0) @@ -1713,7 +1710,7 @@ * * @param unit the desired time unit of the result * @return the time limit - * @see #setKeepAliveTime + * @see #setKeepAliveTime(long, TimeUnit) */ public long getKeepAliveTime(TimeUnit unit) { return unit.convert(keepAliveTime, TimeUnit.NANOSECONDS); @@ -1738,7 +1735,7 @@ * present, thus causing it not to be run if it has not already * started. * - *

      This method may be useful as one part of a cancellation + *

      This method may be useful as one part of a cancellation * scheme. It may fail to remove tasks that have been converted * into other forms before being placed on the internal queue. For * example, a task entered using {@code submit} might be @@ -1747,7 +1744,7 @@ * remove those Futures that have been cancelled. * * @param task the task to remove - * @return true if the task was removed + * @return {@code true} if the task was removed */ public boolean remove(Runnable task) { boolean removed = workQueue.remove(task); @@ -2042,7 +2039,7 @@ * * @param r the runnable task requested to be executed * @param e the executor attempting to execute this task - * @throws RejectedExecutionException always. + * @throws RejectedExecutionException always */ public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { throw new RejectedExecutionException("Task " + r.toString() + @@ -2099,4 +2096,3 @@ } } } - diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/util/regex/MatchResult.java --- a/jdk/src/share/classes/java/util/regex/MatchResult.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/util/regex/MatchResult.java Tue Jul 09 15:26:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -77,7 +77,7 @@ public int start(int group); /** - * Returns the offset after the last character matched.

      + * Returns the offset after the last character matched. * * @return The offset after the last character matched * diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/util/regex/Matcher.java --- a/jdk/src/share/classes/java/util/regex/Matcher.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/util/regex/Matcher.java Tue Jul 09 15:26:20 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,8 +28,8 @@ import java.util.Objects; /** - * An engine that performs match operations on a {@link java.lang.CharSequence - * character sequence} by interpreting a {@link Pattern}. + * An engine that performs match operations on a {@linkplain java.lang.CharSequence + * character sequence} by interpreting a {@link Pattern}. * *

      A matcher is created from a pattern by invoking the pattern's {@link * Pattern#matcher matcher} method. Once created, a matcher can be used to @@ -330,7 +330,7 @@ } /** - * Returns the start index of the previous match.

      + * Returns the start index of the previous match. * * @return The index of the first character matched * @@ -402,7 +402,7 @@ } /** - * Returns the offset after the last character matched.

      + * Returns the offset after the last character matched. * * @return The offset after the last character matched * @@ -647,6 +647,7 @@ * invocations of the {@link #find()} method will start at the first * character not matched by this match.

      * + * @param start the index to start searching for a match * @throws IndexOutOfBoundsException * If start is less than zero or if start is greater than the * length of the input sequence. @@ -736,8 +737,8 @@ * captured during the previous match: Each occurrence of * ${name} or $g * will be replaced by the result of evaluating the corresponding - * {@link #group(String) group(name)} or {@link #group(int) group(g)} - * respectively. For $g, + * {@link #group(String) group(name)} or {@link #group(int) group(g)} + * respectively. For $g, * the first number after the $ is always treated as part of * the group reference. Subsequent numbers are incorporated into g if * they would form a legal group reference. Only the numerals '0' diff -r 6a7dc4611ff2 -r becb627a8655 jdk/src/share/classes/java/util/regex/Pattern.java --- a/jdk/src/share/classes/java/util/regex/Pattern.java Mon Jul 08 11:11:07 2013 -0700 +++ b/jdk/src/share/classes/java/util/regex/Pattern.java Tue Jul 09 15:26:20 2013 -0700 @@ -45,8 +45,8 @@ * *

      A regular expression, specified as a string, must first be compiled into * an instance of this class. The resulting pattern can then be used to create - * a {@link Matcher} object that can match arbitrary {@link - * java.lang.CharSequence character sequences} against the regular + * a {@link Matcher} object that can match arbitrary {@linkplain + * java.lang.CharSequence character sequences} against the regular * expression. All of the state involved in performing a match resides in the * matcher, so many matchers can share the same pattern. * @@ -73,15 +73,14 @@ * such use. * * - * - *

      Summary of regular-expression constructs

      + *

      Summary of regular-expression constructs

      * * * * - * - * + * + * * * * @@ -128,24 +127,24 @@ * * * - * - * - * - * - * - * - * - * - * - * - * - * - * - * + * + * + * + * + * + * + * + * + * + * + * + * + * + * * * * @@ -175,36 +174,36 @@ * * * - * + * * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * * * * @@ -220,19 +219,19 @@ * * * - * * + * * * - * + * * - * + * * - * + * * - * + * * - * + * * - * + * * * * @@ -376,8 +375,7 @@ *
      * * - * - *

      Backslashes, escapes, and quoting

      + *

      Backslashes, escapes, and quoting

      * *

      The backslash character ('\') serves to introduce escaped * constructs, as defined in the table above, as well as to quote characters @@ -405,8 +403,7 @@ * (hello) the string literal "\\(hello\\)" * must be used. * - * - *

      Character Classes

      + *

      Character Classes

      * *

      Character classes may appear within other character classes, and * may be composed by the union operator (implicit) and the intersection @@ -435,7 +432,7 @@ *

      * * - * + * *
      ConstructMatchesConstructMatches
       
       
      Character classes
      [abc]a, b, or c (simple class)
      [^abc]Any character except a, b, or c (negation)
      [a-zA-Z]a through z - * or A through Z, inclusive (range)
      [a-d[m-p]]a through d, - * or m through p: [a-dm-p] (union)
      [a-z&&[def]]d, e, or f (intersection)
      [a-z&&[^bc]]a through z, - * except for b and c: [ad-z] (subtraction)
      [a-z&&[^m-p]]a through z, - * and not m through p: [a-lq-z](subtraction)
      {@code [abc]}{@code a}, {@code b}, or {@code c} (simple class)
      {@code [^abc]}Any character except {@code a}, {@code b}, or {@code c} (negation)
      {@code [a-zA-Z]}{@code a} through {@code z} + * or {@code A} through {@code Z}, inclusive (range)
      {@code [a-d[m-p]]}{@code a} through {@code d}, + * or {@code m} through {@code p}: {@code [a-dm-p]} (union)
      {@code [a-z&&[def]]}{@code d}, {@code e}, or {@code f} (intersection)
      {@code [a-z&&[^bc]]}{@code a} through {@code z}, + * except for {@code b} and {@code c}: {@code [ad-z]} (subtraction)
      {@code [a-z&&[^m-p]]}{@code a} through {@code z}, + * and not {@code m} through {@code p}: {@code [a-lq-z]}(subtraction)
       
      Predefined character classes
      \WA non-word character: [^\w]
       
      POSIX character classes (US-ASCII only)
      POSIX character classes (US-ASCII only)
      \p{Lower}A lower-case alphabetic character: [a-z]
      \p{Upper}An upper-case alphabetic character:[A-Z]
      \p{ASCII}All ASCII:[\x00-\x7F]
      \p{Alpha}An alphabetic character:[\p{Lower}\p{Upper}]
      \p{Digit}A decimal digit: [0-9]
      \p{Alnum}An alphanumeric character:[\p{Alpha}\p{Digit}]
      \p{Punct}Punctuation: One of !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
      \p{Graph}A visible character: [\p{Alnum}\p{Punct}]
      \p{Print}A printable character: [\p{Graph}\x20]
      \p{Blank}A space or a tab: [ \t]
      \p{Cntrl}A control character: [\x00-\x1F\x7F]
      \p{XDigit}A hexadecimal digit: [0-9a-fA-F]
      \p{Space}A whitespace character: [ \t\n\x0B\f\r]
      {@code \p{Lower}}A lower-case alphabetic character: {@code [a-z]}
      {@code \p{Upper}}An upper-case alphabetic character:{@code [A-Z]}
      {@code \p{ASCII}}All ASCII:{@code [\x00-\x7F]}
      {@code \p{Alpha}}An alphabetic character:{@code [\p{Lower}\p{Upper}]}
      {@code \p{Digit}}A decimal digit: {@code [0-9]}
      {@code \p{Alnum}}An alphanumeric character:{@code [\p{Alpha}\p{Digit}]}
      {@code \p{Punct}}Punctuation: One of {@code !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~}
      {@code \p{Graph}}A visible character: {@code [\p{Alnum}\p{Punct}]}
      {@code \p{Print}}A printable character: {@code [\p{Graph}\x20]}
      {@code \p{Blank}}A space or a tab: {@code [ \t]}
      {@code \p{Cntrl}}A control character: {@code [\x00-\x1F\x7F]}
      {@code \p{XDigit}}A hexadecimal digit: {@code [0-9a-fA-F]}
      {@code \p{Space}}A whitespace character: {@code [ \t\n\x0B\f\r]}
       
      java.lang.Character classes (simple java character type)
       
      Classes for Unicode scripts, blocks, categories and binary properties
      \p{IsLatin}
      {@code \p{IsLatin}}A Latin script character (script)
      \p{InGreek}
      {@code \p{InGreek}}A character in the Greek block (block)
      \p{Lu}
      {@code \p{Lu}}An uppercase letter (category)
      \p{IsAlphabetic}
      {@code \p{IsAlphabetic}}An alphabetic character (binary property)
      \p{Sc}
      {@code \p{Sc}}A currency symbol
      \P{InGreek}
      {@code \P{InGreek}}Any character except one in the Greek block (negation)
      [\p{L}&&[^\p{Lu}]] 
      {@code [\p{L}&&[^\p{Lu}]]}Any letter except an uppercase letter (subtraction)
       
      [a-e][i-u]
      5    Intersection[a-z&&[aeiou]]
      {@code [a-z&&[aeiou]]}
      * *

      Note that a different set of metacharacters are in effect inside @@ -444,8 +441,7 @@ * character class, while the expression - becomes a range * forming metacharacter. * - * - *

      Line terminators

      + *

      Line terminators

      * *

      A line terminator is a one- or two-character sequence that marks * the end of a line of the input character sequence. The following are @@ -480,11 +476,9 @@ * except at the end of input. When in {@link #MULTILINE} mode $ * matches just before a line terminator or the end of the input sequence. * - * - *

      Groups and capturing

      + *

      Groups and capturing

      * - * - *
      Group number
      + *

      Group number

      *

      Capturing groups are numbered by counting their opening parentheses from * left to right. In the expression ((A)(B(C))), for example, there * are four such groups:

      @@ -507,8 +501,7 @@ * subsequence may be used later in the expression, via a back reference, and * may also be retrieved from the matcher once the match operation is complete. * - * - *
      Group name
      + *

      Group name

      *

      A capturing group can also be assigned a "name", a named-capturing group, * and then be back-referenced later by the "name". Group names are composed of * the following characters. The first character must be a letter. @@ -537,7 +530,7 @@ * that do not capture text and do not count towards the group total, or * named-capturing group. * - *

      Unicode support

      + *

      Unicode support

      * *

      This class is in conformance with Level 1 of Unicode Technical @@ -568,18 +561,18 @@ *

      * Scripts, blocks, categories and binary properties can be used both inside * and outside of a character class. - * + * *

      - * Scripts are specified either with the prefix {@code Is}, as in + * Scripts are specified either with the prefix {@code Is}, as in * {@code IsHiragana}, or by using the {@code script} keyword (or its short * form {@code sc})as in {@code script=Hiragana} or {@code sc=Hiragana}. *

      * The script names supported by Pattern are the valid script names * accepted and defined by * {@link java.lang.Character.UnicodeScript#forName(String) UnicodeScript.forName}. - * + * *

      - * Blocks are specified with the prefix {@code In}, as in + * Blocks are specified with the prefix {@code In}, as in * {@code InMongolian}, or by using the keyword {@code block} (or its short * form {@code blk}) as in {@code block=Mongolian} or {@code blk=Mongolian}. *

      @@ -587,8 +580,8 @@ * accepted and defined by * {@link java.lang.Character.UnicodeBlock#forName(String) UnicodeBlock.forName}. *

      - * - * Categories may be specified with the optional prefix {@code Is}: + * + * Categories may be specified with the optional prefix {@code Is}: * Both {@code \p{L}} and {@code \p{IsL}} denote the category of Unicode * letters. Same as scripts and blocks, categories can also be specified * by using the keyword {@code general_category} (or its short form @@ -600,8 +593,8 @@ * {@link java.lang.Character Character} class. The category names are those * defined in the Standard, both normative and informative. *

      - * - * Binary properties are specified with the prefix {@code Is}, as in + * + * Binary properties are specified with the prefix {@code Is}, as in * {@code IsAlphabetic}. The supported binary properties by Pattern * are *