Friday, September 14, 2007

Running "N" foreground tasks in Java

A handy helper method for running "N" foreground tasks in Java with a timeout. A more sophisticated technique would permit examination of job status:

/**
 * Invokes <var>n</var> copies of the given <var>runnable</var>, timing out
 * after <strong>10 unit</strong> with {@code InterruptedException}.
 *
 * @param n the number of threads to run
 * @param runnable the thread body to execute
 * @param timeout the timeout
 * @param unit the timeout unit
 *
 * @throws InterruptedException if timed out
 */
public static void invokeNCopiesWithTimeout(final int n,
        final Runnable runnable, final long timeout, final TimeUnit unit)
        throws InterruptedException {
    final ExecutorService pool = newFixedThreadPool(n);

    pool.invokeAll(
            Collections.<Callable<Void>>nCopies(n, new Callable<Void>() {
                public Void call() {
                    runnable.run();
                    return null;
                }
            }));

    pool.awaitTermination(timeout, unit);
}

I find this particularly useful for blackbox concurrency testing. I run, say, 100 threads which both read and write to a common data structure, and accept the lack of exceptions as empirical evidence of safeness. (In truth, it only provides a comfort zone, not a proof. Reasoning about threads is difficult when maintaining disparate interacting components.)

No comments: