--- jsr166/src/test/tck/JSR166TestCase.java 2015/09/04 19:35:46 1.138 +++ jsr166/src/test/tck/JSR166TestCase.java 2015/09/06 21:14:12 1.139 @@ -37,6 +37,8 @@ import java.util.concurrent.BlockingQueu import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import java.util.concurrent.RecursiveAction; @@ -727,11 +729,11 @@ public class JSR166TestCase extends Test /** * Waits out termination of a thread pool or fails doing so. */ - void joinPool(ExecutorService exec) { + void joinPool(ExecutorService pool) { try { - exec.shutdown(); - if (!exec.awaitTermination(2 * LONG_DELAY_MS, MILLISECONDS)) - fail("ExecutorService " + exec + + pool.shutdown(); + if (!pool.awaitTermination(2 * LONG_DELAY_MS, MILLISECONDS)) + fail("ExecutorService " + pool + " did not terminate in a timely manner"); } catch (SecurityException ok) { // Allowed in case test doesn't have privs @@ -740,6 +742,34 @@ public class JSR166TestCase extends Test } } + /** Like Runnable, but with the freedom to throw anything */ + interface Thunk { public void run() throws Throwable; } + + /** + * Runs all the given tasks in parallel, failing if any fail. + * Useful for running multiple variants of tests that are + * necessarily individually slow because they must block. + */ + void testInParallel(Thunk ... thunks) { + ExecutorService pool = Executors.newCachedThreadPool(); + try { + ArrayList> futures = new ArrayList<>(thunks.length); + for (final Thunk thunk : thunks) + futures.add(pool.submit(new CheckedRunnable() { + public void realRun() throws Throwable { thunk.run();}})); + for (Future future : futures) + try { + assertNull(future.get(LONG_DELAY_MS, MILLISECONDS)); + } catch (ExecutionException ex) { + threadUnexpectedException(ex.getCause()); + } catch (Exception ex) { + threadUnexpectedException(ex); + } + } finally { + joinPool(pool); + } + } + /** * A debugging tool to print all stack traces, as jstack does. */