6.Java线程中的重要方法(join)

join()

相当于插队,让某个线程先运行,自己等着。
Waits for this thread to die.

join(),等待线程运行结束。
当需要同步等待线程运行完时,可以使用这个方法。

示例1

t1线程执行完成需要2s,t2线程执行完成需要3s。
两个线程启动后,调用它们的join方法。

    public static void main(String[] args) throws InterruptedException {

        Thread t1 = new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(2);
                log.debug("t1执行完成");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "t1");


        Thread t2 = new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(3);
                log.debug("t2执行完成");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "t2");

        t1.start();
        t2.start();

        log.debug("子线程加入。。");
        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        log.debug("子线程执行完毕。。");

    }

输出:

t1线程从51秒执行到53秒
t2线程从51秒执行到54秒

2025-10-03 12:02:51.940 [main] c.c.e.d.Main - 子线程加入。。
2025-10-03 12:02:53.950 [t1] c.c.e.d.Main - t1执行完成
2025-10-03 12:02:54.952 [t2] c.c.e.d.Main - t2执行完成
2025-10-03 12:02:54.952 [main] c.c.e.d.Main - 子线程执行完毕。。

join(long millis)

Waits at most millis milliseconds for this thread to die. A timeout of 0 means to wait forever.

  • join(long millis),有时限的等待,最多等待millis毫秒。如果在这个时间内,线程没有结束,那也不等了。
  • 如果在时限内,线程执行完成了,那么join就会提前结束。

示例2

同样的,t1线程执行完成需要2s,t2线程执行完成需要3s。
两个线程启动后,调用它们的join方法,但是只等待500ms。
由于500ms后,两个线程都没结束,所以主线程也就不等了,提前打印【子线程执行完毕。。】

    public static void main(String[] args) throws InterruptedException {

        Thread t1 = new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(2);
                log.debug("t1执行完成");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "t1");


        Thread t2 = new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(3);
                log.debug("t2执行完成");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "t2");

        t1.start();
        t2.start();

        log.debug("子线程加入。。");
        try {
            t1.join(500);
            t2.join(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        log.debug("子线程执行完毕。。");

    }

输出:

2025-10-03 12:16:57.186 [main] c.c.e.d.Main - 子线程加入。。
2025-10-03 12:16:58.205 [main] c.c.e.d.Main - 子线程执行完毕。。
2025-10-03 12:16:59.195 [t1] c.c.e.d.Main - t1执行完成
2025-10-03 12:17:00.201 [t2] c.c.e.d.Main - t2执行完成

示例3

同样的,t1线程执行完成需要2s,t2线程执行完成需要3s。
两个线程启动后,调用它们的join方法,等待5000ms。

t1线程从57秒执行到59秒
t2线程从57秒执行到00秒

00秒时,两个线程都执行完成,主线程就没有必要继续等够5秒了,提前结束。

    public static void main(String[] args) throws InterruptedException {

        Thread t1 = new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(2);
                log.debug("t1执行完成");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "t1");


        Thread t2 = new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(3);
                log.debug("t2执行完成");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "t2");

        t1.start();
        t2.start();

        log.debug("子线程加入。。");
        try {
            t1.join(5000);
            t2.join(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        log.debug("子线程执行完毕。。");

    }

输出:

2025-10-03 12:21:57.905 [main] c.c.e.d.Main - 子线程加入。。
2025-10-03 12:21:59.917 [t1] c.c.e.d.Main - t1执行完成
2025-10-03 12:22:00.918 [t2] c.c.e.d.Main - t2执行完成
2025-10-03 12:22:00.919 [main] c.c.e.d.Main - 子线程执行完毕。。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值