Thread.join

public class JoinDetail extends Thread{
    public JoinDetail(String name) {
        super(name);
    }

    @Override
    public void run() {
        long a = System.currentTimeMillis();
        System.out.println(Thread.currentThread().getName() + "start");
        try {
        Thread.sleep(10000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
        a = System.currentTimeMillis() - a;
        System.out.println(Thread.currentThread().getName() + "end" + a);
}

    public static void main(String[] args) {
        long currentTime = System.currentTimeMillis();
        JoinDetail j1 = new JoinDetail("j1");
        HaveThreadLock j2 = new HaveThreadLock("j2",j1);
        j1.start();
        j2.start();
        /*
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        */
        try {
            j1.join(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("主线程执行完毕");
        System.out.println("总共耗时" + (System.currentTimeMillis() - currentTime));
    }
}

执行结果

j2begin
j1start
j2end5000
主线程执行完毕
总共耗时5002
j1end10000

将注释

        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

打开
执行结果

j2begin
j1start
j2end5001
主线程执行完毕
总共耗时8004
j1end10001

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;
            }
        }
    }

线程1调用线程2的join方法,会把线程2对象本身当作syschronized锁对象,获取到了锁然后再判断线程2的alive状态并且wait。
分析结果
在注释情况下,main线程首先获取j1对象锁,然后给join方法中的base赋值,wait释放锁,使j2线程获取到锁,sleep5秒,然后main线程wait时间超时重新获取j1锁发现delay<0了,接着main线程结束。
在打开注释情况下,j2线程先获取j1对象锁,sleep5秒,然后main线程调用j1.join,wait5秒,接着main线程结束。

你可能感兴趣的:(Thread.join)