我们的老师给了我们以下代码:
public static void main(String[]args) {
Thread a = new Thread(new T(2));
Thread b = new Thread(new T(5));
a.start();
b.start();
try {
a.join(); //Thread a now runs completely to the end, before the main-method gets back to a "runnable" state
b.join(); //Thread b runs to death before the main methods u
} catch (InterruptedException ie) {}
System.out.println("done"); //Result: Random Thread a and b outputs
//and in the end "done" from main
}
public class T extends Thread {
private int nr;
public T(int nr) {
this.nr = nr;
}
public void run() {
for (int i=0; i<10; i++) {
System.out.println("Hello " + nr + " " + i);
}
}
线程a和b是相同的,并且两个写入(在for循环中)10都打印到控制台。 在主方法停止之前,线程a和b已完成,除主方法外,所有结果都是随机的。
我的问题是,如果它不应该阻止其他线程(不仅仅是main),如果你在一个线程上调用join()
。他说,join()只是冻结了主要方法。但出于什么原因这应该是好的?他还说,这是完全随机的并且由调度程序管理,在我看来这对于这部分没有意义(调度程序命令线程状态,这很明显,但是在调用join()之后没有,至少不适用于java应用程序。或者我是假的?)。我的观点是,在主线程甚至调用join方法之前,线程a和b完全运行到最后。如果我理解正确的话,Javadoc会告诉我同样的事情。
我希望你们中的某个人能给我一个答案。 :)
答案 0 :(得分:3)
join()
实例上对Thread
的调用将无法完成,直到与该实例对应的线程终止。
Corrollary 1:如果该线程已经死亡,join()
会立即返回。
Corrollary 2:此电话不会影响当前线程以外的线程。
他还说,这完全是随机的,由调度程序管理
你可能没有准确地抓住老师在这里说的话。线程调度,这意味着在线程调度程序完成时,线程将被赋予一些CPU运行时间以及多少CPU时间。绝对不是&#34;完全随机&#34;并且出于大多数实际考虑,所有线程始终运行。同样,这与join
方法的行为没什么关系。
答案 1 :(得分:0)
join
的要点不是让所有其他线程优先于单个线程。相反,它表示一个线程需要等待另一个线程在该(第一个)线程继续之前完成。它并不总是调用join
的主线程。这是对调度程序的一个约束:“在你完成B之前不要做A”。当然,通过使用多个join
,您可以实现更复杂的依赖关系。
答案 2 :(得分:0)
我怀疑老师试图做的是你不能假设除了join
的合同之外的任何东西。即在a
运行完成之前,主线程不会继续。
a.join()
很可能允许b
继续,但在b
完成之前,它也可能完全阻止a
。
如果您在单核计算机上测试此代码,a.join()
很可能会排除b
,但在多核计算机上可能不会。{/ p>