有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

多线程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

问:为什么线程仍在运行并且打印isCompletedExceptionally()=true,即使我手动使用异步停止它。取消(真)


共 (1) 个答案

  1. # 1 楼答案

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

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

    详情如下:

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

    If not already completed, completes this CompletableFuture with a CancellationException. Dependent CompletableFutures that have not already completed will also complete exceptionally, with a CompletionException caused by this CancellationException

    这个方法只是完成CompletableFuture和methods,它依赖于等待由这个CancellationException引起的CompletionException结果。方法不应用于中断线程,而应用于完成依赖方法的工作。未来将破例完成

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

    所以,你的线程继续工作,并因系统原因终止。退出() 查看公共静态ForkJoinPool commonPool()javadoc

    Returns the common pool instance. This pool is statically constructed; its run state is unaffected by attempts to shutdown or shutdownNow. However this pool and any ongoing processing are automatically terminated upon program System.exit. Any program that relies on asynchronous task processing to complete before program termination should invoke commonPool().awaitQuiescence, before exit.