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

Java线程在调用cancel方法后仍不停止?,java,multithreading,thread-safety,threadpool,Java,Multithreading,Thread Safety,Threadpool,问:为什么线程仍在运行并且打印isCompletedExceptionally()=true,即使我手动使用async.cancel(true)停止它 简短回答: 线程仍在运行,因为CompletableFuture cancel方法对runAsync进程没有影响,并且不会中断线程 isCompletedExceptionally()返回true,因为取消操作会引发异常CompletionException 详情如下: 来自javadoc的关于取消方法的信息: 如果尚未完成,则使用 取消例外。尚

问:为什么线程仍在运行并且打印isCompletedExceptionally()=true,即使我手动使用async.cancel(true)停止它

简短回答: 线程仍在运行,因为CompletableFuture cancel方法对runAsync进程没有影响,并且不会中断线程

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

详情如下:

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

如果尚未完成,则使用 取消例外。尚未完成的依赖可完成期货 已完成的也将例外完成,包括 此CancellationException导致的CompletionException

此方法仅完成CompletableFuture和方法,它依赖于等待此CancellationException导致的结果获取CompletionException。方法不应用于中断线程,而应用于完成依赖方法上的工作。未来的工作将例外地完成

您应该在流程中使用此方法,在流程中您进行了一些工作,并决定取消它

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

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


有没有说过它将停止另一个线程?文档中说,如果还没有完成,将通过CancellationException完成这个CompletableFuture。没有说“这将停止其他正在运行的线程”。非常感谢,那么,停止此线程的执行的最佳实践是什么呢?您可以通过调用thread.interrupt来停止线程,或者如果使用executors,则可以调用shutdownNow方法。但通常不需要从外部停止线程。但是如果需要,请阅读《Java并发性实践》一书,第7章取消和关闭
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