CountDownLatch(倒计时器)
指子线程所有执行完毕后,主线程继续执行。适应于火箭发射,发令枪响等。
执行如下代码很容易理解
public class countdown {
public static void main(String[] args) {
final CountDownLatch latch = new CountDownLatch(2);
new Thread(){
public void run() {
try {
System.out.println("子线程"+Thread.currentThread().getName()+"正在执行");
Thread.sleep(3000);
System.out.println("子线程"+Thread.currentThread().getName()+"执行完毕");
latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
}.start();
new Thread(){
public void run() {
try {
System.out.println("子线程"+Thread.currentThread().getName()+"正在执行");
Thread.sleep(3000);
System.out.println("子线程"+Thread.currentThread().getName()+"执行完毕");
latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
}.start();
try {
System.out.println("等待2个子线程执行完毕...");
latch.await(); //主线程在CountDownLatch上等待,当检查所有任务完成后继续工作
System.out.println("2个子线程已经执行完毕!!!");
System.out.println("继续执行主线程!!!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
CyclicBarrier(循环栅栏)
通过它可以实现让一组线程等待至某个状态之后再全部同时执行。
执行如下代码很容易理解
public class cyclicbarrier {
public static void main(String[] args) {
int N = 4;
CyclicBarrier barrier = new CyclicBarrier(N);
for(int i=0;i<N;i++)
new Writer(barrier).start();
}
static class Writer extends Thread{
private CyclicBarrier cyclicBarrier;
public Writer(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
System.out.println("线程"+Thread.currentThread().getName()+"正在进行逻辑耗时操作");
try {
Thread.sleep(5000); //以睡眠来模拟耗时操作
System.out.println("线程"+Thread.currentThread().getName()+"逻辑耗时操作完毕,等待其他线程完毕");
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
}catch(BrokenBarrierException e){
e.printStackTrace();
}
System.out.println("所有线程执行完毕,继续处理其他任务...");
}
}
}
总结:
CountDownLatch : 一个线程(或者多个), 等待另外N个线程完成某个事情之后才能执行。
CyclicBarrier : N个线程相互等待,任何一个线程完成之前,所有的线程都必须等待。
这样应该就清楚一点了,,,
对于CountDownLatch来说,重点是那个“一个线程”, 是它在等待, 而另外那N的线程在把“某个事情”做完之后可以继续等待,可以终止。
而对于CyclicBarrier来说,重点是那N个线程,他们之间任何一个没有完成,所有的线程都必须等待。