版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013276277/article/details/81558911
CountDownLatch是一种灵活的闭锁,他可以使一个或者多个线程等待一组事件发生。闭锁状态包括一个计数器,该计数器被初始化为1个正数,表示需要等待的事件数量。countDown方法递减计数器,表示有一个事件已经发生了,而await方法等待计数器达到0,这表示所有需要等待的事件都已经发生。如果计数器的值非0,那么await会一直阻塞直到计数器为0,或者等待线程中的线程中断,或者等待超时。
使用场景介绍:
(1) 确保某个计算在其需要的所有资源都被初始化之后才继续启动。
(2) 确保某个服务在其依赖的所有其他服务都已经启动之后才启动。当启动服务s时,将首先在S依赖的其他服务的闭锁上等待,在所有有依赖的服务都启动后会释放闭锁S,这样其他依赖S的服务才能继续执行。
(3) 等待知道某个操作的所有参与者(例如,再多玩家游戏中的所有玩家)都就绪再继续执行。在这种情况中,当所有玩家准备就绪时,闭锁将到达结束状态。
以下程序是测试多个线程执行某一任务所需要用到的时间。闭锁的应用在,当所有线程新建完并处于就绪状态时,才打开闭锁,所有线程一起并发执行。
package com.zy.charter5;
import java.util.concurrent.CountDownLatch;
public class TestHarness {
public long timeRasks(int nThreads, final Runnable task) {
final CountDownLatch startGate = new CountDownLatch(1);
final CountDownLatch endGate = new CountDownLatch(nThreads);
for (int i =0; i < nThreads; i++) {
Thread t = new Thread() {
public void run() {
try {
startGate.await();// 在线程执行方法中阻塞住,也就是这边新建的线程都需要等待startGate的countDown()信号
try {
task.run();
} finally {
endGate.countDown(); // 执行完线程需要计数器见一,以便最后计算执行完所有线程所需要的时间
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
t.start();// 开启线程,线程处于就绪状态,但是因为线程被startGate.await()阻塞住了还不能正常运行
System.out.println(t.getName() + "可能要等待一会。。。");
}
long start = System.nanoTime();
System.out.println("还没开始。。");
startGate.countDown();// 计数减到0,全部被startGate.await()阻塞住的线程就会全部开始执行
try {
endGate.await();// 等待endGate.countDown()使所有线程执行完毕,好方便计算所有线程的执行时间
} catch (InterruptedException e) {
e.printStackTrace();
}
long end = System.nanoTime();
return end - start;
}
public static void main(String[] args) {
System.out.println("time used : " + (new TestHarness()).timeRasks(5, new TaskRunnable()));
}
}
class TaskRunnable implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "start to execute ...");
}
}
执行结果:
Thread-0可能要等待一会。。。
Thread-1可能要等待一会。。。
Thread-2可能要等待一会。。。
Thread-3可能要等待一会。。。
Thread-4可能要等待一会。。。
还没开始。。
Thread-0start to execute ...
Thread-1start to execute ...
Thread-2start to execute ...
Thread-3start to execute ...
Thread-4start to execute ...
time used : 939077