gpt4 book ai didi

multithreading - 在主线程上等待回调方法

转载 作者:行者123 更新时间:2023-12-01 22:58:20 24 4
gpt4 key购买 nike

我是 Scala 的新手,关注 Scala Book Concurrency 部分(来自 docs.scala-lang.org)。基于他们在书中给出的示例,我编写了一个非常简单的代码块来测试使用 Futures:

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Failure, Success}

object Main {
def main(args: Array[String]): Unit = {
val a = Future{Thread.sleep(10*100); 42}
a.onComplete {
case Success(x) => println(a)
case Failure(e) => e.printStackTrace
}
Thread.sleep(5000)
}
}

编译并运行时,正确打印出:

Future(Success(42))

到控制台。我无法理解为什么 Thread.sleep() 调用出现在 onComplete 回调方法之后。直觉上,至少对我来说,会在回调之前调用 Thread.sleep(),所以当主线程到达 onComplete 方法时 a 被分配了一个值。如果我将 Thread.sleep() 调用移动到 a.onComplete 之前,控制台不会打印任何内容。我可能想得太多了,但我们将不胜感激任何有助于澄清的问题。

最佳答案

注册回调后使用Thread.sleep()

    a.onComplete {
case Success(x) => println(a)
case Failure(e) => e.printStackTrace
}
Thread.sleep(5000)

然后正在执行 future 主体的线程有时间休眠一秒钟,并将 42 设置为 future 成功执行的结果。到那时(大约 1 秒后),onComplete 回调已经注册,因此线程也会调用它,您会在控制台上看到输出。

顺序基本上是:

  • t = 0:守护线程开始计算 42
  • t = 0:主线程创建并注册回调。
  • t = 1: 守护线程完成42
  • 的计算
  • t = 1 + eps:守护线程找到已注册的回调并使用结果调用它 Success(42)
  • t = 5: 主线程终止
  • t = 5 + eps:程序停止。

(我非正式地使用 eps 作为一些相当小的时间间隔的占位符;+ eps 的意思是“几乎紧接着”。)

如果交换 a.onComplete 和外部 Thread.sleep

    Thread.sleep(5000)
a.onComplete {
case Success(x) => println(a)
case Failure(e) => e.printStackTrace
}

然后执行 future 主体的线程将在一秒后计算结果 42,但它不会看到任何已注册的回调(它必须再等四秒直到回调在主线程上创建和注册)。但是一旦过了 5 秒,主线程注册回调并立即退出。即使到那时它有机会知道结果 42 已经被计算出来,主线程也不会尝试执行回调,因为这不关它的事(那是线程在执行上下文是为了)。因此,在注册回调后,主线程立即退出。有了它,线程池中的所有守护线程都被杀死,程序退出,这样你在控制台就什么也看不到了。

通常的事件顺序大致是这样的:

  • t = 0:守护线程开始计算 42
  • t = 1:守护线程完成了 42 的计算,但不能对它做任何事情。
  • t = 5: 主线程创建并注册回调
  • t = 5 + eps:主线程终止,守护线程被杀死,程序停止。

这样(几乎)没有时间守护线程可以唤醒、找到回调并调用它。

关于multithreading - 在主线程上等待回调方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72494239/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com