CyclicBarrier
CyclicBarrier : N個線程相互等待,任何一個線程完成之前,所有的線程都必須等待。
CountDownLatch是某一個線程等待一個或者N個線程。
主體不同,CountDownLatch的主體是某一個線程。它是要一個或者多個線程完成某一個動作之後自己執行。這些線程互相之間是不等待的。
CyclicBaarier 主體是N個線程,就是說大家在某一個點上互相等待。只有大家都到了這個點,大家才能各自做自己接下來的事情。
還是用導入例子還說:
public class CyclicBarrierTest {
static CyclicBarrier ct = new CyclicBarrier(3);
public static void main(String[] args) throws InterruptedException {
new Thread(new ImportExcel(), "t1").start();
new Thread(new ImportExcel(), "t2").start();
new Thread(new ImportExcel(), "t3").start();
System.out.println("導入成功。。。。。。。");
}
static class ImportExcel implements Runnable{
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() +"導入成功");
ct.await();
System.out.println(Thread.currentThread().getName() +"記錄日誌");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
}
某次運行結果:
導入成功。。。。。。。
t3導入成功
t1導入成功
t2導入成功
t2記錄日誌
t3記錄日誌
t1記錄日誌
結果可以看到,首先主線程是不等待其它線程的。第二,無論怎麼運行,一定是t1,t2,t3都導入成功之後,才能大家各自做日誌記錄。這就是大家互相等待,一定要完成各自的任務才能接着做某事。當然它也能實現各自導入成功之後就通知用戶導入成功:
public class CyclicBarrierTest {
static CyclicBarrier ct = new CyclicBarrier(3,new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() +"通知用戶導入成功");
}
});
public static void main(String[] args) throws InterruptedException {
new Thread(new ImportExcel(), "t1").start();
new Thread(new ImportExcel(), "t2").start();
new Thread(new ImportExcel(), "t3").start();
}
static class ImportExcel implements Runnable{
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() +"導入成功");
ct.await();
System.out.println(Thread.currentThread().getName() +"記錄日誌");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
}
只有導入成功之後,再通知用戶。使用另外一個構造函數 public CyclicBarrier(int parties, Runnable barrierAction)。這個構造函數是只有在所有線程到達某個點之後再執行後面的Runnable中的run方法。