面试专题:如何实现主线程等待子线程运行完在执行

2024-01-25 09:42:41 浏览数 (1)

前言

在Java中,主线程和子线程是并行运行的,这意味着它们可以同时执行。然而,有时候我们需要在子线程执行完毕后,主线程才能继续执行。这时,我们可以使用线程的join()方法来实现主线程等待子线程运行完成再执行,这个在面试中,如果问到线程相关的知识,这个也是必问,本文就来讲解Thread的join方法,如何让主线程等待子线程运行完在执行。

一、join()方法的使用

join()方法是一个线程类的方法,用于等待当前线程终止。当调用join()方法时,当前线程将被挂起,直到被等待的线程终止。例如,

join()方法的原理就是:

将指定的Thread实例对象作为锁对象,在其上进行同步,只要那个线程还活着,那么就会持续等待(或者有限时长)线程终止之后会调用自身this.notifyAll,以通知在其上等待的线程。简单说,只要他活着大家就都等着, 他死了会通知,所以效果就是在哪里调用了谁的join,哪里就要等待这个线程结束,才能继续。      

join有三个方法,实际调用wait方法

代码语言:java复制
thread.join();
代码语言:java复制
public final native void wait(long timeout) throws InterruptedException;

join()方法还有一个重载版本,可以接受一个超时时间参数,该参数表示主线程等待子线程的最长时间。如果子线程在超时时间内没有完成执行,主线程将继续执行。

代码语言:java复制
thread.join(100);
thread.join(1000,10);

二、join()案例代码

上面介绍,join的用法,接来直接用代码演示。首先创建了一个子线程,然后启动它。接着,我们在主线程中调用子线程的join()方法,这将导致主线程等待子线程执行完毕。在子线程执行完毕后,主线程将继续执行。

代码语言:java复制
package com.multi.thread.join;


public class TestJoin {
    public static void main(String[] args) {
        Object lock = new Object();
        //开启一个子线程
        Thread thread = new Thread(() -> {
            for (int i = 0; i < 5; i  ) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()   " : working" ":" Thread.currentThread().getState());
            }
        });
        thread.setName("t1");
        thread.start();

       try {
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(thread.getState());
        System.out.println(Thread.currentThread().getName() ":main end:" Thread.currentThread().getState());
    }
}

点击thread.join()可以看到join源码,底层调用的还是wait方法

上面join类似自定义的wait()方法,不过不建议使用,因为join方法会判断线程是否isAlive,将当前线程对象thread作为锁对象。

代码语言:javascript复制
synchronized (thread) {
    try {
        thread.wait();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

thread.wait()表示对当前方法(main)线程进行阻塞(block),导致主线程会等待thread线程唤醒通过jps命令查看java运行线程,jstack 线程id,可以看到主线程main的状态是WAITING

总结

本文介绍了如何实现主线程等待子线程运行完成再执行的方法,通过线程的join()方法来实现。join()方法可以使主线程等待子线程执行完成,然后继续执行主线程。在实际开发中,我们可以使用join()方法来实现线程间的通信。

我正在参与2024腾讯技术创作特训营第五期有奖征文,快来和我瓜分大奖!

0 人点赞