Adr*_*ebs 25 java multithreading interface try-with-resources
未能调用shutdown()线程执行程序将导致永不终止的应用程序.关闭ExecutorService的最佳做法是:
ExecutorService service = null;
try {
service = Executors.newSingleThreadExecutor();
// add tasks to thread executor
…
} finally {
if (service != null) service.shutdown();
}
Run Code Online (Sandbox Code Playgroud)
由于Java知道try-with-resources概念,如果我们能做到这一点会不会很好?
try (service = Executors.newSingleThreadExecutor())
{
// add tasks to thread executor
…
}
Run Code Online (Sandbox Code Playgroud)
Gho*_*ica 19
这ExecutorService中实际上有2关闭相关的方法; 基于一个简单的事实,即关闭服务的两种方式都有意义.
那么:你怎么自动关闭服务呢?以一致的方式适用于每个人?!
所以,我眼中的合理解释是:你不能使ExecutorService成为AutoClosable,因为该服务没有单一的"关闭"操作; 但是两个!
如果您认为可以充分利用这种自动关闭服务,那么使用"委托"编写自己的实现将是一个5分钟的事情!或者大概10分钟,因为你会创建一个版本shutdown()作为关闭操作; 而一个shutdownNow()代替.
wil*_*mol 19
ExecutorService使用AutoCloseableJava 19+从Java 19开始,ExecutorService实现AutoCloseable.
默认实现在循环中调用shutdown()并等待任务完成。awaitTermination如果被打断,它会调用shutdownNow()。
对于早期的Java,你可以使用Guava的ForwardingExecutorService来装饰你ExeuctorService自己AutoCloseable:
class CloseableExecutorService extends ForwardingExecutorService implements AutoCloseable {
private final ExecutorService delegate;
CloseableExecutorService(ExecutorService delegate) {
this.delegate = checkNotNull(delegate);
}
@Override
protected ExecutorService delegate() {
return delegate;
}
@Override
public void close() {
// copy paste from JDK 19 EA
boolean terminated = isTerminated();
if (!terminated) {
shutdown();
boolean interrupted = false;
while (!terminated) {
try {
terminated = awaitTermination(1L, TimeUnit.DAYS);
} catch (InterruptedException e) {
if (!interrupted) {
shutdownNow();
interrupted = true;
}
}
}
if (interrupted) {
Thread.currentThread().interrupt();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
Luk*_*der 15
这是一个平庸的解决方法
ExecutorService service = Executors.newSingleThreadExecutor();
try (Closeable close = service::shutdown) {
}
Run Code Online (Sandbox Code Playgroud)
当然,您必须永远不要在赋值和try语句之间放置任何东西,也不要service在try语句后使用局部变量.
考虑到警告,请finally改用.