TimeOutController.java |
/* * $Id: TimeOutController.java,v 1.27 2010/09/29 17:21:48 agoubard Exp $ * * See the COPYRIGHT file for redistribution and use restrictions. */ package org.xins.common; /** * Utility class for executing a task with a certain time-out period. * * @version $Revision: 1.27 $ $Date: 2010/09/29 17:21:48 $ * @author <a href="mailto:ernst@ernstdehaan.com">Ernst de Haan</a> * * @since XINS 1.0.0 */ public final class TimeOutController { /** * Constructs a new <code>TimeOutController</code> object. */ private TimeOutController() { // empty } /** * Runs the specified task with a specific time-out. If the task does * not finish within the specified time-out period, then the thread * executing that task is interrupted using the {@link Thread#interrupt()} * method and a {@link TimeOutException} is thrown. * * <p>Note that the specified task could be run either in the current * thread or in a new thread. In the latter case, no initialization is * performed. For example, the <em>Nested Diagnostic Context * identifier</em> (NDC) is not copied from the current thread to the new * one. * * @param task * the task to run, cannot be <code>null</code>. * * @param timeOut * the timeOut in milliseconds, must be > 0. * * @throws IllegalArgumentException * if <code>task == null || timeOut <= 0</code>. * * @throws IllegalThreadStateException * if the specified task is a {@link Thread} that is already started. * * @throws SecurityException * if the thread did not finish within the total time-out period, but * the interruption of the thread was disallowed (see * {@link Thread#interrupt()}); consequently, the thread may still be * running. * * @throws TimeOutException * if the thread did not finish within the total time-out period and was * interrupted. */ public static void execute(Runnable task, int timeOut) throws IllegalArgumentException, IllegalThreadStateException, SecurityException, TimeOutException { // Check preconditions MandatoryArgumentChecker.check("task", task); if (timeOut <= 0) { throw new IllegalArgumentException("timeOut (" + timeOut + ") <= 0"); } // We need a Thread instance. If the argument is already a Thread // instance, then use it, otherwise construct a new Thread instance. Thread thread; if (task instanceof Thread) { thread = (Thread) task; } else { // XXX: To improve performance and manageability, we could use a // thread pool like the one that is available in J2SE 5.0. thread = new Thread(task); } // Start the thread. This may throw an IllegalThreadStateException. thread.start(); // Wait for the thread to finish, within limits try { thread.join(timeOut); } catch (InterruptedException exception) { Utils.logIgnoredException(exception); } // If the thread is still running at this point, it should stop if (thread.isAlive()) { // Interrupt the thread. This may throw a SecurityException thread.interrupt(); throw new TimeOutException(); } } }