From cee580a37dddc7ed72c583de72ff29abb6c27316 Mon Sep 17 00:00:00 2001 From: Doug Lea Date: Mon, 28 Nov 2016 23:47:23 -0800 Subject: [PATCH] 8166646: Miscellaneous changes imported from jsr166 CVS 2016-10 Reviewed-by: martin, smarks, psandoz --- .../java/util/concurrent/CompletionStage.java | 6 +- .../java/util/concurrent/CyclicBarrier.java | 3 +- .../java/util/concurrent/Executor.java | 14 +- .../concurrent/ExecutorCompletionService.java | 4 +- .../java/util/concurrent/Executors.java | 2 +- .../java/util/concurrent/ForkJoinPool.java | 23 +-- .../java/util/concurrent/ForkJoinTask.java | 2 +- .../classes/java/util/concurrent/Future.java | 19 +-- .../util/concurrent/LinkedTransferQueue.java | 4 +- .../classes/java/util/concurrent/Phaser.java | 45 +++--- .../concurrent/PriorityBlockingQueue.java | 5 +- .../concurrent/ScheduledExecutorService.java | 11 +- .../util/concurrent/ThreadLocalRandom.java | 12 +- .../atomic/AtomicIntegerFieldUpdater.java | 8 +- .../atomic/AtomicLongFieldUpdater.java | 12 +- .../atomic/AtomicReferenceFieldUpdater.java | 4 + .../util/concurrent/atomic/package-info.java | 18 +-- .../util/concurrent/locks/StampedLock.java | 2 +- .../java/util/concurrent/package-info.java | 2 +- .../java/util/TreeMap/HeadTailTypeError.java | 8 +- .../util/concurrent/FutureTask/Throw.java | 4 +- .../ThreadPoolExecutor/ThrowingTasks.java | 4 +- .../concurrent/locks/Lock/FlakyMutex.java | 4 +- .../java/util/concurrent/tck/Atomic8Test.java | 131 ++++++++++------ .../concurrent/tck/CompletableFutureTest.java | 142 +++++++++--------- .../tck/ConcurrentHashMap8Test.java | 34 ++++- .../concurrent/tck/ConcurrentHashMapTest.java | 26 ---- .../tck/ConcurrentLinkedDequeTest.java | 14 +- .../tck/ConcurrentLinkedQueueTest.java | 13 +- .../tck/ConcurrentSkipListSetTest.java | 2 +- .../tck/ConcurrentSkipListSubSetTest.java | 2 +- .../tck/ExecutorCompletionService9Test.java | 16 +- .../tck/LinkedTransferQueueTest.java | 15 +- .../tck/PriorityBlockingQueueTest.java | 13 +- .../concurrent/tck/PriorityQueueTest.java | 13 +- .../util/concurrent/tck/StampedLockTest.java | 24 +-- .../tck/SubmissionPublisherTest.java | 2 +- .../tck/ThreadLocalRandom8Test.java | 16 ++ .../concurrent/tck/ThreadLocalRandomTest.java | 35 +++++ .../java/util/concurrent/tck/TreeSetTest.java | 2 +- .../util/concurrent/tck/TreeSubSetTest.java | 2 +- 41 files changed, 411 insertions(+), 307 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/CompletionStage.java b/jdk/src/java.base/share/classes/java/util/concurrent/CompletionStage.java index d855945b829..70b601acdb0 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/CompletionStage.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/CompletionStage.java @@ -856,13 +856,9 @@ public interface CompletionStage { * CompletableFuture, this method may return this stage itself. * Otherwise, invocation of this method may be equivalent in * effect to {@code thenApply(x -> x)}, but returning an instance - * of type {@code CompletableFuture}. A CompletionStage - * implementation that does not choose to interoperate with others - * may throw {@code UnsupportedOperationException}. + * of type {@code CompletableFuture}. * * @return the CompletableFuture - * @throws UnsupportedOperationException if this implementation - * does not interoperate with CompletableFuture */ public CompletableFuture toCompletableFuture(); diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/CyclicBarrier.java b/jdk/src/java.base/share/classes/java/util/concurrent/CyclicBarrier.java index beae1cabb90..97aae44a888 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/CyclicBarrier.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/CyclicBarrier.java @@ -82,8 +82,7 @@ import java.util.concurrent.locks.ReentrantLock; * public Solver(float[][] matrix) { * data = matrix; * N = matrix.length; - * Runnable barrierAction = - * new Runnable() { public void run() { mergeRows(...); }}; + * Runnable barrierAction = () -> mergeRows(...); * barrier = new CyclicBarrier(N, barrierAction); * * List threads = new ArrayList<>(N); diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/Executor.java b/jdk/src/java.base/share/classes/java/util/concurrent/Executor.java index a61570576d8..378cacdc9d0 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/Executor.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/Executor.java @@ -87,14 +87,12 @@ package java.util.concurrent; * this.executor = executor; * } * - * public synchronized void execute(final Runnable r) { - * tasks.add(new Runnable() { - * public void run() { - * try { - * r.run(); - * } finally { - * scheduleNext(); - * } + * public synchronized void execute(Runnable r) { + * tasks.add(() -> { + * try { + * r.run(); + * } finally { + * scheduleNext(); * } * }); * if (active == null) { diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/ExecutorCompletionService.java b/jdk/src/java.base/share/classes/java/util/concurrent/ExecutorCompletionService.java index 9591d9b1942..77208837d57 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/ExecutorCompletionService.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/ExecutorCompletionService.java @@ -80,7 +80,7 @@ package java.util.concurrent; * List> futures = new ArrayList<>(n); * Result result = null; * try { - * solvers.forEach((solver) -> futures.add(cs.submit(solver))); + * solvers.forEach(solver -> futures.add(cs.submit(solver))); * for (int i = n; i > 0; i--) { * try { * Result r = cs.take().get(); @@ -91,7 +91,7 @@ package java.util.concurrent; * } catch (ExecutionException ignore) {} * } * } finally { - * futures.forEach((future) -> future.cancel(true)); + * futures.forEach(future -> future.cancel(true)); * } * * if (result != null) diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/Executors.java b/jdk/src/java.base/share/classes/java/util/concurrent/Executors.java index cd9119029f4..a31e3a1ebac 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/Executors.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/Executors.java @@ -650,7 +650,7 @@ public class Executors { public Thread newThread(final Runnable r) { return super.newThread(new Runnable() { public void run() { - AccessController.doPrivileged(new PrivilegedAction() { + AccessController.doPrivileged(new PrivilegedAction<>() { public Void run() { Thread.currentThread().setContextClassLoader(ccl); r.run(); diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java b/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java index 98524dedc23..c549dbdb30f 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java @@ -38,8 +38,10 @@ package java.util.concurrent; import java.lang.Thread.UncaughtExceptionHandler; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; +import java.security.AccessController; import java.security.AccessControlContext; import java.security.Permissions; +import java.security.PrivilegedAction; import java.security.ProtectionDomain; import java.util.ArrayList; import java.util.Collection; @@ -64,7 +66,8 @@ import java.util.concurrent.locks.LockSupport; * tasks are submitted to the pool from external clients. Especially * when setting asyncMode to true in constructors, {@code * ForkJoinPool}s may also be appropriate for use with event-style - * tasks that are never joined. + * tasks that are never joined. All worker threads are initialized + * with {@link Thread#isDaemon} set {@code true}. * *

A static {@link #commonPool()} is available and appropriate for * most applications. The common pool is used by any ForkJoinTask that @@ -3224,10 +3227,9 @@ public class ForkJoinPool extends AbstractExecutorService { new DefaultForkJoinWorkerThreadFactory(); modifyThreadPermission = new RuntimePermission("modifyThread"); - common = java.security.AccessController.doPrivileged - (new java.security.PrivilegedAction() { - public ForkJoinPool run() { - return new ForkJoinPool((byte)0); }}); + common = AccessController.doPrivileged(new PrivilegedAction<>() { + public ForkJoinPool run() { + return new ForkJoinPool((byte)0); }}); COMMON_PARALLELISM = Math.max(common.mode & SMASK, 1); } @@ -3256,12 +3258,11 @@ public class ForkJoinPool extends AbstractExecutorService { } public final ForkJoinWorkerThread newThread(ForkJoinPool pool) { - return java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public ForkJoinWorkerThread run() { - return new ForkJoinWorkerThread. - InnocuousForkJoinWorkerThread(pool); - }}, INNOCUOUS_ACC); + return AccessController.doPrivileged(new PrivilegedAction<>() { + public ForkJoinWorkerThread run() { + return new ForkJoinWorkerThread. + InnocuousForkJoinWorkerThread(pool); + }}, INNOCUOUS_ACC); } } diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinTask.java b/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinTask.java index bcd51f7d6a2..d9addf48fb8 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinTask.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinTask.java @@ -419,7 +419,7 @@ public abstract class ForkJoinTask implements Future, Serializable { /** Reference queue of stale exceptionally completed tasks. */ private static final ReferenceQueue> exceptionTableRefQueue - = new ReferenceQueue>(); + = new ReferenceQueue<>(); /** * Key-value nodes for exception table. The chained hash table diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/Future.java b/jdk/src/java.base/share/classes/java/util/concurrent/Future.java index 9bd05d63e77..6099c7caf41 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/Future.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/Future.java @@ -50,8 +50,7 @@ package java.util.concurrent; * declare types of the form {@code Future} and * return {@code null} as a result of the underlying task. * - *

- * Sample Usage (Note that the following classes are all + *

Sample Usage (Note that the following classes are all * made-up.) * *

 {@code
@@ -59,13 +58,9 @@ package java.util.concurrent;
  * class App {
  *   ExecutorService executor = ...
  *   ArchiveSearcher searcher = ...
- *   void showSearch(final String target)
- *       throws InterruptedException {
- *     Future future
- *       = executor.submit(new Callable() {
- *         public String call() {
- *             return searcher.search(target);
- *         }});
+ *   void showSearch(String target) throws InterruptedException {
+ *     Callable task = () -> searcher.search(target);
+ *     Future future = executor.submit(task);
  *     displayOtherThings(); // do other things while searching
  *     try {
  *       displayText(future.get()); // use future
@@ -77,11 +72,7 @@ package java.util.concurrent;
  * 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() {
- *     public String call() {
- *       return searcher.search(target);
- *   }});
+ * FutureTask future = new FutureTask<>(task);
  * executor.execute(future);}
* *

Memory consistency effects: Actions taken by the asynchronous computation diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java b/jdk/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java index cb613e3f092..9433af6a72f 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java @@ -95,8 +95,8 @@ public class LinkedTransferQueue extends AbstractQueue * *** Overview of Dual Queues with Slack *** * * Dual Queues, introduced by Scherer and Scott - * (http://www.cs.rice.edu/~wns1/papers/2004-DISC-DDS.pdf) are - * (linked) queues in which nodes may represent either data or + * (http://www.cs.rochester.edu/~scott/papers/2004_DISC_dual_DS.pdf) + * are (linked) queues in which nodes may represent either data or * requests. When a thread tries to enqueue a data node, but * encounters a request node, it instead "matches" and removes it; * and vice versa for enqueuing requests. Blocking Dual Queues diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/Phaser.java b/jdk/src/java.base/share/classes/java/util/concurrent/Phaser.java index 043c0b2b2c8..0a87239ea29 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/Phaser.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/Phaser.java @@ -154,49 +154,46 @@ import java.util.concurrent.locks.LockSupport; *

A {@code Phaser} may be used instead of a {@code CountDownLatch} * to control a one-shot action serving a variable number of parties. * The typical idiom is for the method setting this up to first - * register, then start the actions, then deregister, as in: + * register, then start all the actions, then deregister, as in: * *

 {@code
  * void runTasks(List tasks) {
- *   final Phaser phaser = new Phaser(1); // "1" to register self
+ *   Phaser startingGate = new Phaser(1); // "1" to register self
  *   // create and start threads
- *   for (final Runnable task : tasks) {
- *     phaser.register();
- *     new Thread() {
- *       public void run() {
- *         phaser.arriveAndAwaitAdvance(); // await all creation
- *         task.run();
- *       }
- *     }.start();
+ *   for (Runnable task : tasks) {
+ *     startingGate.register();
+ *     new Thread(() -> {
+ *       startingGate.arriveAndAwaitAdvance();
+ *       task.run();
+ *     }).start();
  *   }
  *
- *   // allow threads to start and deregister self
- *   phaser.arriveAndDeregister();
+ *   // deregister self to allow threads to proceed
+ *   startingGate.arriveAndDeregister();
  * }}
* *

One way to cause a set of threads to repeatedly perform actions * for a given number of iterations is to override {@code onAdvance}: * *

 {@code
- * void startTasks(List tasks, final int iterations) {
- *   final Phaser phaser = new Phaser() {
+ * void startTasks(List tasks, int iterations) {
+ *   Phaser phaser = new Phaser() {
  *     protected boolean onAdvance(int phase, int registeredParties) {
  *       return phase >= iterations || registeredParties == 0;
  *     }
  *   };
  *   phaser.register();
- *   for (final Runnable task : tasks) {
+ *   for (Runnable task : tasks) {
  *     phaser.register();
- *     new Thread() {
- *       public void run() {
- *         do {
- *           task.run();
- *           phaser.arriveAndAwaitAdvance();
- *         } while (!phaser.isTerminated());
- *       }
- *     }.start();
+ *     new Thread(() -> {
+ *       do {
+ *         task.run();
+ *         phaser.arriveAndAwaitAdvance();
+ *       } while (!phaser.isTerminated());
+ *     }).start();
  *   }
- *   phaser.arriveAndDeregister(); // deregister self, don't wait
+ *   // allow threads to proceed; don't wait for them
+ *   phaser.arriveAndDeregister();
  * }}
* * If the main task must later await termination, it diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java b/jdk/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java index 11d6339a3c8..64f03b6940c 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java @@ -933,8 +933,9 @@ public class PriorityBlockingQueue extends AbstractQueue } } - // Similar to Collections.ArraySnapshotSpliterator but avoids - // commitment to toArray until needed + /** + * Immutable snapshot spliterator that binds to elements "late". + */ static final class PBQSpliterator implements Spliterator { final PriorityBlockingQueue queue; Object[] array; diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/ScheduledExecutorService.java b/jdk/src/java.base/share/classes/java/util/concurrent/ScheduledExecutorService.java index c32e2d1dde8..2eae3a2d374 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/ScheduledExecutorService.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/ScheduledExecutorService.java @@ -77,14 +77,11 @@ package java.util.concurrent; * Executors.newScheduledThreadPool(1); * * public void beepForAnHour() { - * final Runnable beeper = new Runnable() { - * public void run() { System.out.println("beep"); } - * }; - * final ScheduledFuture beeperHandle = + * Runnable beeper = () -> System.out.println("beep"); + * ScheduledFuture beeperHandle = * scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS); - * scheduler.schedule(new Runnable() { - * public void run() { beeperHandle.cancel(true); } - * }, 60 * 60, SECONDS); + * Runnable canceller = () -> beeperHandle.cancel(true); + * scheduler.schedule(canceller, 1, HOURS); * } * }}
* diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java b/jdk/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java index e64930755bf..cb1b4f260f5 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java @@ -197,9 +197,17 @@ public class ThreadLocalRandom extends Random { return r; } - // We must define this, but never use it. + /** + * Generates a pseudorandom number with the indicated number of + * low-order bits. Because this class has no subclasses, this + * method cannot be invoked or overridden. + * + * @param bits random bits + * @return the next pseudorandom value from this random number + * generator's sequence + */ protected int next(int bits) { - return (int)(mix64(nextSeed()) >>> (64 - bits)); + return nextInt() >>> (32 - bits); } /** diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java index c86f41ddee7..55af35b0139 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java @@ -60,6 +60,10 @@ import jdk.internal.reflect.Reflection; * guarantee atomicity only with respect to other invocations of * {@code compareAndSet} and {@code set} on the same updater. * + *

Object arguments for parameters of type {@code T} that are not + * instances of the class passed to {@link #newUpdater} will result in + * a {@link ClassCastException} being thrown. + * * @since 1.5 * @author Doug Lea * @param The type of the object holding the updatable field @@ -105,8 +109,6 @@ public abstract class AtomicIntegerFieldUpdater { * @param expect the expected value * @param update the new value * @return {@code true} if successful - * @throws ClassCastException if {@code obj} is not an instance - * of the class possessing the field established in the constructor */ public abstract boolean compareAndSet(T obj, int expect, int update); @@ -125,8 +127,6 @@ public abstract class AtomicIntegerFieldUpdater { * @param expect the expected value * @param update the new value * @return {@code true} if successful - * @throws ClassCastException if {@code obj} is not an instance - * of the class possessing the field established in the constructor */ public abstract boolean weakCompareAndSet(T obj, int expect, int update); diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java index af39d8a4603..ff444676685 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java @@ -60,6 +60,10 @@ import jdk.internal.reflect.Reflection; * guarantee atomicity only with respect to other invocations of * {@code compareAndSet} and {@code set} on the same updater. * + *

Object arguments for parameters of type {@code T} that are not + * instances of the class passed to {@link #newUpdater} will result in + * a {@link ClassCastException} being thrown. + * * @since 1.5 * @author Doug Lea * @param The type of the object holding the updatable field @@ -108,8 +112,6 @@ public abstract class AtomicLongFieldUpdater { * @param expect the expected value * @param update the new value * @return {@code true} if successful - * @throws ClassCastException if {@code obj} is not an instance - * of the class possessing the field established in the constructor */ public abstract boolean compareAndSet(T obj, long expect, long update); @@ -128,8 +130,6 @@ public abstract class AtomicLongFieldUpdater { * @param expect the expected value * @param update the new value * @return {@code true} if successful - * @throws ClassCastException if {@code obj} is not an instance - * of the class possessing the field established in the constructor */ public abstract boolean weakCompareAndSet(T obj, long expect, long update); @@ -510,8 +510,8 @@ public abstract class AtomicLongFieldUpdater { LockedUpdater(final Class tclass, final String fieldName, final Class caller) { - Field field = null; - int modifiers = 0; + final Field field; + final int modifiers; try { field = AccessController.doPrivileged( new PrivilegedExceptionAction() { diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java index faacb7fc432..2b75d5654ae 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java @@ -77,6 +77,10 @@ import jdk.internal.reflect.Reflection; * guarantee atomicity only with respect to other invocations of * {@code compareAndSet} and {@code set} on the same updater. * + *

Object arguments for parameters of type {@code T} that are not + * instances of the class passed to {@link #newUpdater} will result in + * a {@link ClassCastException} being thrown. + * * @since 1.5 * @author Doug Lea * @param The type of the object holding the updatable field diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/package-info.java b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/package-info.java index b0ff27f96e3..8390ff35d0b 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/package-info.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/package-info.java @@ -60,21 +60,9 @@ * } * }} * - *

It is straightforward to define new utility functions that, like - * {@code getAndIncrement}, apply a function to a value atomically. - * For example, given some transformation - *

 {@code long transform(long input)}
- * - * write your utility method as follows: - *
 {@code
- * long getAndTransform(AtomicLong var) {
- *   long prev, next;
- *   do {
- *     prev = var.get();
- *     next = transform(prev);
- *   } while (!var.compareAndSet(prev, next));
- *   return prev; // return next; for transformAndGet
- * }}
+ *

Arbitrary transformations of the contained value are provided both + * by low-level read-modify-write operations such as {@code compareAndSet} + * and by higher-level methods such as {@code getAndUpdate}. * *

These classes are not general purpose replacements for {@code * java.lang.Integer} and related classes. They do not diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/locks/StampedLock.java b/jdk/src/java.base/share/classes/java/util/concurrent/locks/StampedLock.java index 18fac82b111..583749b1523 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/locks/StampedLock.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/locks/StampedLock.java @@ -572,7 +572,7 @@ public class StampedLock implements java.io.Serializable { * before acquiring the lock */ @ReservedStackAccess - public long readLockInterruptibly() throws InterruptedException { + public long readLockInterruptibly() throws InterruptedException { long s, next; if (!Thread.interrupted() // bypass acquireRead on common uncontended case diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/package-info.java b/jdk/src/java.base/share/classes/java/util/concurrent/package-info.java index 46b9398f6e2..0e992a2af08 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/package-info.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/package-info.java @@ -200,7 +200,7 @@ * concurrent collection is thread-safe, but not governed by a * single exclusion lock. In the particular case of * ConcurrentHashMap, it safely permits any number of - * concurrent reads as well as a tunable number of concurrent + * concurrent reads as well as a large number of concurrent * writes. "Synchronized" classes can be useful when you need * to prevent all access to a collection via a single lock, at * the expense of poorer scalability. In other cases in which diff --git a/jdk/test/java/util/TreeMap/HeadTailTypeError.java b/jdk/test/java/util/TreeMap/HeadTailTypeError.java index cc23734c628..88d5ed814bf 100644 --- a/jdk/test/java/util/TreeMap/HeadTailTypeError.java +++ b/jdk/test/java/util/TreeMap/HeadTailTypeError.java @@ -22,10 +22,10 @@ */ /* - @test - @bug 4251519 4251520 - @summary indexOf and lastIndex of used to let you look outside the - valid range in the backing array + * @test + * @bug 4251519 4251520 + * @summary indexOf and lastIndex of used to let you look outside the + * valid range in the backing array */ import java.util.*; diff --git a/jdk/test/java/util/concurrent/FutureTask/Throw.java b/jdk/test/java/util/concurrent/FutureTask/Throw.java index 59d643b6dc4..9e0b453bf30 100644 --- a/jdk/test/java/util/concurrent/FutureTask/Throw.java +++ b/jdk/test/java/util/concurrent/FutureTask/Throw.java @@ -140,8 +140,8 @@ public class Throw { catch (Throwable t) { if (k.isAssignableFrom(t.getClass())) pass(); else unexpected(t);}} - @SuppressWarnings("unchecked") static - void uncheckedThrow(Throwable t) throws T { + @SuppressWarnings("unchecked") + static void uncheckedThrow(Throwable t) throws T { throw (T)t; // rely on vacuous cast } } diff --git a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ThrowingTasks.java b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ThrowingTasks.java index 56a1c9cf551..8a492e715ea 100644 --- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ThrowingTasks.java +++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ThrowingTasks.java @@ -290,8 +290,8 @@ public class ThrowingTasks { try {realMain(args);} catch (Throwable t) {unexpected(t);} System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); if (failed > 0) throw new AssertionError("Some tests failed");} - @SuppressWarnings("unchecked") static - void uncheckedThrow(Throwable t) throws T { + @SuppressWarnings("unchecked") + static void uncheckedThrow(Throwable t) throws T { throw (T)t; // rely on vacuous cast } } diff --git a/jdk/test/java/util/concurrent/locks/Lock/FlakyMutex.java b/jdk/test/java/util/concurrent/locks/Lock/FlakyMutex.java index 913aea78c46..104091e2551 100644 --- a/jdk/test/java/util/concurrent/locks/Lock/FlakyMutex.java +++ b/jdk/test/java/util/concurrent/locks/Lock/FlakyMutex.java @@ -148,8 +148,8 @@ public class FlakyMutex implements Lock { try {realMain(args);} catch (Throwable t) {unexpected(t);} System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); if (failed > 0) throw new AssertionError("Some tests failed");} - @SuppressWarnings("unchecked") static - void uncheckedThrow(Throwable t) throws T { + @SuppressWarnings("unchecked") + static void uncheckedThrow(Throwable t) throws T { throw (T)t; // rely on vacuous cast } } diff --git a/jdk/test/java/util/concurrent/tck/Atomic8Test.java b/jdk/test/java/util/concurrent/tck/Atomic8Test.java index 721f502cdc1..c4a43941c32 100644 --- a/jdk/test/java/util/concurrent/tck/Atomic8Test.java +++ b/jdk/test/java/util/concurrent/tck/Atomic8Test.java @@ -45,6 +45,9 @@ import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; import junit.framework.Test; import junit.framework.TestSuite; +/** + * Tests of atomic class methods accepting lambdas introduced in JDK8. + */ public class Atomic8Test extends JSR166TestCase { public static void main(String[] args) { @@ -54,30 +57,25 @@ public class Atomic8Test extends JSR166TestCase { return new TestSuite(Atomic8Test.class); } - /* - * Tests of atomic class methods accepting lambdas - * introduced in JDK8. - */ - static long addLong17(long x) { return x + 17; } static int addInt17(int x) { return x + 17; } static Integer addInteger17(Integer x) { - return new Integer(x.intValue() + 17); + return x.intValue() + 17; } static Integer sumInteger(Integer x, Integer y) { - return new Integer(x.intValue() + y.intValue()); + return x.intValue() + y.intValue(); } volatile long aLongField; volatile int anIntField; volatile Integer anIntegerField; - AtomicLongFieldUpdater aLongFieldUpdater() { + AtomicLongFieldUpdater aLongFieldUpdater() { return AtomicLongFieldUpdater.newUpdater (Atomic8Test.class, "aLongField"); } - AtomicIntegerFieldUpdater anIntFieldUpdater() { + AtomicIntegerFieldUpdater anIntFieldUpdater() { return AtomicIntegerFieldUpdater.newUpdater (Atomic8Test.class, "anIntField"); } @@ -180,9 +178,9 @@ public class Atomic8Test extends JSR166TestCase { */ public void testReferenceGetAndUpdate() { AtomicReference a = new AtomicReference<>(one); - assertEquals(new Integer(1), a.getAndUpdate(Atomic8Test::addInteger17)); - assertEquals(new Integer(18), a.getAndUpdate(Atomic8Test::addInteger17)); - assertEquals(new Integer(35), a.get()); + assertEquals((Integer) 1, a.getAndUpdate(Atomic8Test::addInteger17)); + assertEquals((Integer) 18, a.getAndUpdate(Atomic8Test::addInteger17)); + assertEquals((Integer) 35, a.get()); } /** @@ -191,9 +189,9 @@ public class Atomic8Test extends JSR166TestCase { */ public void testReferenceUpdateAndGet() { AtomicReference a = new AtomicReference<>(one); - assertEquals(new Integer(18), a.updateAndGet(Atomic8Test::addInteger17)); - assertEquals(new Integer(35), a.updateAndGet(Atomic8Test::addInteger17)); - assertEquals(new Integer(35), a.get()); + assertEquals((Integer) 18, a.updateAndGet(Atomic8Test::addInteger17)); + assertEquals((Integer) 35, a.updateAndGet(Atomic8Test::addInteger17)); + assertEquals((Integer) 35, a.get()); } /** @@ -202,9 +200,9 @@ public class Atomic8Test extends JSR166TestCase { */ public void testReferenceGetAndAccumulate() { AtomicReference a = new AtomicReference<>(one); - assertEquals(new Integer(1), a.getAndAccumulate(2, Atomic8Test::sumInteger)); - assertEquals(new Integer(3), a.getAndAccumulate(3, Atomic8Test::sumInteger)); - assertEquals(new Integer(6), a.get()); + assertEquals((Integer) 1, a.getAndAccumulate(2, Atomic8Test::sumInteger)); + assertEquals((Integer) 3, a.getAndAccumulate(3, Atomic8Test::sumInteger)); + assertEquals((Integer) 6, a.get()); } /** @@ -213,9 +211,9 @@ public class Atomic8Test extends JSR166TestCase { */ public void testReferenceAccumulateAndGet() { AtomicReference a = new AtomicReference<>(one); - assertEquals(new Integer(7), a.accumulateAndGet(6, Atomic8Test::sumInteger)); - assertEquals(new Integer(10), a.accumulateAndGet(3, Atomic8Test::sumInteger)); - assertEquals(new Integer(10), a.get()); + assertEquals((Integer) 7, a.accumulateAndGet(6, Atomic8Test::sumInteger)); + assertEquals((Integer) 10, a.accumulateAndGet(3, Atomic8Test::sumInteger)); + assertEquals((Integer) 10, a.get()); } /** @@ -320,9 +318,9 @@ public class Atomic8Test extends JSR166TestCase { public void testReferenceArrayGetAndUpdate() { AtomicReferenceArray a = new AtomicReferenceArray(1); a.set(0, one); - assertEquals(new Integer(1), a.getAndUpdate(0, Atomic8Test::addInteger17)); - assertEquals(new Integer(18), a.getAndUpdate(0, Atomic8Test::addInteger17)); - assertEquals(new Integer(35), a.get(0)); + assertEquals((Integer) 1, a.getAndUpdate(0, Atomic8Test::addInteger17)); + assertEquals((Integer) 18, a.getAndUpdate(0, Atomic8Test::addInteger17)); + assertEquals((Integer) 35, a.get(0)); } /** @@ -332,8 +330,8 @@ public class Atomic8Test extends JSR166TestCase { public void testReferenceArrayUpdateAndGet() { AtomicReferenceArray a = new AtomicReferenceArray(1); a.set(0, one); - assertEquals(new Integer(18), a.updateAndGet(0, Atomic8Test::addInteger17)); - assertEquals(new Integer(35), a.updateAndGet(0, Atomic8Test::addInteger17)); + assertEquals((Integer) 18, a.updateAndGet(0, Atomic8Test::addInteger17)); + assertEquals((Integer) 35, a.updateAndGet(0, Atomic8Test::addInteger17)); } /** @@ -343,9 +341,9 @@ public class Atomic8Test extends JSR166TestCase { public void testReferenceArrayGetAndAccumulate() { AtomicReferenceArray a = new AtomicReferenceArray(1); a.set(0, one); - assertEquals(new Integer(1), a.getAndAccumulate(0, 2, Atomic8Test::sumInteger)); - assertEquals(new Integer(3), a.getAndAccumulate(0, 3, Atomic8Test::sumInteger)); - assertEquals(new Integer(6), a.get(0)); + assertEquals((Integer) 1, a.getAndAccumulate(0, 2, Atomic8Test::sumInteger)); + assertEquals((Integer) 3, a.getAndAccumulate(0, 3, Atomic8Test::sumInteger)); + assertEquals((Integer) 6, a.get(0)); } /** @@ -355,8 +353,8 @@ public class Atomic8Test extends JSR166TestCase { public void testReferenceArrayAccumulateAndGet() { AtomicReferenceArray a = new AtomicReferenceArray(1); a.set(0, one); - assertEquals(new Integer(7), a.accumulateAndGet(0, 6, Atomic8Test::sumInteger)); - assertEquals(new Integer(10), a.accumulateAndGet(0, 3, Atomic8Test::sumInteger)); + assertEquals((Integer) 7, a.accumulateAndGet(0, 6, Atomic8Test::sumInteger)); + assertEquals((Integer) 10, a.accumulateAndGet(0, 3, Atomic8Test::sumInteger)); } /** @@ -470,10 +468,10 @@ public class Atomic8Test extends JSR166TestCase { public void testReferenceFieldUpdaterGetAndUpdate() { AtomicReferenceFieldUpdater a = anIntegerFieldUpdater(); a.set(this, one); - assertEquals(new Integer(1), a.getAndUpdate(this, Atomic8Test::addInteger17)); - assertEquals(new Integer(18), a.getAndUpdate(this, Atomic8Test::addInteger17)); - assertEquals(new Integer(35), a.get(this)); - assertEquals(new Integer(35), anIntegerField); + assertEquals((Integer) 1, a.getAndUpdate(this, Atomic8Test::addInteger17)); + assertEquals((Integer) 18, a.getAndUpdate(this, Atomic8Test::addInteger17)); + assertEquals((Integer) 35, a.get(this)); + assertEquals((Integer) 35, anIntegerField); } /** @@ -483,10 +481,10 @@ public class Atomic8Test extends JSR166TestCase { public void testReferenceFieldUpdaterUpdateAndGet() { AtomicReferenceFieldUpdater a = anIntegerFieldUpdater(); a.set(this, one); - assertEquals(new Integer(18), a.updateAndGet(this, Atomic8Test::addInteger17)); - assertEquals(new Integer(35), a.updateAndGet(this, Atomic8Test::addInteger17)); - assertEquals(new Integer(35), a.get(this)); - assertEquals(new Integer(35), anIntegerField); + assertEquals((Integer) 18, a.updateAndGet(this, Atomic8Test::addInteger17)); + assertEquals((Integer) 35, a.updateAndGet(this, Atomic8Test::addInteger17)); + assertEquals((Integer) 35, a.get(this)); + assertEquals((Integer) 35, anIntegerField); } /** @@ -496,10 +494,10 @@ public class Atomic8Test extends JSR166TestCase { public void testReferenceFieldUpdaterGetAndAccumulate() { AtomicReferenceFieldUpdater a = anIntegerFieldUpdater(); a.set(this, one); - assertEquals(new Integer(1), a.getAndAccumulate(this, 2, Atomic8Test::sumInteger)); - assertEquals(new Integer(3), a.getAndAccumulate(this, 3, Atomic8Test::sumInteger)); - assertEquals(new Integer(6), a.get(this)); - assertEquals(new Integer(6), anIntegerField); + assertEquals((Integer) 1, a.getAndAccumulate(this, 2, Atomic8Test::sumInteger)); + assertEquals((Integer) 3, a.getAndAccumulate(this, 3, Atomic8Test::sumInteger)); + assertEquals((Integer) 6, a.get(this)); + assertEquals((Integer) 6, anIntegerField); } /** @@ -509,10 +507,10 @@ public class Atomic8Test extends JSR166TestCase { public void testReferenceFieldUpdaterAccumulateAndGet() { AtomicReferenceFieldUpdater a = anIntegerFieldUpdater(); a.set(this, one); - assertEquals(new Integer(7), a.accumulateAndGet(this, 6, Atomic8Test::sumInteger)); - assertEquals(new Integer(10), a.accumulateAndGet(this, 3, Atomic8Test::sumInteger)); - assertEquals(new Integer(10), a.get(this)); - assertEquals(new Integer(10), anIntegerField); + assertEquals((Integer) 7, a.accumulateAndGet(this, 6, Atomic8Test::sumInteger)); + assertEquals((Integer) 10, a.accumulateAndGet(this, 3, Atomic8Test::sumInteger)); + assertEquals((Integer) 10, a.get(this)); + assertEquals((Integer) 10, anIntegerField); } /** @@ -530,9 +528,6 @@ public class Atomic8Test extends JSR166TestCase { () -> aLongFieldUpdater().getAndUpdate(this, null), () -> anIntFieldUpdater().getAndUpdate(this, null), () -> anIntegerFieldUpdater().getAndUpdate(this, null), - ////() -> aLongFieldUpdater().getAndUpdate(null, Atomic8Test::addLong17), - ////() -> anIntFieldUpdater().getAndUpdate(null, Atomic8Test::addInt17), - ////() -> anIntegerFieldUpdater().getAndUpdate(null, Atomic8Test::addInteger17), }; assertThrows(NullPointerException.class, throwingActions); } @@ -593,4 +588,40 @@ public class Atomic8Test extends JSR166TestCase { assertThrows(NullPointerException.class, throwingActions); } + /** + * Object arguments for parameters of type T that are not + * instances of the class passed to the newUpdater call will + * result in a ClassCastException being thrown. + */ + public void testFieldUpdaters_ClassCastException() { + // Use raw types to allow passing wrong object type, provoking CCE + final AtomicLongFieldUpdater longUpdater = aLongFieldUpdater(); + final AtomicIntegerFieldUpdater intUpdater = anIntFieldUpdater(); + final AtomicReferenceFieldUpdater refUpdater = anIntegerFieldUpdater(); + final Object obj = new Object(); + for (Object x : new Object[]{ new Object(), null }) { + Runnable[] throwingActions = { + () -> longUpdater.get(x), + () -> intUpdater.get(x), + () -> refUpdater.get(x), + + () -> longUpdater.set(x, 17L), + () -> intUpdater.set(x, 17), + () -> refUpdater.set(x, (Integer) 17), + + () -> longUpdater.addAndGet(x, 17L), + () -> intUpdater.addAndGet(x, 17), + + () -> longUpdater.getAndUpdate(x, y -> y), + () -> intUpdater.getAndUpdate(x, y -> y), + () -> refUpdater.getAndUpdate(x, y -> y), + + () -> longUpdater.compareAndSet(x, 17L, 42L), + () -> intUpdater.compareAndSet(x, 17, 42), + () -> refUpdater.compareAndSet(x, (Integer) 17, (Integer) 42), + }; + assertThrows(ClassCastException.class, throwingActions); + } + } + } diff --git a/jdk/test/java/util/concurrent/tck/CompletableFutureTest.java b/jdk/test/java/util/concurrent/tck/CompletableFutureTest.java index 12f7ee99b53..bc81edfad81 100644 --- a/jdk/test/java/util/concurrent/tck/CompletableFutureTest.java +++ b/jdk/test/java/util/concurrent/tck/CompletableFutureTest.java @@ -174,26 +174,26 @@ public class CompletableFutureTest extends JSR166TestCase { void checkCompletedWithWrappedCFException(CompletableFuture f) { checkCompletedExceptionally(f, true, - (t) -> assertTrue(t instanceof CFException)); + t -> assertTrue(t instanceof CFException)); } void checkCompletedWithWrappedCancellationException(CompletableFuture f) { checkCompletedExceptionally(f, true, - (t) -> assertTrue(t instanceof CancellationException)); + t -> assertTrue(t instanceof CancellationException)); } void checkCompletedWithTimeoutException(CompletableFuture f) { checkCompletedExceptionally(f, false, - (t) -> assertTrue(t instanceof TimeoutException)); + t -> assertTrue(t instanceof TimeoutException)); } void checkCompletedWithWrappedException(CompletableFuture f, Throwable ex) { - checkCompletedExceptionally(f, true, (t) -> assertSame(t, ex)); + checkCompletedExceptionally(f, true, t -> assertSame(t, ex)); } void checkCompletedExceptionally(CompletableFuture f, Throwable ex) { - checkCompletedExceptionally(f, false, (t) -> assertSame(t, ex)); + checkCompletedExceptionally(f, false, t -> assertSame(t, ex)); } void checkCancelled(CompletableFuture f) { @@ -3284,12 +3284,12 @@ public class CompletableFutureTest extends JSR166TestCase { () -> f.thenApply(null), () -> f.thenApplyAsync(null), - () -> f.thenApplyAsync((x) -> x, null), + () -> f.thenApplyAsync(x -> x, null), () -> f.thenApplyAsync(null, exec), () -> f.thenAccept(null), () -> f.thenAcceptAsync(null), - () -> f.thenAcceptAsync((x) -> {} , null), + () -> f.thenAcceptAsync(x -> {} , null), () -> f.thenAcceptAsync(null, exec), () -> f.thenRun(null), @@ -3324,18 +3324,18 @@ public class CompletableFutureTest extends JSR166TestCase { () -> f.applyToEither(g, null), () -> f.applyToEitherAsync(g, null), () -> f.applyToEitherAsync(g, null, exec), - () -> f.applyToEither(nullFuture, (x) -> x), - () -> f.applyToEitherAsync(nullFuture, (x) -> x), - () -> f.applyToEitherAsync(nullFuture, (x) -> x, exec), - () -> f.applyToEitherAsync(g, (x) -> x, null), + () -> f.applyToEither(nullFuture, x -> x), + () -> f.applyToEitherAsync(nullFuture, x -> x), + () -> f.applyToEitherAsync(nullFuture, x -> x, exec), + () -> f.applyToEitherAsync(g, x -> x, null), () -> f.acceptEither(g, null), () -> f.acceptEitherAsync(g, null), () -> f.acceptEitherAsync(g, null, exec), - () -> f.acceptEither(nullFuture, (x) -> {}), - () -> f.acceptEitherAsync(nullFuture, (x) -> {}), - () -> f.acceptEitherAsync(nullFuture, (x) -> {}, exec), - () -> f.acceptEitherAsync(g, (x) -> {}, null), + () -> f.acceptEither(nullFuture, x -> {}), + () -> f.acceptEitherAsync(nullFuture, x -> {}), + () -> f.acceptEitherAsync(nullFuture, x -> {}, exec), + () -> f.acceptEitherAsync(g, x -> {}, null), () -> f.runAfterEither(g, null), () -> f.runAfterEitherAsync(g, null), @@ -3401,18 +3401,18 @@ public class CompletableFutureTest extends JSR166TestCase { for (CompletableFuture src : srcs) { List> fs = new ArrayList<>(); fs.add(src.thenRunAsync(() -> {}, e)); - fs.add(src.thenAcceptAsync((z) -> {}, e)); - fs.add(src.thenApplyAsync((z) -> z, e)); + fs.add(src.thenAcceptAsync(z -> {}, e)); + fs.add(src.thenApplyAsync(z -> z, e)); fs.add(src.thenCombineAsync(src, (x, y) -> x, e)); fs.add(src.thenAcceptBothAsync(src, (x, y) -> {}, e)); fs.add(src.runAfterBothAsync(src, () -> {}, e)); - fs.add(src.applyToEitherAsync(src, (z) -> z, e)); - fs.add(src.acceptEitherAsync(src, (z) -> {}, e)); + fs.add(src.applyToEitherAsync(src, z -> z, e)); + fs.add(src.acceptEitherAsync(src, z -> {}, e)); fs.add(src.runAfterEitherAsync(src, () -> {}, e)); - fs.add(src.thenComposeAsync((z) -> null, e)); + fs.add(src.thenComposeAsync(z -> null, e)); fs.add(src.whenCompleteAsync((z, t) -> {}, e)); fs.add(src.handleAsync((z, t) -> null, e)); @@ -3445,11 +3445,11 @@ public class CompletableFutureTest extends JSR166TestCase { { List> fs = new ArrayList<>(); - fs.add(complete.applyToEitherAsync(incomplete, (z) -> z, e)); - fs.add(incomplete.applyToEitherAsync(complete, (z) -> z, e)); + fs.add(complete.applyToEitherAsync(incomplete, z -> z, e)); + fs.add(incomplete.applyToEitherAsync(complete, z -> z, e)); - fs.add(complete.acceptEitherAsync(incomplete, (z) -> {}, e)); - fs.add(incomplete.acceptEitherAsync(complete, (z) -> {}, e)); + fs.add(complete.acceptEitherAsync(incomplete, z -> {}, e)); + fs.add(incomplete.acceptEitherAsync(complete, z -> {}, e)); fs.add(complete.runAfterEitherAsync(incomplete, () -> {}, e)); fs.add(incomplete.runAfterEitherAsync(complete, () -> {}, e)); @@ -3488,18 +3488,18 @@ public class CompletableFutureTest extends JSR166TestCase { List> fs = new ArrayList<>(); fs.add(incomplete.thenRunAsync(() -> {}, e)); - fs.add(incomplete.thenAcceptAsync((z) -> {}, e)); - fs.add(incomplete.thenApplyAsync((z) -> z, e)); + fs.add(incomplete.thenAcceptAsync(z -> {}, e)); + fs.add(incomplete.thenApplyAsync(z -> z, e)); fs.add(incomplete.thenCombineAsync(incomplete, (x, y) -> x, e)); fs.add(incomplete.thenAcceptBothAsync(incomplete, (x, y) -> {}, e)); fs.add(incomplete.runAfterBothAsync(incomplete, () -> {}, e)); - fs.add(incomplete.applyToEitherAsync(incomplete, (z) -> z, e)); - fs.add(incomplete.acceptEitherAsync(incomplete, (z) -> {}, e)); + fs.add(incomplete.applyToEitherAsync(incomplete, z -> z, e)); + fs.add(incomplete.acceptEitherAsync(incomplete, z -> {}, e)); fs.add(incomplete.runAfterEitherAsync(incomplete, () -> {}, e)); - fs.add(incomplete.thenComposeAsync((z) -> null, e)); + fs.add(incomplete.thenComposeAsync(z -> null, e)); fs.add(incomplete.whenCompleteAsync((z, t) -> {}, e)); fs.add(incomplete.handleAsync((z, t) -> null, e)); @@ -3720,7 +3720,7 @@ public class CompletableFutureTest extends JSR166TestCase { public void testCompleteAsync2() { CompletableFuture f = new CompletableFuture<>(); CFException ex = new CFException(); - f.completeAsync(() -> {if (true) throw ex; return 1;}); + f.completeAsync(() -> { throw ex; }); try { f.join(); shouldThrow(); @@ -3750,7 +3750,7 @@ public class CompletableFutureTest extends JSR166TestCase { CompletableFuture f = new CompletableFuture<>(); CFException ex = new CFException(); ThreadExecutor executor = new ThreadExecutor(); - f.completeAsync(() -> {if (true) throw ex; return 1;}, executor); + f.completeAsync(() -> { throw ex; }, executor); try { f.join(); shouldThrow(); @@ -3909,31 +3909,31 @@ public class CompletableFutureTest extends JSR166TestCase { List, CompletableFuture>> funs = new ArrayList<>(); - funs.add((y) -> m.thenRun(y, noopRunnable)); - funs.add((y) -> m.thenAccept(y, noopConsumer)); - funs.add((y) -> m.thenApply(y, incFunction)); + funs.add(y -> m.thenRun(y, noopRunnable)); + funs.add(y -> m.thenAccept(y, noopConsumer)); + funs.add(y -> m.thenApply(y, incFunction)); - funs.add((y) -> m.runAfterEither(y, incomplete, noopRunnable)); - funs.add((y) -> m.acceptEither(y, incomplete, noopConsumer)); - funs.add((y) -> m.applyToEither(y, incomplete, incFunction)); + funs.add(y -> m.runAfterEither(y, incomplete, noopRunnable)); + funs.add(y -> m.acceptEither(y, incomplete, noopConsumer)); + funs.add(y -> m.applyToEither(y, incomplete, incFunction)); - funs.add((y) -> m.runAfterBoth(y, v42, noopRunnable)); - funs.add((y) -> m.runAfterBoth(v42, y, noopRunnable)); - funs.add((y) -> m.thenAcceptBoth(y, v42, new SubtractAction(m))); - funs.add((y) -> m.thenAcceptBoth(v42, y, new SubtractAction(m))); - funs.add((y) -> m.thenCombine(y, v42, new SubtractFunction(m))); - funs.add((y) -> m.thenCombine(v42, y, new SubtractFunction(m))); + funs.add(y -> m.runAfterBoth(y, v42, noopRunnable)); + funs.add(y -> m.runAfterBoth(v42, y, noopRunnable)); + funs.add(y -> m.thenAcceptBoth(y, v42, new SubtractAction(m))); + funs.add(y -> m.thenAcceptBoth(v42, y, new SubtractAction(m))); + funs.add(y -> m.thenCombine(y, v42, new SubtractFunction(m))); + funs.add(y -> m.thenCombine(v42, y, new SubtractFunction(m))); - funs.add((y) -> m.whenComplete(y, (Integer r, Throwable t) -> {})); + funs.add(y -> m.whenComplete(y, (Integer r, Throwable t) -> {})); - funs.add((y) -> m.thenCompose(y, new CompletableFutureInc(m))); + funs.add(y -> m.thenCompose(y, new CompletableFutureInc(m))); - funs.add((y) -> CompletableFuture.allOf(y)); - funs.add((y) -> CompletableFuture.allOf(y, v42)); - funs.add((y) -> CompletableFuture.allOf(v42, y)); - funs.add((y) -> CompletableFuture.anyOf(y)); - funs.add((y) -> CompletableFuture.anyOf(y, incomplete)); - funs.add((y) -> CompletableFuture.anyOf(incomplete, y)); + funs.add(y -> CompletableFuture.allOf(y)); + funs.add(y -> CompletableFuture.allOf(y, v42)); + funs.add(y -> CompletableFuture.allOf(v42, y)); + funs.add(y -> CompletableFuture.anyOf(y)); + funs.add(y -> CompletableFuture.anyOf(y, incomplete)); + funs.add(y -> CompletableFuture.anyOf(incomplete, y)); for (Function, CompletableFuture> fun : funs) { @@ -3990,12 +3990,12 @@ public class CompletableFutureTest extends JSR166TestCase { public void testMinimalCompletionStage_minimality() { if (!testImplementationDetails) return; Function toSignature = - (method) -> method.getName() + Arrays.toString(method.getParameterTypes()); + method -> method.getName() + Arrays.toString(method.getParameterTypes()); Predicate isNotStatic = - (method) -> (method.getModifiers() & Modifier.STATIC) == 0; + method -> (method.getModifiers() & Modifier.STATIC) == 0; List minimalMethods = Stream.of(Object.class, CompletionStage.class) - .flatMap((klazz) -> Stream.of(klazz.getMethods())) + .flatMap(klazz -> Stream.of(klazz.getMethods())) .filter(isNotStatic) .collect(Collectors.toList()); // Methods from CompletableFuture permitted NOT to throw UOE @@ -4011,7 +4011,7 @@ public class CompletableFutureTest extends JSR166TestCase { .collect(Collectors.toSet()); List allMethods = Stream.of(CompletableFuture.class.getMethods()) .filter(isNotStatic) - .filter((method) -> !permittedMethodSignatures.contains(toSignature.apply(method))) + .filter(method -> !permittedMethodSignatures.contains(toSignature.apply(method))) .collect(Collectors.toList()); List> stages = new ArrayList<>(); @@ -4171,7 +4171,7 @@ public class CompletableFutureTest extends JSR166TestCase { CompletionStage minimal = f.minimalCompletionStage(); CompletableFuture g = new CompletableFuture<>(); if (!createIncomplete) assertTrue(f.complete(v1)); - minimal.thenAccept((x) -> g.complete(x)); + minimal.thenAccept(x -> g.complete(x)); if (createIncomplete) assertTrue(f.complete(v1)); g.join(); checkCompletedNormally(g, v1); @@ -4195,7 +4195,7 @@ public class CompletableFutureTest extends JSR166TestCase { static Function> compose (Function> f, Function> g) { - return (x) -> f.apply(x).thenCompose(g); + return x -> f.apply(x).thenCompose(g); } static void assertZero(CompletableFuture f) { @@ -4275,9 +4275,9 @@ public class CompletableFutureTest extends JSR166TestCase { // Some mutually non-commutative functions Function> triple - = (x) -> Monad.unit(3 * x); + = x -> Monad.unit(3 * x); Function> inc - = (x) -> Monad.unit(x + 1); + = x -> Monad.unit(x + 1); // unit is a right identity: m >>= unit === m Monad.assertFutureEquals(inc.apply(5L).thenCompose(unit), @@ -4289,7 +4289,7 @@ public class CompletableFutureTest extends JSR166TestCase { // associativity: (m >>= f) >>= g === m >>= ( \x -> (f x >>= g) ) Monad.assertFutureEquals( unit.apply(5L).thenCompose(inc).thenCompose(triple), - unit.apply(5L).thenCompose((x) -> inc.apply(x).thenCompose(triple))); + unit.apply(5L).thenCompose(x -> inc.apply(x).thenCompose(triple))); // The case for CompletableFuture as an additive monad is weaker... @@ -4299,7 +4299,7 @@ public class CompletableFutureTest extends JSR166TestCase { // left zero: zero >>= f === zero Monad.assertZero(zero.thenCompose(inc)); // right zero: f >>= (\x -> zero) === zero - Monad.assertZero(inc.apply(5L).thenCompose((x) -> zero)); + Monad.assertZero(inc.apply(5L).thenCompose(x -> zero)); // f plus zero === f Monad.assertFutureEquals(Monad.unit(5L), @@ -4357,8 +4357,8 @@ public class CompletableFutureTest extends JSR166TestCase { final AtomicInteger count = new AtomicInteger(0); for (int i = 0; i < n; i++) { head.thenRun(() -> count.getAndIncrement()); - head.thenAccept((x) -> count.getAndIncrement()); - head.thenApply((x) -> count.getAndIncrement()); + head.thenAccept(x -> count.getAndIncrement()); + head.thenApply(x -> count.getAndIncrement()); head.runAfterBoth(complete, () -> count.getAndIncrement()); head.thenAcceptBoth(complete, (x, y) -> count.getAndIncrement()); @@ -4368,11 +4368,11 @@ public class CompletableFutureTest extends JSR166TestCase { complete.thenCombine(head, (x, y) -> count.getAndIncrement()); head.runAfterEither(new CompletableFuture(), () -> count.getAndIncrement()); - head.acceptEither(new CompletableFuture(), (x) -> count.getAndIncrement()); - head.applyToEither(new CompletableFuture(), (x) -> count.getAndIncrement()); + head.acceptEither(new CompletableFuture(), x -> count.getAndIncrement()); + head.applyToEither(new CompletableFuture(), x -> count.getAndIncrement()); new CompletableFuture().runAfterEither(head, () -> count.getAndIncrement()); - new CompletableFuture().acceptEither(head, (x) -> count.getAndIncrement()); - new CompletableFuture().applyToEither(head, (x) -> count.getAndIncrement()); + new CompletableFuture().acceptEither(head, x -> count.getAndIncrement()); + new CompletableFuture().applyToEither(head, x -> count.getAndIncrement()); } head.complete(null); assertEquals(5 * 3 * n, count.get()); @@ -4389,11 +4389,11 @@ public class CompletableFutureTest extends JSR166TestCase { f.complete(null); f = new CompletableFuture<>(); - f.acceptEither(incomplete, (x) -> {}); + f.acceptEither(incomplete, x -> {}); f.complete(null); f = new CompletableFuture<>(); - f.applyToEither(incomplete, (x) -> x); + f.applyToEither(incomplete, x -> x); f.complete(null); f = new CompletableFuture<>(); @@ -4407,11 +4407,11 @@ public class CompletableFutureTest extends JSR166TestCase { f.complete(null); f = new CompletableFuture<>(); - incomplete.acceptEither(f, (x) -> {}); + incomplete.acceptEither(f, x -> {}); f.complete(null); f = new CompletableFuture<>(); - incomplete.applyToEither(f, (x) -> x); + incomplete.applyToEither(f, x -> x); f.complete(null); f = new CompletableFuture<>(); diff --git a/jdk/test/java/util/concurrent/tck/ConcurrentHashMap8Test.java b/jdk/test/java/util/concurrent/tck/ConcurrentHashMap8Test.java index fd62ada71cb..00f8dc6bb28 100644 --- a/jdk/test/java/util/concurrent/tck/ConcurrentHashMap8Test.java +++ b/jdk/test/java/util/concurrent/tck/ConcurrentHashMap8Test.java @@ -43,6 +43,8 @@ import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; import java.util.Spliterator; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.LongAdder; import java.util.function.BiFunction; @@ -88,7 +90,7 @@ public class ConcurrentHashMap8Test extends JSR166TestCase { */ public void testComputeIfAbsent() { ConcurrentHashMap map = map5(); - map.computeIfAbsent(six, (x) -> "Z"); + map.computeIfAbsent(six, x -> "Z"); assertTrue(map.containsKey(six)); } @@ -97,7 +99,7 @@ public class ConcurrentHashMap8Test extends JSR166TestCase { */ public void testComputeIfAbsent2() { ConcurrentHashMap map = map5(); - assertEquals("A", map.computeIfAbsent(one, (x) -> "Z")); + assertEquals("A", map.computeIfAbsent(one, x -> "Z")); } /** @@ -105,7 +107,7 @@ public class ConcurrentHashMap8Test extends JSR166TestCase { */ public void testComputeIfAbsent3() { ConcurrentHashMap map = map5(); - map.computeIfAbsent(six, (x) -> null); + map.computeIfAbsent(six, x -> null); assertFalse(map.containsKey(six)); } @@ -1114,4 +1116,30 @@ public class ConcurrentHashMap8Test extends JSR166TestCase { assertNull(r); } + /** + * Tests performance of computeIfAbsent when the element is present. + * See JDK-8161372 + * ant -Djsr166.tckTestClass=ConcurrentHashMapTest -Djsr166.methodFilter=testcomputeIfAbsent_performance -Djsr166.expensiveTests=true tck + */ + public void testcomputeIfAbsent_performance() { + final int mapSize = 20; + final int iterations = expensiveTests ? (1 << 23) : mapSize * 2; + final int threads = expensiveTests ? 10 : 2; + final ConcurrentHashMap map = new ConcurrentHashMap<>(); + for (int i = 0; i < mapSize; i++) + map.put(i, i); + final ExecutorService pool = Executors.newFixedThreadPool(2); + try (PoolCleaner cleaner = cleaner(pool)) { + Runnable r = new CheckedRunnable() { + public void realRun() { + int result = 0; + for (int i = 0; i < iterations; i++) + result += map.computeIfAbsent(i % mapSize, k -> k + k); + if (result == -42) throw new Error(); + }}; + for (int i = 0; i < threads; i++) + pool.execute(r); + } + } + } diff --git a/jdk/test/java/util/concurrent/tck/ConcurrentHashMapTest.java b/jdk/test/java/util/concurrent/tck/ConcurrentHashMapTest.java index 26095ad1bb0..b6e6f72d854 100644 --- a/jdk/test/java/util/concurrent/tck/ConcurrentHashMapTest.java +++ b/jdk/test/java/util/concurrent/tck/ConcurrentHashMapTest.java @@ -864,30 +864,4 @@ public class ConcurrentHashMapTest extends JSR166TestCase { assertEquals(mapSize, map.size()); } - /** - * Tests performance of computeIfAbsent when the element is present. - * See JDK-8161372 - * ant -Djsr166.tckTestClass=ConcurrentHashMapTest -Djsr166.methodFilter=testcomputeIfAbsent_performance -Djsr166.expensiveTests=true tck - */ - public void testcomputeIfAbsent_performance() { - final int mapSize = 20; - final int iterations = expensiveTests ? (1 << 23) : mapSize * 2; - final int threads = expensiveTests ? 10 : 2; - final ConcurrentHashMap map = new ConcurrentHashMap<>(); - for (int i = 0; i < mapSize; i++) - map.put(i, i); - final ExecutorService pool = Executors.newFixedThreadPool(2); - try (PoolCleaner cleaner = cleaner(pool)) { - Runnable r = new CheckedRunnable() { - public void realRun() { - int result = 0; - for (int i = 0; i < iterations; i++) - result += map.computeIfAbsent(i % mapSize, (k) -> k + k); - if (result == -42) throw new Error(); - }}; - for (int i = 0; i < threads; i++) - pool.execute(r); - } - } - } diff --git a/jdk/test/java/util/concurrent/tck/ConcurrentLinkedDequeTest.java b/jdk/test/java/util/concurrent/tck/ConcurrentLinkedDequeTest.java index daab5381529..bf1c055dc7f 100644 --- a/jdk/test/java/util/concurrent/tck/ConcurrentLinkedDequeTest.java +++ b/jdk/test/java/util/concurrent/tck/ConcurrentLinkedDequeTest.java @@ -52,12 +52,20 @@ public class ConcurrentLinkedDequeTest extends JSR166TestCase { } public static Test suite() { - return new TestSuite(ConcurrentLinkedDequeTest.class); + class Implementation implements CollectionImplementation { + public Class klazz() { return ConcurrentLinkedDeque.class; } + public Collection emptyCollection() { return new ConcurrentLinkedDeque(); } + public Object makeElement(int i) { return i; } + public boolean isConcurrent() { return true; } + public boolean permitsNulls() { return false; } + } + return newTestSuite(ConcurrentLinkedDequeTest.class, + CollectionTest.testSuite(new Implementation())); } /** * Returns a new deque of given size containing consecutive - * Integers 0 ... n. + * Integers 0 ... n - 1. */ private ConcurrentLinkedDeque populatedDeque(int n) { ConcurrentLinkedDeque q = new ConcurrentLinkedDeque(); @@ -66,6 +74,8 @@ public class ConcurrentLinkedDequeTest extends JSR166TestCase { assertTrue(q.offer(new Integer(i))); assertFalse(q.isEmpty()); assertEquals(n, q.size()); + assertEquals((Integer) 0, q.peekFirst()); + assertEquals((Integer) (n - 1), q.peekLast()); return q; } diff --git a/jdk/test/java/util/concurrent/tck/ConcurrentLinkedQueueTest.java b/jdk/test/java/util/concurrent/tck/ConcurrentLinkedQueueTest.java index bafaa6581f0..1c3a65bb424 100644 --- a/jdk/test/java/util/concurrent/tck/ConcurrentLinkedQueueTest.java +++ b/jdk/test/java/util/concurrent/tck/ConcurrentLinkedQueueTest.java @@ -50,12 +50,20 @@ public class ConcurrentLinkedQueueTest extends JSR166TestCase { } public static Test suite() { - return new TestSuite(ConcurrentLinkedQueueTest.class); + class Implementation implements CollectionImplementation { + public Class klazz() { return ConcurrentLinkedQueue.class; } + public Collection emptyCollection() { return new ConcurrentLinkedQueue(); } + public Object makeElement(int i) { return i; } + public boolean isConcurrent() { return true; } + public boolean permitsNulls() { return false; } + } + return newTestSuite(ConcurrentLinkedQueueTest.class, + CollectionTest.testSuite(new Implementation())); } /** * Returns a new queue of given size containing consecutive - * Integers 0 ... n. + * Integers 0 ... n - 1. */ private ConcurrentLinkedQueue populatedQueue(int n) { ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(); @@ -64,6 +72,7 @@ public class ConcurrentLinkedQueueTest extends JSR166TestCase { assertTrue(q.offer(new Integer(i))); assertFalse(q.isEmpty()); assertEquals(n, q.size()); + assertEquals((Integer) 0, q.peek()); return q; } diff --git a/jdk/test/java/util/concurrent/tck/ConcurrentSkipListSetTest.java b/jdk/test/java/util/concurrent/tck/ConcurrentSkipListSetTest.java index 28c9f6bd81b..ae91219f622 100644 --- a/jdk/test/java/util/concurrent/tck/ConcurrentSkipListSetTest.java +++ b/jdk/test/java/util/concurrent/tck/ConcurrentSkipListSetTest.java @@ -62,7 +62,7 @@ public class ConcurrentSkipListSetTest extends JSR166TestCase { /** * Returns a new set of given size containing consecutive - * Integers 0 ... n. + * Integers 0 ... n - 1. */ private ConcurrentSkipListSet populatedSet(int n) { ConcurrentSkipListSet q = diff --git a/jdk/test/java/util/concurrent/tck/ConcurrentSkipListSubSetTest.java b/jdk/test/java/util/concurrent/tck/ConcurrentSkipListSubSetTest.java index bad618f3fab..4b299e74b83 100644 --- a/jdk/test/java/util/concurrent/tck/ConcurrentSkipListSubSetTest.java +++ b/jdk/test/java/util/concurrent/tck/ConcurrentSkipListSubSetTest.java @@ -57,7 +57,7 @@ public class ConcurrentSkipListSubSetTest extends JSR166TestCase { /** * Returns a new set of given size containing consecutive - * Integers 0 ... n. + * Integers 0 ... n - 1. */ private NavigableSet populatedSet(int n) { ConcurrentSkipListSet q = diff --git a/jdk/test/java/util/concurrent/tck/ExecutorCompletionService9Test.java b/jdk/test/java/util/concurrent/tck/ExecutorCompletionService9Test.java index d72d7dcc78f..4ca78a09a49 100644 --- a/jdk/test/java/util/concurrent/tck/ExecutorCompletionService9Test.java +++ b/jdk/test/java/util/concurrent/tck/ExecutorCompletionService9Test.java @@ -34,6 +34,7 @@ import java.util.ArrayList; import java.util.Collection; +import java.util.Comparator; import java.util.List; import java.util.Set; import java.util.HashSet; @@ -77,7 +78,7 @@ public class ExecutorCompletionService9Test extends JSR166TestCase { List> futures = new ArrayList<>(n); Integer result = null; try { - solvers.forEach((solver) -> futures.add(cs.submit(solver))); + solvers.forEach(solver -> futures.add(cs.submit(solver))); for (int i = n; i > 0; i--) { try { Integer r = cs.take().get(); @@ -88,17 +89,17 @@ public class ExecutorCompletionService9Test extends JSR166TestCase { } catch (ExecutionException ignore) {} } } finally { - futures.forEach((future) -> future.cancel(true)); + futures.forEach(future -> future.cancel(true)); } if (result != null) use(result); } - HashSet results; + ArrayList results; void use(Integer x) { - if (results == null) results = new HashSet(); + if (results == null) results = new ArrayList(); results.add(x); } @@ -107,6 +108,7 @@ public class ExecutorCompletionService9Test extends JSR166TestCase { */ public void testSolveAll() throws InterruptedException, ExecutionException { + results = null; Set> solvers = Set.of( () -> null, () -> 1, @@ -114,7 +116,8 @@ public class ExecutorCompletionService9Test extends JSR166TestCase { () -> 3, () -> null); solveAll(cachedThreadPool, solvers); - assertEquals(Set.of(1, 2, 3), results); + results.sort(Comparator.naturalOrder()); + assertEquals(List.of(1, 2, 3), results); } /** @@ -122,6 +125,7 @@ public class ExecutorCompletionService9Test extends JSR166TestCase { */ public void testSolveAny() throws InterruptedException { + results = null; Set> solvers = Set.of( () -> { throw new ArithmeticException(); }, () -> null, @@ -129,7 +133,7 @@ public class ExecutorCompletionService9Test extends JSR166TestCase { () -> 2); solveAny(cachedThreadPool, solvers); assertEquals(1, results.size()); - Integer elt = results.iterator().next(); + Integer elt = results.get(0); assertTrue(elt.equals(1) || elt.equals(2)); } diff --git a/jdk/test/java/util/concurrent/tck/LinkedTransferQueueTest.java b/jdk/test/java/util/concurrent/tck/LinkedTransferQueueTest.java index dd57870a306..6abec8a37d5 100644 --- a/jdk/test/java/util/concurrent/tck/LinkedTransferQueueTest.java +++ b/jdk/test/java/util/concurrent/tck/LinkedTransferQueueTest.java @@ -51,14 +51,6 @@ import junit.framework.Test; @SuppressWarnings({"unchecked", "rawtypes"}) public class LinkedTransferQueueTest extends JSR166TestCase { - static class Implementation implements CollectionImplementation { - public Class klazz() { return LinkedTransferQueue.class; } - public Collection emptyCollection() { return new LinkedTransferQueue(); } - public Object makeElement(int i) { return i; } - public boolean isConcurrent() { return true; } - public boolean permitsNulls() { return false; } - } - public static class Generic extends BlockingQueueTest { protected BlockingQueue emptyCollection() { return new LinkedTransferQueue(); @@ -70,6 +62,13 @@ public class LinkedTransferQueueTest extends JSR166TestCase { } public static Test suite() { + class Implementation implements CollectionImplementation { + public Class klazz() { return LinkedTransferQueue.class; } + public Collection emptyCollection() { return new LinkedTransferQueue(); } + public Object makeElement(int i) { return i; } + public boolean isConcurrent() { return true; } + public boolean permitsNulls() { return false; } + } return newTestSuite(LinkedTransferQueueTest.class, new Generic().testSuite(), CollectionTest.testSuite(new Implementation())); diff --git a/jdk/test/java/util/concurrent/tck/PriorityBlockingQueueTest.java b/jdk/test/java/util/concurrent/tck/PriorityBlockingQueueTest.java index 7b22c6ed7b4..088c389b2cc 100644 --- a/jdk/test/java/util/concurrent/tck/PriorityBlockingQueueTest.java +++ b/jdk/test/java/util/concurrent/tck/PriorityBlockingQueueTest.java @@ -69,9 +69,17 @@ public class PriorityBlockingQueueTest extends JSR166TestCase { } public static Test suite() { + class Implementation implements CollectionImplementation { + public Class klazz() { return PriorityBlockingQueue.class; } + public Collection emptyCollection() { return new PriorityBlockingQueue(); } + public Object makeElement(int i) { return i; } + public boolean isConcurrent() { return true; } + public boolean permitsNulls() { return false; } + } return newTestSuite(PriorityBlockingQueueTest.class, new Generic().testSuite(), - new InitialCapacity().testSuite()); + new InitialCapacity().testSuite(), + CollectionTest.testSuite(new Implementation())); } /** Sample Comparator */ @@ -83,7 +91,7 @@ public class PriorityBlockingQueueTest extends JSR166TestCase { /** * Returns a new queue of given size containing consecutive - * Integers 0 ... n. + * Integers 0 ... n - 1. */ private PriorityBlockingQueue populatedQueue(int n) { PriorityBlockingQueue q = @@ -96,6 +104,7 @@ public class PriorityBlockingQueueTest extends JSR166TestCase { assertFalse(q.isEmpty()); assertEquals(Integer.MAX_VALUE, q.remainingCapacity()); assertEquals(n, q.size()); + assertEquals((Integer) 0, q.peek()); return q; } diff --git a/jdk/test/java/util/concurrent/tck/PriorityQueueTest.java b/jdk/test/java/util/concurrent/tck/PriorityQueueTest.java index e16497e2dcc..91e155dd85b 100644 --- a/jdk/test/java/util/concurrent/tck/PriorityQueueTest.java +++ b/jdk/test/java/util/concurrent/tck/PriorityQueueTest.java @@ -49,7 +49,15 @@ public class PriorityQueueTest extends JSR166TestCase { main(suite(), args); } public static Test suite() { - return new TestSuite(PriorityQueueTest.class); + class Implementation implements CollectionImplementation { + public Class klazz() { return PriorityQueue.class; } + public Collection emptyCollection() { return new PriorityQueue(); } + public Object makeElement(int i) { return i; } + public boolean isConcurrent() { return false; } + public boolean permitsNulls() { return false; } + } + return newTestSuite(PriorityQueueTest.class, + CollectionTest.testSuite(new Implementation())); } static class MyReverseComparator implements Comparator { @@ -60,7 +68,7 @@ public class PriorityQueueTest extends JSR166TestCase { /** * Returns a new queue of given size containing consecutive - * Integers 0 ... n. + * Integers 0 ... n - 1. */ private PriorityQueue populatedQueue(int n) { PriorityQueue q = new PriorityQueue(n); @@ -71,6 +79,7 @@ public class PriorityQueueTest extends JSR166TestCase { assertTrue(q.offer(new Integer(i))); assertFalse(q.isEmpty()); assertEquals(n, q.size()); + assertEquals((Integer) 0, q.peek()); return q; } diff --git a/jdk/test/java/util/concurrent/tck/StampedLockTest.java b/jdk/test/java/util/concurrent/tck/StampedLockTest.java index a03be993f88..ea0b8f9892b 100644 --- a/jdk/test/java/util/concurrent/tck/StampedLockTest.java +++ b/jdk/test/java/util/concurrent/tck/StampedLockTest.java @@ -110,12 +110,12 @@ public class StampedLockTest extends JSR166TestCase { List> readLockers() { List> readLockers = new ArrayList<>(); - readLockers.add((sl) -> sl.readLock()); - readLockers.add((sl) -> sl.tryReadLock()); - readLockers.add((sl) -> readLockInterruptiblyUninterrupted(sl)); - readLockers.add((sl) -> tryReadLockUninterrupted(sl, Long.MIN_VALUE, DAYS)); - readLockers.add((sl) -> tryReadLockUninterrupted(sl, 0L, DAYS)); - readLockers.add((sl) -> sl.tryConvertToReadLock(sl.tryOptimisticRead())); + readLockers.add(sl -> sl.readLock()); + readLockers.add(sl -> sl.tryReadLock()); + readLockers.add(sl -> readLockInterruptiblyUninterrupted(sl)); + readLockers.add(sl -> tryReadLockUninterrupted(sl, Long.MIN_VALUE, DAYS)); + readLockers.add(sl -> tryReadLockUninterrupted(sl, 0L, DAYS)); + readLockers.add(sl -> sl.tryConvertToReadLock(sl.tryOptimisticRead())); return readLockers; } @@ -131,12 +131,12 @@ public class StampedLockTest extends JSR166TestCase { List> writeLockers() { List> writeLockers = new ArrayList<>(); - writeLockers.add((sl) -> sl.writeLock()); - writeLockers.add((sl) -> sl.tryWriteLock()); - writeLockers.add((sl) -> writeLockInterruptiblyUninterrupted(sl)); - writeLockers.add((sl) -> tryWriteLockUninterrupted(sl, Long.MIN_VALUE, DAYS)); - writeLockers.add((sl) -> tryWriteLockUninterrupted(sl, 0L, DAYS)); - writeLockers.add((sl) -> sl.tryConvertToWriteLock(sl.tryOptimisticRead())); + writeLockers.add(sl -> sl.writeLock()); + writeLockers.add(sl -> sl.tryWriteLock()); + writeLockers.add(sl -> writeLockInterruptiblyUninterrupted(sl)); + writeLockers.add(sl -> tryWriteLockUninterrupted(sl, Long.MIN_VALUE, DAYS)); + writeLockers.add(sl -> tryWriteLockUninterrupted(sl, 0L, DAYS)); + writeLockers.add(sl -> sl.tryConvertToWriteLock(sl.tryOptimisticRead())); return writeLockers; } diff --git a/jdk/test/java/util/concurrent/tck/SubmissionPublisherTest.java b/jdk/test/java/util/concurrent/tck/SubmissionPublisherTest.java index d72f1af9f5c..9478cf3f86d 100644 --- a/jdk/test/java/util/concurrent/tck/SubmissionPublisherTest.java +++ b/jdk/test/java/util/concurrent/tck/SubmissionPublisherTest.java @@ -963,7 +963,7 @@ public class SubmissionPublisherTest extends JSR166TestCase { AtomicInteger sum = new AtomicInteger(); SubmissionPublisher p = basicPublisher(); CompletableFuture f = - p.consume((Integer x) -> { sum.getAndAdd(x.intValue()); }); + p.consume((Integer x) -> sum.getAndAdd(x.intValue())); int n = 20; for (int i = 1; i <= n; ++i) p.submit(i); diff --git a/jdk/test/java/util/concurrent/tck/ThreadLocalRandom8Test.java b/jdk/test/java/util/concurrent/tck/ThreadLocalRandom8Test.java index c80af6290ec..eef34d34149 100644 --- a/jdk/test/java/util/concurrent/tck/ThreadLocalRandom8Test.java +++ b/jdk/test/java/util/concurrent/tck/ThreadLocalRandom8Test.java @@ -259,4 +259,20 @@ public class ThreadLocalRandom8Test extends JSR166TestCase { assertEquals(size, counter.sum()); } + /** + * A deserialized ThreadLocalRandom is always identical to + * ThreadLocalRandom.current() + */ + public void testSerialization() { + assertSame( + ThreadLocalRandom.current(), + serialClone(ThreadLocalRandom.current())); + // In the current implementation, there is exactly one shared instance + if (testImplementationDetails) + assertSame( + ThreadLocalRandom.current(), + java.util.concurrent.CompletableFuture.supplyAsync( + () -> serialClone(ThreadLocalRandom.current())).join()); + } + } diff --git a/jdk/test/java/util/concurrent/tck/ThreadLocalRandomTest.java b/jdk/test/java/util/concurrent/tck/ThreadLocalRandomTest.java index da50bbe2495..394bc464142 100644 --- a/jdk/test/java/util/concurrent/tck/ThreadLocalRandomTest.java +++ b/jdk/test/java/util/concurrent/tck/ThreadLocalRandomTest.java @@ -78,6 +78,41 @@ public class ThreadLocalRandomTest extends JSR166TestCase { } catch (UnsupportedOperationException success) {} } + /** + * Repeated calls to next (only accessible via reflection) produce + * at least two distinct results, and repeated calls produce all + * possible values. + */ + public void testNext() throws ReflectiveOperationException { + ThreadLocalRandom rnd = ThreadLocalRandom.current(); + try { + java.lang.reflect.Method m + = ThreadLocalRandom.class.getDeclaredMethod( + "next", new Class[] { int.class }); + m.setAccessible(true); + + int i; + { + int val = new java.util.Random().nextInt(4); + for (i = 0; i < NCALLS; i++) { + int q = (int) m.invoke(rnd, new Object[] { 2 }); + if (val == q) break; + } + assertTrue(i < NCALLS); + } + + { + int r = (int) m.invoke(rnd, new Object[] { 3 }); + for (i = 0; i < NCALLS; i++) { + int q = (int) m.invoke(rnd, new Object[] { 3 }); + assertTrue(q < (1<<3)); + if (r != q) break; + } + assertTrue(i < NCALLS); + } + } catch (SecurityException acceptable) {} + } + /** * Repeated calls to nextInt produce at least two distinct results */ diff --git a/jdk/test/java/util/concurrent/tck/TreeSetTest.java b/jdk/test/java/util/concurrent/tck/TreeSetTest.java index dc5b007b0d3..af37e4c0550 100644 --- a/jdk/test/java/util/concurrent/tck/TreeSetTest.java +++ b/jdk/test/java/util/concurrent/tck/TreeSetTest.java @@ -67,7 +67,7 @@ public class TreeSetTest extends JSR166TestCase { /** * Returns a new set of given size containing consecutive - * Integers 0 ... n. + * Integers 0 ... n - 1. */ private TreeSet populatedSet(int n) { TreeSet q = new TreeSet(); diff --git a/jdk/test/java/util/concurrent/tck/TreeSubSetTest.java b/jdk/test/java/util/concurrent/tck/TreeSubSetTest.java index afc0604075d..b8cc70ae83d 100644 --- a/jdk/test/java/util/concurrent/tck/TreeSubSetTest.java +++ b/jdk/test/java/util/concurrent/tck/TreeSubSetTest.java @@ -58,7 +58,7 @@ public class TreeSubSetTest extends JSR166TestCase { /** * Returns a new set of given size containing consecutive - * Integers 0 ... n. + * Integers 0 ... n - 1. */ private NavigableSet populatedSet(int n) { TreeSet q = new TreeSet();