java多线程系统 —— (5)join()

1. join()方法介绍

join()方法的主要作用是让“主线程”等待“子线程”结束之后才能继续运行,它可以使得线程之间的并行执行变为串行执行。在A线程中调用了B线程的join()方法时,表示只有当B线程执行完毕时,A线程才能继续执行。

join方法中如果传入参数,则表示这样的意思:如果A线程中掉用B线程的join(10),则表示A线程会等待B线程执行10毫秒,10毫秒过后,A、B线程并行执行。需要注意的是,jdk规定,join(0)的意思不是A线程等待B线程0秒,而是A线程等待B线程无限时间,直到B线程执行完毕,即join(0)等价于join()。(其实join()中调用的是join(0))

join方法必须在线程start方法调用之后调用才有意义。这个也很容易理解:如果一个线程都没有start,那它也就无法同步了。

2. join()方法示例

通过代码来演示join()方法:

public class JoinTest {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 5; i++){
                    System.out.println("子线程运行" + i);
                }
            }
        });
        thread.start();
        thread.join();  //使主线程等待子线程执行完毕
        for (int i = 0; i < 5; i++){
            System.out.println("主线程运行" + i);
        }
    }

}

运行结果:
在这里插入图片描述
此时如果我们将thread.join()这行代码注释掉,运行结果就会变成:
在这里插入图片描述
可以看出join()方法使子线程“加入”到了“主线程”中,主线程要等到子线程完成后才会继续执行。

3. join()方法源码解析

从上面的示例可以看出,join方法和wait()方法有些类似,wait()方法也是使线程进入阻塞状态,等待其他线程调用notify()方法唤醒。而join()方法不需要其他线程主动唤醒,当调用线程执行完毕后,它又会自己自动运行。实际上,join()方法内部也是调用了wait()方法来实现的,来看一下源码:

public final void join() throws InterruptedException {
    join(0);
}

public final synchronized void join(long millis)
throws InterruptedException {
    long base = System.currentTimeMillis();
    long now = 0;

    if (millis < 0) {
        throw new IllegalArgumentException("timeout value is negative");
    }

    if (millis == 0) {
        while (isAlive()) {
            wait(0);
        }
    } else {
        while (isAlive()) {
            long delay = millis - now;
            if (delay <= 0) {
                break;
            }
            wait(delay);
            now = System.currentTimeMillis() - base;
        }
    }
}

在源码当中可以看出join()方法实际是调用join(long millis)方法,join(long millis)方法中我们是通过isAlive()方法来判断该线程是否还存活的。如果该线程还存活,则进行wait()操作,注意,这里调用wait()方法的是当前线程,当前线程是谁呢?正是主线程!

那这里又有问题出现了,wait()方法必须出现在同步代码块中,而这里是拿了谁的锁呢?最后又是谁调用了notify()方法唤醒该线程呢?

从源码中可以看出synchronize加在了join()方法上,所以synchronize应该是锁住了当前的主线程,锁住该线程的,正是子线程。当子线程执行完成后,会执行notify()方法唤醒主线程,这时主线程就会继续执行!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值