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依然在正常运行。

猜你喜欢

转载自blog.csdn.net/single_0910/article/details/113767906