java等待线程执行终止的join方法

    科技2025-09-13  28

    join方法介绍

    join方法是Thread类的方法,不是Object对象的方法,是无参的且返回值为void的方法。

    等待子线程执行完成,再继续执行主线程

    来看一个示范:

    package com.tim.base.easystart.thread.base; public class JoinTest { public static void main(String[] args) throws InterruptedException { System.out.println("main thread start"); Thread threadA = new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("child thread: threadA is over"); } }); Thread threadB = new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("child thread: threadB is over"); } }); threadA.start(); threadB.start(); System.out.println("threadA and threadB has been started"); //等待threadA和threadB执行完毕返回 threadA.join(); threadB.join(); System.out.println("all child thread over!"); } }

    输出结果:

    main thread start threadA and threadB has been started child thread: threadA is over child thread: threadB is over all child thread over!

    可以看出2个子线程threadA和threadB启动之后,main线程继续执行,等执行完join方法之后,main线程暂停执行,等待2个线程执行完成,才继续执行join方法之后的程序代码。

    线程中断与join方法

    public class JoinInterruptTest { public static void main(String[] args) { System.out.println("main thread start"); Thread threadA = new Thread(new Runnable() { @Override public void run() { System.out.println("child thread: threadA begin"); for (;;) { try { Thread.sleep(500); System.out.println("child thread:threadA is executing"); } catch (InterruptedException e) { e.printStackTrace(); } } } }); Thread mainThread = Thread.currentThread(); Thread threadB = new Thread(new Runnable() { @Override public void run() { System.out.println("child thread: threadB begin"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("child thread: threadB will interrupt mainThread"); mainThread.interrupt(); } }); threadA.start(); threadB.start(); try { threadA.join(); } catch (InterruptedException e) { System.out.println("main thread:" + e); } } }

    输出结果:

    main thread start child thread: threadA begin child thread: threadB begin child thread:threadA is executing child thread:threadA is executing child thread: threadB will interrupt mainThread main thread:java.lang.InterruptedException child thread:threadA is executing child thread:threadA is executing

    child thread:threadA is executing child thread:threadA is executing

    threadB执行过程中调用了主线程mainThread的interrupt方法,为主线程设置了中断标志,这时在threadA.join等待threadA返回的try{}catch{}代码块中会捕获到InterruptedException,但是threadA并没有被中断,还是继续执行。

    一直执行的线程休眠中被中断的不会导致线程退出

    还发现一个有趣的现象:在上面的代码中将mainThread.interrupt();换成threadA.interrupt();

    package com.tim.base.easystart.thread.base; public class JoinInterruptTest { public static void main(String[] args) { System.out.println("main thread start"); Thread threadA = new Thread(new Runnable() { @Override public void run() { System.out.println("child thread: threadA begin"); for (;;) { try { Thread.sleep(1000); } catch (InterruptedException e) { System.out.println("threadA is interrupted..." + e); } System.out.println("threadA is still executing..."); } } }); Thread mainThread = Thread.currentThread(); Thread threadB = new Thread(new Runnable() { @Override public void run() { System.out.println("child thread: threadB begin"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("child thread: threadB will interrupt mainThread"); threadA.interrupt(); } }); threadA.start(); threadB.start(); try { threadA.join(); } catch (InterruptedException e) { System.out.println("main thread:" + e); } } }

    输出结果:

    main thread start child thread: threadA begin child thread: threadB begin threadA is still executing… child thread: threadB will interrupt mainThread threadA is interrupted…java.lang.InterruptedException: sleep interrupted threadA is still executing… threadA is still executing…

    threadA is still executing… threadA is still executing…

    可以看出threadA在sleep的时候被设置中断标志后,线程并没有停止运行,还是在继续执行。

    Processed: 0.010, SQL: 8