CyclicBarrier是一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时CyclicBarrier很有用。因为该barrier在释放等待线程后可以重用,所以称它为循环的barrier。
CyclicBarrier类似于CountDownLatch也是个计数器, 不同的是CyclicBarrier数的是调用了CyclicBarrier.await()进入等待的线程数, 当线程数达到了CyclicBarrier初始时规 定的数目时,所有进入等待状态的线程被唤醒并继续。CyclicBarrier就象它名字的意思一样可看成是个障碍, 所有的线程必须到齐后才能一起通过这个障碍。 CyclicBarrier初 始时还可带一个Runnable的参数,此Runnable任务在CyclicBarrier的数目达到后,所有其它线程被唤醒前被执行。
构造方法摘要
CyclicBarrier(int parties)
创建一个新的CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,但它不会在每个barrier上执行预定义的操作。
CyclicBarrier(int parties, Runnable barrierAction)
创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,并在启动 barrier 时执行给定的屏障操作,该操作由最后一个进入barrier的线程执行
方法摘要
int await()
在所有参与者都已经在此barrier上调用await方法之前,将一直等待
int await(long timeout, TimeUnit unit)
在所有参与者都已经在此屏障上调用 await 方法之前,将一直等待
int getNumberWaiting()
返回当前在屏障处等待的参与者数目
int getParties()
返回要求启动此 barrier 的参与者数目
boolean isBroken()
查询此屏障是否处于损坏状态
void reset()
将屏障重置为其初始状态
例一
public class RunnerTask implements Runnable
{
private final CyclicBarrier cyclicBarrier;
private String name;
public RunnerTask(CyclicBarrier cyclicBarrier, String name)
{
super();
this.name = name;
this.cyclicBarrier = cyclicBarrier;
}
public void run()
{
try
{
try
{
// 模拟等待
Thread.sleep(new Random().nextInt(5) * 1000);
System.out.println(name + "准备......");
cyclicBarrier.await();
System.out.println(name + "跑!");
}
catch (BrokenBarrierException e)
{
e.printStackTrace();
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
public class RunnerTest
{
public static void main(String[] args)
{
CyclicBarrier cyclicBarrier = new CyclicBarrier(5);
for (int i = 1; i <= 5; i++)
{
new Thread(new RunnerTask(cyclicBarrier, "运动员" + i)).start();
}
}
}
运动员3准备......
运动员2准备......
运动员4准备......
运动员5准备......
运动员1准备......
运动员3跑!
运动员2跑!
运动员1跑!
运动员5跑!
运动员4跑!
例二
public class CyclicBarrierTest2
{
public static void main(String[] args)
{
ExecutorService service = Executors.newCachedThreadPool();
final CyclicBarrier cb = new CyclicBarrier(3);
for (int i = 0; i < 3; i++)
{
Runnable runnable = new Runnable()
{
public void run()
{
try
{
Thread.sleep((long) (Math.random() * 10000));
System.out.println("线程" + Thread.currentThread().getName()
+ "即将到达集合地点1,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");
cb.await();
Thread.sleep((long) (Math.random() * 10000));
System.out.println("线程" + Thread.currentThread().getName()
+ "即将到达集合地点2,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");
cb.await();
Thread.sleep((long) (Math.random() * 10000));
System.out.println("线程" + Thread.currentThread().getName()
+ "即将到达集合地点3,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");
cb.await();
}
catch (Exception e)
{
e.printStackTrace();
}
}
};
service.execute(runnable);
}
service.shutdown();
}
}
线程pool-1-thread-1即将到达集合地点1,当前已有0个已经到达,正在等候
线程pool-1-thread-3即将到达集合地点1,当前已有1个已经到达,正在等候
线程pool-1-thread-2即将到达集合地点1,当前已有2个已经到达,正在等候
线程pool-1-thread-3即将到达集合地点2,当前已有0个已经到达,正在等候
线程pool-1-thread-2即将到达集合地点2,当前已有1个已经到达,正在等候
线程pool-1-thread-1即将到达集合地点2,当前已有2个已经到达,正在等候
线程pool-1-thread-1即将到达集合地点3,当前已有0个已经到达,正在等候
线程pool-1-thread-3即将到达集合地点3,当前已有1个已经到达,正在等候
线程pool-1-thread-2即将到达集合地点3,当前已有2个已经到达,正在等候
例三
public class CyclicBarrierTest
{
public static void main(String[] args)
{
ExecutorService service = Executors.newCachedThreadPool();
final CyclicBarrier cb = new CyclicBarrier(3, new Runnable()
{
public void run()
{
System.out.println("********我最先执行***********");
}
});
for (int i = 0; i < 3; i++)
{
Runnable runnable = new Runnable()
{
public void run()
{
try
{
Thread.sleep((long) (Math.random() * 10000));
System.out.println("线程" + Thread.currentThread().getName()
+ "即将到达集合地点1,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");
cb.await();
Thread.sleep((long) (Math.random() * 10000));
System.out.println("线程" + Thread.currentThread().getName()
+ "即将到达集合地点2,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");
cb.await();
Thread.sleep((long) (Math.random() * 10000));
System.out.println("线程" + Thread.currentThread().getName()
+ "即将到达集合地点3,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");
cb.await();
}
catch (Exception e)
{
e.printStackTrace();
}
}
};
service.execute(runnable);
}
service.shutdown();
}
}
线程pool-1-thread-1即将到达集合地点1,当前已有0个已经到达,正在等候
线程pool-1-thread-3即将到达集合地点1,当前已有1个已经到达,正在等候
线程pool-1-thread-2即将到达集合地点1,当前已有2个已经到达,正在等候
********我最先执行***********
线程pool-1-thread-1即将到达集合地点2,当前已有0个已经到达,正在等候
线程pool-1-thread-3即将到达集合地点2,当前已有1个已经到达,正在等候
线程pool-1-thread-2即将到达集合地点2,当前已有2个已经到达,正在等候
********我最先执行***********
线程pool-1-thread-1即将到达集合地点3,当前已有0个已经到达,正在等候
线程pool-1-thread-3即将到达集合地点3,当前已有1个已经到达,正在等候
线程pool-1-thread-2即将到达集合地点3,当前已有2个已经到达,正在等候
********我最先执行***********
原帖地址:http://www.cnblogs.com/liuling/p/2013-8-21-01.html
CyclicBarrier类似于CountDownLatch也是个计数器, 不同的是CyclicBarrier数的是调用了CyclicBarrier.await()进入等待的线程数, 当线程数达到了CyclicBarrier初始时规 定的数目时,所有进入等待状态的线程被唤醒并继续。CyclicBarrier就象它名字的意思一样可看成是个障碍, 所有的线程必须到齐后才能一起通过这个障碍。 CyclicBarrier初 始时还可带一个Runnable的参数,此Runnable任务在CyclicBarrier的数目达到后,所有其它线程被唤醒前被执行。
构造方法摘要
CyclicBarrier(int parties)
创建一个新的CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,但它不会在每个barrier上执行预定义的操作。
CyclicBarrier(int parties, Runnable barrierAction)
创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,并在启动 barrier 时执行给定的屏障操作,该操作由最后一个进入barrier的线程执行
方法摘要
int await()
在所有参与者都已经在此barrier上调用await方法之前,将一直等待
int await(long timeout, TimeUnit unit)
在所有参与者都已经在此屏障上调用 await 方法之前,将一直等待
int getNumberWaiting()
返回当前在屏障处等待的参与者数目
int getParties()
返回要求启动此 barrier 的参与者数目
boolean isBroken()
查询此屏障是否处于损坏状态
void reset()
将屏障重置为其初始状态
例一
public class RunnerTask implements Runnable
{
private final CyclicBarrier cyclicBarrier;
private String name;
public RunnerTask(CyclicBarrier cyclicBarrier, String name)
{
super();
this.name = name;
this.cyclicBarrier = cyclicBarrier;
}
public void run()
{
try
{
try
{
// 模拟等待
Thread.sleep(new Random().nextInt(5) * 1000);
System.out.println(name + "准备......");
cyclicBarrier.await();
System.out.println(name + "跑!");
}
catch (BrokenBarrierException e)
{
e.printStackTrace();
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
public class RunnerTest
{
public static void main(String[] args)
{
CyclicBarrier cyclicBarrier = new CyclicBarrier(5);
for (int i = 1; i <= 5; i++)
{
new Thread(new RunnerTask(cyclicBarrier, "运动员" + i)).start();
}
}
}
运动员3准备......
运动员2准备......
运动员4准备......
运动员5准备......
运动员1准备......
运动员3跑!
运动员2跑!
运动员1跑!
运动员5跑!
运动员4跑!
例二
public class CyclicBarrierTest2
{
public static void main(String[] args)
{
ExecutorService service = Executors.newCachedThreadPool();
final CyclicBarrier cb = new CyclicBarrier(3);
for (int i = 0; i < 3; i++)
{
Runnable runnable = new Runnable()
{
public void run()
{
try
{
Thread.sleep((long) (Math.random() * 10000));
System.out.println("线程" + Thread.currentThread().getName()
+ "即将到达集合地点1,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");
cb.await();
Thread.sleep((long) (Math.random() * 10000));
System.out.println("线程" + Thread.currentThread().getName()
+ "即将到达集合地点2,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");
cb.await();
Thread.sleep((long) (Math.random() * 10000));
System.out.println("线程" + Thread.currentThread().getName()
+ "即将到达集合地点3,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");
cb.await();
}
catch (Exception e)
{
e.printStackTrace();
}
}
};
service.execute(runnable);
}
service.shutdown();
}
}
线程pool-1-thread-1即将到达集合地点1,当前已有0个已经到达,正在等候
线程pool-1-thread-3即将到达集合地点1,当前已有1个已经到达,正在等候
线程pool-1-thread-2即将到达集合地点1,当前已有2个已经到达,正在等候
线程pool-1-thread-3即将到达集合地点2,当前已有0个已经到达,正在等候
线程pool-1-thread-2即将到达集合地点2,当前已有1个已经到达,正在等候
线程pool-1-thread-1即将到达集合地点2,当前已有2个已经到达,正在等候
线程pool-1-thread-1即将到达集合地点3,当前已有0个已经到达,正在等候
线程pool-1-thread-3即将到达集合地点3,当前已有1个已经到达,正在等候
线程pool-1-thread-2即将到达集合地点3,当前已有2个已经到达,正在等候
例三
public class CyclicBarrierTest
{
public static void main(String[] args)
{
ExecutorService service = Executors.newCachedThreadPool();
final CyclicBarrier cb = new CyclicBarrier(3, new Runnable()
{
public void run()
{
System.out.println("********我最先执行***********");
}
});
for (int i = 0; i < 3; i++)
{
Runnable runnable = new Runnable()
{
public void run()
{
try
{
Thread.sleep((long) (Math.random() * 10000));
System.out.println("线程" + Thread.currentThread().getName()
+ "即将到达集合地点1,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");
cb.await();
Thread.sleep((long) (Math.random() * 10000));
System.out.println("线程" + Thread.currentThread().getName()
+ "即将到达集合地点2,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");
cb.await();
Thread.sleep((long) (Math.random() * 10000));
System.out.println("线程" + Thread.currentThread().getName()
+ "即将到达集合地点3,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");
cb.await();
}
catch (Exception e)
{
e.printStackTrace();
}
}
};
service.execute(runnable);
}
service.shutdown();
}
}
线程pool-1-thread-1即将到达集合地点1,当前已有0个已经到达,正在等候
线程pool-1-thread-3即将到达集合地点1,当前已有1个已经到达,正在等候
线程pool-1-thread-2即将到达集合地点1,当前已有2个已经到达,正在等候
********我最先执行***********
线程pool-1-thread-1即将到达集合地点2,当前已有0个已经到达,正在等候
线程pool-1-thread-3即将到达集合地点2,当前已有1个已经到达,正在等候
线程pool-1-thread-2即将到达集合地点2,当前已有2个已经到达,正在等候
********我最先执行***********
线程pool-1-thread-1即将到达集合地点3,当前已有0个已经到达,正在等候
线程pool-1-thread-3即将到达集合地点3,当前已有1个已经到达,正在等候
线程pool-1-thread-2即将到达集合地点3,当前已有2个已经到达,正在等候
********我最先执行***********
原帖地址:http://www.cnblogs.com/liuling/p/2013-8-21-01.html