并发:CyclicBarrier的使用

CyclicBarrier:一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。
CyclicBarrier 支持一个可选的 Runnable 命令,在一组线程中的最后一个线程到达之后(但在释放所有线程之前),该命令只在每个屏障点运行一次。若在继续所有参与线程之前更新共享状态,此屏障操作 很有用。

1、使用构造方法为:CyclicBarrier(int parties, Runnable barrierAction) :创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,并在启动 barrier 时执行给定的屏障操作,该操作由最后一个进入 barrier 的线程执行。
[color=blue]注意:barrierAction只会执行一次[/color]
看一下《Think In Java》的例子:
赛马游戏:(这个例子仔细看看,是写的很不错的)。

class Horse implements Runnable {
private static int counter = 0;
private final int id = counter++;//马的编号
private int strides = 0;//步伐
private static Random rand = new Random(47);
private static CyclicBarrier barrier;

public Horse(CyclicBarrier b) {
barrier = b;
}

public synchronized int getStrides() {
return strides;
}

@Override
public void run() {
try {
while (!Thread.interrupted()) {
synchronized (this) {
strides += rand.nextInt(3);
}
barrier.await();
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}

public String toString() {
return "Horse : " + id;
}

public String tracks() {
StringBuilder s = new StringBuilder();
for (int i = 0; i < getStrides(); i++) {
s.append("*");
}
s.append(id);
return s.toString();
}

}

public class HorseRace {
static final int FINISH_LINE = 10;
private List<Horse> horses = new ArrayList<Horse>();
private ExecutorService exec = Executors.newCachedThreadPool();
private CyclicBarrier barrier;

public HorseRace(int nHorse, final int pause) {
barrier = new CyclicBarrier(nHorse, new Runnable() {
@Override
public void run() {
StringBuilder s = new StringBuilder();
for(int i = 0; i < FINISH_LINE; i++){
s.append("=");
}
System.out.println(s);
for(Horse horse : horses){
System.out.println(horse.tracks());
}
for(Horse horse : horses){
if(horse.getStrides() >= FINISH_LINE){
System.out.println(horse + " won!");
exec.shutdown();
return;
}
try {
TimeUnit.MILLISECONDS.sleep(pause);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("one time");
}
});
for(int i = 0; i < nHorse; i++){
Horse horse = new Horse(barrier);
horses.add(horse);
exec.execute(horse);
}
}
public static void main(String[] args){
int nHorses = 2;
int pause = 5;
new HorseRace(nHorses, pause);
}
}

2、构造方法为:CyclicBarrier(int parties) :创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,但它不会在启动 barrier 时执行预定义的操作。
[color=blue]注意:这个构造,barrier的计数为0时,没有其他统一的动作,各个线程会各自执行剩下的代码。比如下面的代码,若有5个线程相互等待,当barrier的计数为0时,将输出5次hello:
[/color]

public void run() {
try {
barrier.await();
System.out.println("hello");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值