这个线程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 :
等待这个线程死亡。
有一个线程正在运行您的示例代码,这可能是主线程 。
- 主线程创build并启动
t1
和t2
线程。 两个线程开始并行运行。 - 主线程调用
t1.join()
等待t1
线程完成。 -
t1
线程完成,t1.join()
方法在主线程中返回。 请注意,t1
可能在join()
调用之前已经完成,在这种情况下join()
调用将立即返回。 - 主线程调用
t2.join()
等待t2
线程完成。 -
t2
线程完成(或者它可能在t1
线程完成之前完成)并且t2.join()
方法在主线程中返回。
理解t1
和t2
线程并行运行是非常重要的,但是启动它们的主线程需要等待它们完成才能继续运行。 这是一种常见的模式。 另外, t1
和/或t2
可能在主线程调用join()
之前完成。 如果是的话join()
不会等待,而是立即返回。
t1.join()
意味着导致t2停止,直到t1终止?
不。调用t1.join()
的主线程将停止运行,并等待t1
线程完成。 t2
线程并行运行,不受t1
或t1.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
的情况也是如此。 无论谁启动t1
或t2
线程(在这种情况下是main
方法),main将等到t1
和t2
完成任务。
然而,重要的一点是, t1
和t2
本身可以并行运行,而不pipe t1
和t2
上的连接调用顺序如何。 这是必须等待的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实现。 一些例子是
- 在
ExecutorService
上使用invokeAll - 使用CountDownLatch
- 使用ForkJoinPool或newWorkStealingPool的
Executors
(自java 8以来)
参考相关的SE问题:
等到所有的线程在java中完成他们的工作