我正在研究Thread join()方法,我遇到了ThreadJoinMethod帖子 在stackoverflow上。我修改了代码以开发一个工作示例,我很困惑 输出。代码段是。
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
我对输出感到困惑。在t1上调用join
后,将连接当前线程
和t2,但为什么语句"Currently Running Thread: main"
在t1和t2之后打印
完成?我在这里错过了一些重要的概念吗?因为main()将在之后加入t1和t2
之前的连接语句。有人可以详细说明吗?
答案 0 :(得分:4)
线程在您调用start()
后启动。这意味着它可以在任何后续行之前启动,甚至可以在它之后的行之前完成。
答案 1 :(得分:2)
你正在以错误的方式解释它。 join()
方法会导致main
主题等待t1
和t2
。因此,在main
和t1
完成之前,t2
不会退出。首先打印的是完全随意的,主要取决于线程的优先级。要设置预定义的行为,您必须同步线程。
答案 2 :(得分:2)
System.out.println
实例 OutputStream
同步(至少在我在PC上的实现中)。
每个println
之间的时间间隔非常短,因此来自另一个线程的println
很可能无法执行。
所以看起来你在println
上有一定的顺序(至少很有可能)。插入一些 sleeps 并让循环计数更高,你应该能够观察到不同的行为。
答案 3 :(得分:1)
这只是跑得太快了。在这两个线程中插入一个短暂的睡眠。
答案 4 :(得分:1)
以下是join()
方法的说明:
Blocks the current Thread (Thread.currentThread()) until the receiver finishes its execution and dies.
(来自javadoc)
实际上,你可能会阻止等待t1&amp;的主线程。 t2停止。
答案 5 :(得分:1)
线程t1和t2在您的陈述
之前开始并完成了他们的工作 System.out.println("Currently running thread: " + Thread.currentThread().getName());
实际上可以在屏幕上产生任何输出。因此线程t1和t2已经完成了它们的任务,并且主线程可以在线程加入时通过run()方法完成。
如果你想学习和理解加入两个线程的概念,请在run方法的for循环中提供Thread.sleep(1000)。