官方定义:A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.
有道翻译:一种同步辅助程序,允许一个或多个线程等待,直到在其他线程中执行的一组操作完成。
个人理解,实际就是一个倒计时计数器,人为指定计数器的起始值,从起始值开始倒计时计数。
主要方法:
await():阻塞,直到倒计时为0开始执行;
countDown():倒计时方法,没执行一次减一,如果新计数为零,则所有等待的线程都将被重新启用;
getCount():返回当前计数。
说这么多,也不知道到底是个啥,看例子:
例1:
三个运动员百米赛跑,一个裁判倒计时发枪。裁判需要等待运动员全部都准备好了,才会发枪
所以这段时间裁判需要除以等待状态,当所有的运动员都汇报准备好了,裁判发枪
//也就是说await()会一直等待CountDownLatch的初始值全部countDown()后才会线下执行
public static void main(String[] args) {
CountDownLatch latch = new CountDownLatch(3);
Thread t1 = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("博尔特准备完毕");
latch.countDown();
System.out.println("剩下的记数器:"+latch.getCount());
}
},"t1");
Thread t2 = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(7000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("加特林准备完毕");
latch.countDown();
System.out.println("剩下的记数器:"+latch.getCount());
}
},"t2");
Thread t3 = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("鲍威尔准备完毕");
latch.countDown();
System.out.println("剩下的记数器:"+latch.getCount());
}
},"t3");
t1.start();
t2.start();
t3.start();
try {
System.out.println("我是裁判,你们好好准备,准备好了都说一声....");
latch.await();
System.out.println("好的,都准备好了,我要发枪了");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
运行结果:
我是裁判,你们好好准备,准备好了都说一声...
博尔特准备完毕
剩下的记数器:2
加特林准备完毕
剩下的记数器:1
鲍威尔准备完毕
剩下的记数器:0
好的,都准备好了,我要发枪了
例2:
其实刚才说的是裁判等运动员准备的过程,实际上细细分析,我们会发现,实际上也有一个运动员等枪响的动作。运动员听见枪响后,同时起跑。
public static void main(String[] args) {
CountDownLatch latch = new CountDownLatch(1);
Thread t1 = new Thread(new Runnable() {
public void run() {
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("博尔特起跑");
}
},"t1");
Thread t2 = new Thread(new Runnable() {
public void run() {
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("鲍威尔起跑");
}
},"t2");
Thread t3 = new Thread(new Runnable() {
public void run() {
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("加特林起跑");
}
},"t3");
t1.start();
t2.start();
t3.start();
try {
System.out.println("各就位");
Thread.sleep(3000);
System.out.println("发枪....");
latch.countDown();
} catch (Exception e) {
e.printStackTrace();
}
}
运行结果:
各就位
发枪....
博尔特起跑
加特林起跑
鲍威尔起跑
例3
模拟发枪起跑,到运动员跑完全程,比赛结束的过程:
public static void main(String[] args) {
CountDownLatch start = new CountDownLatch(1);
CountDownLatch end = new CountDownLatch(3);
Thread t1 = new Thread(new Runnable() {
public void run() {
try {
start.await();
System.out.println("博尔特起跑");
Thread.sleep(9580);
System.out.println("博尔特跑完了全程");
end.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"t1");
Thread t2 = new Thread(new Runnable() {
public void run() {
try {
start.await();
System.out.println("鲍威尔起跑");
Thread.sleep(9760);
System.out.println("鲍威尔跑完了全程");
end.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"t2");
Thread t3 = new Thread(new Runnable() {
public void run() {
try {
start.await();
System.out.println("加特林起跑");
Thread.sleep(9620);
System.out.println("加特林跑完了全程");
end.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"t3");
t1.start();
t2.start();
t3.start();
try {
System.out.println("各就位");
Thread.sleep(1000);
System.out.println("发枪.....");
start.countDown();
Thread.sleep(2000);
System.out.println("这是一场精彩的比赛");
Thread.sleep(2000);
System.out.println("加特林加速");
Thread.sleep(2000);
System.out.println("博尔特反超");
Thread.sleep(2000);
System.out.println("博尔特一直保持领先");
end.await();
System.out.println("比赛结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
运行结果:
各就位
发枪.....
鲍威尔起跑
加特林起跑
博尔特起跑
这是一场精彩的比赛
加特林加速
博尔特反超
博尔特一直保持领先
博尔特跑完了全程
加特林跑完了全程
鲍威尔跑完了全程
比赛结束
相信已经基本理解了CountDownLatch用法了吧