在下面的代码,我赶上百秒后一个TimeoutException如预期。在这一点上我希望的代码从主和程序终止退出,但会将打印到控制台。如何获得任务停止超时后执行?

private static final ExecutorService THREAD_POOL = Executors.newCachedThreadPool();

private static <T> T timedCall(Callable<T> c, long timeout, TimeUnit timeUnit) throws InterruptedException, ExecutionException, TimeoutException {
    FutureTask<T> task = new FutureTask<T>(c);
    THREAD_POOL.execute(task);
    return task.get(timeout, timeUnit);
}


public static void main(String[] args) {

    try {
        int returnCode = timedCall(new Callable<Integer>() {
            public Integer call() throws Exception {
                for (int i=0; i < 1000000; i++) {
                    System.out.println(new java.util.Date());
                    Thread.sleep(1000);
                }
                return 0;
            }
        }, 100, TimeUnit.SECONDS);
    } catch (Exception e) {
        e.printStackTrace();
        return;
    }


}
有帮助吗?

解决方案

您需要取消在超时你的任务(和中断它的线程)。这就是cancel(true)方法是。 :

private static final ExecutorService THREAD_POOL = Executors.newCachedThreadPool();

private static <T> T timedCall(FutureTask<T> task, long timeout, TimeUnit timeUnit) throws InterruptedException, ExecutionException, TimeoutException {
    THREAD_POOL.execute(task);
    return task.get(timeout, timeUnit);
}


public static void main(String[] args) {
        try {
            FutureTask<Integer> task = new FutureTask<Integer>(new Callable<Integer>() {
                public Integer call() throws Exception {
                        for (int i=0; i < 1000000; i++) {
                                if (Thread.interrupted()) return 1;
                                System.out.println(new java.util.Date());
                                Thread.sleep(1000);
                        }
                        return 0;
                }
            });
            int returnCode = timedCall(task, 100, TimeUnit.SECONDS);
        } catch (Exception e) {
                e.printStackTrace();
                task.cancel(true);
        }
        return;
}

其他提示

您必须赎回要能够迅速停止,在需要的时候。

您的代码:

public Integer call() throws Exception {
    for (int i=0; i < 1000000 && !task.cancelled(); i++) {
        System.out.println(new java.util.Date());
        Thread.sleep(1000); // throws InterruptedException when thread is interrupted
    }
    return 0;
}

已经能够做到这一点得益于调用Thread.sleep()。一点是,futureTask.cancel(true)会中断其他线程,并且代码需要这种中断反应。 Thread.sleep()做到这一点。如果您没有使用Thread.sleep()或其他中断阻塞的代码,你就必须自己检查Thread.currentThread().isInterrupted(),和(例如,通过投掷new InterruptedException()),当你发现这是真的,尽快退出。

您需要从您的异常处理程序调用futureTask.cancel(true);取消和中断是运行在任务线程。

我的建议是,以了解中断机制(这是伟大的文章:的使用InterruptedException的交易),并使用它。

一旦你抓住了TimeoutException异常,你需要打电话给你任务的取消(true)方法...

或致电shutdownNow时()关闭您的ExecutorService ...

或通过调用System.exit退出VM(0)

根据需要

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top