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方法。