• CyclicBarrier


    CyclicBarrier


    CyclicBarrier,一个同步辅助类,在API中是这么介绍的:

    它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。

    其内部实现使用了ReentrantLock和Condition

    /** The lock for guarding barrier entry */
    private final ReentrantLock lock = new ReentrantLock();
    /** Condition to wait on until tripped */
    private final Condition trip = lock.newCondition();
    

    构造函数

    public CyclicBarrier(int parties, Runnable barrierAction) {
        if (parties <= 0) throw new IllegalArgumentException();
        this.parties = parties;
        this.count = parties;
        this.barrierCommand = barrierAction;
    }
    

    重要方法

    //当所有的参与者都到达了这个屏障就进行释放,否则一直等待。
    其内部使用的是dowait(false, 0L)方法实现
    public int await() throws InterruptedException, BrokenBarrierException {
        try {
            return dowait(false, 0L);
        } catch (TimeoutException toe) {
            throw new Error(toe); // cannot happen
        }
    }
    //进行超时控制
    public int await(long timeout, TimeUnit unit)
            throws InterruptedException,
                   BrokenBarrierException,
                   TimeoutException {
            return dowait(true, unit.toNanos(timeout));
        }
    //将屏障重置为初始状态
    public void reset() {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            breakBarrier();   // break the current generation
            nextGeneration(); // start a new generation
        } finally {
            lock.unlock();
        }
    }
    //返回此时在屏障前等待的线程数
    public int getNumberWaiting() {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            return parties - count;
        } finally {
            lock.unlock();
        }
    }
    

    使用案例

    场景:四个人相约玩游戏,只有大家都准备的时候,游戏才开始

    /**
     * @ClassName: PlayThread
     * @author: Yang.X.P
     * @date: 2018-09-17 15:27
     **/
    public class PlayThread implements Runnable {
        private CyclicBarrier cyclicBarrier = new CyclicBarrier(4, () ->
                System.out.println("玩家准备完成,进入游戏中···"));
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + "已准备");
            try {
                cyclicBarrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
        }
    }
    class Game {
        public static void main(String[] args) {
            PlayThread playThread = new PlayThread();
            for(int i = 0; i < 4; i++){
                Thread newPlayer = new Thread(playThread);
                newPlayer.start();
            }
        }
    }
    

    参考资料:

    http://cmsblogs.com/?p=2241

  • 相关阅读:
    Windows Phone 应用程序的全球化 狼人:
    幽默:编程语言 / 操作系统
    幽默:编程语言 / 操作系统
    程序员的幽默
    游戏杆编程心得二:如何判断按钮的有效按下
    DirectX 7.0 SDK在VC 6.0环境中使用的注意事项
    游戏杆编程心得
    HTML 5 WebSocket 示例
    HTML 5 WebSocket 示例
    慎用VC 6.0
  • 原文地址:https://www.cnblogs.com/fruitknife/p/9703134.html
Copyright © 2020-2023  润新知