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:其实和锁有点类似,可以用作限流