# HG changeset patch # User dl # Date 1568484712 25200 # Sat Sep 14 11:11:52 2019 -0700 # Node ID 39667b7907c964b3534659cb39eddd0694fe6176 # Parent e81db54dfaaf98594963ce5025e3d08084728403 8225490: Miscellaneous changes imported from jsr166 CVS 2019-09 Reviewed-by: martin, alanb diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -385,7 +385,7 @@ * cases where old nodes can be reused because their next fields * won't change. On average, only about one-sixth of them need * cloning when a table doubles. The nodes they replace will be - * garbage collectable as soon as they are no longer referenced by + * garbage collectible as soon as they are no longer referenced by * any reader thread that may be in the midst of concurrently * traversing table. Upon transfer, the old table bin contains * only a special forwarding node (with hash field "MOVED") that @@ -3286,9 +3286,8 @@ return true; } - private static final Unsafe U = Unsafe.getUnsafe(); private static final long LOCKSTATE - = U.objectFieldOffset(TreeBin.class, "lockState"); + = U.objectFieldOffset(TreeBin.class, "lockState"); } /* ----------------Table Traversal -------------- */ @@ -6345,28 +6344,20 @@ // Unsafe mechanics private static final Unsafe U = Unsafe.getUnsafe(); - private static final long SIZECTL; - private static final long TRANSFERINDEX; - private static final long BASECOUNT; - private static final long CELLSBUSY; - private static final long CELLVALUE; - private static final int ABASE; + private static final long SIZECTL + = U.objectFieldOffset(ConcurrentHashMap.class, "sizeCtl"); + private static final long TRANSFERINDEX + = U.objectFieldOffset(ConcurrentHashMap.class, "transferIndex"); + private static final long BASECOUNT + = U.objectFieldOffset(ConcurrentHashMap.class, "baseCount"); + private static final long CELLSBUSY + = U.objectFieldOffset(ConcurrentHashMap.class, "cellsBusy"); + private static final long CELLVALUE + = U.objectFieldOffset(CounterCell.class, "value"); + private static final int ABASE = U.arrayBaseOffset(Node[].class); private static final int ASHIFT; static { - SIZECTL = U.objectFieldOffset - (ConcurrentHashMap.class, "sizeCtl"); - TRANSFERINDEX = U.objectFieldOffset - (ConcurrentHashMap.class, "transferIndex"); - BASECOUNT = U.objectFieldOffset - (ConcurrentHashMap.class, "baseCount"); - CELLSBUSY = U.objectFieldOffset - (ConcurrentHashMap.class, "cellsBusy"); - - CELLVALUE = U.objectFieldOffset - (CounterCell.class, "value"); - - ABASE = U.arrayBaseOffset(Node[].class); int scale = U.arrayIndexScale(Node[].class); if ((scale & (scale - 1)) != 0) throw new ExceptionInInitializerError("array index scale not a power of two"); diff --git a/src/java.base/share/classes/java/util/concurrent/Phaser.java b/src/java.base/share/classes/java/util/concurrent/Phaser.java --- a/src/java.base/share/classes/java/util/concurrent/Phaser.java +++ b/src/java.base/share/classes/java/util/concurrent/Phaser.java @@ -97,7 +97,7 @@ * associated recovery within handlers of those exceptions, * often after invoking {@code forceTermination}. Phasers may * also be used by tasks executing in a {@link ForkJoinPool}. - * Progress is ensured if the pool's parallelismLevel can + * Progress is ensured if the pool's parallelism level can * accommodate the maximum number of simultaneously blocked * parties. * diff --git a/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java b/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java --- a/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java +++ b/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java @@ -1053,18 +1053,18 @@ // Unsafe mechanics private static final Unsafe U = Unsafe.getUnsafe(); - private static final long SEED = U.objectFieldOffset - (Thread.class, "threadLocalRandomSeed"); - private static final long PROBE = U.objectFieldOffset - (Thread.class, "threadLocalRandomProbe"); - private static final long SECONDARY = U.objectFieldOffset - (Thread.class, "threadLocalRandomSecondarySeed"); - private static final long THREADLOCALS = U.objectFieldOffset - (Thread.class, "threadLocals"); - private static final long INHERITABLETHREADLOCALS = U.objectFieldOffset - (Thread.class, "inheritableThreadLocals"); - private static final long INHERITEDACCESSCONTROLCONTEXT = U.objectFieldOffset - (Thread.class, "inheritedAccessControlContext"); + private static final long SEED + = U.objectFieldOffset(Thread.class, "threadLocalRandomSeed"); + private static final long PROBE + = U.objectFieldOffset(Thread.class, "threadLocalRandomProbe"); + private static final long SECONDARY + = U.objectFieldOffset(Thread.class, "threadLocalRandomSecondarySeed"); + private static final long THREADLOCALS + = U.objectFieldOffset(Thread.class, "threadLocals"); + private static final long INHERITABLETHREADLOCALS + = U.objectFieldOffset(Thread.class, "inheritableThreadLocals"); + private static final long INHERITEDACCESSCONTROLCONTEXT + = U.objectFieldOffset(Thread.class, "inheritedAccessControlContext"); /** Rarely-used holder for the second of a pair of Gaussians */ private static final ThreadLocal nextLocalGaussian = diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java @@ -38,6 +38,7 @@ import java.lang.invoke.VarHandle; import java.util.function.IntBinaryOperator; import java.util.function.IntUnaryOperator; +import jdk.internal.misc.Unsafe; /** * An {@code int} value that may be updated atomically. See the @@ -58,8 +59,9 @@ * This class intended to be implemented using VarHandles, but there * are unresolved cyclic startup dependencies. */ - private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe(); - private static final long VALUE = U.objectFieldOffset(AtomicInteger.class, "value"); + private static final Unsafe U = Unsafe.getUnsafe(); + private static final long VALUE + = U.objectFieldOffset(AtomicInteger.class, "value"); private volatile int value; diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java @@ -38,6 +38,7 @@ import java.lang.invoke.VarHandle; import java.util.function.LongBinaryOperator; import java.util.function.LongUnaryOperator; +import jdk.internal.misc.Unsafe; /** * A {@code long} value that may be updated atomically. See the @@ -72,8 +73,9 @@ * This class intended to be implemented using VarHandles, but there * are unresolved cyclic startup dependencies. */ - private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe(); - private static final long VALUE = U.objectFieldOffset(AtomicLong.class, "value"); + private static final Unsafe U = Unsafe.getUnsafe(); + private static final long VALUE + = U.objectFieldOffset(AtomicLong.class, "value"); private volatile long value; diff --git a/src/java.base/share/classes/java/util/concurrent/package-info.java b/src/java.base/share/classes/java/util/concurrent/package-info.java --- a/src/java.base/share/classes/java/util/concurrent/package-info.java +++ b/src/java.base/share/classes/java/util/concurrent/package-info.java @@ -226,9 +226,8 @@ * *

Memory Consistency Properties

* - * * Chapter 17 of - * The Java™ Language Specification defines the + * The Java™ Language Specification defines the * happens-before relation on memory operations such as reads and * writes of shared variables. The results of a write by one thread are * guaranteed to be visible to a read by another thread only if the write @@ -302,6 +301,8 @@ * * * + * @jls 17.4.5 Happens-before Order + * * @since 1.5 */ package java.util.concurrent; diff --git a/test/jdk/java/util/Map/Get.java b/test/jdk/java/util/Map/Get.java --- a/test/jdk/java/util/Map/Get.java +++ b/test/jdk/java/util/Map/Get.java @@ -120,8 +120,8 @@ //--------------------- Infrastructure --------------------------- static volatile int passed = 0, failed = 0; static void pass() { passed++; } - static void fail() { failed++; (new Error("Failure")).printStackTrace(System.err); } - static void fail(String msg) { failed++; (new Error("Failure: " + msg)).printStackTrace(System.err); } + static void fail() { failed++; new Error("Failure").printStackTrace(System.err); } + static void fail(String msg) { failed++; new Error("Failure: " + msg).printStackTrace(System.err); } static void unexpected(String msg, Throwable t) { System.err.println("Unexpected: " + msg); unexpected(t); } static void unexpected(Throwable t) { failed++; t.printStackTrace(System.err); } static void check(boolean cond) { if (cond) pass(); else fail(); } diff --git a/test/jdk/java/util/concurrent/BlockingQueue/OfferDrainToLoops.java b/test/jdk/java/util/concurrent/BlockingQueue/OfferDrainToLoops.java --- a/test/jdk/java/util/concurrent/BlockingQueue/OfferDrainToLoops.java +++ b/test/jdk/java/util/concurrent/BlockingQueue/OfferDrainToLoops.java @@ -34,6 +34,7 @@ /* * @test * @bug 6805775 6815766 + * @library /test/lib * @run main OfferDrainToLoops 100 * @summary Test concurrent offer vs. drainTo */ @@ -47,10 +48,12 @@ import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedTransferQueue; import java.util.concurrent.atomic.AtomicLong; +import jdk.test.lib.Utils; @SuppressWarnings({"unchecked", "rawtypes", "deprecation"}) public class OfferDrainToLoops { - final long testDurationMillisDefault = 10L * 1000L; + static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000); + final long testDurationMillisDefault = 10_000L; final long testDurationMillis; OfferDrainToLoops(String[] args) { @@ -76,7 +79,6 @@ System.out.println(q.getClass().getSimpleName()); final long testDurationNanos = testDurationMillis * 1000L * 1000L; final long quittingTimeNanos = System.nanoTime() + testDurationNanos; - final long timeoutMillis = 10L * 1000L; final SplittableRandom rnd = new SplittableRandom(); // Poor man's bounded buffer. @@ -155,13 +157,13 @@ }}}; for (Thread thread : new Thread[] { offerer, drainer, scanner }) { - thread.join(timeoutMillis + testDurationMillis); + thread.join(LONG_DELAY_MS + testDurationMillis); if (thread.isAlive()) { System.err.printf("Hung thread: %s%n", thread.getName()); failed++; for (StackTraceElement e : thread.getStackTrace()) System.err.println(e); - thread.join(timeoutMillis); + thread.join(LONG_DELAY_MS); } } } diff --git a/test/jdk/java/util/concurrent/ConcurrentHashMap/MapCheck.java b/test/jdk/java/util/concurrent/ConcurrentHashMap/MapCheck.java --- a/test/jdk/java/util/concurrent/ConcurrentHashMap/MapCheck.java +++ b/test/jdk/java/util/concurrent/ConcurrentHashMap/MapCheck.java @@ -537,7 +537,7 @@ static void printStats() { for (Iterator it = accum.entrySet().iterator(); it.hasNext(); ) { Map.Entry e = (Map.Entry)(it.next()); - Stats stats = ((Stats)(e.getValue())); + Stats stats = (Stats)(e.getValue()); int n = stats.number; double t; if (n > 0) diff --git a/test/jdk/java/util/concurrent/ConcurrentHashMap/MapLoops.java b/test/jdk/java/util/concurrent/ConcurrentHashMap/MapLoops.java --- a/test/jdk/java/util/concurrent/ConcurrentHashMap/MapLoops.java +++ b/test/jdk/java/util/concurrent/ConcurrentHashMap/MapLoops.java @@ -99,8 +99,8 @@ nops = Integer.parseInt(args[5]); // normalize probabilities wrt random number generator - removesPerMaxRandom = (int)(((double)premove/100.0 * 0x7FFFFFFFL)); - insertsPerMaxRandom = (int)(((double)pinsert/100.0 * 0x7FFFFFFFL)); + removesPerMaxRandom = (int)((double)premove/100.0 * 0x7FFFFFFFL); + insertsPerMaxRandom = (int)((double)pinsert/100.0 * 0x7FFFFFFFL); System.out.print("Class: " + mapClass.getName()); System.out.print(" threads: " + maxThreads); @@ -172,7 +172,7 @@ long time = timer.getTime(); long tpo = time / (i * (long)nops); System.out.print(LoopHelpers.rightJustify(tpo) + " ns per op"); - double secs = (double)(time) / 1000000000.0; + double secs = (double)time / 1000000000.0; System.out.println("\t " + secs + "s run time"); map.clear(); } diff --git a/test/jdk/java/util/concurrent/ConcurrentHashMap/ToArray.java b/test/jdk/java/util/concurrent/ConcurrentHashMap/ToArray.java --- a/test/jdk/java/util/concurrent/ConcurrentHashMap/ToArray.java +++ b/test/jdk/java/util/concurrent/ConcurrentHashMap/ToArray.java @@ -24,37 +24,40 @@ /* * @test * @bug 4486658 8010293 - * @summary thread safety of toArray methods of subCollections + * @summary thread safety of toArray methods of collection views * @author Martin Buchholz */ +import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.Collectors; import java.util.stream.IntStream; public class ToArray { public static void main(String[] args) throws Throwable { - // Execute a number of times to increase the probability of - // failure if there is an issue - for (int i = 0; i < 16; i++) { + final int runsPerTest = Integer.getInteger("jsr166.runsPerTest", 1); + final int reps = 10 * runsPerTest; + for (int i = reps; i--> 0; ) executeTest(); - } } static void executeTest() throws Throwable { - final Throwable[] throwable = new Throwable[1]; final ConcurrentHashMap m = new ConcurrentHashMap<>(); - - // Number of workers equal to the number of processors - // Each worker will put globally unique keys into the map - final int nWorkers = Runtime.getRuntime().availableProcessors(); + final ThreadLocalRandom rnd = ThreadLocalRandom.current(); + final int nCPU = Runtime.getRuntime().availableProcessors(); + final int minWorkers = 2; + final int maxWorkers = Math.max(minWorkers, Math.min(32, nCPU)); + final int nWorkers = rnd.nextInt(minWorkers, maxWorkers + 1); final int sizePerWorker = 1024; final int maxSize = nWorkers * sizePerWorker; - // The foreman keeps checking that the size of the arrays - // obtained from the key and value sets is never less than the - // previously observed size and is never greater than the maximum size + // The foreman busy-checks that the size of the arrays obtained + // from the keys and values views grows monotonically until it + // reaches the maximum size. + // NOTE: these size constraints are not specific to toArray and are // applicable to any form of traversal of the collection views CompletableFuture foreman = CompletableFuture.runAsync(new Runnable() { @@ -62,44 +65,37 @@ private boolean checkProgress(Object[] a) { int size = a.length; - if (size < prevSize) throw new RuntimeException("WRONG WAY"); - if (size > maxSize) throw new RuntimeException("OVERSHOOT"); - if (size == maxSize) return true; + if (size < prevSize || size > maxSize) + throw new AssertionError( + String.format("prevSize=%d size=%d maxSize=%d", + prevSize, size, maxSize)); prevSize = size; - return false; + return size == maxSize; } - @Override public void run() { - try { - Integer[] empty = new Integer[0]; - while (true) { - if (checkProgress(m.values().toArray())) return; - if (checkProgress(m.keySet().toArray())) return; - if (checkProgress(m.values().toArray(empty))) return; - if (checkProgress(m.keySet().toArray(empty))) return; - } - } - catch (Throwable t) { - throwable[0] = t; - } + Integer[] empty = new Integer[0]; + for (;;) + if (checkProgress(m.values().toArray()) + & checkProgress(m.keySet().toArray()) + & checkProgress(m.values().toArray(empty)) + & checkProgress(m.keySet().toArray(empty))) + return; } }); - // Create workers - // Each worker will put globally unique keys into the map - CompletableFuture[] workers = IntStream.range(0, nWorkers). - mapToObj(w -> CompletableFuture.runAsync(() -> { - for (int i = 0, o = w * sizePerWorker; i < sizePerWorker; i++) - m.put(o + i, i); - })). - toArray(CompletableFuture[]::new); + // Each worker puts globally unique keys into the map + List> workers = + IntStream.range(0, nWorkers) + .mapToObj(w -> (Runnable) () -> { + for (int i = 0, o = w * sizePerWorker; i < sizePerWorker; i++) + m.put(o + i, i); + }) + .map(CompletableFuture::runAsync) + .collect(Collectors.toList()); - // Wait for workers and then foreman to complete - CompletableFuture.allOf(workers).join(); + // Wait for workers and foreman to complete + workers.forEach(CompletableFuture::join); foreman.join(); - - if (throwable[0] != null) - throw throwable[0]; } } diff --git a/test/jdk/java/util/concurrent/ConcurrentQueues/OfferRemoveLoops.java b/test/jdk/java/util/concurrent/ConcurrentQueues/OfferRemoveLoops.java --- a/test/jdk/java/util/concurrent/ConcurrentQueues/OfferRemoveLoops.java +++ b/test/jdk/java/util/concurrent/ConcurrentQueues/OfferRemoveLoops.java @@ -25,7 +25,8 @@ * @test * @bug 6316155 6595669 6871697 6868712 * @summary Test concurrent offer vs. remove - * @run main OfferRemoveLoops 300 + * @library /test/lib + * @run main OfferRemoveLoops 100 * @author Martin Buchholz */ @@ -43,10 +44,12 @@ import java.util.concurrent.LinkedTransferQueue; import java.util.concurrent.PriorityBlockingQueue; import java.util.concurrent.Semaphore; +import jdk.test.lib.Utils; @SuppressWarnings({"unchecked", "rawtypes", "deprecation"}) public class OfferRemoveLoops { - final long testDurationMillisDefault = 10L * 1000L; + static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000); + final long testDurationMillisDefault = 10_000L; final long testDurationMillis; OfferRemoveLoops(String[] args) { @@ -75,7 +78,6 @@ System.err.println(q.getClass().getSimpleName()); final long testDurationNanos = testDurationMillis * 1000L * 1000L; final long quittingTimeNanos = System.nanoTime() + testDurationNanos; - final long timeoutMillis = 10L * 1000L; final int maxChunkSize = 1042; final int maxQueueSize = 10 * maxChunkSize; final CountDownLatch done = new CountDownLatch(3); @@ -156,7 +158,7 @@ done.countDown(); }}; - if (! done.await(timeoutMillis + testDurationMillis, MILLISECONDS)) { + if (! done.await(LONG_DELAY_MS + testDurationMillis, MILLISECONDS)) { for (Thread thread : new Thread[] { offerer, remover, scanner }) { if (thread.isAlive()) { System.err.printf("Hung thread: %s%n", thread.getName()); diff --git a/test/jdk/java/util/concurrent/FutureTask/BlockingTaskExecutor.java b/test/jdk/java/util/concurrent/FutureTask/BlockingTaskExecutor.java --- a/test/jdk/java/util/concurrent/FutureTask/BlockingTaskExecutor.java +++ b/test/jdk/java/util/concurrent/FutureTask/BlockingTaskExecutor.java @@ -103,7 +103,7 @@ */ static class NotificationReceiver { /** Has the notifiee been notified? */ - boolean notified = false; + boolean notified; /** * Notify the notification receiver. diff --git a/test/jdk/java/util/concurrent/FutureTask/CancelledFutureLoops.java b/test/jdk/java/util/concurrent/FutureTask/CancelledFutureLoops.java --- a/test/jdk/java/util/concurrent/FutureTask/CancelledFutureLoops.java +++ b/test/jdk/java/util/concurrent/FutureTask/CancelledFutureLoops.java @@ -130,7 +130,7 @@ long endTime = System.nanoTime(); long time = endTime - timer.startTime; if (print) { - double secs = (double)(time) / 1000000000.0; + double secs = (double)time / 1000000000.0; System.out.println("\t " + secs + "s run time"); } diff --git a/test/jdk/java/util/concurrent/FutureTask/DoneTimedGetLoops.java b/test/jdk/java/util/concurrent/FutureTask/DoneTimedGetLoops.java --- a/test/jdk/java/util/concurrent/FutureTask/DoneTimedGetLoops.java +++ b/test/jdk/java/util/concurrent/FutureTask/DoneTimedGetLoops.java @@ -33,6 +33,7 @@ /* * @test + * @library /test/lib * @run main DoneTimedGetLoops 300 * @summary isDone returning true guarantees that subsequent timed get * will never throw TimeoutException. @@ -42,10 +43,12 @@ import java.util.concurrent.FutureTask; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; +import jdk.test.lib.Utils; @SuppressWarnings({"unchecked", "rawtypes", "deprecation"}) public class DoneTimedGetLoops { - final long testDurationMillisDefault = 10L * 1000L; + static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000); + final long testDurationMillisDefault = 10_000L; final long testDurationMillis; static class PublicFutureTask extends FutureTask { @@ -63,7 +66,6 @@ void test(String[] args) throws Throwable { final long testDurationNanos = testDurationMillis * 1000L * 1000L; final long quittingTimeNanos = System.nanoTime() + testDurationNanos; - final long timeoutMillis = 10L * 1000L; final AtomicReference normalRef = new AtomicReference<>(); @@ -136,13 +138,13 @@ setterException, doneTimedGetNormal, doneTimedGetAbnormal }) { - thread.join(timeoutMillis + testDurationMillis); + thread.join(LONG_DELAY_MS + testDurationMillis); if (thread.isAlive()) { System.err.printf("Hung thread: %s%n", thread.getName()); failed++; for (StackTraceElement e : thread.getStackTrace()) System.err.println(e); - thread.join(timeoutMillis); + thread.join(LONG_DELAY_MS); } } } diff --git a/test/jdk/java/util/concurrent/Phaser/FickleRegister.java b/test/jdk/java/util/concurrent/Phaser/FickleRegister.java --- a/test/jdk/java/util/concurrent/Phaser/FickleRegister.java +++ b/test/jdk/java/util/concurrent/Phaser/FickleRegister.java @@ -43,7 +43,7 @@ public class FickleRegister { final AtomicLong count = new AtomicLong(0); - final long testDurationMillisDefault = 10L * 1000L; + final long testDurationMillisDefault = 10_000L; final long testDurationMillis; final long quittingTimeNanos; final int chunkSize = 1000; diff --git a/test/jdk/java/util/concurrent/Phaser/TieredArriveLoops.java b/test/jdk/java/util/concurrent/Phaser/TieredArriveLoops.java --- a/test/jdk/java/util/concurrent/Phaser/TieredArriveLoops.java +++ b/test/jdk/java/util/concurrent/Phaser/TieredArriveLoops.java @@ -40,7 +40,7 @@ import java.util.concurrent.Phaser; public class TieredArriveLoops { - final long testDurationMillisDefault = 10L * 1000L; + final long testDurationMillisDefault = 10_000L; final long testDurationMillis; final long quittingTimeNanos; diff --git a/test/jdk/java/util/concurrent/ScheduledThreadPoolExecutor/GCRetention.java b/test/jdk/java/util/concurrent/ScheduledThreadPoolExecutor/GCRetention.java --- a/test/jdk/java/util/concurrent/ScheduledThreadPoolExecutor/GCRetention.java +++ b/test/jdk/java/util/concurrent/ScheduledThreadPoolExecutor/GCRetention.java @@ -86,7 +86,7 @@ if (q.remove(1000) != null) break; System.out.printf( - "%d/%d unqueued references remaining%n", j, n); + "%d/%d unqueued references remaining%n", j + 1, n); } } } diff --git a/test/jdk/java/util/concurrent/TimeUnit/Basic.java b/test/jdk/java/util/concurrent/TimeUnit/Basic.java --- a/test/jdk/java/util/concurrent/TimeUnit/Basic.java +++ b/test/jdk/java/util/concurrent/TimeUnit/Basic.java @@ -24,6 +24,7 @@ /* @test * @bug 5057341 6363898 * @summary Basic tests for TimeUnit + * @library /test/lib * @author Martin Buchholz */ @@ -39,12 +40,20 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.util.List; import java.io.ObjectOutputStream; import java.io.ObjectInputStream; import java.util.Arrays; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import jdk.test.lib.Utils; public class Basic { + static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000); + private static void realMain(String[] args) throws Throwable { for (TimeUnit u : TimeUnit.values()) { @@ -71,18 +80,33 @@ equal(1000L, MILLISECONDS.toMicros(1)); equal(1000L, MICROSECONDS.toNanos(1)); - long t0 = System.nanoTime(); - MILLISECONDS.sleep(3); /* See windows bug 6313903, might not sleep */ - long elapsedMillis = (System.nanoTime() - t0)/(1000L * 1000L); - System.out.printf("elapsed=%d%n", elapsedMillis); - check(elapsedMillis >= 0); - /* Might not sleep on windows: check(elapsedMillis >= 3); */ - check(elapsedMillis < 1000); + //---------------------------------------------------------------- + // TimeUnit.sleep sleeps for at least the specified time. + // TimeUnit.sleep(x, unit) for x <= 0 does not sleep at all. + //---------------------------------------------------------------- + ThreadLocalRandom rnd = ThreadLocalRandom.current(); + int maxTimeoutMillis = rnd.nextInt(1, 12); + List> workers = + IntStream.range(-1, maxTimeoutMillis + 1) + .mapToObj(timeoutMillis -> (Runnable) () -> { + try { + long startTime = System.nanoTime(); + MILLISECONDS.sleep(timeoutMillis); + long elapsedNanos = System.nanoTime() - startTime; + long timeoutNanos = MILLISECONDS.toNanos(timeoutMillis); + check(elapsedNanos >= timeoutNanos); + } catch (InterruptedException fail) { + throw new AssertionError(fail); + }}) + .map(CompletableFuture::runAsync) + .collect(Collectors.toList()); + + workers.forEach(CompletableFuture::join); //---------------------------------------------------------------- // Tests for serialized form compatibility with previous release //---------------------------------------------------------------- - byte[] serializedForm = /* Generated using tiger */ + byte[] serializedForm = /* Generated using JDK 5 */ {-84, -19, 0, 5, '~', 'r', 0, 29, 'j', 'a', 'v', 'a', '.', 'u', 't', 'i', 'l', '.', 'c', 'o', 'n', 'c', 'u', 'r', 'r', 'e', 'n', 't', '.', 'T', 'i', 'm', 'e', 'U', 'n', 'i', 't', 0, 0, diff --git a/test/jdk/java/util/concurrent/atomic/DoubleAdderDemo.java b/test/jdk/java/util/concurrent/atomic/DoubleAdderDemo.java --- a/test/jdk/java/util/concurrent/atomic/DoubleAdderDemo.java +++ b/test/jdk/java/util/concurrent/atomic/DoubleAdderDemo.java @@ -103,8 +103,8 @@ long total = (long)nthreads * incs; if (sum != (double)total) throw new Error(sum + " != " + total); - double secs = (double)time / (1000L * 1000 * 1000); - long rate = total * (1000L) / time; + double secs = (double)time / 1000_000_000L; + long rate = total * 1000L / time; System.out.printf("threads:%3d Time: %7.3fsec Incs per microsec: %4d\n", nthreads, secs, rate); } diff --git a/test/jdk/java/util/concurrent/tck/AbstractQueuedLongSynchronizerTest.java b/test/jdk/java/util/concurrent/tck/AbstractQueuedLongSynchronizerTest.java --- a/test/jdk/java/util/concurrent/tck/AbstractQueuedLongSynchronizerTest.java +++ b/test/jdk/java/util/concurrent/tck/AbstractQueuedLongSynchronizerTest.java @@ -39,7 +39,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.HashSet; -import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.AbstractQueuedLongSynchronizer; import java.util.concurrent.locks.AbstractQueuedLongSynchronizer.ConditionObject; @@ -1286,19 +1286,31 @@ /** * Tests scenario for * JDK-8191937: Lost interrupt in AbstractQueuedSynchronizer when tryAcquire methods throw + * ant -Djsr166.tckTestClass=AbstractQueuedLongSynchronizerTest -Djsr166.methodFilter=testInterruptedFailingAcquire -Djsr166.runsPerTest=10000 tck */ - public void testInterruptedFailingAcquire() throws InterruptedException { - final RuntimeException ex = new RuntimeException(); + public void testInterruptedFailingAcquire() throws Throwable { + class PleaseThrow extends RuntimeException {} + final PleaseThrow ex = new PleaseThrow(); + final AtomicBoolean thrown = new AtomicBoolean(); // A synchronizer only offering a choice of failure modes class Sync extends AbstractQueuedLongSynchronizer { - boolean pleaseThrow; + volatile boolean pleaseThrow; + void maybeThrow() { + if (pleaseThrow) { + // assert: tryAcquire methods can throw at most once + if (! thrown.compareAndSet(false, true)) + throw new AssertionError(); + throw ex; + } + } + @Override protected boolean tryAcquire(long ignored) { - if (pleaseThrow) throw ex; + maybeThrow(); return false; } @Override protected long tryAcquireShared(long ignored) { - if (pleaseThrow) throw ex; + maybeThrow(); return -1; } @Override protected boolean tryRelease(long ignored) { @@ -1310,30 +1322,87 @@ } final Sync s = new Sync(); + final boolean acquireInterruptibly = randomBoolean(); + final Action[] uninterruptibleAcquireActions = { + () -> s.acquire(1), + () -> s.acquireShared(1), + }; + final long nanosTimeout = MILLISECONDS.toNanos(2 * LONG_DELAY_MS); + final Action[] interruptibleAcquireActions = { + () -> s.acquireInterruptibly(1), + () -> s.acquireSharedInterruptibly(1), + () -> s.tryAcquireNanos(1, nanosTimeout), + () -> s.tryAcquireSharedNanos(1, nanosTimeout), + }; + final Action[] releaseActions = { + () -> s.release(1), + () -> s.releaseShared(1), + }; + final Action acquireAction = acquireInterruptibly + ? chooseRandomly(interruptibleAcquireActions) + : chooseRandomly(uninterruptibleAcquireActions); + final Action releaseAction + = chooseRandomly(releaseActions); + // From os_posix.cpp: + // + // NOTE that since there is no "lock" around the interrupt and + // is_interrupted operations, there is the possibility that the + // interrupted flag (in osThread) will be "false" but that the + // low-level events will be in the signaled state. This is + // intentional. The effect of this is that Object.wait() and + // LockSupport.park() will appear to have a spurious wakeup, which + // is allowed and not harmful, and the possibility is so rare that + // it is not worth the added complexity to add yet another lock. final Thread thread = newStartedThread(new CheckedRunnable() { - public void realRun() { + public void realRun() throws Throwable { try { - if (ThreadLocalRandom.current().nextBoolean()) - s.acquire(1); - else - s.acquireShared(1); + acquireAction.run(); shouldThrow(); - } catch (Throwable t) { - assertSame(ex, t); - assertTrue(Thread.interrupted()); + } catch (InterruptedException possible) { + assertTrue(acquireInterruptibly); + assertFalse(Thread.interrupted()); + } catch (PleaseThrow possible) { + awaitInterrupted(); } }}); - waitForThreadToEnterWaitState(thread); - assertSame(thread, s.getFirstQueuedThread()); - assertTrue(s.hasQueuedPredecessors()); - assertTrue(s.hasQueuedThreads()); - assertEquals(1, s.getQueueLength()); + for (long startTime = 0L;; ) { + waitForThreadToEnterWaitState(thread); + if (s.getFirstQueuedThread() == thread + && s.hasQueuedPredecessors() + && s.hasQueuedThreads() + && s.getQueueLength() == 1 + && s.hasContended()) + break; + if (startTime == 0L) + startTime = System.nanoTime(); + else if (millisElapsedSince(startTime) > LONG_DELAY_MS) + fail("timed out waiting for AQS state: " + + "thread state=" + thread.getState() + + ", queued threads=" + s.getQueuedThreads()); + Thread.yield(); + } s.pleaseThrow = true; - thread.interrupt(); - s.release(1); + // release and interrupt, in random order + if (randomBoolean()) { + thread.interrupt(); + releaseAction.run(); + } else { + releaseAction.run(); + thread.interrupt(); + } awaitTermination(thread); + + if (! acquireInterruptibly) + assertTrue(thrown.get()); + + assertNull(s.getFirstQueuedThread()); + assertFalse(s.hasQueuedPredecessors()); + assertFalse(s.hasQueuedThreads()); + assertEquals(0, s.getQueueLength()); + assertTrue(s.getQueuedThreads().isEmpty()); + assertTrue(s.hasContended()); } } diff --git a/test/jdk/java/util/concurrent/tck/AbstractQueuedSynchronizerTest.java b/test/jdk/java/util/concurrent/tck/AbstractQueuedSynchronizerTest.java --- a/test/jdk/java/util/concurrent/tck/AbstractQueuedSynchronizerTest.java +++ b/test/jdk/java/util/concurrent/tck/AbstractQueuedSynchronizerTest.java @@ -40,7 +40,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.HashSet; -import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.AbstractQueuedSynchronizer; import java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject; @@ -1337,19 +1337,31 @@ /** * Tests scenario for * JDK-8191937: Lost interrupt in AbstractQueuedSynchronizer when tryAcquire methods throw + * ant -Djsr166.tckTestClass=AbstractQueuedSynchronizerTest -Djsr166.methodFilter=testInterruptedFailingAcquire -Djsr166.runsPerTest=10000 tck */ - public void testInterruptedFailingAcquire() throws InterruptedException { - final RuntimeException ex = new RuntimeException(); + public void testInterruptedFailingAcquire() throws Throwable { + class PleaseThrow extends RuntimeException {} + final PleaseThrow ex = new PleaseThrow(); + final AtomicBoolean thrown = new AtomicBoolean(); // A synchronizer only offering a choice of failure modes class Sync extends AbstractQueuedSynchronizer { - boolean pleaseThrow; + volatile boolean pleaseThrow; + void maybeThrow() { + if (pleaseThrow) { + // assert: tryAcquire methods can throw at most once + if (! thrown.compareAndSet(false, true)) + throw new AssertionError(); + throw ex; + } + } + @Override protected boolean tryAcquire(int ignored) { - if (pleaseThrow) throw ex; + maybeThrow(); return false; } @Override protected int tryAcquireShared(int ignored) { - if (pleaseThrow) throw ex; + maybeThrow(); return -1; } @Override protected boolean tryRelease(int ignored) { @@ -1361,30 +1373,87 @@ } final Sync s = new Sync(); + final boolean acquireInterruptibly = randomBoolean(); + final Action[] uninterruptibleAcquireActions = { + () -> s.acquire(1), + () -> s.acquireShared(1), + }; + final long nanosTimeout = MILLISECONDS.toNanos(2 * LONG_DELAY_MS); + final Action[] interruptibleAcquireActions = { + () -> s.acquireInterruptibly(1), + () -> s.acquireSharedInterruptibly(1), + () -> s.tryAcquireNanos(1, nanosTimeout), + () -> s.tryAcquireSharedNanos(1, nanosTimeout), + }; + final Action[] releaseActions = { + () -> s.release(1), + () -> s.releaseShared(1), + }; + final Action acquireAction = acquireInterruptibly + ? chooseRandomly(interruptibleAcquireActions) + : chooseRandomly(uninterruptibleAcquireActions); + final Action releaseAction + = chooseRandomly(releaseActions); + // From os_posix.cpp: + // + // NOTE that since there is no "lock" around the interrupt and + // is_interrupted operations, there is the possibility that the + // interrupted flag (in osThread) will be "false" but that the + // low-level events will be in the signaled state. This is + // intentional. The effect of this is that Object.wait() and + // LockSupport.park() will appear to have a spurious wakeup, which + // is allowed and not harmful, and the possibility is so rare that + // it is not worth the added complexity to add yet another lock. final Thread thread = newStartedThread(new CheckedRunnable() { - public void realRun() { + public void realRun() throws Throwable { try { - if (ThreadLocalRandom.current().nextBoolean()) - s.acquire(1); - else - s.acquireShared(1); + acquireAction.run(); shouldThrow(); - } catch (Throwable t) { - assertSame(ex, t); - assertTrue(Thread.interrupted()); + } catch (InterruptedException possible) { + assertTrue(acquireInterruptibly); + assertFalse(Thread.interrupted()); + } catch (PleaseThrow possible) { + awaitInterrupted(); } }}); - waitForThreadToEnterWaitState(thread); - assertSame(thread, s.getFirstQueuedThread()); - assertTrue(s.hasQueuedPredecessors()); - assertTrue(s.hasQueuedThreads()); - assertEquals(1, s.getQueueLength()); + for (long startTime = 0L;; ) { + waitForThreadToEnterWaitState(thread); + if (s.getFirstQueuedThread() == thread + && s.hasQueuedPredecessors() + && s.hasQueuedThreads() + && s.getQueueLength() == 1 + && s.hasContended()) + break; + if (startTime == 0L) + startTime = System.nanoTime(); + else if (millisElapsedSince(startTime) > LONG_DELAY_MS) + fail("timed out waiting for AQS state: " + + "thread state=" + thread.getState() + + ", queued threads=" + s.getQueuedThreads()); + Thread.yield(); + } s.pleaseThrow = true; - thread.interrupt(); - s.release(1); + // release and interrupt, in random order + if (randomBoolean()) { + thread.interrupt(); + releaseAction.run(); + } else { + releaseAction.run(); + thread.interrupt(); + } awaitTermination(thread); + + if (! acquireInterruptibly) + assertTrue(thrown.get()); + + assertNull(s.getFirstQueuedThread()); + assertFalse(s.hasQueuedPredecessors()); + assertFalse(s.hasQueuedThreads()); + assertEquals(0, s.getQueueLength()); + assertTrue(s.getQueuedThreads().isEmpty()); + assertTrue(s.hasContended()); } } diff --git a/test/jdk/java/util/concurrent/tck/ArrayBlockingQueueTest.java b/test/jdk/java/util/concurrent/tck/ArrayBlockingQueueTest.java --- a/test/jdk/java/util/concurrent/tck/ArrayBlockingQueueTest.java +++ b/test/jdk/java/util/concurrent/tck/ArrayBlockingQueueTest.java @@ -61,7 +61,7 @@ class Implementation implements CollectionImplementation { public Class klazz() { return ArrayBlockingQueue.class; } public Collection emptyCollection() { - boolean fair = ThreadLocalRandom.current().nextBoolean(); + boolean fair = randomBoolean(); return populatedQueue(0, SIZE, 2 * SIZE, fair); } public Object makeElement(int i) { return i; } @@ -367,7 +367,7 @@ }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); t.interrupt(); awaitTermination(t); assertEquals(SIZE, q.size()); @@ -409,7 +409,7 @@ assertEquals(0, q.take()); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); t.interrupt(); awaitTermination(t); assertEquals(0, q.remainingCapacity()); @@ -431,21 +431,21 @@ Thread.currentThread().interrupt(); try { - q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS); + q.offer(new Object(), randomTimeout(), randomTimeUnit()); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); pleaseInterrupt.countDown(); try { - q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS); + q.offer(new Object(), LONGER_DELAY_MS, MILLISECONDS); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.TIMED_WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); t.interrupt(); awaitTermination(t); } @@ -486,7 +486,7 @@ }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); t.interrupt(); awaitTermination(t); } @@ -539,29 +539,26 @@ final CountDownLatch pleaseInterrupt = new CountDownLatch(1); Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { - long startTime = System.nanoTime(); for (int i = 0; i < SIZE; i++) assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS)); Thread.currentThread().interrupt(); try { - q.poll(LONG_DELAY_MS, MILLISECONDS); + q.poll(randomTimeout(), randomTimeUnit()); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); pleaseInterrupt.countDown(); try { - q.poll(LONG_DELAY_MS, MILLISECONDS); + q.poll(LONGER_DELAY_MS, MILLISECONDS); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); - - assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.TIMED_WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); t.interrupt(); awaitTermination(t); checkEmpty(q); diff --git a/test/jdk/java/util/concurrent/tck/BlockingQueueTest.java b/test/jdk/java/util/concurrent/tck/BlockingQueueTest.java --- a/test/jdk/java/util/concurrent/tck/BlockingQueueTest.java +++ b/test/jdk/java/util/concurrent/tck/BlockingQueueTest.java @@ -253,7 +253,7 @@ Thread.currentThread().interrupt(); try { - q.poll(LONG_DELAY_MS, MILLISECONDS); + q.poll(randomTimeout(), randomTimeUnit()); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); @@ -274,7 +274,7 @@ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); barrier.await(); - assertThreadBlocks(t, Thread.State.TIMED_WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); t.interrupt(); awaitTermination(t); } @@ -296,7 +296,7 @@ }}); await(threadStarted); - assertThreadBlocks(t, Thread.State.WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); t.interrupt(); awaitTermination(t); } @@ -325,19 +325,19 @@ */ public void testTimedPollFromEmptyBlocksInterruptibly() { final BlockingQueue q = emptyCollection(); - final CountDownLatch threadStarted = new CountDownLatch(1); + final CountDownLatch pleaseInterrupt = new CountDownLatch(1); Thread t = newStartedThread(new CheckedRunnable() { public void realRun() { - threadStarted.countDown(); + pleaseInterrupt.countDown(); try { - q.poll(2 * LONG_DELAY_MS, MILLISECONDS); + q.poll(LONGER_DELAY_MS, MILLISECONDS); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); }}); - await(threadStarted); - assertThreadBlocks(t, Thread.State.TIMED_WAITING); + await(pleaseInterrupt); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); t.interrupt(); awaitTermination(t); } @@ -352,7 +352,7 @@ public void realRun() { Thread.currentThread().interrupt(); try { - q.poll(2 * LONG_DELAY_MS, MILLISECONDS); + q.poll(LONGER_DELAY_MS, MILLISECONDS); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); diff --git a/test/jdk/java/util/concurrent/tck/ConcurrentLinkedDequeTest.java b/test/jdk/java/util/concurrent/tck/ConcurrentLinkedDequeTest.java --- a/test/jdk/java/util/concurrent/tck/ConcurrentLinkedDequeTest.java +++ b/test/jdk/java/util/concurrent/tck/ConcurrentLinkedDequeTest.java @@ -940,7 +940,7 @@ } void runAsync(Runnable r1, Runnable r2) { - boolean b = ThreadLocalRandom.current().nextBoolean(); + boolean b = randomBoolean(); CompletableFuture f1 = CompletableFuture.runAsync(b ? r1 : r2); CompletableFuture f2 = CompletableFuture.runAsync(b ? r2 : r1); f1.join(); @@ -1003,10 +1003,6 @@ } } - T chooseRandomly(T... choices) { - return choices[ThreadLocalRandom.current().nextInt(choices.length)]; - } - /** * Non-traversing Deque operations (that return null) are linearizable. * Don't return null when the deque is observably never empty. diff --git a/test/jdk/java/util/concurrent/tck/CountDownLatchTest.java b/test/jdk/java/util/concurrent/tck/CountDownLatchTest.java --- a/test/jdk/java/util/concurrent/tck/CountDownLatchTest.java +++ b/test/jdk/java/util/concurrent/tck/CountDownLatchTest.java @@ -36,6 +36,7 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ThreadLocalRandom; import junit.framework.Test; import junit.framework.TestSuite; @@ -99,7 +100,7 @@ assertEquals(2, l.getCount()); l.countDown(); assertEquals(1, l.getCount()); - assertThreadBlocks(t, Thread.State.WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); l.countDown(); assertEquals(0, l.getCount()); awaitTermination(t); @@ -124,7 +125,7 @@ assertEquals(2, l.getCount()); l.countDown(); assertEquals(1, l.getCount()); - assertThreadBlocks(t, Thread.State.TIMED_WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); l.countDown(); assertEquals(0, l.getCount()); awaitTermination(t); @@ -156,7 +157,7 @@ }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); t.interrupt(); awaitTermination(t); } @@ -165,29 +166,30 @@ * timed await throws InterruptedException if interrupted before counted down */ public void testTimedAwait_Interruptible() { - final CountDownLatch l = new CountDownLatch(1); + final int initialCount = ThreadLocalRandom.current().nextInt(1, 3); + final CountDownLatch l = new CountDownLatch(initialCount); final CountDownLatch pleaseInterrupt = new CountDownLatch(1); Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { Thread.currentThread().interrupt(); try { - l.await(LONG_DELAY_MS, MILLISECONDS); + l.await(randomTimeout(), randomTimeUnit()); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); pleaseInterrupt.countDown(); try { - l.await(LONG_DELAY_MS, MILLISECONDS); + l.await(LONGER_DELAY_MS, MILLISECONDS); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); - assertEquals(1, l.getCount()); + assertEquals(initialCount, l.getCount()); }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.TIMED_WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); t.interrupt(); awaitTermination(t); } @@ -200,7 +202,11 @@ Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { assertEquals(1, l.getCount()); + + long startTime = System.nanoTime(); assertFalse(l.await(timeoutMillis(), MILLISECONDS)); + assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); + assertEquals(1, l.getCount()); }}); diff --git a/test/jdk/java/util/concurrent/tck/CyclicBarrierTest.java b/test/jdk/java/util/concurrent/tck/CyclicBarrierTest.java --- a/test/jdk/java/util/concurrent/tck/CyclicBarrierTest.java +++ b/test/jdk/java/util/concurrent/tck/CyclicBarrierTest.java @@ -42,7 +42,6 @@ import java.util.concurrent.Executors; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import junit.framework.Test; @@ -323,34 +322,6 @@ } /** - * All threads block while a barrier is broken. - */ - public void testReset_Leakage() throws InterruptedException { - final CyclicBarrier c = new CyclicBarrier(2); - final AtomicBoolean done = new AtomicBoolean(); - Thread t = newStartedThread(new CheckedRunnable() { - public void realRun() { - while (!done.get()) { - try { - while (c.isBroken()) - c.reset(); - - c.await(); - shouldThrow(); - } - catch (BrokenBarrierException | InterruptedException ok) {} - }}}); - - for (int i = 0; i < 4; i++) { - delay(timeoutMillis()); - t.interrupt(); - } - done.set(true); - t.interrupt(); - awaitTermination(t); - } - - /** * Reset of a non-broken barrier does not break barrier */ public void testResetWithoutBreakage() throws Exception { @@ -505,7 +476,7 @@ final ExecutorService e = Executors.newFixedThreadPool(nTasks); final Runnable awaiter = () -> { try { - if (ThreadLocalRandom.current().nextBoolean()) + if (randomBoolean()) barrier.await(); else barrier.await(LONG_DELAY_MS, MILLISECONDS); diff --git a/test/jdk/java/util/concurrent/tck/DelayQueueTest.java b/test/jdk/java/util/concurrent/tck/DelayQueueTest.java --- a/test/jdk/java/util/concurrent/tck/DelayQueueTest.java +++ b/test/jdk/java/util/concurrent/tck/DelayQueueTest.java @@ -332,7 +332,7 @@ } /** - * timed offer does not time out + * Queue is unbounded, so timed offer never times out */ public void testTimedOffer() throws InterruptedException { final DelayQueue q = new DelayQueue(); @@ -384,7 +384,7 @@ }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); t.interrupt(); awaitTermination(t); } @@ -436,30 +436,27 @@ final DelayQueue q = populatedQueue(SIZE); Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { - long startTime = System.nanoTime(); for (int i = 0; i < SIZE; i++) assertEquals(new PDelay(i), ((PDelay)q.poll(LONG_DELAY_MS, MILLISECONDS))); Thread.currentThread().interrupt(); try { - q.poll(LONG_DELAY_MS, MILLISECONDS); + q.poll(randomTimeout(), randomTimeUnit()); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); pleaseInterrupt.countDown(); try { - q.poll(LONG_DELAY_MS, MILLISECONDS); + q.poll(LONGER_DELAY_MS, MILLISECONDS); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); - - assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.TIMED_WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); t.interrupt(); awaitTermination(t); checkEmpty(q); diff --git a/test/jdk/java/util/concurrent/tck/DoubleAccumulatorTest.java b/test/jdk/java/util/concurrent/tck/DoubleAccumulatorTest.java --- a/test/jdk/java/util/concurrent/tck/DoubleAccumulatorTest.java +++ b/test/jdk/java/util/concurrent/tck/DoubleAccumulatorTest.java @@ -156,7 +156,7 @@ = new DoubleAccumulator((x, y) -> x + y, 0.0); final int nThreads = ThreadLocalRandom.current().nextInt(1, 5); final Phaser phaser = new Phaser(nThreads + 1); - final int incs = 1_000_000; + final int incs = expensiveTests ? 1_000_000 : 100_000; final double total = nThreads * incs/2.0 * (incs - 1); // Gauss final Runnable task = () -> { phaser.arriveAndAwaitAdvance(); diff --git a/test/jdk/java/util/concurrent/tck/ForkJoinPool9Test.java b/test/jdk/java/util/concurrent/tck/ForkJoinPool9Test.java --- a/test/jdk/java/util/concurrent/tck/ForkJoinPool9Test.java +++ b/test/jdk/java/util/concurrent/tck/ForkJoinPool9Test.java @@ -38,7 +38,6 @@ import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinTask; import java.util.concurrent.Future; -import java.util.concurrent.ThreadLocalRandom; import java.util.stream.Stream; import junit.framework.Test; @@ -81,7 +80,7 @@ Thread currentThread = Thread.currentThread(); Stream.of(systemClassLoader, null).forEach(cl -> { - if (ThreadLocalRandom.current().nextBoolean()) + if (randomBoolean()) // should always be permitted, without effect currentThread.setContextClassLoader(cl); }); diff --git a/test/jdk/java/util/concurrent/tck/FutureTaskTest.java b/test/jdk/java/util/concurrent/tck/FutureTaskTest.java --- a/test/jdk/java/util/concurrent/tck/FutureTaskTest.java +++ b/test/jdk/java/util/concurrent/tck/FutureTaskTest.java @@ -747,7 +747,7 @@ /** * get is interruptible */ - public void testGet_interruptible() { + public void testGet_Interruptible() { final CountDownLatch pleaseInterrupt = new CountDownLatch(1); final FutureTask task = new FutureTask(new NoOpCallable()); Thread t = newStartedThread(new CheckedRunnable() { @@ -776,27 +776,28 @@ /** * timed get is interruptible */ - public void testTimedGet_interruptible() { + public void testTimedGet_Interruptible() { final CountDownLatch pleaseInterrupt = new CountDownLatch(1); final FutureTask task = new FutureTask(new NoOpCallable()); Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws Exception { Thread.currentThread().interrupt(); try { - task.get(2*LONG_DELAY_MS, MILLISECONDS); + task.get(randomTimeout(), randomTimeUnit()); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); pleaseInterrupt.countDown(); try { - task.get(2*LONG_DELAY_MS, MILLISECONDS); + task.get(LONGER_DELAY_MS, MILLISECONDS); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); }}); await(pleaseInterrupt); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); t.interrupt(); awaitTermination(t); checkNotDone(task); diff --git a/test/jdk/java/util/concurrent/tck/JSR166TestCase.java b/test/jdk/java/util/concurrent/tck/JSR166TestCase.java --- a/test/jdk/java/util/concurrent/tck/JSR166TestCase.java +++ b/test/jdk/java/util/concurrent/tck/JSR166TestCase.java @@ -311,12 +311,13 @@ static volatile TestCase currentTestCase; // static volatile int currentRun = 0; static { - Runnable checkForWedgedTest = new Runnable() { public void run() { + Runnable wedgedTestDetector = new Runnable() { public void run() { // Avoid spurious reports with enormous runsPerTest. // A single test case run should never take more than 1 second. // But let's cap it at the high end too ... - final int timeoutMinutes = - Math.min(15, Math.max(runsPerTest / 60, 1)); + final int timeoutMinutesMin = Math.max(runsPerTest / 60, 1) + * Math.max((int) delayFactor, 1); + final int timeoutMinutes = Math.min(15, timeoutMinutesMin); for (TestCase lastTestCase = currentTestCase;;) { try { MINUTES.sleep(timeoutMinutes); } catch (InterruptedException unexpected) { break; } @@ -336,7 +337,7 @@ } lastTestCase = currentTestCase; }}}; - Thread thread = new Thread(checkForWedgedTest, "checkForWedgedTest"); + Thread thread = new Thread(wedgedTestDetector, "WedgedTestDetector"); thread.setDaemon(true); thread.start(); } @@ -380,7 +381,7 @@ // Never report first run of any test; treat it as a // warmup run, notably to trigger all needed classloading, if (i > 0) - System.out.printf("%n%s: %d%n", toString(), elapsedMillis); + System.out.printf("%s: %d%n", toString(), elapsedMillis); } } @@ -683,6 +684,12 @@ public static long MEDIUM_DELAY_MS; public static long LONG_DELAY_MS; + /** + * A delay significantly longer than LONG_DELAY_MS. + * Use this in a thread that is waited for via awaitTermination(Thread). + */ + public static long LONGER_DELAY_MS; + private static final long RANDOM_TIMEOUT; private static final long RANDOM_EXPIRED_TIMEOUT; private static final TimeUnit RANDOM_TIMEUNIT; @@ -711,6 +718,20 @@ static TimeUnit randomTimeUnit() { return RANDOM_TIMEUNIT; } /** + * Returns a random boolean; a "coin flip". + */ + static boolean randomBoolean() { + return ThreadLocalRandom.current().nextBoolean(); + } + + /** + * Returns a random element from given choices. + */ + T chooseRandomly(T... choices) { + return choices[ThreadLocalRandom.current().nextInt(choices.length)]; + } + + /** * Returns the shortest timed delay. This can be scaled up for * slow machines using the jsr166.delay.factor system property, * or via jtreg's -timeoutFactor: flag. @@ -728,6 +749,7 @@ SMALL_DELAY_MS = SHORT_DELAY_MS * 5; MEDIUM_DELAY_MS = SHORT_DELAY_MS * 10; LONG_DELAY_MS = SHORT_DELAY_MS * 200; + LONGER_DELAY_MS = 2 * LONG_DELAY_MS; } private static final long TIMEOUT_DELAY_MS @@ -766,8 +788,8 @@ */ public void threadRecordFailure(Throwable t) { System.err.println(t); - dumpTestThreads(); - threadFailure.compareAndSet(null, t); + if (threadFailure.compareAndSet(null, t)) + dumpTestThreads(); } public void setUp() { @@ -1088,6 +1110,39 @@ } } + /** Returns true if thread info might be useful in a thread dump. */ + static boolean threadOfInterest(ThreadInfo info) { + final String name = info.getThreadName(); + String lockName; + if (name == null) + return true; + if (name.equals("Signal Dispatcher") + || name.equals("WedgedTestDetector")) + return false; + if (name.equals("Reference Handler")) { + // Reference Handler stacktrace changed in JDK-8156500 + StackTraceElement[] stackTrace; String methodName; + if ((stackTrace = info.getStackTrace()) != null + && stackTrace.length > 0 + && (methodName = stackTrace[0].getMethodName()) != null + && methodName.equals("waitForReferencePendingList")) + return false; + // jdk8 Reference Handler stacktrace + if ((lockName = info.getLockName()) != null + && lockName.startsWith("java.lang.ref")) + return false; + } + if ((name.equals("Finalizer") || name.equals("Common-Cleaner")) + && (lockName = info.getLockName()) != null + && lockName.startsWith("java.lang.ref")) + return false; + if (name.startsWith("ForkJoinPool.commonPool-worker") + && (lockName = info.getLockName()) != null + && lockName.startsWith("java.util.concurrent.ForkJoinPool")) + return false; + return true; + } + /** * A debugging tool to print stack traces of most threads, as jstack does. * Uninteresting threads are filtered out. @@ -1104,23 +1159,9 @@ ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); System.err.println("------ stacktrace dump start ------"); - for (ThreadInfo info : threadMXBean.dumpAllThreads(true, true)) { - final String name = info.getThreadName(); - String lockName; - if ("Signal Dispatcher".equals(name)) - continue; - if ("Reference Handler".equals(name) - && (lockName = info.getLockName()) != null - && lockName.startsWith("java.lang.ref.Reference$Lock")) - continue; - if ("Finalizer".equals(name) - && (lockName = info.getLockName()) != null - && lockName.startsWith("java.lang.ref.ReferenceQueue$Lock")) - continue; - if ("checkForWedgedTest".equals(name)) - continue; - System.err.print(info); - } + for (ThreadInfo info : threadMXBean.dumpAllThreads(true, true)) + if (threadOfInterest(info)) + System.err.print(info); System.err.println("------ stacktrace dump end ------"); if (sm != null) System.setSecurityManager(sm); @@ -1393,6 +1434,20 @@ } /** + * Spin-waits up to LONG_DELAY_MS milliseconds for the current thread to + * be interrupted. Clears the interrupt status before returning. + */ + void awaitInterrupted() { + for (long startTime = 0L; !Thread.interrupted(); ) { + if (startTime == 0L) + startTime = System.nanoTime(); + else if (millisElapsedSince(startTime) > LONG_DELAY_MS) + fail("timed out waiting for thread interrupt"); + Thread.yield(); + } + } + + /** * Returns the number of milliseconds since time given by * startNanoTime, which must have been previously returned from a * call to {@link System#nanoTime()}. @@ -1401,19 +1456,6 @@ return NANOSECONDS.toMillis(System.nanoTime() - startNanoTime); } -// void assertTerminatesPromptly(long timeoutMillis, Runnable r) { -// long startTime = System.nanoTime(); -// try { -// r.run(); -// } catch (Throwable fail) { threadUnexpectedException(fail); } -// if (millisElapsedSince(startTime) > timeoutMillis/2) -// throw new AssertionError("did not return promptly"); -// } - -// void assertTerminatesPromptly(Runnable r) { -// assertTerminatesPromptly(LONG_DELAY_MS/2, r); -// } - /** * Checks that timed f.get() returns the expected value, and does not * wait for the timeout to elapse before returning. @@ -1448,15 +1490,21 @@ * to terminate (using {@link Thread#join(long)}), else interrupts * the thread (in the hope that it may terminate later) and fails. */ - void awaitTermination(Thread t, long timeoutMillis) { + void awaitTermination(Thread thread, long timeoutMillis) { try { - t.join(timeoutMillis); + thread.join(timeoutMillis); } catch (InterruptedException fail) { threadUnexpectedException(fail); - } finally { - if (t.getState() != Thread.State.TERMINATED) { - t.interrupt(); - threadFail("timed out waiting for thread to terminate"); + } + if (thread.getState() != Thread.State.TERMINATED) { + String detail = String.format( + "timed out waiting for thread to terminate, thread=%s, state=%s" , + thread, thread.getState()); + try { + threadFail(detail); + } finally { + // Interrupt thread __after__ having reported its stack trace + thread.interrupt(); } } } diff --git a/test/jdk/java/util/concurrent/tck/LinkedBlockingDequeTest.java b/test/jdk/java/util/concurrent/tck/LinkedBlockingDequeTest.java --- a/test/jdk/java/util/concurrent/tck/LinkedBlockingDequeTest.java +++ b/test/jdk/java/util/concurrent/tck/LinkedBlockingDequeTest.java @@ -631,7 +631,7 @@ }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); t.interrupt(); awaitTermination(t); assertEquals(SIZE, q.size()); @@ -673,7 +673,7 @@ assertEquals(0, q.take()); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); t.interrupt(); awaitTermination(t); assertEquals(0, q.remainingCapacity()); @@ -690,26 +690,27 @@ q.put(new Object()); q.put(new Object()); long startTime = System.nanoTime(); + assertFalse(q.offer(new Object(), timeoutMillis(), MILLISECONDS)); assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); Thread.currentThread().interrupt(); try { - q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS); + q.offer(new Object(), randomTimeout(), randomTimeUnit()); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); pleaseInterrupt.countDown(); try { - q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS); + q.offer(new Object(), LONGER_DELAY_MS, MILLISECONDS); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.TIMED_WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); t.interrupt(); awaitTermination(t); } @@ -750,7 +751,7 @@ }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); t.interrupt(); awaitTermination(t); } @@ -802,29 +803,26 @@ final CountDownLatch pleaseInterrupt = new CountDownLatch(1); Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { - long startTime = System.nanoTime(); for (int i = 0; i < SIZE; i++) assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS)); Thread.currentThread().interrupt(); try { - q.poll(LONG_DELAY_MS, MILLISECONDS); + q.poll(randomTimeout(), randomTimeUnit()); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); pleaseInterrupt.countDown(); try { - q.poll(LONG_DELAY_MS, MILLISECONDS); + q.poll(LONGER_DELAY_MS, MILLISECONDS); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); - - assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.TIMED_WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); t.interrupt(); awaitTermination(t); checkEmpty(q); @@ -883,7 +881,7 @@ }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); t.interrupt(); awaitTermination(t); assertEquals(SIZE, q.size()); @@ -918,7 +916,7 @@ assertEquals(capacity - 1, q.take()); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); t.interrupt(); awaitTermination(t); assertEquals(0, q.remainingCapacity()); @@ -935,26 +933,27 @@ q.putFirst(new Object()); q.putFirst(new Object()); long startTime = System.nanoTime(); + assertFalse(q.offerFirst(new Object(), timeoutMillis(), MILLISECONDS)); assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); Thread.currentThread().interrupt(); try { - q.offerFirst(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS); + q.offerFirst(new Object(), randomTimeout(), randomTimeUnit()); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); pleaseInterrupt.countDown(); try { - q.offerFirst(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS); + q.offerFirst(new Object(), LONGER_DELAY_MS, MILLISECONDS); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.TIMED_WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); t.interrupt(); awaitTermination(t); } @@ -986,7 +985,7 @@ }}); await(threadStarted); - assertThreadBlocks(t, Thread.State.WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); t.interrupt(); awaitTermination(t); } @@ -1027,7 +1026,7 @@ }}); await(threadStarted); - assertThreadBlocks(t, Thread.State.WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); t.interrupt(); awaitTermination(t); } @@ -1077,7 +1076,7 @@ }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); t.interrupt(); awaitTermination(t); } @@ -1118,29 +1117,26 @@ final CountDownLatch pleaseInterrupt = new CountDownLatch(1); Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { - long startTime = System.nanoTime(); for (int i = 0; i < SIZE; i++) assertEquals(i, q.pollFirst(LONG_DELAY_MS, MILLISECONDS)); Thread.currentThread().interrupt(); try { - q.pollFirst(LONG_DELAY_MS, MILLISECONDS); + q.pollFirst(randomTimeout(), randomTimeUnit()); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); pleaseInterrupt.countDown(); try { - q.pollFirst(LONG_DELAY_MS, MILLISECONDS); + q.pollFirst(LONGER_DELAY_MS, MILLISECONDS); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); - - assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.TIMED_WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); t.interrupt(); awaitTermination(t); } @@ -1164,7 +1160,7 @@ Thread.currentThread().interrupt(); try { - q.pollFirst(LONG_DELAY_MS, MILLISECONDS); + q.pollFirst(randomTimeout(), randomTimeUnit()); shouldThrow(); } catch (InterruptedException success) {} @@ -1174,6 +1170,7 @@ shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); + assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); }}); @@ -1182,7 +1179,7 @@ assertTrue(q.offerFirst(zero, LONG_DELAY_MS, MILLISECONDS)); assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); barrier.await(); - assertThreadBlocks(t, Thread.State.TIMED_WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); t.interrupt(); awaitTermination(t); } @@ -1240,7 +1237,7 @@ }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); t.interrupt(); awaitTermination(t); assertEquals(SIZE, q.size()); @@ -1282,7 +1279,7 @@ assertEquals(0, q.take()); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); t.interrupt(); awaitTermination(t); assertEquals(0, q.remainingCapacity()); @@ -1299,24 +1296,25 @@ q.putLast(new Object()); q.putLast(new Object()); long startTime = System.nanoTime(); + assertFalse(q.offerLast(new Object(), timeoutMillis(), MILLISECONDS)); assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); Thread.currentThread().interrupt(); try { - q.offerLast(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS); + q.offerLast(new Object(), randomTimeout(), randomTimeUnit()); shouldThrow(); } catch (InterruptedException success) {} pleaseInterrupt.countDown(); try { - q.offerLast(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS); + q.offerLast(new Object(), LONGER_DELAY_MS, MILLISECONDS); shouldThrow(); } catch (InterruptedException success) {} }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.TIMED_WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); t.interrupt(); awaitTermination(t); } @@ -1358,7 +1356,7 @@ }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); t.interrupt(); awaitTermination(t); } @@ -1399,30 +1397,27 @@ final CountDownLatch pleaseInterrupt = new CountDownLatch(1); Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { - long startTime = System.nanoTime(); for (int i = 0; i < SIZE; i++) assertEquals(SIZE - i - 1, q.pollLast(LONG_DELAY_MS, MILLISECONDS)); Thread.currentThread().interrupt(); try { - q.pollLast(LONG_DELAY_MS, MILLISECONDS); + q.pollLast(randomTimeout(), randomTimeUnit()); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); pleaseInterrupt.countDown(); try { - q.pollLast(LONG_DELAY_MS, MILLISECONDS); + q.pollLast(LONGER_DELAY_MS, MILLISECONDS); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); - - assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.TIMED_WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); t.interrupt(); awaitTermination(t); checkEmpty(q); @@ -1447,7 +1442,7 @@ Thread.currentThread().interrupt(); try { - q.poll(LONG_DELAY_MS, MILLISECONDS); + q.poll(randomTimeout(), randomTimeUnit()); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); @@ -1468,7 +1463,7 @@ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); barrier.await(); - assertThreadBlocks(t, Thread.State.TIMED_WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); t.interrupt(); awaitTermination(t); } diff --git a/test/jdk/java/util/concurrent/tck/LinkedBlockingQueueTest.java b/test/jdk/java/util/concurrent/tck/LinkedBlockingQueueTest.java --- a/test/jdk/java/util/concurrent/tck/LinkedBlockingQueueTest.java +++ b/test/jdk/java/util/concurrent/tck/LinkedBlockingQueueTest.java @@ -318,7 +318,7 @@ }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); t.interrupt(); awaitTermination(t); assertEquals(SIZE, q.size()); @@ -360,7 +360,7 @@ assertEquals(0, q.take()); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); t.interrupt(); awaitTermination(t); assertEquals(0, q.remainingCapacity()); @@ -376,28 +376,28 @@ public void realRun() throws InterruptedException { q.put(new Object()); q.put(new Object()); + long startTime = System.nanoTime(); - long startTime = System.nanoTime(); assertFalse(q.offer(new Object(), timeoutMillis(), MILLISECONDS)); assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); Thread.currentThread().interrupt(); try { - q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS); + q.offer(new Object(), randomTimeout(), randomTimeUnit()); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); pleaseInterrupt.countDown(); try { - q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS); + q.offer(new Object(), LONGER_DELAY_MS, MILLISECONDS); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.TIMED_WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); t.interrupt(); awaitTermination(t); } @@ -438,7 +438,7 @@ }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); t.interrupt(); awaitTermination(t); } @@ -490,29 +490,26 @@ final CountDownLatch pleaseInterrupt = new CountDownLatch(1); Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { - long startTime = System.nanoTime(); for (int i = 0; i < SIZE; i++) assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS)); Thread.currentThread().interrupt(); try { - q.poll(LONG_DELAY_MS, MILLISECONDS); + q.poll(randomTimeout(), randomTimeUnit()); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); pleaseInterrupt.countDown(); try { - q.poll(LONG_DELAY_MS, MILLISECONDS); + q.poll(LONGER_DELAY_MS, MILLISECONDS); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); - - assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.TIMED_WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); t.interrupt(); awaitTermination(t); checkEmpty(q); diff --git a/test/jdk/java/util/concurrent/tck/LinkedTransferQueueTest.java b/test/jdk/java/util/concurrent/tck/LinkedTransferQueueTest.java --- a/test/jdk/java/util/concurrent/tck/LinkedTransferQueueTest.java +++ b/test/jdk/java/util/concurrent/tck/LinkedTransferQueueTest.java @@ -254,7 +254,7 @@ }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); t.interrupt(); awaitTermination(t); } @@ -308,29 +308,26 @@ final CountDownLatch pleaseInterrupt = new CountDownLatch(1); Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { - long startTime = System.nanoTime(); for (int i = 0; i < SIZE; i++) assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS)); Thread.currentThread().interrupt(); try { - q.poll(LONG_DELAY_MS, MILLISECONDS); + q.poll(randomTimeout(), randomTimeUnit()); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); pleaseInterrupt.countDown(); try { - q.poll(LONG_DELAY_MS, MILLISECONDS); + q.poll(LONGER_DELAY_MS, MILLISECONDS); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); - - assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.TIMED_WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); t.interrupt(); awaitTermination(t); checkEmpty(q); @@ -344,16 +341,14 @@ final BlockingQueue q = populatedQueue(SIZE); Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { - long startTime = System.nanoTime(); Thread.currentThread().interrupt(); for (int i = 0; i < SIZE; ++i) - assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS)); + assertEquals(i, (int) q.poll(randomTimeout(), randomTimeUnit())); try { - q.poll(LONG_DELAY_MS, MILLISECONDS); + q.poll(randomTimeout(), randomTimeUnit()); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); - assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); }}); awaitTermination(t); @@ -982,25 +977,23 @@ Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { - long startTime = System.nanoTime(); Thread.currentThread().interrupt(); try { - q.tryTransfer(new Object(), LONG_DELAY_MS, MILLISECONDS); + q.tryTransfer(new Object(), randomTimeout(), randomTimeUnit()); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); pleaseInterrupt.countDown(); try { - q.tryTransfer(new Object(), LONG_DELAY_MS, MILLISECONDS); + q.tryTransfer(new Object(), LONGER_DELAY_MS, MILLISECONDS); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); - assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.TIMED_WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); t.interrupt(); awaitTermination(t); checkEmpty(q); diff --git a/test/jdk/java/util/concurrent/tck/LongAccumulatorTest.java b/test/jdk/java/util/concurrent/tck/LongAccumulatorTest.java --- a/test/jdk/java/util/concurrent/tck/LongAccumulatorTest.java +++ b/test/jdk/java/util/concurrent/tck/LongAccumulatorTest.java @@ -150,7 +150,7 @@ = new LongAccumulator((x, y) -> x + y, 0L); final int nThreads = ThreadLocalRandom.current().nextInt(1, 5); final Phaser phaser = new Phaser(nThreads + 1); - final int incs = 1_000_000; + final int incs = expensiveTests ? 1_000_000 : 100_000; final long total = nThreads * incs/2L * (incs - 1); // Gauss final Runnable task = () -> { phaser.arriveAndAwaitAdvance(); diff --git a/test/jdk/java/util/concurrent/tck/MapTest.java b/test/jdk/java/util/concurrent/tck/MapTest.java --- a/test/jdk/java/util/concurrent/tck/MapTest.java +++ b/test/jdk/java/util/concurrent/tck/MapTest.java @@ -122,6 +122,7 @@ */ public void testBug8186171() { if (!impl.supportsSetValue()) return; + if (!atLeastJava10()) return; // jdk9 is no longer maintained final ThreadLocalRandom rnd = ThreadLocalRandom.current(); final boolean permitsNullValues = impl.permitsNullValues(); final Object v1 = (permitsNullValues && rnd.nextBoolean()) diff --git a/test/jdk/java/util/concurrent/tck/PhaserTest.java b/test/jdk/java/util/concurrent/tck/PhaserTest.java --- a/test/jdk/java/util/concurrent/tck/PhaserTest.java +++ b/test/jdk/java/util/concurrent/tck/PhaserTest.java @@ -480,7 +480,7 @@ /** * awaitAdvanceInterruptibly blocks interruptibly */ - public void testAwaitAdvanceInterruptibly_interruptible() throws InterruptedException { + public void testAwaitAdvanceInterruptibly_Interruptible() throws InterruptedException { final Phaser phaser = new Phaser(1); final CountDownLatch pleaseInterrupt = new CountDownLatch(2); @@ -505,14 +505,14 @@ public void realRun() throws TimeoutException { Thread.currentThread().interrupt(); try { - phaser.awaitAdvanceInterruptibly(0, 2*LONG_DELAY_MS, MILLISECONDS); + phaser.awaitAdvanceInterruptibly(0, randomTimeout(), randomTimeUnit()); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); pleaseInterrupt.countDown(); try { - phaser.awaitAdvanceInterruptibly(0, 2*LONG_DELAY_MS, MILLISECONDS); + phaser.awaitAdvanceInterruptibly(0, LONGER_DELAY_MS, MILLISECONDS); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); @@ -520,8 +520,8 @@ await(pleaseInterrupt); assertState(phaser, 0, 1, 1); - assertThreadBlocks(t1, Thread.State.WAITING); - assertThreadBlocks(t2, Thread.State.TIMED_WAITING); + if (randomBoolean()) assertThreadBlocks(t1, Thread.State.WAITING); + if (randomBoolean()) assertThreadBlocks(t2, Thread.State.TIMED_WAITING); t1.interrupt(); t2.interrupt(); awaitTermination(t1); diff --git a/test/jdk/java/util/concurrent/tck/PriorityBlockingQueueTest.java b/test/jdk/java/util/concurrent/tck/PriorityBlockingQueueTest.java --- a/test/jdk/java/util/concurrent/tck/PriorityBlockingQueueTest.java +++ b/test/jdk/java/util/concurrent/tck/PriorityBlockingQueueTest.java @@ -346,7 +346,7 @@ } /** - * timed offer does not time out + * Queue is unbounded, so timed offer never times out */ public void testTimedOffer() { final PriorityBlockingQueue q = new PriorityBlockingQueue(2); @@ -397,7 +397,7 @@ }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); t.interrupt(); awaitTermination(t); } @@ -449,29 +449,26 @@ final CountDownLatch pleaseInterrupt = new CountDownLatch(1); Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { - long startTime = System.nanoTime(); for (int i = 0; i < SIZE; i++) assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS)); Thread.currentThread().interrupt(); try { - q.poll(LONG_DELAY_MS, MILLISECONDS); + q.poll(randomTimeout(), randomTimeUnit()); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); pleaseInterrupt.countDown(); try { - q.poll(LONG_DELAY_MS, MILLISECONDS); + q.poll(LONGER_DELAY_MS, MILLISECONDS); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); - - assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.TIMED_WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); t.interrupt(); awaitTermination(t); } diff --git a/test/jdk/java/util/concurrent/tck/ScheduledExecutorSubclassTest.java b/test/jdk/java/util/concurrent/tck/ScheduledExecutorSubclassTest.java --- a/test/jdk/java/util/concurrent/tck/ScheduledExecutorSubclassTest.java +++ b/test/jdk/java/util/concurrent/tck/ScheduledExecutorSubclassTest.java @@ -707,7 +707,7 @@ Runnable waiter = new CheckedRunnable() { public void realRun() { threadsStarted.countDown(); try { - MILLISECONDS.sleep(2 * LONG_DELAY_MS); + MILLISECONDS.sleep(LONGER_DELAY_MS); } catch (InterruptedException success) {} ran.getAndIncrement(); }}; diff --git a/test/jdk/java/util/concurrent/tck/ScheduledExecutorTest.java b/test/jdk/java/util/concurrent/tck/ScheduledExecutorTest.java --- a/test/jdk/java/util/concurrent/tck/ScheduledExecutorTest.java +++ b/test/jdk/java/util/concurrent/tck/ScheduledExecutorTest.java @@ -666,7 +666,7 @@ Runnable waiter = new CheckedRunnable() { public void realRun() { threadsStarted.countDown(); try { - MILLISECONDS.sleep(2 * LONG_DELAY_MS); + MILLISECONDS.sleep(LONGER_DELAY_MS); } catch (InterruptedException success) {} ran.getAndIncrement(); }}; diff --git a/test/jdk/java/util/concurrent/tck/SemaphoreTest.java b/test/jdk/java/util/concurrent/tck/SemaphoreTest.java --- a/test/jdk/java/util/concurrent/tck/SemaphoreTest.java +++ b/test/jdk/java/util/concurrent/tck/SemaphoreTest.java @@ -38,7 +38,6 @@ import java.util.Collection; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Semaphore; -import java.util.concurrent.ThreadLocalRandom; import junit.framework.Test; import junit.framework.TestSuite; @@ -220,24 +219,22 @@ /** * timed tryAcquire times out */ - public void testTryAcquire_timeout() { - final boolean fair = ThreadLocalRandom.current().nextBoolean(); + public void testTryAcquire_timeout() throws InterruptedException { + final boolean fair = randomBoolean(); final Semaphore s = new Semaphore(0, fair); final long startTime = System.nanoTime(); - try { assertFalse(s.tryAcquire(timeoutMillis(), MILLISECONDS)); } - catch (InterruptedException e) { threadUnexpectedException(e); } + assertFalse(s.tryAcquire(timeoutMillis(), MILLISECONDS)); assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); } /** * timed tryAcquire(N) times out */ - public void testTryAcquireN_timeout() { - final boolean fair = ThreadLocalRandom.current().nextBoolean(); + public void testTryAcquireN_timeout() throws InterruptedException { + final boolean fair = randomBoolean(); final Semaphore s = new Semaphore(2, fair); final long startTime = System.nanoTime(); - try { assertFalse(s.tryAcquire(3, timeoutMillis(), MILLISECONDS)); } - catch (InterruptedException e) { threadUnexpectedException(e); } + assertFalse(s.tryAcquire(3, timeoutMillis(), MILLISECONDS)); assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); } diff --git a/test/jdk/java/util/concurrent/tck/SynchronousQueueTest.java b/test/jdk/java/util/concurrent/tck/SynchronousQueueTest.java --- a/test/jdk/java/util/concurrent/tck/SynchronousQueueTest.java +++ b/test/jdk/java/util/concurrent/tck/SynchronousQueueTest.java @@ -45,7 +45,6 @@ import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; import java.util.concurrent.SynchronousQueue; -import java.util.concurrent.ThreadLocalRandom; import junit.framework.Test; @@ -166,7 +165,7 @@ }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); t.interrupt(); awaitTermination(t); assertEquals(0, q.remainingCapacity()); @@ -207,7 +206,7 @@ catch (InterruptedException e) { threadUnexpectedException(e); } await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); t.interrupt(); awaitTermination(t); assertEquals(0, q.remainingCapacity()); @@ -217,32 +216,33 @@ * timed offer times out if elements not taken */ public void testTimedOffer() { - final boolean fair = ThreadLocalRandom.current().nextBoolean(); + final boolean fair = randomBoolean(); final SynchronousQueue q = new SynchronousQueue(fair); final CountDownLatch pleaseInterrupt = new CountDownLatch(1); Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { long startTime = System.nanoTime(); + assertFalse(q.offer(new Object(), timeoutMillis(), MILLISECONDS)); assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); Thread.currentThread().interrupt(); try { - q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS); + q.offer(new Object(), randomTimeout(), randomTimeUnit()); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); pleaseInterrupt.countDown(); try { - q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS); + q.offer(new Object(), LONGER_DELAY_MS, MILLISECONDS); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.TIMED_WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); t.interrupt(); awaitTermination(t); } @@ -272,7 +272,7 @@ * timed poll with nonzero timeout times out if no active putter */ public void testTimedPoll() { - final boolean fair = ThreadLocalRandom.current().nextBoolean(); + final boolean fair = randomBoolean(); final SynchronousQueue q = new SynchronousQueue(fair); final long startTime = System.nanoTime(); try { assertNull(q.poll(timeoutMillis(), MILLISECONDS)); } @@ -285,7 +285,7 @@ * after offer succeeds; on interruption throws */ public void testTimedPollWithOffer() { - final boolean fair = ThreadLocalRandom.current().nextBoolean(); + final boolean fair = randomBoolean(); final SynchronousQueue q = new SynchronousQueue(fair); final CountDownLatch pleaseOffer = new CountDownLatch(1); final CountDownLatch pleaseInterrupt = new CountDownLatch(1); @@ -301,7 +301,7 @@ Thread.currentThread().interrupt(); try { - q.poll(LONG_DELAY_MS, MILLISECONDS); + q.poll(randomTimeout(), randomTimeUnit()); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); @@ -323,7 +323,7 @@ assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.TIMED_WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); t.interrupt(); awaitTermination(t); } diff --git a/test/jdk/java/util/concurrent/tck/ThreadPoolExecutorSubclassTest.java b/test/jdk/java/util/concurrent/tck/ThreadPoolExecutorSubclassTest.java --- a/test/jdk/java/util/concurrent/tck/ThreadPoolExecutorSubclassTest.java +++ b/test/jdk/java/util/concurrent/tck/ThreadPoolExecutorSubclassTest.java @@ -796,7 +796,7 @@ Runnable waiter = new CheckedRunnable() { public void realRun() { threadsStarted.countDown(); try { - MILLISECONDS.sleep(2 * LONG_DELAY_MS); + MILLISECONDS.sleep(LONGER_DELAY_MS); } catch (InterruptedException success) {} ran.getAndIncrement(); }}; @@ -1669,7 +1669,7 @@ l.add(latchAwaitingStringTask(latch)); l.add(null); try { - e.invokeAny(l, randomTimeout(), MILLISECONDS); + e.invokeAny(l, randomTimeout(), randomTimeUnit()); shouldThrow(); } catch (NullPointerException success) {} latch.countDown(); diff --git a/test/jdk/java/util/concurrent/tck/ThreadPoolExecutorTest.java b/test/jdk/java/util/concurrent/tck/ThreadPoolExecutorTest.java --- a/test/jdk/java/util/concurrent/tck/ThreadPoolExecutorTest.java +++ b/test/jdk/java/util/concurrent/tck/ThreadPoolExecutorTest.java @@ -699,7 +699,7 @@ Runnable waiter = new CheckedRunnable() { public void realRun() { threadsStarted.countDown(); try { - MILLISECONDS.sleep(2 * LONG_DELAY_MS); + MILLISECONDS.sleep(LONGER_DELAY_MS); } catch (InterruptedException success) {} ran.getAndIncrement(); }}; diff --git a/test/jdk/java/util/concurrent/tck/TimeUnitTest.java b/test/jdk/java/util/concurrent/tck/TimeUnitTest.java --- a/test/jdk/java/util/concurrent/tck/TimeUnitTest.java +++ b/test/jdk/java/util/concurrent/tck/TimeUnitTest.java @@ -56,243 +56,56 @@ return new TestSuite(TimeUnitTest.class); } - // (loops to 88888 check increments at all time divisions.) - - /** - * convert correctly converts sample values across the units - */ - public void testConvert() { - for (long t = 0; t < 88888; ++t) { - assertEquals(t*60*60*24, - SECONDS.convert(t, DAYS)); - assertEquals(t*60*60, - SECONDS.convert(t, HOURS)); - assertEquals(t*60, - SECONDS.convert(t, MINUTES)); - assertEquals(t, - SECONDS.convert(t, SECONDS)); - assertEquals(t, - SECONDS.convert(1000L*t, MILLISECONDS)); - assertEquals(t, - SECONDS.convert(1000000L*t, MICROSECONDS)); - assertEquals(t, - SECONDS.convert(1000000000L*t, NANOSECONDS)); - - assertEquals(1000L*t*60*60*24, - MILLISECONDS.convert(t, DAYS)); - assertEquals(1000L*t*60*60, - MILLISECONDS.convert(t, HOURS)); - assertEquals(1000L*t*60, - MILLISECONDS.convert(t, MINUTES)); - assertEquals(1000L*t, - MILLISECONDS.convert(t, SECONDS)); - assertEquals(t, - MILLISECONDS.convert(t, MILLISECONDS)); - assertEquals(t, - MILLISECONDS.convert(1000L*t, MICROSECONDS)); - assertEquals(t, - MILLISECONDS.convert(1000000L*t, NANOSECONDS)); - - assertEquals(1000000L*t*60*60*24, - MICROSECONDS.convert(t, DAYS)); - assertEquals(1000000L*t*60*60, - MICROSECONDS.convert(t, HOURS)); - assertEquals(1000000L*t*60, - MICROSECONDS.convert(t, MINUTES)); - assertEquals(1000000L*t, - MICROSECONDS.convert(t, SECONDS)); - assertEquals(1000L*t, - MICROSECONDS.convert(t, MILLISECONDS)); - assertEquals(t, - MICROSECONDS.convert(t, MICROSECONDS)); - assertEquals(t, - MICROSECONDS.convert(1000L*t, NANOSECONDS)); - - assertEquals(1000000000L*t*60*60*24, - NANOSECONDS.convert(t, DAYS)); - assertEquals(1000000000L*t*60*60, - NANOSECONDS.convert(t, HOURS)); - assertEquals(1000000000L*t*60, - NANOSECONDS.convert(t, MINUTES)); - assertEquals(1000000000L*t, - NANOSECONDS.convert(t, SECONDS)); - assertEquals(1000000L*t, - NANOSECONDS.convert(t, MILLISECONDS)); - assertEquals(1000L*t, - NANOSECONDS.convert(t, MICROSECONDS)); - assertEquals(t, - NANOSECONDS.convert(t, NANOSECONDS)); + void testConversion(TimeUnit x, TimeUnit y, long n, long expected) { + assertEquals(expected, x.convert(n, y)); + switch (x) { + case NANOSECONDS: assertEquals(expected, y.toNanos(n)); break; + case MICROSECONDS: assertEquals(expected, y.toMicros(n)); break; + case MILLISECONDS: assertEquals(expected, y.toMillis(n)); break; + case SECONDS: assertEquals(expected, y.toSeconds(n)); break; + case MINUTES: assertEquals(expected, y.toMinutes(n)); break; + case HOURS: assertEquals(expected, y.toHours(n)); break; + case DAYS: assertEquals(expected, y.toDays(n)); break; + default: throw new AssertionError(); } - for (TimeUnit x : TimeUnit.values()) { - long[] zs = { - 0, 1, -1, - Integer.MAX_VALUE, Integer.MIN_VALUE, - Long.MAX_VALUE, Long.MIN_VALUE, - }; - for (long z : zs) assertEquals(z, x.convert(z, x)); - } + if (n > 0) testConversion(x, y, -n, -expected); } - /** - * toNanos correctly converts sample values in different units to - * nanoseconds - */ - public void testToNanos() { - for (long t = 0; t < 88888; ++t) { - assertEquals(t*1000000000L*60*60*24, - DAYS.toNanos(t)); - assertEquals(t*1000000000L*60*60, - HOURS.toNanos(t)); - assertEquals(t*1000000000L*60, - MINUTES.toNanos(t)); - assertEquals(1000000000L*t, - SECONDS.toNanos(t)); - assertEquals(1000000L*t, - MILLISECONDS.toNanos(t)); - assertEquals(1000L*t, - MICROSECONDS.toNanos(t)); - assertEquals(t, - NANOSECONDS.toNanos(t)); + void testConversion(TimeUnit x, TimeUnit y) { + long ratio = x.toNanos(1)/y.toNanos(1); + assertTrue(ratio > 0); + long[] ns = { 0, 1, 2, Long.MAX_VALUE/ratio, Long.MIN_VALUE/ratio }; + for (long n : ns) { + testConversion(y, x, n, n * ratio); + long[] ks = { n * ratio, n * ratio + 1, n * ratio - 1 }; + for (long k : ks) { + testConversion(x, y, k, k / ratio); + } } } /** - * toMicros correctly converts sample values in different units to - * microseconds - */ - public void testToMicros() { - for (long t = 0; t < 88888; ++t) { - assertEquals(t*1000000L*60*60*24, - DAYS.toMicros(t)); - assertEquals(t*1000000L*60*60, - HOURS.toMicros(t)); - assertEquals(t*1000000L*60, - MINUTES.toMicros(t)); - assertEquals(1000000L*t, - SECONDS.toMicros(t)); - assertEquals(1000L*t, - MILLISECONDS.toMicros(t)); - assertEquals(t, - MICROSECONDS.toMicros(t)); - assertEquals(t, - NANOSECONDS.toMicros(t*1000L)); - } - } - - /** - * toMillis correctly converts sample values in different units to - * milliseconds + * Conversion methods correctly convert sample values */ - public void testToMillis() { - for (long t = 0; t < 88888; ++t) { - assertEquals(t*1000L*60*60*24, - DAYS.toMillis(t)); - assertEquals(t*1000L*60*60, - HOURS.toMillis(t)); - assertEquals(t*1000L*60, - MINUTES.toMillis(t)); - assertEquals(1000L*t, - SECONDS.toMillis(t)); - assertEquals(t, - MILLISECONDS.toMillis(t)); - assertEquals(t, - MICROSECONDS.toMillis(t*1000L)); - assertEquals(t, - NANOSECONDS.toMillis(t*1000000L)); - } - } + public void testConversions() { + // Sanity check + assertEquals(1, NANOSECONDS.toNanos(1)); + assertEquals(1000L * NANOSECONDS.toNanos(1), MICROSECONDS.toNanos(1)); + assertEquals(1000L * MICROSECONDS.toNanos(1), MILLISECONDS.toNanos(1)); + assertEquals(1000L * MILLISECONDS.toNanos(1), SECONDS.toNanos(1)); + assertEquals(60L * SECONDS.toNanos(1), MINUTES.toNanos(1)); + assertEquals(60L * MINUTES.toNanos(1), HOURS.toNanos(1)); + assertEquals(24L * HOURS.toNanos(1), DAYS.toNanos(1)); - /** - * toSeconds correctly converts sample values in different units to - * seconds - */ - public void testToSeconds() { - for (long t = 0; t < 88888; ++t) { - assertEquals(t*60*60*24, - DAYS.toSeconds(t)); - assertEquals(t*60*60, - HOURS.toSeconds(t)); - assertEquals(t*60, - MINUTES.toSeconds(t)); - assertEquals(t, - SECONDS.toSeconds(t)); - assertEquals(t, - MILLISECONDS.toSeconds(t*1000L)); - assertEquals(t, - MICROSECONDS.toSeconds(t*1000000L)); - assertEquals(t, - NANOSECONDS.toSeconds(t*1000000000L)); + for (TimeUnit x : TimeUnit.values()) { + assertEquals(x.toNanos(1), NANOSECONDS.convert(1, x)); } - } - - /** - * toMinutes correctly converts sample values in different units to - * minutes - */ - public void testToMinutes() { - for (long t = 0; t < 88888; ++t) { - assertEquals(t*60*24, - DAYS.toMinutes(t)); - assertEquals(t*60, - HOURS.toMinutes(t)); - assertEquals(t, - MINUTES.toMinutes(t)); - assertEquals(t, - SECONDS.toMinutes(t*60)); - assertEquals(t, - MILLISECONDS.toMinutes(t*1000L*60)); - assertEquals(t, - MICROSECONDS.toMinutes(t*1000000L*60)); - assertEquals(t, - NANOSECONDS.toMinutes(t*1000000000L*60)); - } - } - /** - * toHours correctly converts sample values in different units to - * hours - */ - public void testToHours() { - for (long t = 0; t < 88888; ++t) { - assertEquals(t*24, - DAYS.toHours(t)); - assertEquals(t, - HOURS.toHours(t)); - assertEquals(t, - MINUTES.toHours(t*60)); - assertEquals(t, - SECONDS.toHours(t*60*60)); - assertEquals(t, - MILLISECONDS.toHours(t*1000L*60*60)); - assertEquals(t, - MICROSECONDS.toHours(t*1000000L*60*60)); - assertEquals(t, - NANOSECONDS.toHours(t*1000000000L*60*60)); - } - } - - /** - * toDays correctly converts sample values in different units to - * days - */ - public void testToDays() { - for (long t = 0; t < 88888; ++t) { - assertEquals(t, - DAYS.toDays(t)); - assertEquals(t, - HOURS.toDays(t*24)); - assertEquals(t, - MINUTES.toDays(t*60*24)); - assertEquals(t, - SECONDS.toDays(t*60*60*24)); - assertEquals(t, - MILLISECONDS.toDays(t*1000L*60*60*24)); - assertEquals(t, - MICROSECONDS.toDays(t*1000000L*60*60*24)); - assertEquals(t, - NANOSECONDS.toDays(t*1000000000L*60*60*24)); - } + for (TimeUnit x : TimeUnit.values()) + for (TimeUnit y : TimeUnit.values()) + if (x.toNanos(1) >= y.toNanos(1)) + testConversion(x, y); } /** @@ -494,14 +307,21 @@ * toString returns name of unit */ public void testToString() { + assertEquals("NANOSECONDS", NANOSECONDS.toString()); + assertEquals("MICROSECONDS", MICROSECONDS.toString()); + assertEquals("MILLISECONDS", MILLISECONDS.toString()); assertEquals("SECONDS", SECONDS.toString()); + assertEquals("MINUTES", MINUTES.toString()); + assertEquals("HOURS", HOURS.toString()); + assertEquals("DAYS", DAYS.toString()); } /** * name returns name of unit */ public void testName() { - assertEquals("SECONDS", SECONDS.name()); + for (TimeUnit x : TimeUnit.values()) + assertEquals(x.toString(), x.name()); } /** @@ -512,10 +332,8 @@ Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { Object o = new Object(); - TimeUnit tu = MILLISECONDS; - try { - tu.timedWait(o, LONG_DELAY_MS); + MILLISECONDS.timedWait(o, LONGER_DELAY_MS); threadShouldThrow(); } catch (IllegalMonitorStateException success) {} }}); @@ -531,12 +349,11 @@ Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { Object o = new Object(); - TimeUnit tu = MILLISECONDS; Thread.currentThread().interrupt(); try { synchronized (o) { - tu.timedWait(o, LONG_DELAY_MS); + MILLISECONDS.timedWait(o, LONGER_DELAY_MS); } shouldThrow(); } catch (InterruptedException success) {} @@ -545,7 +362,7 @@ pleaseInterrupt.countDown(); try { synchronized (o) { - tu.timedWait(o, LONG_DELAY_MS); + MILLISECONDS.timedWait(o, LONGER_DELAY_MS); } shouldThrow(); } catch (InterruptedException success) {} @@ -553,7 +370,7 @@ }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.TIMED_WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); t.interrupt(); awaitTermination(t); } @@ -565,28 +382,27 @@ final CountDownLatch pleaseInterrupt = new CountDownLatch(1); final Thread s = newStartedThread(new CheckedInterruptedRunnable() { public void realRun() throws InterruptedException { - Thread.sleep(LONG_DELAY_MS); + Thread.sleep(LONGER_DELAY_MS); }}); final Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { - TimeUnit tu = MILLISECONDS; Thread.currentThread().interrupt(); try { - tu.timedJoin(s, LONG_DELAY_MS); + MILLISECONDS.timedJoin(s, LONGER_DELAY_MS); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); pleaseInterrupt.countDown(); try { - tu.timedJoin(s, LONG_DELAY_MS); + MILLISECONDS.timedJoin(s, LONGER_DELAY_MS); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.TIMED_WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); t.interrupt(); awaitTermination(t); s.interrupt(); @@ -594,35 +410,46 @@ } /** - * timedSleep throws InterruptedException when interrupted + * timeUnit.sleep throws InterruptedException when interrupted */ public void testTimedSleep_Interruptible() { final CountDownLatch pleaseInterrupt = new CountDownLatch(1); Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { - TimeUnit tu = MILLISECONDS; Thread.currentThread().interrupt(); try { - tu.sleep(LONG_DELAY_MS); + MILLISECONDS.sleep(LONGER_DELAY_MS); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); pleaseInterrupt.countDown(); try { - tu.sleep(LONG_DELAY_MS); + MILLISECONDS.sleep(LONGER_DELAY_MS); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); }}); await(pleaseInterrupt); - assertThreadBlocks(t, Thread.State.TIMED_WAITING); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); t.interrupt(); awaitTermination(t); } /** + * timeUnit.sleep(x) for x <= 0 does not sleep at all. + */ + public void testTimedSleep_nonPositive() throws InterruptedException { + boolean interrupt = randomBoolean(); + if (interrupt) Thread.currentThread().interrupt(); + randomTimeUnit().sleep(0L); + randomTimeUnit().sleep(-1L); + randomTimeUnit().sleep(Long.MIN_VALUE); + if (interrupt) assertTrue(Thread.interrupted()); + } + + /** * a deserialized/reserialized unit is the same instance */ public void testSerialization() throws Exception {