場景:有三個線程t1、t2、t3。確保三個線程t1執行完后t2執行,t2執行完成后t3執行。
1、thread.Join把指定的線程加入到當前線程,可以將兩個交替執行的線程合並為順序執行的線程。比如在線程B中調用了線程A的Join()方法,直到線程A執行完畢后,才會繼續執行線程B
public class ThreadTest1 { // T1、T2、T3三個線程順序執行 public static void main(String[] args) { Thread t1 = new Thread(new Work(null)); Thread t2 = new Thread(new Work(t1)); Thread t3 = new Thread(new Work(t2)); t1.start(); t2.start(); t3.start(); } static class Work implements Runnable { private Thread beforeThread; public Work(Thread beforeThread) { this.beforeThread = beforeThread; } public void run() { if (beforeThread != null) { try { beforeThread.join(); System.out.println("thread start:" + Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } } else { System.out.println("thread start:" + Thread.currentThread().getName()); } } } }
2、使用CountDownLatch
CountDownLatch(閉鎖)是一個很有用的工具類,利用它我們可以攔截一個或多個線程使其在某個條件成熟后再執行。它的內部提供了一個計數器,在構造閉鎖時必須指定計數器的初始值,且計數器的初始值必須大於0。另外它還提供了一個countDown方法來操作計數器的值,每調用一次countDown方法計數器都會減1,直到計數器的值減為0時就代表條件已成熟,所有因調用await方法而阻塞的線程都會被喚醒。這就是CountDownLatch的內部機制,看起來很簡單,無非就是阻塞一部分線程讓其在達到某個條件之后再執行。
public class ThreadTest2 { // T1、T2、T3三個線程順序執行 public static void main(String[] args) { CountDownLatch c0 = new CountDownLatch(0); //計數器為0 CountDownLatch c1 = new CountDownLatch(1); //計數器為1 CountDownLatch c2 = new CountDownLatch(1); //計數器為1 Thread t1 = new Thread(new Work(c0, c1)); //c0為0,t1可以執行。t1的計數器減1 Thread t2 = new Thread(new Work(c1, c2)); //t1的計數器為0時,t2才能執行。t2的計數器c2減1 Thread t3 = new Thread(new Work(c2, c2)); //t2的計數器c2為0時,t3才能執行 t1.start(); t2.start(); t3.start(); } //定義Work線程類,需要傳入開始和結束的CountDownLatch參數 static class Work implements Runnable { CountDownLatch c1; CountDownLatch c2; Work(CountDownLatch c1, CountDownLatch c2) { super(); this.c1 = c1; this.c2 = c2; } public void run() { try { c1.await();//前一線程為0才可以執行 System.out.println("thread start:" + Thread.currentThread().getName()); c2.countDown();//本線程計數器減少 } catch (InterruptedException e) { } } } }