这个线程join代码是什么意思?

在这个代码中,这两个连接和中断是什么意思? t1.join()导致t2停止,直到t1终止?

 Thread t1 = new Thread(new EventThread("e1")); t1.start(); Thread t2 = new Thread(new EventThread("e2")); t2.start(); while (true) { try { t1.join(); t2.join(); break; } catch (InterruptedException e) { e.printStackTrace(); } } 

引用Thread.join()方法javadocs :

等待这个线程死亡。

有一个线程正在运行您的示例代码,这可能是主线程 。

  1. 主线程创build并启动t1t2线程。 两个线程开始并行运行。
  2. 主线程调用t1.join()等待t1线程完成。
  3. t1线程完成, t1.join()方法在主线程中返回。 请注意, t1可能在join()调用之前已经完成,在这种情况下join()调用将立即返回。
  4. 主线程调用t2.join()等待t2线程完成。
  5. t2线程完成(或者它可能在t1线程完成之前完成)并且t2.join()方法在主线程中返回。

理解t1t2线程并行运行是非常重要的,但是启动它们的主线程需要等待它们完成才能继续运行。 这是一种常见的模式。 另外, t1和/或t2可能在主线程调用join() 之前完成。 如果是的话join()不会等待,而是立即返回。

t1.join()意味着导致t2停止,直到t1终止?

不。调用t1.join()线程将停止运行,并等待t1线程完成。 t2线程并行运行,不受t1t1.join()调用的影响。

在try / catch方面, join()抛出InterruptedException意味着正在调用join()的主线程本身可能被另一个线程中断。

这是一个最喜欢的Java面试问题。

 Thread t1 = new Thread(new EventThread("e1")); t1.start(); Thread e2 = new Thread(new EventThread("e2")); t2.start(); while (true) { try { t1.join(); // 1 t2.join(); // 2 These lines (1,2) are in in public static void main break; } } 

t1.join()表示t1表示类似于“ 我想先完成 ”的事情。 t2的情况也是如此。 无论谁启动t1t2线程(在这种情况下是main方法),main将等到t1t2完成任务。

然而,重要的一点是, t1t2本身可以并行运行,而不pipe t1t2的连接调用顺序如何。 这是必须等待main/daemon线程。

join()意味着等待一个线程完成。 这是一个阻止方法。 你的主线程( join()那个线程)将在t1.join()行等待,直到t1完成它的工作,然后为t2.join()做同样的t2.join()

当线程tA调用tB.join()时,它的原因不仅仅是等待tB死亡或者tA被中断,而是在tB线程中tB.join()之后的下一个语句之间的关系之前创build。

线程中的所有操作都会在任何其他线程从该线程上的join()成功返回之前发生。

这意味着程序

 class App { // shared, not synchronized variable = bad practice static int sharedVar = 0; public static void main(String[] args) throws Exception { Thread threadB = new Thread(() -> {sharedVar = 1;}); threadB.start(); threadB.join(); while (true) System.out.print(sharedVar); } } 

始终打印

 >> 1111111111111111111111111 ... 

但是程序

 class App { // shared, not synchronized variable = bad practice static int sharedVar = 0; public static void main(String[] args) throws Exception { Thread threadB = new Thread(() -> {sharedVar = 1;}); threadB.start(); // threadB.join(); COMMENT JOIN while (true) System.out.print(sharedVar); } } 

不仅可以打印

 >> 0000000000 ... 000000111111111111111111111111 ... 

 >> 00000000000000000000000000000000000000000000 ... 

始终只有“0”。

由于Java内存模型不需要将“sharedVar”的新值从threadB转移到主线程而没有heppens-before关系(线程启动,线程连接,“synchonized”关键字的使用,AtomicXXXvariables的使用等)。

从联接的 oracle文档页面

join方法允许一个线程等待另一个线程的完成。

如果t1是线程正在执行的Thread对象,

 t1.join() : causes the current thread to pause execution until t1's thread terminates. 

如果t2是线程当前正在执行的Thread对象,

 t2.join(); causes the current thread to pause execution until t2's thread terminates. 

join API是低级的API,已经在早期版本的Java中引入。 许多事情在一段时间内(特别是在jdk1.5版本上)在并发前端已经改变了。

你可以用java.util.concurrent API实现。 一些例子是

  1. ExecutorService上使用invokeAll
  2. 使用CountDownLatch
  3. 使用ForkJoinPool或newWorkStealingPool的Executors (自java 8以来)

参考相关的SE问题:

等到所有的线程在java中完成他们的工作