Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么即使我没有';t调用get()或join()?_Java_Multithreading_Completable Future - Fatal编程技术网

Java 为什么即使我没有';t调用get()或join()?

Java 为什么即使我没有';t调用get()或join()?,java,multithreading,completable-future,Java,Multithreading,Completable Future,我在学习CompletableFuture时遇到了一个问题。get()/join()方法正在阻止调用。如果我不给他们打电话怎么办 此代码调用get(): 输出: Hello World! World! Hello 此代码既不调用get()也不调用join(): 输出: Hello World! World! Hello 我不知道为什么案例2的runnable块工作。第二个案例“工作”,因为您睡眠主线程的时间足够长(5秒)。工作是在引号之间,因为它不是真正的工作,只是完成。我在这里假设代码

我在学习
CompletableFuture
时遇到了一个问题。
get()
/
join()
方法正在阻止调用。如果我不给他们打电话怎么办

此代码调用
get()

输出:

Hello
World!
World!
Hello
此代码既不调用
get()
也不调用
join()

输出:

Hello
World!
World!
Hello
我不知道为什么案例2的runnable块工作。

第二个案例“工作”,因为您睡眠主线程的时间足够长(5秒)。工作是在引号之间,因为它不是真正的工作,只是完成。我在这里假设代码应该输出
helloworld以被视为“正常工作”


在这两种情况下,在主线程结束时使用此睡眠时间尝试相同的代码:

Thread.sleep(100)

1。第一个线程的行为方式相同,因为get操作阻塞了主线程。事实上,对于第一种情况,你甚至不需要最后的睡眠时间

输出:
你好,世界


2。第二个案例不会输出
Hello
,因为没有人告诉主线程:“嘿,等这个完成”。这就是
get()
所做的:阻止调用者以等待任务完成。如果没有它,并且在最后设置了较低的睡眠时间,则会调用runnable,但无法在主线程停止之前完成其工作

输出:
世界


这也是为什么在第一种情况下,
helloworld
(首先是runnable的输出,然后是main的输出,这意味着主线程被阻塞,直到
get()
返回)被写入,而第二个线程显示出阅读困难的微妙迹象:
World Hello

但这不是诵读困难症,它只是执行它被告知的事情。在第二种情况下,会发生以下情况:

1。可运行的被称为

2.主线程继续其进程,打印(“世界!)

3.
睡眠时间设置为:runnable上1秒/main上5秒。(runnable的睡眠也可以在第二步中执行,但我将其放在这里是为了澄清行为)

4.可运行任务在1秒后打印(“Hello”),可完成的未来完成

5。5秒后,主线程停止

因此,您的runnable可以打印
Hello
,因为它能够在这5秒超时之间执行命令

World! . . . . . .(1)Hello. . . . . . . . . . .(5)[END]
例如,如果将最后5秒的超时时间减少到0.5秒,则

World!. . (0.5)[END]
我不知道为什么case2的
Runnable
块在工作

没有理由不起作用

runAsync(…)
方法表示以异步方式执行任务。假设应用程序没有过早结束,则无论您是否等待任务完成,任务最终都会完成

CompletableFuture
提供了多种等待任务完成的方法。但在您的示例中,您并没有将其用于此目的。相反,主方法中的
线程.sleep(…)
调用具有相同的效果;也就是说,它等待任务(可能)完成的时间足够长。所以
“您好“
世界“
之前输出

重申一下,
get()
调用不会导致任务发生。而是等待它发生


使用
sleep
等待事件(如任务完成)发生是个坏主意:

  • 睡眠不能判断事件是否发生过
  • 你通常不知道事件发生需要多长时间,你也不知道要睡多久
  • 如果你睡得太久,你就有“死时间”(见下文)
  • 如果你没有睡足够长的时间,事件可能还没有发生。所以你需要一次又一次的测试和睡眠,然后
  • 即使在本例中,理论上也有可能1在任务中的
    睡眠
    之前完成main中的
    睡眠

    基本上,
    CompletableFuture
    的目的是提供一种有效的方法来等待任务完成并交付结果。你应该用它

    举例说明。您的应用程序在输出
    “Hello”
    “World!”
    之间等待(并浪费)约4秒。如果按预期使用
    CompletableFuture
    ,则不会有这4秒的“死区时间”



    1-例如,某些外部代理可能能够选择性地“暂停”正在运行任务的线程。这可以通过设置断点来完成

    CompletableFuture
    的整个思想是,它们立即被安排启动(尽管您无法可靠地判断它们将在哪个线程中执行),当您到达
    get
    join
    时,结果可能已经准备好,即
    CompletableFuture
    可能已经完成。在内部,一旦管道中的某个阶段准备就绪,该特定的
    CompletableFuture
    将设置为completed。例如:

    String result = 
       CompletableFuture.supplyAsync(() -> "ab")
                        .thenApply(String::toUpperCase)
                        .thenApply(x -> x.substring(1))
                        .join();
    
    与以下内容相同:

    CompletableFuture<String> cf1 = CompletableFuture.supplyAsync(() -> "ab");
    CompletableFuture<String> cf2 = cf1.thenApply(String::toUpperCase);
    CompletableFuture<String> cf3 = cf2.thenApply(x -> x.substring(1));
    String result = cf3.join();
    
    这将输出:

    started work
    b
    

    因此,即使工作开始了,最终的值也是
    b
    ,而不是
    a

    ,你为什么不希望它运行呢?@LouisWasserman我学到的材料中没有任何东西是我没有写下来的。所以我认为它不会起作用。就像流Api的终端操作一样。@LouisWasserman,像反应流这样的设计很常见,对于初学者来说,“推”和“拉”方法之间的区别并不总是显而易见的。好问题。“拉”行为的其他示例:在Python中,生成器实际上什么都不做
    started work
    b