JDK1.5开始提供的并发编程,辅助工具类。
字面意思回环栅栏,通过它可以实现让一组线程达到某个状态之后再全部同时执行。
叫做回环是因为当所有等待线程都被释放以后,CyclicBarrier可以被重用。
叫做栅栏是描述所有线程被栅栏挡住了,当都达到时,一起跳过栅栏执行。
演示代码:
import java.util.Map;
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CyclicBarrier;
/**
* CountDownLatch和CyclicBarrier对比
* 1、countdownlatch放行由第三者控制,CyclicBarrier放行由一组线程本身控制
* 2、countdownlatch放行条件>=线程数,CyclicBarrier放行条件=线程数
*/
public class UseCyclicBarrier {
/**
* 第一个参数,表示那个一起执行的线程个数。
* 第二个参数,表示线程都处于barrier时,一起执行之前,先执行的一个线程。
*/
//private static CyclicBarrier barrier = new CyclicBarrier(6);
private static CyclicBarrier barrier = new CyclicBarrier(6,new CollectThread());
//存放工作线程运行结果,模拟数据
private static ConcurrentHashMap<String,Long> resultMap = new ConcurrentHashMap<>();
//负责屏障开放以后的工作
private static class CollectThread implements Runnable{
@Override
public void run() {
StringBuffer str = new StringBuffer();
for (Map.Entry<String,Long> workResult : resultMap.entrySet()){
str.append(" ["+workResult.getValue()+"] ");
}
System.out.println("This result:"+str.toString());
System.out.println("This CollectThread:"+Thread.currentThread().getId());
}
}
//工作线程
private static class WorkThread implements Runnable{
@Override
public void run() {
System.out.println("This WorkThread:"+Thread.currentThread().getId());
String name = Thread.currentThread().getName();
Long id = Thread.currentThread().getId();
resultMap.put(name,id);
try {
Random random = new Random();
if (random.nextBoolean()){
System.out.println("This WorkThread:"+Thread.currentThread().getId()+" do somthing");
Thread.sleep(1000);
}
System.out.println("This WorkThread:"+Thread.currentThread().getId()+" is await");
//使线程处于barrier状态
barrier.await();
System.out.println("This WorkThread:"+Thread.currentThread().getId()+" end business");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
for (int i=0;i<6;i++){
new Thread(new WorkThread()).start();
}
}
}