Thread join method


Preface

In many cases, the main thread creates and runs the sub-threads. If a lot of time-consuming operations are required in the sub-threads, the main thread often ends earlier than the sub-threads.
If the main thread wants to wait for the execution of the child thread to complete before executing. For example, the child thread processes a data operation, and the main thread wants to obtain this data, you can use the join method.

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

in conclusion

Insert picture description here

join与synchronized

Join internally uses wait() for waiting, while synchronized internally uses [object lock] for synchronization.

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

in conclusion

  • Join internally uses wait() for waiting, while synchronized internally uses [object lock] for synchronization.
  • Sleep(long) will cause the thread to block and 不会release the synchronization lock. Join(long) uses wait(long) internally to release the synchronization lock.

join and exception

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

operation result

Insert picture description here

in conclusion

Although Demo16ThreadB was abnormally terminated, Demo16ThreadA is still running normally.

Guess you like

Origin blog.csdn.net/single_0910/article/details/113767906