“Java join 线程”的版本间的差异
跳到导航
跳到搜索
Jihongchang(讨论 | 贡献) |
Jihongchang(讨论 | 贡献) |
||
第83行: | 第83行: | ||
从控制台输出可以看出,主线程执行到 i==20 时启动,并 join 了名为“被 Join 的线程”的线程,所以主线程将一直处于阻塞状态,直到名为“被 Join 的线程”的线程执行完成。 | 从控制台输出可以看出,主线程执行到 i==20 时启动,并 join 了名为“被 Join 的线程”的线程,所以主线程将一直处于阻塞状态,直到名为“被 Join 的线程”的线程执行完成。 | ||
+ | |||
+ | |||
+ | |||
=== join() 方法的3种重载形式 === | === join() 方法的3种重载形式 === |
2023年2月20日 (一) 11:48的最新版本
Thread 提供了一个线程等待另一个线程完成的方法——join()方法。
当在某个程序执行流中调用其他线程的 join() 方法时,调用线程将被阻塞,知道被 join() 方法加入的 join 线程执行完为止。
join() 方法通常由使用线程的程序调用,以将大问题划分成许多小问题,每个小问题分配一个线程。
当所有的小问题都得到处理后,再调用主线程来进一步操作。
代码
JoinThread.java
public class JoinThread extends Thread {
// 提供一个有参数的构造器,用于设置该线程的名字
public JoinThread(String name) {
super(name);
}
// 重写 run() 方法,定义线程执行体
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(getName() + " " + i);
}
}
}
Test.java
public class Test {
public static void main(String[] args) throws InterruptedException {
// 启动子线程
new JoinThread("新线程").start();
for(int i = 0; i< 100; i++) {
if (i == 20) {
JoinThread jt = new JoinThread("被 Join 的线程");
jt.start();
// main 线程调用了 jt 线程的 join 方法,main 线程必须等 jt 执行结束才会向下执行
jt.join();
}// end if
System.out.println(Thread.currentThread().getName() + " " + i);
} //end for
}// end main
}
……
main 16
新线程 93
新线程 94
新线程 95
新线程 96
main 17
新线程 97
新线程 98
main 18
新线程 99
main 19
被 Join 的线程 0
被 Join 的线程 1
被 Join 的线程 2
被 Join 的线程 3
……
被 Join 的线程 96
被 Join 的线程 97
被 Join 的线程 98
被 Join 的线程 99
main 20
main 21
main 22
……
main 99
上面程序中一共有3个线程,主方法开始时就启动了名为“新线程”的子线程,该子线程会和 main 线程并发执行。
当主线程的循环变量 i 等于 20 时,启动了名为“被 Join 的线程”的线程,该线程不会和 main 线程并发执行,main 线程必须等该线程执行结束后才可以向下执行。
在名为“被 Join 的线程”执行时,实际上只有2个子线程并发执行,而主线程处于等待状态。
从控制台输出可以看出,主线程执行到 i==20 时启动,并 join 了名为“被 Join 的线程”的线程,所以主线程将一直处于阻塞状态,直到名为“被 Join 的线程”的线程执行完成。
join() 方法的3种重载形式
- join():等待被 join 的线程执行完成
- join(long millis):等待被 join 的线程的时间最长为 millis 毫秒。如果在 millis 毫秒内被 join 的线程还没有执行结束,则不再等待。
- join(long millis, int nanos):等待被 join 的线程的时间最长为 millis 毫秒加 nanos 纳秒。
通常我们很少使用第3种形式的方法,原因有两个:程序对时间的精度无须精确到纳秒;计算机硬件、操作系统本身也无法精确到纳秒。