【问题标题】:Java Thread.join : what is the behaviour when calling join on multiple threadsJava Thread.join:在多个线程上调用 join 时的行为是什么
【发布时间】:2018-05-30 13:32:22
【问题描述】:

这里是一些示例代码。 MyRunnable 类只打印“Thread x started”,并且有一个 Thread.sleep(4000)。其余的对我的问题并不重要。以下代码在另一个类中:

Thread t1 = new Thread(new MyRunnable, "t1");
Thread t2 = new Thread(new MyRunnable, "t2");
Thread t3 = new Thread(new MyRunnable, "t3");

t1.start(); t2.start(); t3.start();

try {
  t1.join();
  t2.join();
  t3.join();
} catch(InterruptedException e) {
 ...

我知道join 会强制程序等待this 线程完成。因此,在阅读程序时,我期望 t1->t2->t3 是终止的顺序。但是,我同时终止了 t1、t2 和 t3。

问题:上面的代码发生了什么(从运行时的角度来看)?执行顺序是什么?

谢谢

【问题讨论】:

  • 没有必要。当您到达t1.join() 时,所有或部分线程已经可以完成运行。
  • 顺便说一句,您设置的线程没有执行顺序。 JVM 可以选择在t1t2 之前完成t3
  • 您应该问自己的问题是:“谁在等待线程?” (ps.我想只有主线程在等待)
  • "其余的对我的问题并不重要" - 至少应该提供一个MCVE

标签: java multithreading concurrency


【解决方案1】:

当您start 线程时,JVM 会安排它们执行。那时,它们和创建它们的线程都在 CPU 内核上竞争运行时。没有预定义的顺序,它们将获得该运行时,如果有足够的内核可用,它们可能都并行运行。

我希望 t1->t2->t3 是终止顺序

不一定。您的joins 将按顺序执行,这意味着调用线程将等到它看到t1 已终止,然后等到它看到t2 已终止,然后等到它看到t3 已终止;但这只是您检查(并在必要时等待)。它们可以按任何顺序运行和完成。

想象自己在一个有三扇门的走廊里。每扇门后面都有一个拿着笔记本的人。你沿着走廊走,敲了敲每一扇门。这告诉每个有笔记本的人在笔记本上写一些东西。然后你打开第一扇门:如果这个人写完了,你就去隔壁;如果没有,你等到他们完成,然后继续前进。然后你用第二扇门,然后用第三扇门。人们可能以任何顺序完成写作,但您按顺序检查了他们:第一,第二,第三。

【讨论】:

  • 所以没有“暂停”?据我了解,主线程正在暂停一切,直到线程 t1 终止。我从您的回复中得到的是所有线程都在后台继续。但是,主线程正在等待 t1 继续
  • @S.Castro:发出t1.join() 调用的线程被暂停(可能),但该线程,而不是任何其他线程。然后,一旦join 返回并且代码调用t2.join(),同一个线程(可能)等待,等等。
【解决方案2】:

大多数时候,名称非常重要且不言自明; 调用线程会等待直到:

1.线程t1加入它

2.线程t2加入它

3.线程 t3 加入它。

在这些加入调用返回之前,之后的任何事情都不会被执行。 存在其他形式的 join(),我们指定了我们希望等待给定线程终止的最长时间。

线程 (t1, t2, t3) 当然可以以不同的顺序完成,不保证终止的顺序。这似乎是合乎逻辑的,因为他们可能正在执行不同时间复杂度的不同任务。

已经很好地讨论了见Java Multithreading concept and join() method

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多