2015-04-03 26 views
2

我正在學習如何在java中使用countdownLatch,並且我在代碼中創建了一個如下所示的簡單示例。如何使線程按順序使用CountDownlatch工作?

我對這種機制的理解是,它只是一種強制只有一個線程等待其他線程等待其他線程完成工作,然後那個線程正在等待的時候,當另一個線程開始工作時(s)完成。

我的問題是,如果我有4個線程't1,t2,t3和t4',它們應該按照所述的順序開始,並且每個線程應該在前導/前導結束時開始。換句話說,t2應等待t1並在t1結束時啓動,並且t3應等待t2並在t2結束時啓動,t4應等待t3並在t3完成時啓動。

1-如何使用CountDownLatch和循環障礙來做到這一點?

2-是傳遞給CountDownLatch類構造函數的countDown參數應該表示等待的線程數?

代碼

public class MainClass { 

public static void main(String[] args) { 

    CountDownLatch latch1 = new CountDownLatch(1); 
    Thread t1 = new Thread(new AscendingOrder(latch1)); 
    Thread t2 = new Thread(new DescendingOrder(latch1)); 

    t1.start(); 
    t2.start(); 
} 

static class AscendingOrder implements Runnable { 

    private CountDownLatch latch; 

    public AscendingOrder(CountDownLatch latch) { 
     // TODO Auto-generated constructor stub 
     this.latch = latch; 
    } 

    public void run() { 
     // TODO Auto-generated method stub 
     System.out.println("thread t1 started."); 

     for (int i = 0; i < 10; i++) 
      System.out.println(i); 

     this.latch.countDown(); 
    } 

} 

static class DescendingOrder implements Runnable { 

    private CountDownLatch latch; 

    public DescendingOrder(CountDownLatch latch1) { 
     // TODO Auto-generated constructor stub 
     this.latch = latch1; 
    } 

    public void run() { 
     // TODO Auto-generated method stub 
     System.out.println("thread t2 started and waiting"); 

     try { 
      this.latch.await(); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     for (int i = 10; i > 0; i--) 
      System.out.println(i); 
    } 

} 

}

+0

可能會或可能不適用,但是:對於順序執行任務(即「Runnable」或「Callable」,而不是線程),您可以將它們提交給某個順序執行程序(單線程執行程序)在一些已經存在的線程中(例如'main')。 – 2015-04-03 10:18:21

回答

0

1-如何這樣做使用CountDownLatch和環狀阻擋?

的CyclicBarrier是不理想的這個問題,我已經寫了後兩相比較,請看看here

public class CountDownLatchTest { 

    public static void main(String[] args) { 
     CountDownLatch first = new CountDownLatch(1); 
     CountDownLatch prev = first; 
     for(int i=0;i<10;i++) { 
      CountDownLatch next = new CountDownLatch(1); 
      new TestThread(prev, next, i).start(); 
      prev = next; 
     }  
     first.countDown(); 

    } 

    public static class TestThread extends Thread { 

     private CountDownLatch prev; 
     private CountDownLatch next; 
     private int id; 

     public TestThread(CountDownLatch prev, CountDownLatch next, int id) { 
      this.prev = prev; 
      this.next = next; 
      this.id = id; 
     } 

     public void run() { 
      if (prev != null) { 
       try { 
        prev.await(); 
       } catch (InterruptedException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
      try { 
       doWork(); 
      } finally { 
       if (next != null) { 
        next.countDown(); 
       } 
      } 
     } 

     public void doWork() { 
      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      System.out.println("Work done in Thread : " 
        + id); 
     } 

    } 
} 

2 - 是傳遞給 CountDownLatch類的構造函數倒計時參數應該代表等待的線程數量?

CountDownLatch.await()將等到CountDownLatch.countDown()方法被調用countDown參數次。