一、简介
CountDownLatch的构造方法接受一个int类型的参数作为计数器,如果你想等待N个点完成,这里就传入N。
每调用一次CountDownLatch的countDown()方法时,N就会减1,CountDownLatch的await()方法会阻塞当前线程,直到N = 0时。
由于countDown()方法可以用在任何地方,所以这里说的N,可以是N个线程,也可以是1个线程里的N个执行步骤。用在多个线程时,只需要把这个CountDownLatch的引用传递到线程里即可。
如果在某个解析sheet的线程处理得比较慢,不可能让主线程一直等待,所以可以使用另外一个带指定时间的await()方法——await(long time, TimeUnit unit),这个方法等待特定时间后,就会不再阻塞当前线程。join()也有类似的方法。
注意:计数器必须大于等于0,只是等于0时候,计数器就是0,调用await()方法时不会阻塞当前线程。CountDownLatch不可能重新初始化或则修改CountDownLatch对象的内部计数器的值。一个线程调用countDown()方法happen-before,另外一个线程调用await()方法。
2、实例
需要三个线程分别循环按顺序打印出a,b,c,d,e,f,g,h,i,即线程1打印a,d,g;线程2打印b,e,h;线程3打印c,f,i。
import java.util.concurrent.*;
public class test {
static CountDownLatch a = new CountDownLatch(1);
static CountDownLatch b = new CountDownLatch(1);
static CountDownLatch c = new CountDownLatch(1);
static class runnable1 implements Runnable{
@Override
public void run() {
try {
System.out.println("a");
b.countDown();
a.await();
System.out.println("d");
a = new CountDownLatch(1);
b.countDown();
a.await();
System.out.println("g");
b.countDown();
} catch(Exception e) {
e.printStackTrace();
}
}
}
static class runnable2 implements Runnable{
@Override
public void run() {
try {
b.await();
System.out.println("b");
b = new CountDownLatch(1);
c.countDown();
b.await();
System.out.println("e");
b = new CountDownLatch(1);
c.countDown();
b.await();
System.out.println("h");
c.countDown();
} catch(Exception e) {
e.printStackTrace();
}
}
}
static class runnable3 implements Runnable{
@Override
public void run() {
try {
c.await();
System.out.println("c");
c = new CountDownLatch(1);
a.countDown();
c.await();
System.out.println("f");
c = new CountDownLatch(1);
a.countDown();
c.await();
System.out.println("i");
} catch(Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args){
Thread thread1 = new Thread(new runnable1());
Thread thread2 = new Thread(new runnable2());
Thread thread3 = new Thread(new runnable3());
thread1.start();
thread2.start();
thread3.start();
}
}