CountDownLatch、CyclicBarrier和 Semaphore

241 阅读2分钟

0号:这周天气不错啊,星期天来吃鸡啊

1号:好啊

2号:我AWM贼强

3号:请叫我盒子精

四个小伙伴相约一起下午两点玩吃鸡,于是...

ContDownlatch(上号)


/**
 * CountDownLatchGame
 *
 * @author robot
 * @date 2019/12/10 14:07
 */
public class CountDownLatchGame {

    private static CountDownLatch countDownLatch = new CountDownLatch(4);


    public static class Player implements Runnable {
        private String name;
        private int time;

        public Player(String name, int time) {
            this.name = name;
            this.time = time;
        }

        @Override
        public void run() {
            try {
                TimeUnit.SECONDS.sleep(time);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("2点" + time + "秒,"+name + "号 已上号");
            countDownLatch.countDown();
        }
    }

    public static void main(String[] args) {
        System.out.println("下午两点等待所有人上号");
        Player a = new Player("0", 1);
        Player b = new Player("1", 2);
        Player c = new Player("2", 5);
        Player d = new Player("3", 10);
        a.run();
        b.run();
        c.run();
        d.run();
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("所有人上号");
    }
}

这时4个小伙伴都已经上号了

CyclicBarrier(准备)

这不4人已经上好号了,肯定要换上一套骚气的衣服开始比赛

/**
 * CyclicBarrierGame
 * @author robot
 * @date 2019/12/10 15:38
 */
public class CyclicBarrierGame {

    private static final int SIZE = 4;

    public static void main(String[] args) throws InterruptedException {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(4);
        ExecutorService executorService = new ThreadPoolExecutor(10, 100, 
                1, TimeUnit.SECONDS, new LinkedBlockingQueue<>());

        for (int i = 0; i < SIZE; i++) {
            final int threadNum = i;
            Thread.sleep(1000);
            executorService.execute(() -> {
                System.out.println(threadNum + "号 换好衣服!");
                try {
                    cyclicBarrier.await();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                System.out.println(threadNum + "号 准备好了!");
            });
        }
        executorService.shutdown();
    }

Semaphore(抢)

另外一个小伙伴看见你们在玩,我也想玩,只有4人的队伍,这时谁抢到位置谁就可以玩

/**
 * SemaphoreGame
 *
 * @author robot
 * @date 2019/12/10 16:03
 */
public class SemaphoreGame {

    public static void main(String[] args) {

        final Semaphore semaphore = new Semaphore(4);
        ExecutorService executorService = new ThreadPoolExecutor(10, 100,
                1, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
        for (int i = 0; i < 5; i++) {
            final int threadNum = i;
            executorService.execute(() -> {
                try {
                    if (semaphore.tryAcquire()) {
                        System.out.println(threadNum + "号:我进游戏了");
                    } else {
                        System.out.println(threadNum + "号:卧槽,队伍满了");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }
        executorService.shutdown();
    }
}

总结

愉快的周末就这样结束了,让我们来总结一下

CountDownLatch:一般用于某个线程A等待若干个其他线程执行完任务之后,它才执行

CyclicBarrier:一般用于一组线程互相等待至某个状态,然后这一组线程再同时执行

CountDownLatch是不能够重用的,而CyclicBarrier是可以重用的

Semaphore:其实和锁有点类似,可以用作限流