java join方法底层原理

join底层是用wait实现的,使用了并发设计模式中的保护性暂停模式。
join的用法很简单,在线程t1中调用t2.join(),代表t1线程会等待t2线程执行结束。如果加个参数timeout,代表最多等待timeout就不等了。

在看源码之前,需要搞清楚当前运行的线程和调用方法的线程的区别。下面这个案例中,在main线程中调用t1.function(),那么执行到function()方法内部时,当前线程仍然是main,调用function的线程对象是t1。

public class Main {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        TestThread t1 = new TestThread("t1");
        t1.start();
        t1.function();
    }
}
class TestThread extends Thread{
    public TestThread(String name) {
        setName(name);
    }

    @Override
    public void run() {
        super.run();
        while (true);
    }

    public void function() {
        System.out.println("当前线程:" + currentThread().getName()); // 输出main
        System.out.println("调用function的对象" + this.getName()); // 输出t1
    }
}

上面的案例弄懂了,来看一下join的源码。假设在t1中调用t2.join()。那么当前线程仍然是t1,调用join的线程对象是t2。而wait方法是让当前线程等待,所以在这里就是让t1线程等待。而isAlive是判断调用join的线程是否存活,也就是这里的t2。如果这些都弄明白了那源码也就很简单了。

// join执行完毕则说明t2线程已经终止
public final synchronized void join(final long millis) throwsInterruptedException {
    if (millis > 0) {  // 以下是保护性暂停的经典代码
        if (isAlive()) {
            final long startTime = System.nanoTime();
            long delay = millis;
            do {
                wait(delay);
            } while (isAlive() && (delay = millis -
                    TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime)) > 0);  // 如果t2存活且没超时,则让t1等待delay
        }
    } else if (millis == 0) {
        while (isAlive()) { // 如果t2存活
            wait(0);  // 就让t1等待
        }
    } else {
        throw new IllegalArgumentException("timeout value is negative");
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值