Thread中join的作用和原理

文章介紹內容
  1. Thread.join 作用
  2. Thread.join的實現原理
  3. 什麼時候會使用Thread.join
  4. 擴展

1作用

當多線程情況每個單線程都在競爭獲取cpu執行權,順序是先得先折行,先爲保證子線程執行順序,通過Thread.join 控制主線程讓子線程執行完再執行下一個子線程,底部實現原理使用Object中wait

dome1


public class ThreadJoin {

    static Thread thread1=new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("thread1");
        }
    });
    static Thread thread2=new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("thread2");
        }
    });
    static Thread thread3=new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("thread3");
        }
    });

    public static void main(String[] args) throws InterruptedException {
        thread1.run();
        thread1.join();
        thread2.run();
        thread1.join();
        thread3.run();
        thread3.join();
    }

}

執行結果 :

thread1
thread2
thread3

Process finished with exit code 0

顯現:
當代碼中不加 thread.join();在多線程執行中是不能確保他們順序,輸出結果是無序的,添加後執行是有需。

原理

參考下圖理解原理
在這裏插入圖片描述
查看源碼:

....
public final void join() throws InterruptedException {
        join(0);
}
    ....
 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;
            }
        }
    }

總結:當主線程調用run子線程,子線程調用join,會對主線程進行阻塞通過join源碼可以看出synchronized , wait()方法等待執行完再執行主線程執行第二個子線程,保證每一個線程的執行完再執行下一個子線程

什麼時候是使用

當多線程情況下需要,列如:t1,t2線程,在執行t1時需要t1的結果進行其他業務邏輯是可以採用Thread.join等待子線程執行完再做下面邏輯操作
具體參考deom2

public void joinDemo(){
   //....
   Thread t=new Thread(payService);
   t.start();
   //.... 
   //其他業務邏輯處理,不需要確定t線程是否執行完
   insertData();
   //後續的處理,需要依賴t線程的執行結果,可以在這裏調用join方法等待t線程執行結束
   t.join();
}

擴展

我們還可以通過多線程隊裏FIFO方式達到順序執行過程
思路,通過線程池Executors.newSingleThreadExecutor() 單線程模式裏,底層使用FIFO(先進先出)實現多線程有序執行

參考dome1修改

 ExecutorService executorService=Executors.newSingleThreadExecutor();
        executorService.execute( thread1);
        executorService.execute( thread2);
        executorService.execute( thread3);
        executorService.isShutdown();

輸出結果一致

有理解不恰當地方歡迎吐槽~~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章