Thread.join()方法實現main()方法等待所有子執行緒執行完成[base jdk8]
程式碼實現
/**
* Created by Administrator on 2018/2/3.
*/
public class JoinTest {
public static void main(String[] args) {
Thread t1 = new Thread(new MyRunnable(), "t1");
Thread t2 = new Thread(new MyRunnable(), "t2");
Thread t3 = new Thread(new MyRunnable(), "t3");
t1.start();
/**
* start second thread after waiting for 2 seconds or if it's finished
*/
try {
/**
* main thread wait 2000ms for wait t1 execute finished
*/
t1.join(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.start();
/**
* start third thread only when first thread is finished
* t.join() = t.join(0) JDK: A timeout of 0 means to wait forever 意思是永遠等待,其實是等到t結束後
*/
try {
/**
* main thread wait t1 execute finished forever
*/
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
t3.start();
/**
* let all threads finish execution before finishing main thread
*/
try {
/**
* main thread wait t2 execute finished forever
*/
t2.join();
/**
* main thread wait t3 execute finished forever
*/
t3.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("All threads are dead, exiting main thread");
}
}
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Thread started:::" + Thread.currentThread().getName());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread ended:::" + Thread.currentThread().getName());
}
}
關鍵剖析
Join可以實現執行緒的執行順序,內部具體實現流程分析
try {
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
public final void join() throws InterruptedException {
join(0);
}
/**
* synchronized修飾,獲得鎖
*/
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;
}
/**
* 呼叫Object的wait()方法會釋放鎖
*/
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
通過不斷輪詢的方式去觀察執行緒是否還是活動執行緒join(0)是不斷的詢問執行緒的狀態,直到執行緒銷燬join()方法才會結束。
當millis>0時,不在是wait(0),而是wait(delay),delay是還剩餘的millis時間。有人會問第一次wait(delay)後不就已經經過這millis的時間,
為什麼還會有while執行多次wait(delay)呢?因為這裡不僅要考慮wait在delay時間後被喚醒,還要考慮到在delay時間內,被notify喚醒,喚醒後還沒有執行到millis的時間,因此要多次呼叫wait(delay)方法。
join方法底層呼叫的是wait方法,但要實現wait的提前是要獲得鎖,執行到wait方法才可以釋放鎖,而sleep方法不釋放鎖。
相關文章
- Java多種方法實現等待所有子執行緒完成再繼續執行Java執行緒
- Java多執行緒/併發07、Thread.Join()讓呼叫執行緒等待子執行緒Java執行緒thread
- 主執行緒等待所有其他執行緒執行完畢,然後再繼續執行主執行緒的邏輯,有以下幾種方法可以實現:執行緒
- java 如何實現等待子執行緒結束Java執行緒
- Java非同步判斷執行緒池所有任務是否執行完成的方法Java非同步執行緒
- JVM程式用一個主執行緒來執行main()方法JVM執行緒AI
- Java:多執行緒等待所有執行緒結束(CountDownLatch/CyclicBarrier) .Java執行緒CountDownLatch
- 執行緒間通訊_等待/通知之Thread.join()執行緒thread
- 模擬主執行緒等待子執行緒的過程執行緒
- Java 執行緒池獲取池中所有執行緒列表的方法Java執行緒
- java實現多執行緒的方法Java執行緒
- Java多執行緒的實現方法Java執行緒
- java執行緒執行緒休眠,sleep方法Java執行緒
- 使用Runnable介面實現執行緒的方法執行緒
- Java多執行緒【三種實現方法】Java執行緒
- Thread 中的 join() 方法的作用是呼叫執行緒等待該執行緒執行完後,再繼續執行thread執行緒
- AS執行main()方法報錯:SourceSet with name ‘main‘ not foundAI
- 多執行緒(五)---執行緒的Yield方法執行緒
- 執行緒同步方法執行緒
- 24. 一個普通main方法的執行,是單執行緒模式還是多執行緒模式?為什麼?AI執行緒模式
- Android執行緒篇(一)實現執行緒的幾種方法及區別Android執行緒
- PHP多執行緒的實現方法詳解PHP執行緒
- 執行緒、開啟執行緒的兩種方式、執行緒下的Join方法、守護執行緒執行緒
- Java併發和多執行緒4:使用通用同步工具CountDownLatch實現執行緒等待Java執行緒CountDownLatch
- 執行時Hook所有Block方法呼叫的技術實現HookBloC
- [深入學習C#]C#實現多執行緒的方法:執行緒(Thread類)和執行緒池(ThreadPool)C#執行緒thread
- 多執行緒核心技術(1)-執行緒的基本方法執行緒
- Android 執行緒優化之執行緒池shutdown方法Android執行緒優化
- java執行緒學習5——執行緒同步之同步方法Java執行緒
- 多執行緒併發執行及解決方法執行緒
- QT 主執行緒子執行緒互相傳值QT執行緒
- 聊聊執行緒技術與執行緒實現模型執行緒模型
- 執行緒等待兩種方法的喚醒的效率比較執行緒
- 建立執行緒的4種方法 and 執行緒的生命週期執行緒
- Java 多執行緒基礎(六)執行緒等待與喚醒Java執行緒
- Win32執行緒——等待另一個執行緒結束Win32執行緒
- Java—執行緒的生命週期及執行緒控制方法詳解Java執行緒
- java 多執行緒之使用 interrupt 停止執行緒的幾種方法Java執行緒