引言:更多线程的认识可以看一篇博客:
JAVA-Thread类实现多线程-CSDN博客
一、join()的作用
我们知道线程是随机调度执行的,但是有时候我们需要另一个任务完成了,我们才能继续,这个时候我们就可以使用join去等待线程结束。
例如:别人向我转100万,需要转完了我再看是否接收到了100万。
二、代码举例
public static void main(String[] args) throws InterruptedException {Thread t = new Thread(() -> {for (int i = 0; i < 3; i++) {System.out.println("我正在向作者赚钱");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});System.out.println("作者准备接收钱");//创建t线程,并调用run方法t.start();//main线程等待t线程结束t.join();System.out.println("作者收到了,等待结束");}
结果:
谁调用join谁就等,在主线程中调用 t.join() ,就是main线程等待 “t” 线程结束。
三、join() 抛出的异常
除了join,sleep也会抛出这样的一个异常:
如果是run方法中使用,不能使用throws向上抛,因为Thread类中没有处理这个异常,我们只能使用try catch处理掉这个异常。
如果是在主方法中我们可以通过throws抛给JVM来处理这个异常,或者try catch 也是可以的:
四、join()的重载
方法 | 说明 |
public void join() | 死等线程结束 |
public void join(long millis) | 等待线程结束,最多millis毫秒 |
public void join(long millis , int nanos) | 同理,但可以更高精度(纳秒级别) |
第三种了解就可以了,普通的计算机很难精确到纳秒,精确到毫秒就不错了。
这里着重讲一下第三种,只要时间到就继续执行,不会等到 t 线程结束。
public static void main(String[] args) throws InterruptedException {Thread t = new Thread(() -> {//大概5秒for (int i = 0; i < 5; i++) {System.out.println("hello Thread");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});t.start();System.out.println("main开始等待");//大概3秒t.join(3000);System.out.println("main等待结束");}
任意线程都可以进行等待,不是只有主线程可以去等待别的线程。
五、多个线程的等待
public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {//大概5秒for (int i = 0; i < 5; i++) {System.out.println("hello t1");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});Thread t2 = new Thread(() -> {//大概5秒for (int i = 0; i < 5; i++) {System.out.println("hello t2");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});t1.start();t2.start();System.out.println("main开始等待");//大概3秒t1.join();t2.join();System.out.println("main等待结束");}
这样写可以保证线程之间的执行关系:
public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {//大概5秒for (int i = 0; i < 3; i++) {System.out.println("hello t1");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});Thread t2 = new Thread(() -> {//大概5秒for (int i = 0; i < 3; i++) {System.out.println("hello t2");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});t1.start();t1.join();t2.start();t2.join();}