文章目录
- 含义
- 方法及示例
- void join()
- void join(long millis)
- join(long millis, int nanos)
- 使用场景分析
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0gTMx81dsQWZ4lmZf1GLlpXazVmcvwFciV2dsQXYtJ3bm9CX9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5SO2YTMzQmNihjY5cjMhV2YxYzXxAjNyQTMxMzLcJTMxIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
含义
翻看下源码的注释: Waits for this thread to die
乍理解起来有点晦涩, 简单来说: 等待该线程终止. 需要明确的是主线程等待子线程(假设有个子线程thread)的终止。即在主线程的代码块中,如果碰到了
thread.join()
方法,此时主线程需要等子线程
thread
结束了(Waits for this thread to die.),才能继续执行
thread.join()
之后的代码块。
后面会有示例说明
方法及示例
void join()
重点看注释 ,这里就不多说了。
package com.artisan.test;
import java.util.stream.IntStream;
public class JoinThreadDemo {
public static void main(String[] args) throws InterruptedException {
System.out.println(Thread.currentThread().getName() + " 主线程 start");
System.out.println("------------------------------------------------");
// 定义一个线程
Thread t = new Thread(() -> {
// 打印 1 到 10 的数字
IntStream.range(0, 10).forEach(i -> System.out.println(Thread.currentThread().getName() + ">>>>>>" + i));
Optional.of(Thread.currentThread().getName() + " 打印完毕").ifPresent(System.out::println);
},"artisan-thread");
// 启动线程
t.start();
// 在主线程中 ,开启了一个新的线程t ,调用 t.join方法,确保该线程执行结束后,才会继续执行主线程中剩下的逻辑
t.join();
Optional.of("------------------------------------------------").ifPresent(System.out::println);
System.out.println(Thread.currentThread().getName() + " 主线程 over");
}
}
输出:
可以看到 ,调用了
t.join()
后, 主线程main线程,一直等到该线程执行结束后,才继续执行main线程自己剩下的业务逻辑。
我们继续来看下在main线程开启多个线程,分别join的情况
package com.artisan.test;
import java.util.Optional;
import java.util.stream.IntStream;
public class JoinThreadDemo {
public static void main(String[] args) throws InterruptedException {
System.out.println(Thread.currentThread().getName() + " 主线程 start");
System.out.println("------------------------------------------------");
// 定义一个线程
Thread t = new Thread(() -> {
// 打印 1 到 10 的数字
IntStream.range(0, 10).forEach(i -> System.out.println(Thread.currentThread().getName() + ">>>>>>" + i));
Optional.of(Thread.currentThread().getName() + " 打印完毕").ifPresent(System.out::println);
},"artisan-thread");
Thread t2 = new Thread(() -> {
// 打印 1 到 10 的数字
IntStream.range(0, 10).forEach(i -> System.out.println(Thread.currentThread().getName() + ">>>>>>" + i));
Optional.of(Thread.currentThread().getName() + " 打印完毕").ifPresent(System.out::println);
},"littleART-thread");
// 启动线程
t.start();
t2.start();
// 在主线程中 ,开启了一个新的线程t ,调用 t.join方法,确保该线程执行结束后,才会继续执行主线程中剩下的逻辑
t.join();
t2.join();
Optional.of("------------------------------------------------").ifPresent(System.out::println);
System.out.println(Thread.currentThread().getName() + " 主线程 over");
}
}
日志输出如下
可以看到 , main线程依然是等待t1和t2执行完以后才继续执行自己的逻辑,但是t1 和 t2 是交替执行的,主要取决于CPU的调度,这是正确的。
void join(long millis)
等待多少毫秒后,如果未完成,继续当前线程的任务。
举个例子来演示下
package com.artisan.test;
import java.util.Optional;
import java.util.stream.IntStream;
public class JoinThreadDemo {
public static void main(String[] args) throws InterruptedException {
System.out.println(Thread.currentThread().getName() + " 主线程 start");
System.out.println("------------------------------------------------");
// 定义一个线程
Thread t = new Thread(() -> {
try {
// 先休眠10S,再输出 0 到 9
Thread.sleep(10_000);
Optional.of(Thread.currentThread().getName() + " 休眠结束...继续干活").ifPresent(System.out::println);
IntStream.range(0, 10).forEach(i -> System.out.println(Thread.currentThread().getName() + ">>>>>>" + i));
Optional.of(Thread.currentThread().getName() + " 打印完毕").ifPresent(System.out::println);
} catch (InterruptedException e) {
e.printStackTrace();
}
},"artisan-thread");
t.start();
// t 线程等待 1000毫秒 即 1秒,如果未完成,则不等待,继续主线程中逻辑
t.join(1000);
Optional.of("---------------等待1秒结束,继续主线程的业务----------------").ifPresent(System.out::println);
System.out.println(Thread.currentThread().getName() + " 主线程 over");
}
}
输出:
可以看到 线程t在调用
join(1000)
,等待1秒后,该任务没有完成,主线程继续执行剩下的逻辑, 执行完以后没有退出 是因为
t
这个线程是user thread ,而不是daemon thread, 所以还是会继续执行的。
join(long millis, int nanos)
这个其实和
join(long milli)
一样 ,只是等待的时间加上纳秒 wait for specified time (milliseconds + nanos). 没啥好演示的了。。。