Java ExecutorService.awaitTermination运行超时,尽管任务处于活动状态
我有以下实施:Java ExecutorService.awaitTermination运行超时,尽管任务处于活动状态,java,multithreading,Java,Multithreading,我有以下实施: final ExecutorService service = Executors.newFixedThreadPool(4); final List<Callable> taskList = new LinkedList<>(); for (Path path : paths) { final SomeCallable task = new SomeCallable(path); taskList.add(task); service.su
final ExecutorService service = Executors.newFixedThreadPool(4);
final List<Callable> taskList = new LinkedList<>();
for (Path path : paths) {
final SomeCallable task = new SomeCallable(path);
taskList.add(task);
service.submit(task);
}
synchronized (this) {
try {
this.wait();
shutdown(service);
} catch (InterruptedException e) {
shutdown(service);
}
}
我的问题是:Path
是一个包含大量Path
实例的列表。所有这些路径都将在SomeCallable
实例中进行一些处理。通常,此
线程会等待所有路径在其SomeCallable
中成功处理。处理完所有路径后,将调用关闭(服务)
但是,此
线程可能会中断,必须立即关闭。因此,我在catch
-块中调用shutdown(service)
。工作原理是,当前运行的SomeCallable
-实例将完成,ExecutorService线程池中的任何任务都不会启动。尽管如此,等待终止
始终运行到2分钟超时。为什么会这样
我假设
waittermination
等待当前活动的运行任务终止(因此,最多等待4个任务->线程池大小)。就我而言,两分钟就足以完成这4项任务。通过调用shutdownNow()
不应从队列中启动新任务,我想知道为什么我仍然得到超时
有什么想法吗?“就我而言,两分钟就足以完成4项任务。”-你是说正常完成吗,或者在中断时停止做他们正在做的事情并完成?我的意思是正常完成-在Callables中没有永远运行的循环。我担心问题超出了您提供的信息范围。您认为缺少哪些信息?假设我有100条路径,所有路径都将提交到服务。然后调用this.wait()。如果现在,在处理了20个任务后发生中断,则调用方法
shutdown()
。列表abortedCallables
随后包含80项。即,我有20个已处理的任务和80个尚未启动的任务。因此,从我的观点来看,应该没有超时。很明显,SomeCallable实例没有完成,但是在不知道它们正在做什么(它们正在运行什么代码)的情况下,很难说出原因。“两分钟——在我的情况下——足够4个任务完成。”-你是说正常完成吗,或者在中断时停止做他们正在做的事情并完成?我的意思是正常完成-在Callables中没有永远运行的循环。我担心问题超出了您提供的信息范围。您认为缺少哪些信息?假设我有100条路径,所有路径都将提交到服务。然后调用this.wait()。如果现在,在处理了20个任务后发生中断,则调用方法shutdown()
。列表abortedCallables
随后包含80项。即,我有20个已处理的任务和80个尚未启动的任务。因此,在我看来,根本不应该有超时。很明显,SomeCallable实例还没有完成,但是如果不知道它们正在做什么(它们正在运行什么代码),就不可能知道为什么。
protected void shutdown(final ExecutorService service) {
List<Runnable> abortedCallables = service.shutdownNow();
try {
if (!service.awaitTermination(2, TimeUnit.MINUTES)) {
System.out.println("timeout");
}
}
catch (InterruptedException e) {
// (Re-)cancel all Callables if current thread has been interrupted
service.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
}