加入和睡眠的两个代码块。难以确定为什么输出为3,5,5,所有3个线程,然后是4,4,4,然后3,3,3等等。相反,它应该首先等待第一个线程完成,然后再次打印5,4,3,2,1。
public class DemoJoin {
public static void main(String args[]) {
NewThread ob1 = new NewThread("One");
NewThread ob2 = new NewThread("Two");
NewThread ob3 = new NewThread("Three");
/*System.out.println("Thread One is alive: "
+ ob1.t.isAlive());
System.out.println("Thread Two is alive: "
+ ob2.t.isAlive());
System.out.println("Thread Three is alive: "
+ ob3.t.isAlive());*/
// wait for threads to finish
try {
System.out.println("Waiting for threads to finish.");
ob1.t.join();
ob2.t.join();
ob3.t.join();
} catch (Exception e) {
System.out.println("Main thread Interrupted");
}
System.out.println("Thread One is alive: "
+ ob1.t.isAlive());
System.out.println("Thread Two is alive: "
+ ob2.t.isAlive());
System.out.println("Thread Three is alive: "
+ ob3.t.isAlive());
System.out.println("Main thread exiting.");
}
}
线程类:
package com.demo.test;
public class NewThread implements Runnable {
String name; // name of thread
Thread t;
NewThread(String threadname) {
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
t.start(); // Start the thread
}
// This is the entry point for thread.
public void run() {
try {
for(int i = 5; i > 0; i--) {
System.out.println(name + ": " + i);
Thread.sleep(1000);
}
} catch (Exception e) {
System.out.println(name + " interrupted.");
}
System.out.println(name + " exiting.");
}
}
问题是如果我没有注释睡眠,我从所有3个线程获得5,5,5然后是4,4,4等等。
但是使用Join,第二个线程应该等待第一个线程完成。即我的输出应该是来自第一个线程的5,4,3,2,1然后再来自第二个线程的5,4,3,2,1。
如果我取消注释睡眠,那么我会得到确切的输出。
我想理解为什么睡眠导致所有3个线程同时执行,即使存在连接。
答案 0 :(得分:2)
但是使用Join,第二个线程应该等待第一个线程完成
join
没有序列化你创建的三个线程之间的线程执行,相反,join
将阻塞主线程,直到每个创建的线程完成,在序列中{ {1}},ob1
,ob2
。
您已经启动了3个后台线程运行(在ob3
构造函数中),因此在主线程命中第一个NewClass
之前已经发生了并行执行。
来自docs
join方法允许一个线程等待另一个线程的完成。 ...
join
会导致当前线程暂停执行,直到该线程终止。 (强调我的)
这里你实际上有4个主题 - main,以及你创建的三个主题。
一旦启动,三个线程将因此同时执行(因此打印输出的排序不稳定),并且主线程将阻塞,直到所有三个完成。
回复:
如果我取消注释睡眠,那么我会得到确切的输出。
这里也不能保证 - 只是在您的设置中没有1秒睡眠时,第一个线程在第二个线程开始输出之前完全完成。我得到的输出是:
t.join();