Probleme bei der Verwendung von CompletableFuture in JDK8
伊谢尔伦
伊谢尔伦 2017-06-15 09:22:15
0
2
909
        CompletableFuture cf1 = CompletableFuture.supplyAsync(() -> {
            System.out.println("enter into completableFuture()");
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("start to out of completableFuture()");
            return "a";
        });

        System.out.println("do something else");

        cf1.thenApply(v -> v + " b").thenAcceptAsync(v ->
                System.out.println(v)
        );
        
        System.out.println("finalize...");
        
        //注释最后一行,无法得到预期结果
        //TimeUnit.SECONDS.sleep(10);

Das Ergebnis ist:

do something else
enter into completableFuture()
finalize...
start to out of completableFuture()
a b

Wenn Sie die letzte Zeile des obigen Codes auskommentieren, erhalten Sie nicht die erwarteten Ergebnisse.

Warum müssen wir das Programm explizit 10 Sekunden lang schlafen lassen?

伊谢尔伦
伊谢尔伦

小伙看你根骨奇佳,潜力无限,来学PHP伐。

Antworte allen(2)
某草草

CompletableFuture.supplyAsync的javadoc:

Returns a new CompletableFuture that is asynchronously completed by a task running in the ForkJoinPool.commonPool() with the value obtained by calling the given Supplier.

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.

如果你把最后的sleep改成ForkJoinPool.commonPool().awaitQuiescence(2, TimeUnit.SECONDS);也能达到你预期结果

某草草

搜索一下:守护线程
当线程中只剩下守护线程时JVM就会退出,反之还有任意一个用户线程在,JVM都不会退出。
我们可以猜测CompletableFuture.supplyAsync启动了一个守护线程,实际上CompletableFuture内部默认使用ForkJoinPool,该线程池初始化一个线程工厂类:

    defaultForkJoinWorkerThreadFactory = new DefaultForkJoinWorkerThreadFactory();

查看他的的实现,每次都是创建守护进程。至于为什么一定要主线程sleep就很好理解。

Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage