1. 背景
CyclicBarrier类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。
2. 示范代码
下面这段代码演示了打扑克游戏,够4个人则开桌,共计开5桌:
package com.clzhang.sample.thread;import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.CyclicBarrier;public class SyncCyclicBarrier { class PokerPlayer implements Runnable { private CyclicBarrier barrier; private String name; public PokerPlayer(CyclicBarrier barrier, String name) { this.barrier = barrier; this.name = name; } @Override public void run() { try { Thread.sleep((long) (Math.random() * 3000)); System.out.println(name + "坐好了..."); // 在所有参与者都执行到这儿之后,再执行await()语句之后的代码。 barrier.await(); System.out.println(name + "已经发牌!"); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } } public static void main(String[] args) throws Exception { final int PER_TABLE_PLAYERS = 4; // 多少人够开一桌的 final int TOTAL_TABLES= 5; // 共计开多少桌 CyclicBarrier barrier = new CyclicBarrier(PER_TABLE_PLAYERS); SyncCyclicBarrier ins = new SyncCyclicBarrier(); ExecutorService executorPool = Executors.newFixedThreadPool(PER_TABLE_PLAYERS); for(int i=0; i
输出
3号玩家坐好了...
1号玩家坐好了...0号玩家坐好了...2号玩家坐好了...2号玩家已经发牌!3号玩家已经发牌!0号玩家已经发牌!1号玩家已经发牌!4号玩家坐好了...7号玩家坐好了...6号玩家坐好了...5号玩家坐好了...4号玩家已经发牌!5号玩家已经发牌!7号玩家已经发牌!6号玩家已经发牌!11号玩家坐好了...9号玩家坐好了...8号玩家坐好了...10号玩家坐好了...11号玩家已经发牌!10号玩家已经发牌!9号玩家已经发牌!8号玩家已经发牌!13号玩家坐好了...14号玩家坐好了...15号玩家坐好了...12号玩家坐好了...13号玩家已经发牌!14号玩家已经发牌!12号玩家已经发牌!15号玩家已经发牌!16号玩家坐好了...18号玩家坐好了...19号玩家坐好了...17号玩家坐好了...16号玩家已经发牌!18号玩家已经发牌!17号玩家已经发牌!19号玩家已经发牌!