当前位置: 首页 > 知识库问答 >
问题:

主线程在完成完全未来之前退出

漆雕奇
2023-03-14
    CompletableFuture feature = CompletableFuture.supplyAsync (() ->       composeMethod ( )).
            thenAccept (s -> System.out.println ("wassup java" + s)).
            thenRun (() -> System.out.println (" imm immortal"));
    nonblockingmethod ( );

这是我正在研究的完全未来的例子

private static void nonblockingmethod() {
        System.out.println ("why  should i wait for you ");
    }

    private static String composeMethod() {
        try {
            TimeUnit.MILLISECONDS.sleep (3);
            File file = Paths.get ("/Users/solo/solo1.txt").toFile ( );

            if (!file.exists ( )) {
                file.createNewFile ( );
            }

        } catch (Exception e) {

        }
        return "   resultdaa";
    }

首先我从SupplySync调用compose方法,在这里我执行方法composeMethod,有三毫秒的延迟,然后它将创建一个文件并返回一个字符串作为结果。完成后,我调用Run方法,它只打印一个方法,然后有一个非阻塞方法从主线程运行。

我在这里面临的问题是,主线程执行完nonblockingmethod()并在3毫秒延迟之前退出进程,而随后的composeMethod操作则是如此。这是预期的行为还是我必须使用get或join阻止主线程,或者我错过了任何东西

共有1个答案

谭伟
2023-03-14

supplyAsync中提供的任务将在ForkJoinPool#commonPool中执行。如果您查看公共池中的线程,您可以看到它们是Deamon线程,这意味着当没有活动的非守护线程时,JVM不会等待守护线程关闭以完成其执行。在您的例子中,您在composeMethod中有一个睡眠,同时,主线程执行并完成其工作,JVM没有任何活动的非守护进程线程。因此,JVM将转到关闭,而无需等待任务完成。如果运行下面的示例,您可以确认线程池和线程类型。

CompletableFuture feature = CompletableFuture.supplyAsync(() -> {
    System.out.println("Thread : " + Thread.currentThread());
    System.out.println("Is Daemon : " + Thread.currentThread().isDaemon());
    return composeMethod();
}).thenAccept(s -> System.out.println("wassup java" + s)).thenRun(() -> System.out.println(" imm immortal"));

输出:

Thread : Thread[ForkJoinPool.commonPool-worker-1,5,main] // This line may be bit different but it indicates that your task is executing on Common pool
Is Daemon : true
why  should i wait for you 

要解决问题,您可以通过自己的执行人,如下所示:

ExecutorService executorService = Executors.newFixedThreadPool(8);
CompletableFuture feature = CompletableFuture.supplyAsync(() -> {
        System.out.println("Thread : " + Thread.currentThread());
        System.out.println("Is Daemon : " + Thread.currentThread().isDaemon());
        return composeMethod();
    }, executorService).thenAccept(s -> System.out.println("wassup java" + s))
            .thenRun(() -> System.out.println(" imm immortal"));
executorService.shutdown();
nonblockingmethod();

输出:

Thread : Thread[pool-1-thread-1,5,main]
Is Daemon : false
why  should i wait for you 
wassup java   resultdaa
 imm immortal
 类似资料:
  • 问题内容: 主线程将在子线程完成执行之前退出? 我读了两篇文章 http://www.cs.mtu.edu/~shene/NSF-3/e-Book/FUNDAMENTALS/thread- management.html 在以上文章的“线程终止”段中,它用红色表示“如果父线程终止,则其所有子线程也终止。” http://www.roseindia.net/java/thread/overview-

  • 我试图理解Python线程的“守护进程”标志。这我知道 线程可以标记为“守护线程”。此标志的意义在于,当只剩下守护进程线程时,整个Python程序将退出。初始值从创建线程继承。 但在我的例子中,python程序在守护进程线程离开并且线程没有完成其工作之前退出。 主程序 第一个线程只写5000个第一个整数,而第二个线程不写任何数字

  • 我正在学习Java8以及更多关于“可完成的未来”的细节。以下是有趣的教程:https://www.callicoder.com/java-8-completablefuture-tutorial/ 我编写了以下Java类: (为了运行该代码,您需要resteasy-Client库) 但是我不明白为什么即使收集了所有的响应,主方法也不会终止... 我错过什么了吗?是否有一些“完整”的方法可以在任何地

  • 我想用Java 8-9启动线程,使用异步模式,这些是我的类和我的线程: 我有三根线。我的类包含单个方法 按以下方式设置我的%s: 正在创建线程: 最后,我的问题是我如何使用异步模式启动这三个线程。

  • 我想从android客户端上传图像文件到服务器(服务器制作缩略图,并返回缩略图的url)。 然而,我塞进了这个错误消息。 我试着在stackoverflow中找到这个错误代码,但是我找不到Android的答案。 这是客户端代码(imgURL看起来像/storage/emulated/0/dcim/img/1493742568136.jpg)

  • 我有一个关于CompletableFuture方法的问题: JavaDoc的意思是: 返回一个新的完成阶段,当此阶段正常完成时,将使用此阶段的结果作为所提供函数的参数来执行该阶段。有关异常完成的规则,请参阅完成阶段文档。 穿线呢?这将在哪个线程中执行?如果未来由线程池来完成呢?