java,多线程时用的join()函数

    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()的底层代码,在线程A内部调用线程B的join()函数时,会暂停A线程,等线程B执行结束后才会结束暂停。如果调用的join带有时间参数,则时间计时结束也会结束wait()过程。

上面的isAlive()和wait()的函数对象是不一样的,isAlive对象是被调用的线程B,wait(0)的对象是对应的是正在执行的线程A。

另一个要注意的点是,线程的状态大致分为开始、就绪、运行、阻塞和死亡,isAlive()仅在就绪或者运行时算作真,故未start的线程join无效。

 

下面举个例子

设置两个线程类 ,并在一个子线程中调用另一个线程的join方法。

public class Thread1 extends Thread {
    public Thread1(String name) {
        super(name);
    }
    
    @Override
    public void run() {
        for (int i = 0; i < 3; i++) {
            System.out.println(Thread.currentThread().getName() + ":"+i);
        }
    }
}
public class Thread2 extends Thread {
    public Thread2(String name) {
        super(name);
    }

    @Override
    public void run() {
        Thread1 B = new Thread1("B");
        B.start();
        try {
            B.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        for (int i = 0; i < 3; i++) {
            System.out.println(Thread.currentThread().getName() + ":"+i);
        }
    }
}

主类中按一定次序启用线程

 

public class ThreadTest {
    public static void main(String[] args) throws InterruptedException {
        Thread2 A = new Thread2("A");
        Thread1 C = new Thread1("C");
        Thread1 D = new Thread1("D");
        Thread1 E = new Thread1("E");
        C.start();
        A.start();
        D.start();
        D.join();
        E.start();
    }
}

 

得到结果如下

 可以看到,在A中启用B的join方法时,并未影响到主线程,主线程仍然向后运行并开启了D,而A只能在B之后得到运行。主线程中启用D的join方法后,则暂停执行,即E暂时无法start。

posted @ 2020-06-04 19:54  D目录  阅读(667)  评论(1编辑  收藏  举报