CountDownLatch
CountDownLatch
CountDownLatch与CyclicBarrier有点儿相似。
CyclicBarrier所描述的是“允许一组线程互相等待,直到到达某个公共屏障点,才会进行后续任务”,而CountDownLatch所描述的是”在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待“。在API中是这样描述的:
用给定的计数 初始化 CountDownLatch。由于调用了 countDown() 方法,所以在当前计数到达零之前,await 方法会一直受阻塞。之后,会释放所有等待的线程,await 的所有后续调用都将立即返回。这种现象只出现一次——计数无法被重置。如果需要重置计数,请考虑使用 CyclicBarrier。
其内部实现使用了队列同步器:
private static final class Sync extends AbstractQueuedSynchronizer
构造方法
//有一个参数,计数器,表示线程的数量
public CountDownLatch(int count) {
if (count < 0) throw new IllegalArgumentException("count < 0");
this.sync = new Sync(count);
}
公共方法
//在计数器变为0或者该线程被中断之前一直保持等待
public void await() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
//加了等待时间
public boolean await(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
}
//count减一
public void countDown() {
sync.releaseShared(1);
}
//返回当前的count值
public long getCount() {
return sync.getCount();
}
使用实例
还是四个人相约玩游戏,游戏大厅和飞机等待玩家准备,四人都准备了,游戏才开始。
package my.syn;
import java.util.concurrent.CountDownLatch;
import static my.syn.MyGame.countDownLatch;
/**
* @ClassName: MyGame
* @author: Yang.X.P
* @date: 2018-09-17 16:24
**/
public class MyGame implements Runnable{
static CountDownLatch countDownLatch = new CountDownLatch(4);
@Override
public void run() {
System.out.println("游戏大厅已加载好,等待所有玩家准备好,即可进入");
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("所有人到准备好了,游戏开始...");
}
public static void main(String[] args){
Player player = new Player();
MyGame myGame = new MyGame();
Aircraft aircraft = new Aircraft();
Thread airThread = new Thread(aircraft);
Thread gameThread = new Thread(myGame);
gameThread.start();
airThread.start();
for (int i = 0; i < 4; i++) {
Thread playerThread = new Thread(player);
playerThread.start();
}
}
}
class Aircraft implements Runnable {
@Override
public void run() {
System.out.println("飞机准备好了,等待起飞");
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("玩家到齐,飞机起飞!");
}
}
class Player implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "准备好了");
countDownLatch.countDown();
}
}
参考资料: