Thread之join方法
前言
在很多情况下,都由主线程创建并运行子线程,如果子线程中需要大量的耗时操作,主线程往往早于子线程结束。
 如果主线程想等待子线程执行完成后再执行。比如子线程处理一个数据运算,而主线程想获取这个数据,可以用join方法。
public final void join() throws InterruptedException
 等待该线程终止。
 抛出:
 InterruptedException - 如果任何线程中断了当前线程。当抛出该异常时,当前线程的中断状态被清除。
join()
public class Demo15 {
    public static void main(String[] args) throws InterruptedException {
        Demo15Thread t = new Demo15Thread();
        t.start();
        System.out.println("等待子线程运算");
        //等待该线程结束
        t.join();
        System.out.println("主线程结束");
    }
}
class Demo15Thread extends  Thread{
    @SneakyThrows
    @Override
    public void run() {
        //模拟大强度运算
        Thread.sleep(1500);
        System.out.println("子线程计算的值为: "+9584623333135895L);
    }
}
结论

join与synchronized
join内部使用wait()进行等待,而synchronized内部使用【对象锁】进行同步。
join与sleep
public class Demo15 {
    public static void main(String[] args) throws InterruptedException {
        Demo15ThreadA threadA = new Demo15ThreadA();
        Demo15ThreadB threadB = new Demo15ThreadB(threadA);
        Demo15ThreadC threadC = new Demo15ThreadC(threadA);
        threadB.start();
        threadC.start();
    }
}
class Demo15ThreadA extends  Thread{
    @SneakyThrows
    @Override
    public void run() {
        System.out.println("线程A开始于:" + System.currentTimeMillis());
        Thread.sleep(1000);
        System.out.println("线程A结束于:" + System.currentTimeMillis());
    }
    public synchronized void getTime(){
        System.out.println("方法执行时间: "+System.currentTimeMillis());
    }
}
class Demo15ThreadB extends  Thread{
    private Demo15ThreadA threadA;
    public Demo15ThreadB(Demo15ThreadA threadA){
        this.threadA = threadA;
    }
    @SneakyThrows
    @Override
    public void run() {
        synchronized (threadA){
            threadA.start();
            //sleep会导致线程阻塞,不会释放锁
            Thread.sleep(2000L);
            //join(long)内部使用wait(long),所以它会释放同步锁
            //threadA.join(2000L);
            while(true){
            }
        }
    }
}
class Demo15ThreadC extends  Thread{
    private Demo15ThreadA threadA;
    public Demo15ThreadC(Demo15ThreadA threadA){
        this.threadA = threadA;
    }
    @Override
    public void run() {
        threadA.getTime();
    }
}
结论
- join内部使用wait()进行等待,而synchronized内部使用【对象锁】进行同步。
- sleep(long)会导致线程阻塞,不会释放同步锁,join(long)内部使用wait(long),会释放同步锁
join与异常
public class Demo16 {
    public static void main(String[] args) throws InterruptedException {
        Demo16ThreadB threadB = new Demo16ThreadB();
        threadB.start();
        //使threadB优先执行
        Thread.sleep(300);
        Demo16ThreadC threadC = new Demo16ThreadC(threadB);
        threadC.start();
    }
}
class Demo16ThreadA extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            // 模拟耗时操作
            String s = new String();
            Math.random();
        }
    }
}
class Demo16ThreadB extends Thread{
    @Override
    public void run() {
        try {
            Demo16ThreadA t = new Demo16ThreadA();
            t.start();
            //t线程加入到Demo16ThreadB中
            t.join();
            System.out.println("Demo16ThreadB线程正常结束");
        } catch (InterruptedException e) {
            System.out.println("Demo16ThreadB线程异常结束");
            e.printStackTrace();
        }
    }
}
class Demo16ThreadC extends Thread{
    private Demo16ThreadB threadB;
    public Demo16ThreadC(Demo16ThreadB threadB){
        this.threadB = threadB;
    }
    @Override
    public void run() {
        //模拟InterruptedException,中断Demo16ThreadB
        threadB.interrupt();
    }
}
运行结果

结论
尽管Demo16ThreadB被异常终端,但是Demo16ThreadA依然在正常运行。
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号