进程通讯-join

join:线程加塞。

官方释义:Waits for this thread to die.(等待当前线程死掉)

 

join()方法是java.lang.Thread类的成员方法,因此只有Thread的实例可以调用。

 

join的用法实例:

/**
 * Thread的join()线程加塞方法测试
 */
public class Join {

    @Test
    public void test(){
        Thread joinThread = new Thread(new Runnable() {
            @Override
            public void run() {
                b();
            }
        });

        new Join().a(joinThread);
    }

    public void a(Thread joinThread){
        System.out.println("a方法被调用");
        joinThread.start();
        try {
            joinThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("a方法执行完毕");
    }

    public void b(){
        System.out.println("b方法被调用");
        System.out.println("b方法执行完毕");
    }

运行结果:

结果分析:

在主线程中加塞,可见主线程是等到加塞线程死掉后才运行加塞线程后的代码。

 

源码分析:java.lang.Thread join()方法的源码

/**
     * Waits at most {@code millis} milliseconds for this thread to
     * die. A timeout of {@code 0} means to wait forever.
     *
     * <p> This implementation uses a loop of {@code this.wait} calls
     * conditioned on {@code this.isAlive}. As a thread terminates the
     * {@code this.notifyAll} method is invoked. It is recommended that
     * applications not use {@code wait}, {@code notify}, or
     * {@code notifyAll} on {@code Thread} instances.
     *
     * @param  millis
     *         the time to wait in milliseconds
     *
     * @throws  IllegalArgumentException
     *          if the value of {@code millis} is negative
     *
     * @throws  InterruptedException
     *          if any thread has interrupted the current thread. The
     *          <i>interrupted status</i> of the current thread is
     *          cleared when this exception is thrown.
     */
    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) {
            // 如果子线程还活着,就继续等待,这里的wait是主线程等待,不是加塞线程,因为synchronized是加在方法上的,锁的是当前调用方法的对象,当前调用方法的对象是加塞线程的实例,而调用的地方是主线程里面,相当于在主线程中执行了obj.wait(),只不过此时的obj是一个加塞线程对象而已。
            while (isAlive()) {
                wait(0);
            }
        } else {
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
    }

那么何时这个wait被notify呢? 官方注释有描述 

As a thread terminates the {@code this.notifyAll} method is invoked

当一个线程运行结束时,this.notifyAll方法会被调用,也就是当加塞线程运行完毕是,加塞线程对象的notifyAll方法会被调用,恰好主线程中的锁对象是加塞线程的对象,所以此时主线程被唤醒。

 

如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:

  1. 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。

  2. 关注公众号 『逆行的碎石机』,不定期分享原创知识。

  3. 同时可以期待后续文章ing🚀

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值