文章介紹內容
- Thread.join 作用
- Thread.join的實現原理
- 什麼時候會使用Thread.join
- 擴展
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();
輸出結果一致
有理解不恰當地方歡迎吐槽~~