在这段代码中,两者加入和断开是什么意思? 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();
}
}
答案 0 :(得分:281)
引用Thread.join()
method javadocs:
join()
等待此线程死亡。
有一个线程正在运行您的示例代码,可能是main thread。
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()
的 main 线程将停止运行并等待t1
线程完成。 t2
主题并行运行,完全不受t1
或t1.join()
调用的影响。
就try / catch而言,join()
抛出InterruptedException
意味着调用join()
的主线程本身可能会被另一个线程中断。
while (true) {
在while
循环中使用连接是一种奇怪的模式。通常,您将执行第一个连接,然后在每种情况下适当地处理InterruptedException
的第二个连接。无需将它们放在循环中。
答案 1 :(得分:64)
这是最喜欢的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
本身可以并行运行,而不管t1
和{{上的加入调用序列 1}}。 t2
主题必须等待。
答案 2 :(得分:43)
join()
表示等待线程完成。这是一种阻止方法。您的主线程(执行join()
的线程)将在t1.join()
行等待t1
完成其工作,然后对t2.join()
执行相同操作。
答案 3 :(得分:17)
一张图片胜过千言万语。
Main thread-->----->--->-->--block##########continue--->---->
\ | |
sub thread start()\ | join() |
\ | |
---sub thread----->--->--->--finish
希望有用,有关详细信息,请点击here
答案 4 :(得分:8)
当线程tA调用tB.join()时,其原因不仅等待tB死亡或tA自身中断,而且创建发生在tB中的最后一个语句与tA线程中tB.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内存模型不需要转移' “共享”的新价值'从threadB到主线程没有heppens-before关系(线程开始,线程连接,'同步'关键字的使用,AtomicXXX变量的使用等)。
答案 5 :(得分:2)
来自oracle文档page on Joins
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中引入。在并发方面,很多事情都在一段时间内发生了变化(尤其是jdk 1.5发布)。
您可以使用java.util.concurrent API实现相同的功能。一些例子是
ExecutorService
Executors
或{{1}} {{1}}(自java 8开始)参考相关的SE问题:
答案 6 :(得分:2)
简单地说:
t1.join()
完成t1
后返回。
除了等待它完成之外,它对t1
进行线程无效。
当然,代码如下
t1.join()
只会在执行之后执行
t1.join()
返回。
答案 7 :(得分:0)
对我来说,Join()的行为总是令人困惑,因为我试图记住谁将等待谁。 不要试图那样记住它。
在下面,它是纯的wait()和notify()机制。
我们都知道,当我们在任何对象(t1)上调用wait()时,调用对象(主)都会发送到等候室(处于阻塞状态)。
在这里,主线程正在调用join(),它是幕后的wait()。因此主线程将等待,直到通知它。 在t1结束运行(线程完成)时发出通知。
收到通知后,main从等候室出来并继续执行。
答案 8 :(得分:0)
希望有帮助!
package join;
public class ThreadJoinApp {
Thread th = new Thread("Thread 1") {
public void run() {
System.out.println("Current thread execution - " + Thread.currentThread().getName());
for (int i = 0; i < 10; i++) {
System.out.println("Current thread execution - " + Thread.currentThread().getName() + " at index - " + i);
}
}
};
Thread th2 = new Thread("Thread 2") {
public void run() {
System.out.println("Current thread execution - " + Thread.currentThread().getName());
//Thread 2 waits until the thread 1 successfully completes.
try {
th.join();
} catch( InterruptedException ex) {
System.out.println("Exception has been caught");
}
for (int i = 0; i < 10; i++) {
System.out.println("Current thread execution - " + Thread.currentThread().getName() + " at index - " + i);
}
}
};
public static void main(String[] args) {
ThreadJoinApp threadJoinApp = new ThreadJoinApp();
threadJoinApp.th.start();
threadJoinApp.th2.start();
}
//Happy coding -- Parthasarathy S
}
答案 9 :(得分:-3)
让我们说主线程启动线程t1和t2。现在,当调用t1.join()时,主线程会自行挂起,直到线程t1死掉,然后自行恢复。 类似地,当t2.join()执行时,主线程再次挂起,直到线程t2死亡然后恢复。
所以,这就是它的工作原理。
此外,这里并不真正需要while循环。