スレッド結合メソッド


序文

多くの場合、メインスレッドはサブスレッドを作成して実行します。サブスレッドで時間のかかる操作が大量に必要な場合、メインスレッドはサブスレッドよりも早く終了することがよくあります。
メインスレッドが子スレッドの実行が完了するのを待ってから実行する場合。たとえば、子スレッドがデータ操作を処理し、メインスレッドがこのデータを取得したい場合は、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);
    }
}

結論として

ここに画像の説明を挿入

参加与同期

参加は内部で待機にwait()を使用し、同期は内部で同期に[オブジェクトロック]を使用します。

参加する

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

結論として

  • 参加は内部で待機にwait()を使用し、同期は内部で同期に[オブジェクトロック]を使用します。
  • Sleep(long)により、スレッド不会は同期ロックをブロックして解放します。Join(long)は内部でwait(long)を使用して同期ロック解放します。

参加と例外

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