CountDownLatch
监听某个线程的初始化,等待初始化执行完毕后,通知主线程工作。延迟、阻塞的是主线程,在单个线程中。
CyclicBarrier
针对多个线程、线程池,多个线程初始化准备之后,去操作同一件事件(必须一定要所有准备才可执行,通知各的主线程去执行正常工作)。
package demo2;
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Created by liudan on 2017/7/30.
*/
public class DemoCyclicBarrier {
/**
* 假设一个场景:3个运动员,当跑步运动员准备好了,才一起出发
*/
static class Runner implements Runnable {
private CyclicBarrier CYCLIC_BARRIER;
private String name;
public Runner(CyclicBarrier CYCLIC_BARRIER, String name) {
this.CYCLIC_BARRIER = CYCLIC_BARRIER;
this.name = name;
}
@Override
public void run() {
try {
Thread.sleep(1000 * (new Random().nextInt(5)));
System.err.println(name + " 准备好了");
CYCLIC_BARRIER.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.err.println("Go!");
}
public static void main(String[] args) {
CyclicBarrier CYCLIC_BARRIER = new CyclicBarrier(3);
ExecutorService executorService = Executors.newFixedThreadPool(3);
executorService.execute(new Runner(CYCLIC_BARRIER, "1号"));
executorService.execute(new Runner(CYCLIC_BARRIER, "2号"));
executorService.execute(new Runner(CYCLIC_BARRIER, "2号"));
executorService.shutdown();
}
}
}
输出:
1号 准备好了 2号 准备好了 2号 准备好了 Go! Go! Go!
案例2
public class TestCyclicBarrier {
private static final int THREAD_NUM = 5;
public static class WorkerThread implements Runnable{
CyclicBarrier barrier;
public WorkerThread(CyclicBarrier b){
this.barrier = b;
}
@Override
public void run() {
// TODO Auto-generated method stub
try{
System.out.println("Worker's waiting");
//线程在这里等待,直到所有线程都到达barrier。
barrier.await();
System.out.println("ID:"+Thread.currentThread().getId()+" Working");
}catch(Exception e){
e.printStackTrace();
}
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
CyclicBarrier cb = new CyclicBarrier(THREAD_NUM, new Runnable() {
//当所有线程到达barrier时执行
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("Inside Barrier");
}
});
for(int i=0;i<THREAD_NUM;i++){
new Thread(new WorkerThread(cb)).start();
}
}
}
/*
以下是输出:
Worker's waiting
Worker's waiting
Worker's waiting
Worker's waiting
Worker's waiting
Inside Barrier
ID:12 Working
ID:8 Working
ID:11 Working
ID:9 Working
ID:10 Working
*/