0

我正在使用ExecutorService进行连接任务,如下所示:

ExecutorService executor = Executors.newSingleThreadExecutor();
Future<ApplicationConnection> future = (Future<ApplicationConnection>) executor.submit(new ConnectThread(crf, connoptions));
connection = future.get(300000, TimeUnit.SECONDS);
executor.shutdownNow();

call()方法调用一个.connect()方法(专有 API)。这种连接方法会产生各种线程池等。我担心的是,如果将来超时并杀死执行程序,将来可能已经通过调用该.connect()方法产生的线程也会结束吗?我知道杀死一个线程也会杀死任何子线程,但这是否遵循相同的逻辑?

4

2 回答 2

2

你的假设是对的,如果Future超时,一些挂起的线程将保留。更糟糕的是,shutdownNow()甚至不会关闭您的池线程(更不用说专有的 API 线程)。它只是停止接受新工作。ExecutorService一旦所有正在运行的任务完成,线程池将终止所有线程。

您可以做的是尝试取消未来并中断它。首先处理InterruptedException你的未来:

class ConnectThread implements Callbale<ApplicationConnection> {

    public ApplicationConnection call() {
        try {
            return prioprietaryApi.connect();
        } catch(InterruptedException e) {
            prioprietaryApi.cleanUp();
            throw e;
        }
    }

}

现在只需运行:

future.cancel(true);

但是您的专有 API 可能无法处理InterruptedException(它不会从 重新抛出它connect(),而且您可能无权访问任何cleanUp()方法。

在这种情况下……算了吧。这Future最终将终止并自行清理,忽略您不再等待它的事实。当然,这可能会导致各种可扩展性问题。

顺便说一句,如果您想要实现的唯一目标是限制给定方法运行的最长时间,请TimeLimiter考虑。

于 2012-12-17T18:49:23.090 回答
1

根据javadoc

尝试停止所有正在执行的任务,停止等待任务的处理,并返回等待执行的任务列表。除了尽最大努力停止处理正在执行的任务之外,没有任何保证。例如,典型的实现将通过 Thread.interrupt() 取消,因此任何未能响应中断的任务可能永远不会终止。

于 2012-12-17T18:46:03.510 回答