方案有三:
- 【執行緒 t1】代碼執行完,呼叫【執行緒t2】的start()方法,【t2】執行完呼叫【執行緒t3】的start()方法;
- 使用執行緒間通信,3個執行緒使用同一把鎖,【執行緒t1】執行完后,使用 JUC 中
signal()/signalAll()方法喚醒【執行緒t2】,以此類推; - 【推薦使用】 使用執行緒為我們提供的
join()方法,
備注:
??代碼中使用 sleep() 也是為了更方便復現問題
方案一
??方案一是最 low 的一種方式,不做介紹,不建議使用
public class SortThread1 {
public static void main(String[] args) throws InterruptedException {
Thread t3 = new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(1);
System.out.println(Thread.currentThread().getName() + "執行緒執行完畢");
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "t3");
Thread t2 = new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName() + "執行緒執行完畢");
// 執行執行緒3
t3.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "t2");
Thread t1 = new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(2);
System.out.println(Thread.currentThread().getName() + "執行緒執行完畢");
// 執行執行緒2
t2.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
},"t1");
// 執行執行緒1
t1.start();
}
}
方案二
??采用執行緒間通信,三個執行緒同時啟動,使用一把鎖,三個執行緒 t1,t2,t3,按順序執行,執行緒 t1 執行完成后,通知執行緒 t2 ,t2 獲取鎖后,繼續執行,以此類推
public class SortThread2 {
public static void main(String[] args) {
// 創建Lock
Lock lock = new ReentrantLock();
Condition condition1 = lock.newCondition();
Condition condition2 = lock.newCondition();
Condition condition3 = lock.newCondition();
Thread t1 = new Thread(() -> {
// 加鎖
lock.lock();
try {
TimeUnit.SECONDS.sleep(2);
System.out.println(Thread.currentThread().getName() + "執行緒執行完畢");
// 喚醒t2執行緒
condition2.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 釋放鎖
lock.unlock();
}
}, "t1");
Thread t2 = new Thread(() -> {
// 加鎖
lock.lock();
try {
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName() + "執行緒執行完畢");
// 喚醒t3執行緒
condition3.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 釋放鎖
lock.unlock();
}
}, "t2");
Thread t3 = new Thread(() -> {
// 加鎖
lock.lock();
try {
TimeUnit.SECONDS.sleep(1);
System.out.println(Thread.currentThread().getName() + "執行緒執行完畢");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 釋放鎖
lock.unlock();
}
}, "t3");
// 啟動執行緒
t1.start();
t2.start();
t3.start();
}
}
方案三
??【推薦使用】使用執行緒為我們提供的 join() 方法,join() 方法會等待當前執行緒,join(0)則會一直等待執行緒死亡,join() 和 join(long millis) 方法原始碼,如下圖所示:


public class SortThread3 {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(2);
System.out.println(Thread.currentThread().getName() + "執行緒執行完畢");
} catch (InterruptedException e) {
e.printStackTrace();
}
},"t1");
Thread t2 = new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName() + "執行緒執行完畢");
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "t2");
Thread t3 = new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(1);
System.out.println(Thread.currentThread().getName() + "執行緒執行完畢");
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "t3");
t1.start();
t1.join(); // 一直等待t1執行,執行緒死亡后,執行執行緒t2
t2.start();
t2.join(); // 一直等待t2執行,執行緒死亡后,執行執行緒t3
t3.start();
t3.join(); // 一直等待t3執行,執行緒死亡后,執行主執行緒
// 使用帶引數join()方法
// t1.start();
// t1.join(10); // 等待t1執行緒10ms,t1執行緒代碼內sleep 2s,則不再繼續等待t1,執行t2執行緒
// t2.start();
// t2.join(10); // 等待t2執行緒10ms,t2執行緒代碼內sleep 3s,則不再繼續等待t2,執行t2執行緒
// t3.start();
// t3.join(10); // 等待t3執行緒10ms,t3執行緒代碼內sleep 1s.因為 sleep 等待時間原因,最終輸出結果是:【t3執行 > t1執行 > t2執行 > main主執行緒】
}
}
博主寫作不易,加個關注唄
求關注、求點贊,加個關注不迷路 ヾ(?°?°?)ノ゙
我不能保證所寫的內容都正確,但是可以保證不復制、不粘貼,保證每一句話、每一行代碼都是親手敲過的,錯誤也請指出,望輕噴 Thanks?(・ω・)ノ
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/341874.html
標籤:java
