java:Thread的join方法

说明

Thread的join方法的作用是等待该线程执行完。例如,假设线程对象是ta,在ta上调用join方法,意思是等待线程ta执行完。
利用这个方法,可以人为控制线程执行的顺序。

join方法有几个形式:

void join()      相当于调用join(0)
join(long millis)
join(long millis, int nanos)
join(Duration duration)

如果join方法的时间参数值是0,表示一直等待。

一个示例

在下面的代码中,在主线程中创建了threadA和threadB两个线程。
先启动threadA,然后调用threadA.join();
再启动threadB,然后调用threadB.join();

package com.thb;

import java.util.concurrent.TimeUnit;

public class Test6 {

    public static void main(String[] args) throws InterruptedException {
        // 创建一个线程
        Thread threadA = new Thread(() -> {
            System.out.println("进入线程: " + Thread.currentThread().getName());
            try {
                System.out.println(Thread.currentThread().getName() + " 睡眠");
                TimeUnit.SECONDS.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " 被唤醒");
            System.out.println("离开线程: " + Thread.currentThread().getName());
        }, "threadA");

        // 创建一个线程
        Thread threadB = new Thread(() -> {
            System.out.println("进入线程: " + Thread.currentThread().getName());
            try {
                System.out.println(Thread.currentThread().getName() + " 睡眠");
                TimeUnit.SECONDS.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " 被唤醒");
            System.out.println("离开线程: " + Thread.currentThread().getName());
        }, "threadB");

        // 启动threadA
        threadA.start();
        // 等待threadA执行完
        threadA.join();
        System.out.println("*".repeat(60));

        // 启动threadB
        threadB.start();
        // 等待threadB执行完
        threadB.join();
        System.out.println("*".repeat(60));

        System.out.println("当前线程: " + Thread.currentThread().getName());
    }

}

执行输出:

进入线程: threadA
threadA 睡眠
threadA 被唤醒
离开线程: threadA
************************************************************
进入线程: threadB
threadB 睡眠
threadB 被唤醒
离开线程: threadB
************************************************************
当前线程: main

无论执行多少次,上面的输出是一样的。从上面的输出可以看出,先执行完了threadA,然后再执行threadB。

join方法源码分析

看Thread.java的源码,在join方法中,关键的是下面的判断isAlive()和等待wait(0)
在这里插入图片描述
我们以上面的threadA为例:

  • isAlive()方法是在threadA这个对象上调用的,即threadA.isAlive(),它就是判断threadA有没有结束。这个理解起来没有困难。
  • 如果threadA没有结束,就调用wait(0)方法,其实也是threadA.wait(0)。这个我开始理解不了。我开始认为是让threadA等待,这跟让threadA执行完的目标看似矛盾。但其实,这个代码语句是在主线程中执行threadA.join()调用走进来的,当前正在运行的线程是主线程,而Java对象的wait方法是让当前线程等待,直到被唤醒,也就是让主线程等待。

在这里插入图片描述

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值