* 倒计时门闩会导致一条或多条线程在“门口”一直等待,直到另一条线程打开这扇门,线程才得以继续运行!
* 它是由一个计数变量和两个操作组成,这两个操作分别是:导致一条线程等待直到计数变成0 以及 递减计数变量
* 类--> java.util.CountDownLatch实现了倒计时门闩同步器。
* 通过这个类的构造方法CountDownLatch(int count)并指定计数个数,来初始化一个CountDownLatch实例。
* 当Count为负数,改方法会抛出一个Java.lang.IllegalArgumentException
* CountDownLatch:
* Method:
countDown() 递减计数,当计数降至0时,释放所有等待线程,当改方法被调用时Count已经成为0,那么什么也不会发生
long getCount() 返回当前的计数,改方法用于测试和调试很有用
void await() 除非线程被中断,否则强制调用线程一直等待到计数器倒数为0。当count==0,改方法立即返回。
示例如下:
主线程首先创建了一对倒计时门闩,这个startSignal门闩会在主线程就绪之前禁止任何线程执行,
而doneSigal门闩会使得主线程等待所有的工作线程全部结束而执行
public class CountDownLatchDemo {
final static int NTHREADS = 3;
public static void main(String[] args) {
// 开始信号量
final CountDownLatch startSingal = new CountDownLatch(1);
// 结束信号量
final CountDownLatch doneSingal = new CountDownLatch(NTHREADS);
Runnable r = new Runnable() {
@Override
public void run() {
try {
report("entered run()");
startSingal.await(); // 等待计数器降至为0 ,除非打断线程才能返回
report("doing work");
Thread.sleep((int) Math.random() * 1000);
doneSingal.countDown();
} catch (Exception e) {
e.printStackTrace();
}
}
void report(String s) {
System.out.println(System.currentTimeMillis() + ":"
+ Thread.currentThread() + ":" + s);
}
};
ExecutorService executor = Executors.newFixedThreadPool(NTHREADS);
for (int i = 0; i < NTHREADS; i++) {
executor.execute(r);
}
try {
System.out.println("main thread doing something");
Thread.sleep(1000);// 线程沉睡1s
startSingal.countDown(); // 让所有的线程开始执行
System.out.println("main thread doing something else");
doneSingal.await();
executor.shutdown();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}