2

我正在研究 Thread join() 方法,我遇到了 stackoverflow 上的ThreadJoinMethod帖子。我修改了代码以开发一个工作示例,但我对输出感到困惑。代码片段是。

class JoinRunnable implements Runnable{

  public void run() {
    for(int i =0 ; i < 4 ; i++){
      System.out.println(i);
    }
  }
}
public class TestJoin{
  public static void main(String[] args) throws InterruptedException {
    JoinRunnable joinRunnable = new JoinRunnable();
    Thread t1 = new Thread(joinRunnable);
    Thread t2 = new Thread(joinRunnable);
    t1.start();
    t2.start();
    System.out.println("Currently running thread: " + Thread.currentThread().getName());
    t1.join();
    t2.join();
    System.out.println("I must wait");
  }
}

以下程序的输出是:-

0
1
2
3
0
1
2
3
Currently running thread: main
I must wait

我对输出感到困惑。当前线程将在调用joint1 和 t2 后加入,但为什么语句"Currently Running Thread: main"在 t1 和 t2 完成后打印?我在这里错过了一些重要的概念吗?因为 main() 将在连接语句之后而不是之前连接 t1 和 t2。有人可以详细说明吗?

4

6 回答 6

4

线程在您调用之后开始start() 这意味着它可以在任何之后的行之前开始,甚至可以在它之后的行之前完成。

于 2013-08-07T13:49:22.367 回答
2

System.out.println在底层实例上同步(至少我的 PC 上的实现中)。OutputStream

每个之间的时间间隔println非常短,因此println来自另一个线程的 a 不太可能有机会被执行。

所以看起来你有一定的顺序println(至少很有可能)。插入一些睡眠并让循环计数更高,您应该能够观察到不同的行为。

于 2013-08-07T13:57:16.793 回答
2

您正在以错误的方式解释它。join()方法导致main线程等待t1t2。所以在andmain完成之前不会退出。首先打印什么是完全任意的,主要取决于线程的优先级。要设置预定义的行为,您必须同步线程。t1t2

于 2013-08-07T13:50:26.610 回答
1

以下是该join()方法的描述:(
Blocks the current Thread (Thread.currentThread()) until the receiver finishes its execution and dies.来自 javadoc)
确实,您可能会阻塞正在等待 t1 和 t2 停止的主线程。

于 2013-08-07T13:52:35.947 回答
1

线程 t1 和 t2 在您的声明之前开始并完成了他们的工作

 System.out.println("Currently running thread: " + Thread.currentThread().getName());

实际上可以在屏幕上产生任何输出。所以线程 t1 和 t2 已经完成了他们的任务,主线程可以继续前进,因为加入的线程是通过他们的 run() 方法完成的。

如果您想学习和理解连接两个线程的概念,请在运行方法的 for 循环中提供 Thread.sleep(1000)。

于 2013-08-07T14:07:19.703 回答
1

这只是跑得太快了。在这两个线程中插入一个短暂的睡眠。

于 2013-08-07T13:49:52.203 回答