浅谈join

概述:

join使线程进入等待,在当前线程中调用另一个线程对象.join(),会使当前线程一直等待直到另一个线程执行完。join是Thread方法中定义的,与wait不同,wait是在Object中定义的。这样定义是因为调用Thread对象的join方法,当这个Thread对象的任务执行完成之后,在这个Thread对象上阻塞的线程会自动被唤醒。join在底层的实现用到了保护暂停模式,比如在main线程中调用t.join,就相当于使用synchronize代码块对这个t对象尝试获得锁,当获取到锁之后,就会执行t对象中的wait(), 也就是main线程就会释放锁,进入到waitSet队列中等待,当线程t执行完任务之后,在线程退出之前会做清理工作,main线程就是在将线程t从线程组移除之后被唤醒的。所以说当实现线程间的等待唤醒机制,最好就不要用线程对象作为同步锁。

源码分析:

    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()) {
                // 如果提前被唤醒,则再次进入wait(delay)
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
    }

从源码中可以看出,调用t.join()相当于

    synchronized (t){
        while (t.isAlive()){
            t.wait(0);
        }
    }

join原理是同步模式保护性暂停的体现,一个线程需要等待另个线程执行完成才会向下执行。变相一下,如果一个线程需要等待获取另一个线程传递结果时,那么就有点像Future的思想了。

posted @ 2021-10-18 16:31  活有梦想与追求  阅读(124)  评论(0)    收藏  举报