在jdk5之后,提供了一些辅助类来帮助我们进行并发编程,CountDownLatch就是其中之一。看alibaba开源项目中用到CountDownLatch,决定总结一下
CountDownLatch类位于java.util.concurrent包下,利用它可以实现类似计数器的功能。比如一个任务要等待其他任务执行完毕后才能执行,此时就可以通过CountDownLatch来实现 CountDownLatch提供了一个构造器:
public CountDownLatch(int count) { if (count < 0) throw new IllegalArgumentException("count < 0"); this.sync = new Sync(count); }有以下几个重要的方法
public void await() throws InterruptedException { }; //调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行 public boolean await(long timeout, TimeUnit unit) throws InterruptedException { }; //和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行 public void countDown() { }; //将count值减1看下面代码示例
public class CountDownLatchDemo { public static void main(String[] args) throws InterruptedException { CountDownLatchDemo demo = new CountDownLatchDemo(); demo.testCountDownLatch(); } public void testCountDownLatch() throws InterruptedException { ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10,50,10, TimeUnit.SECONDS,new LinkedBlockingQueue()); int threadCount = 5; CountDownLatch start = new CountDownLatch(1); CountDownLatch end = new CountDownLatch(threadCount); for (int i=0;i<threadCount;i++){ threadPoolExecutor.execute(new Runnable() { @Override public void run() { try { start.await(); Thread.sleep(3000); System.out.println("执行子线程" + Thread.currentThread().getName()+""); } catch (InterruptedException e) { e.printStackTrace(); } end.countDown(); //将count值减1 } }); } threadPoolExecutor.shutdown(); System.out.println("执行主线程-1..."); long begin = System.currentTimeMillis(); start.countDown(); //执行此语句之前 所有的子线程挂起等待 之后子线程开始执行 System.out.println("执行主线程-2..."); end.await(); //所有的子线程执行完之前 挂起主线程 System.out.println("执行主线程-3..."); System.out.println("执行时间:"+ (System.currentTimeMillis()-begin)+"ms"); } }执行结果如下
执行主线程-1... 执行主线程-2... 执行子线程pool-1-thread-3 执行子线程pool-1-thread-5 执行子线程pool-1-thread-1 执行子线程pool-1-thread-2 执行子线程pool-1-thread-4 执行主线程-3... 执行时间:3000ms