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

完全可执行的未来执行顺序

松钟展
2023-03-14

我试图理解java中完整期货的非阻塞回调性质

 CompletableFuture.supplyAsync(() -> {
        try {
            //Thread.sleep(20000);
            System.out.println("supplyAsync Thread name " + Thread.currentThread().getName());
            return "str";

        } catch (Exception e) {
            return "";
        }


    }).thenApply(str -> {
        System.out.println("thenApply Thread name " + Thread.currentThread().getName());
        return str;
    }).thenApply(str1 -> {
        System.out.println("thenApply Thread name " + Thread.currentThread().getName());
        return str1;
    }).thenAccept(str3 -> {
        System.out.println("thenAccept Thread name " + Thread.currentThread().getName());
    });
    System.out.println("Thread name " + Thread.currentThread().getName());

有了上面的代码,我总是看到下面看到的输出

线程名称ForkJoinPool.common池工人-1
thenApply Thread name main
thenApply Thread name main
thenAcceptThread name main
Thread name main

这个顺序似乎建议主线程等待所有Futures线程的执行。
我试图将Thread.sleep添加到供应Async方法,输出是

主线程名称

futures线程中的print语句似乎都未执行。我对非阻塞的理解是能够打印

线程名称主SupplySync线程名称
ForkJoinPool。commonPool-worker-1
然后应用线程名称main
然后应用线程名称main
然后接受线程名称main

如果在Javascript中执行类似的代码,则可以执行上述控制台输出

在Java中是否可以实现上述功能?

共有1个答案

蒋高超
2023-03-14

不,它没有阻塞。默认情况下,completable future在ForkJoinPool上执行其任务。commonPool其中commonPool的线程是守护进程,意思是线程。当主线程完成其执行时,JVM将终止池中所有其他守护进程线程,这就是为什么在第二种情况下,您只看到threadname Main

然而,你可以通过自己的执行者来完成未来。

CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(2000);
                System.out.println("supplyAsync Thread name " + Thread.currentThread().getName());
                System.out.println("Is daemon Thread: " + Thread.currentThread().isDaemon());
                return "str";

            } catch (Exception e) {
                return "";
            }

        }, Executors.newFixedThreadPool(4)).thenApply(str -> {
            System.out.println("thenApply Thread name " + Thread.currentThread().getName());
            return str;
        }).thenApply(str1 -> {
            System.out.println("thenApply Thread name " + Thread.currentThread().getName());
            return str1;
        }).thenAccept(str3 -> {
            System.out.println("thenAccept Thread name " + Thread.currentThread().getName());
        });
        System.out.println("Thread name " + Thread.currentThread().getName());

如果运行上述代码,您可以得到如下输出:

Thread name main
supplyAsync Thread name pool-1-thread-1
Is daemon Thread: false
thenApply Thread name1 pool-1-thread-1
thenApply Thread name1 pool-1-thread-1
thenAccept Thread name1 pool-1-thread-1
 类似资料:
  • 我有3种方法需要并行运行,因为它们彼此独立,并在最后合并每种方法的结果,并将其作为响应发送。我还需要处理异常。 在不同的帖子中,我找到了下面的代码并进行了相应的修改。 上述各项是否应正确并行运行?我知道这需要更多的时间,我想确保我做对了。

  • 我有一个shell脚本,它执行sql构建工作。 当从unix提示符手动调用它时,它正在执行并按预期给出结果。 但是当它从java调用时,它并没有完全执行。 手动执行: MODIFY_PATCH_CREATION. ksh 118765CP_14052906_28112015134449_16 日志文件显示为: 但是如果我从java程序执行相同的操作,如下所示: Java代码: 当作为java Sh

  • 假设我有以下一组代码,可以在将来做一些事情: 假设我为这段代码提供了默认的ExecutionContext,我知道在后台会发生什么,但我想知道的是如何处理未来?我的意思是,应该有一些线程或一组线程可能会等待未来完成?这些线程被阻塞了吗?从某种意义上说,他们是在等待未来的结束? 现在在以下场景中: 假设x有一个超时,我可以这样调用: 我真的在阻挡吗?有没有更好的异步超时方法? 编辑:下面的超时比我上

  • 问题内容: 我想使用asyncio调用loop.run_in_executor在Executor中启动一个阻塞函数,然后在以后取消它,但这似乎对我不起作用。 这是代码: 我希望上面的代码仅允许阻塞函数输出: 然后查看非阻塞函数的输出。但是,即使我取消了,阻碍性的未来仍在继续。 可能吗?还有其他方法吗? 谢谢 问题答案: 在这种情况下,一旦它真正开始运行,就无法取消它,因为您依赖的行为,并且它的文档

  • 我编写了两个功能文件,每个功能文件打开不同的浏览器URL,例如一个是open google。com和secnd一个开放的亚马逊。但事实并非如此。 两个浏览器都打开了谷歌。通用域名格式。此外,它不能与浏览器交互,任何编码到浏览器的操作都不会执行。此外,关闭第一个浏览器会导致第二个浏览器出现空指针异常。 cucumber版本6我从AbstractCucumberTesNG继承开始。然后我创建登录。功能

  • 我正在使用谷歌表单来触发这个脚本。 当我用播放按钮运行脚本时,它工作得很好。 当我让提交触发器运行它时,复选框填充正常,但setValue日期没有。 我也试过了但是我得到了相同的结果。 最终目标是让J列在每次提交表单时填充A列中的快照格式日期 我需要此格式在另一张工作表上运行countIfs。 另一种选择是以某种方式将格式标记嵌入到CountIfs命令中,以便它们匹配。