Java 执行器关闭现在有被阻止的任务吗?
我正在为线程池使用执行器,并提交任务。Can executorService.shutdownNow将关闭所有任务,即使其中一些任务可能在对数据库或套接字的I/O调用中被阻止?否,无法保证。如果你看到了API文档。上面说, 除了尽最大努力尝试停止处理积极执行的任务之外,没有其他保证Java 执行器关闭现在有被阻止的任务吗?,java,executorservice,Java,Executorservice,我正在为线程池使用执行器,并提交任务。Can executorService.shutdownNow将关闭所有任务,即使其中一些任务可能在对数据库或套接字的I/O调用中被阻止?否,无法保证。如果你看到了API文档。上面说, 除了尽最大努力尝试停止处理积极执行的任务之外,没有其他保证 如果要在关闭请求后阻止直到所有任务完成执行,请使用。这取决于任务是否编写良好 表示:“shutdown()方法将允许在终止之前执行以前提交的任务,而shutdownNow()方法将阻止等待的任务启动并尝试停止当前正在
如果要在关闭请求后阻止直到所有任务完成执行,请使用。这取决于任务是否编写良好 表示:“shutdown()方法将允许在终止之前执行以前提交的任务,而shutdownNow()方法将阻止等待的任务启动并尝试停止当前正在执行的任务。” 然而,Java不会“凭空”杀死线程。它试图打断他们。一个好的任务会在shtudownNow试图中断它们时抛出某种类型的
中断异常
,并以优雅的方式结束。您提到了套接字通信——大多数体面的客户端的阻塞方法在被中断时都会抛出一个中断的异常
坏任务的一个例子可能是(相当明显地)使用
运行线程,而(true){readChunk();if(endOfChunks){break;}}
。这不提供优雅的中断检查!旧的规则是不要使用while循环等待,而是对可以被中断的“阻止器”对象使用syncronized
。简单地说:你不能依赖它。ExecutorService
只是运行任务;如果他们真的取消了努力,这取决于任务的执行。一些I/O可以(也将)被中断,特别是java.nio
之类的东西,但是java.io
很可能不会被中断。请参阅以获得更多解释。当无法处理中断(java.io)时,需要非标准关闭逻辑
我封装这个问题的解决方案结合了“实践中的Java并发性”中的示例“TrackingExecutorService”和“SocketUsingTask”
- 定义“可关闭”接口
- 扩展ThreadPoolExecutor以跟踪执行“可关闭”接口的已提交任务的运行
- 重写ThreadPoolExecutor的Shutdownow,通过“Shutdownable”接口调用非标准关闭逻辑
是-等待终止是理想的方式。唯一的终止方式是作为子进程而不是子线程运行。进程可以终止。
public interface Shutdownable {
public void shutdown();
}
public class ShutdowningExecutor extends ThreadPoolExecutor{
private final Set runningShutdownables
= Collections.synchronizedSet(new HashSet());
@Override
protected RunnableFuture newTaskFor(final Callable callable){
if (callable instanceof Shutdownable) {
runningShutdownables.add((Shutdownable) callable);
return super.newTaskFor(new Callable(){
@Override
public T call() throws Exception {
T t = callable.call();
runningShutdownables.remove((Shutdownable) callable);
return t;
}
});
} else
return super.newTaskFor(callable);
}
public void shutdownAll() {
for(Shutdownable shutdownable : runningShutdownables) {
shutdownable.shutdown();
}
}
@Override
public List shutdownNow(){
shutdownAll();
return super.shutdownNow();
}
}
public abstract class ShutdownableViaCloseable implements Shutdownable{
private Closeable closeable;
protected synchronized void setCloseable(Closeable c) { closeable = c; }
public synchronized void shutdown() {
try {
if (closeable != null)
closeable.close();
} catch (IOException ignored) { }
}
}
public class MySocketTask extends ShutdownableViaCloseable implements Callable {
public MySocketTask(Socket s) {
setCloseable(s);
//constructor stuff
}
public Void call() {
try (Socket socket = this.socket) {
while(!socket.isClosed) {
//do stuff
}
}
}
}