--- jsr166/src/test/tck/JSR166TestCase.java 2015/09/26 19:08:26 1.147 +++ jsr166/src/test/tck/JSR166TestCase.java 2015/10/03 19:29:11 1.152 @@ -15,6 +15,7 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.lang.management.ManagementFactory; import java.lang.management.ThreadInfo; +import java.lang.management.ThreadMXBean; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Modifier; @@ -597,7 +598,7 @@ public class JSR166TestCase extends Test fail(reason); } catch (AssertionFailedError t) { threadRecordFailure(t); - fail(reason); + throw t; } } @@ -743,9 +744,19 @@ public class JSR166TestCase extends Test } /** + * Allows use of try-with-resources with per-test thread pools. + */ + static class PoolCloser + implements AutoCloseable { + public final T pool; + public PoolCloser(T pool) { this.pool = pool; } + public void close() { joinPool(pool); } + } + + /** * Waits out termination of a thread pool or fails doing so. */ - void joinPool(ExecutorService pool) { + static void joinPool(ExecutorService pool) { try { pool.shutdown(); if (!pool.awaitTermination(2 * LONG_DELAY_MS, MILLISECONDS)) @@ -767,8 +778,9 @@ public class JSR166TestCase extends Test * necessarily individually slow because they must block. */ void testInParallel(Action ... actions) { - ExecutorService pool = Executors.newCachedThreadPool(); - try { + try (PoolCloser poolCloser + = new PoolCloser<>(Executors.newCachedThreadPool())) { + ExecutorService pool = poolCloser.pool; ArrayList> futures = new ArrayList<>(actions.length); for (final Action action : actions) futures.add(pool.submit(new CheckedRunnable() { @@ -781,19 +793,29 @@ public class JSR166TestCase extends Test } catch (Exception ex) { threadUnexpectedException(ex); } - } finally { - joinPool(pool); } } /** * A debugging tool to print all stack traces, as jstack does. + * Uninteresting threads are filtered out. */ static void printAllStackTraces() { - for (ThreadInfo info : - ManagementFactory.getThreadMXBean() - .dumpAllThreads(true, true)) + ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); + System.err.println("------ stacktrace dump start ------"); + for (ThreadInfo info : threadMXBean.dumpAllThreads(true, true)) { + String name = info.getThreadName(); + if ("Signal Dispatcher".equals(name)) + continue; + if ("Reference Handler".equals(name) + && info.getLockName().startsWith("java.lang.ref.Reference$Lock")) + continue; + if ("Finalizer".equals(name) + && info.getLockName().startsWith("java.lang.ref.ReferenceQueue$Lock")) + continue; System.err.print(info); + } + System.err.println("------ stacktrace dump end ------"); } /** @@ -1254,6 +1276,13 @@ public class JSR166TestCase extends Test }}; } + public Runnable countDowner(final CountDownLatch latch) { + return new CheckedRunnable() { + public void realRun() throws InterruptedException { + latch.countDown(); + }}; + } + public Runnable awaiter(final CountDownLatch latch) { return new CheckedRunnable() { public void realRun() throws InterruptedException {