Java线程在调用cancel方法后仍不停止


public class my {
public static void main(String[] args) throws InterruptedException {
SomeService service = new SomeService();
CompletableFuture<Void> async = CompletableFuture.runAsync(() -> {
try (AutoClosableResource<SomeService> resource = new AutoClosableResource<>(service, service::disconnect)) {
resource.get().connect();
int i = 0;
while (true) {
System.out.println("--------------inside while" + i);
Thread.sleep(500);
i++;
}
} catch (Exception e) {
e.printStackTrace();
}
});
System.out.println("ouside while");
Thread.sleep(2500);
async.cancel(true);
System.out.println(async.isCompletedExceptionally());
Thread.sleep(1000);
}
public static class SomeService {
public void connect() {
System.out.println("connect");
}
public Integer disconnect() {
System.out.println("disconnect");
return null;
}
}
public static class AutoClosableResource<T> implements AutoCloseable {
private final T resource;
private final Runnable closeFunction;
private AutoClosableResource(T resource, Runnable closeFunction) {
this.resource = resource;
this.closeFunction = closeFunction;
}
public T get() {
return resource;
}
@Override
public void close() throws Exception {
closeFunction.run();
}
}

}

-------output--------

ouside while connect
--------------inside while0
--------------inside while1
--------------inside while2
--------------inside while3
--------------inside while4 true
--------------inside while5
--------------inside while6

Q: 为什么线程仍然在运行和打印isCompletedExceptionally((=true,即使我手动停止它,async.concel(true(;

简短回答:线程仍在运行,因为CompletableFuturecancel方法对运行Async进程没有影响,也不会中断线程。

async.isCompletedExceptionally((返回true,因为取消操作引发异常CompletionException

详细信息:

来自javadoc的关于取消方法的信息:

如果尚未完成,请使用CancellationException。尚未已经完成的也将例外完成此CancellationException 引起的CompletionException

此方法刚刚完成CompletableFuture和方法,它们依赖于等待此CancellationException引起的CompletionException的结果。方法不应用于中断线程,而应用于完成依赖方法的工作。未来将异常完成

你应该在流程中使用这种方法,在那里你做了一些工作,并决定取消它

因此,由于System.exit((,您的线程继续工作并终止查看公共静态ForkJoinPool commonPool((javadoc

返回公共池实例。此池是静态构建的;其运行状态不受关闭或shutdownNow尝试的影响。但是,此池和任何正在进行的处理都是自动的在程序System.exit时终止。任何依赖要在程序终止前完成的异步任务处理应在退出前调用commonPool((.awaitQuience。

最新更新