16.4 控制线程 16.4.1 join线程

16.4 控制线程

Java的线程(Thread类)支持提供了一些便捷的工具方法,通过这些便捷的工具方法可以很好地控制线程的执行.

16.4.1 join线程

join方法

**join方法可以让一个线程等待另一个线程完成**。

join()方法有如下三种重载形式

Thread类的join方法 描述
void join() 等待被join的线程执行完成。
void join(long millis) 等待被join的线程的时间最长为millis毫秒。如果在millis毫秒内被join的线程还没有执行结束,则不再等待。
void join(long millis, int nanos) 等待被join的线程的时间最长为millis毫秒加nanos毫微秒。很少使用这种形式,原因有两个:程序对时间的精度无须精确到毫微秒;计算机硬件、操作系统本身也无法精确到毫微秒。

当前线程 等待 调用join方法的线程

例如,在当前线程中调用如下代码:

1
B.join();

当前线程要等待B线程运行结束.
这个当前线程要看调用join方法的代码位于哪个线程中

  • 如果在主线程的代码中调用B.join(),则主线程必须等待B线程执行完毕
  • 如果在A线程的代码中调用B.join(),则线程A必须等待线程B执行完毕

join方法的作用

join方法通常由使用线程的程序调用,以将大问题划分成许多小问题,每个小问题分配一个线程。当所有的小问题都得到处理后,再调用主线程来进一步操作。

程序 join方法示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class JoinThread extends Thread {
// 提供一个有参数的构造器,用于设置该线程的名字
public JoinThread(String name) {
super(name);
}

// 重写run()方法,定义线程执行体
public void run() {
for (int i = 0; i <= 30; i++) {
System.out.println(getName() + " " + i);
if(i==30){
System.out.println("================== "+getName()+" 死亡");
}
}
}

public static void main(String[] args) throws Exception {
// 启动子线程
new JoinThread("线程A").start();
for (int i = 0; i < 30; i++) {
if (i == 10) {
JoinThread jt = new JoinThread("线程B");
jt.start();
// main线程中调用了jt线程的join()方法
// main线程必须等jt执行结束才会向下执行
System.out.println("-----------------主线程 等待 线程B 开始---------------------");
jt.join();
System.out.println("-----------------主线程 等待 线程B 结束---------------------");
}
System.out.println("主线程 " + i);
}
System.out.println("================== 主线程 死亡");
}
}

运行效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
主线程  0
线程A 0
主线程 1
......
主线程 8
线程A 7
主线程 9
线程A 8
-----------------主线程 等待 线程B 开始---------------------
线程B 0
线程A 9
线程B 1
线程A 10
......
线程A 28
线程B 22
线程A 29
线程B 23
线程A 30
线程B 24
================== 线程A 死亡
线程B 25
线程B 26
......
线程B 29
线程B 30
================== 线程B 死亡
-----------------主线程 等待 线程B 结束---------------------
主线程 10
主线程 11
......
主线程 28
主线程 29
================== 主线程 死亡

分析

上面程序中一共有3个线程:

  • 主线程开始时就启动线程A,然后,线程A将会和主线程并发执行。
  • 主线程的循环变量i等于10时,启动线程B,线程B不会和主线程并发执行,主线程必须等线程B执行结束后才可以向下执行
  • 线程B的线程执行时,实际上只有线程A线程B这2个子线程并发执行,而主线程处于等待状态。