--- jsr166/src/test/tck/JSR166TestCase.java 2019/09/07 17:40:05 1.266 +++ jsr166/src/test/tck/JSR166TestCase.java 2020/02/01 18:52:17 1.271 @@ -49,6 +49,7 @@ import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.lang.management.ManagementFactory; +import java.lang.management.LockInfo; import java.lang.management.ThreadInfo; import java.lang.management.ThreadMXBean; import java.lang.reflect.Constructor; @@ -243,6 +244,9 @@ public class JSR166TestCase extends Test } } + private static final ThreadMXBean THREAD_MXBEAN + = ManagementFactory.getThreadMXBean(); + /** * The scaling factor to apply to standard delays used in tests. * May be initialized from any of: @@ -354,7 +358,7 @@ public class JSR166TestCase extends Test // 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); } } @@ -700,6 +704,13 @@ public class JSR166TestCase extends Test /** * Returns a random element from given choices. */ + T chooseRandomly(List choices) { + return choices.get(ThreadLocalRandom.current().nextInt(choices.size())); + } + + /** + * Returns a random element from given choices. + */ T chooseRandomly(T... choices) { return choices[ThreadLocalRandom.current().nextInt(choices.length)]; } @@ -1130,9 +1141,8 @@ public class JSR166TestCase extends Test } } - ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); System.err.println("------ stacktrace dump start ------"); - for (ThreadInfo info : threadMXBean.dumpAllThreads(true, true)) + for (ThreadInfo info : THREAD_MXBEAN.dumpAllThreads(true, true)) if (threadOfInterest(info)) System.err.print(info); System.err.println("------ stacktrace dump end ------"); @@ -1161,6 +1171,17 @@ public class JSR166TestCase extends Test } /** + * Returns the thread's blocker's class name, if any, else null. + */ + String blockerClassName(Thread thread) { + ThreadInfo threadInfo; LockInfo lockInfo; + if ((threadInfo = THREAD_MXBEAN.getThreadInfo(thread.getId(), 0)) != null + && (lockInfo = threadInfo.getLockInfo()) != null) + return lockInfo.getClassName(); + return null; + } + + /** * Checks that future.get times out, with the default timeout of * {@code timeoutMillis()}. */ @@ -1179,8 +1200,9 @@ public class JSR166TestCase extends Test } catch (TimeoutException success) { } catch (Exception fail) { threadUnexpectedException(fail); - } finally { future.cancel(true); } + } assertTrue(millisElapsedSince(startTime) >= timeoutMillis); + assertFalse(future.isDone()); } /** @@ -1459,6 +1481,14 @@ public class JSR166TestCase extends Test } /** + * Returns a new started daemon Thread running the given action, + * wrapped in a CheckedRunnable. + */ + Thread newStartedThread(Action action) { + return newStartedThread(checkedRunnable(action)); + } + + /** * Waits for the specified time (in milliseconds) for the thread * to terminate (using {@link Thread#join(long)}), else interrupts * the thread (in the hope that it may terminate later) and fails. @@ -1505,6 +1535,13 @@ public class JSR166TestCase extends Test } } + Runnable checkedRunnable(Action action) { + return new CheckedRunnable() { + public void realRun() throws Throwable { + action.run(); + }}; + } + public abstract class ThreadShouldThrow extends Thread { protected abstract void realRun() throws Throwable; @@ -1743,7 +1780,7 @@ public class JSR166TestCase extends Test public int await() { try { - return super.await(2 * LONG_DELAY_MS, MILLISECONDS); + return super.await(LONGER_DELAY_MS, MILLISECONDS); } catch (TimeoutException timedOut) { throw new AssertionError("timed out"); } catch (Exception fail) {