Java并发编程之——CountDownLatch的使用

时间:2023-02-09 20:48:36

最近在开发Android项目的时候有一个需求:在Service中开启多个线程并发的执行任务,当这三个线程执行完毕之后,主线程才能继续往下执行。刚开始使用的是AsyncTask+AtomicInteger的方式,然后在onpostexecute回调中对AtomicInteger进行自增且判断其值是否达到了要求的值,如果达到了要求的值就继续执行相应的操作,否则跳过。但是发现这种方式并不能很好的实现想要的效果!于是研究了下Java并发编程中的CountDownLatch使用。


CountDownLatch位于包java.util.concurrent下面,它的应用场景是:有一个任务,需要等待其他几个任务完成之后才能继续执行,这个时候就可以使用CountDownLatch了。


CountDownLatch有一个构造器,count代表计数值,也就是任务的个数。

 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计数值减一


下面是演示代码:

package com.easyliu.java.demo;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CountDownLatchTest {
private static CountDownLatch sCountDownLatch = null;
private static final int THREAD_NUMBER = 3;

/**
* @param args
*/
public static void main(String[] args) {
sCountDownLatch = new CountDownLatch(THREAD_NUMBER);
//线程池
ExecutorService fixedThreadPool = Executors
.newFixedThreadPool(THREAD_NUMBER);
//执行线程
fixedThreadPool.execute(new ConsumeRunnable("one"));
fixedThreadPool.execute(new ConsumeRunnable("two"));
fixedThreadPool.execute(new ConsumeRunnable("three"));
System.out.println("等待3个子线程执行完毕...");
try {
sCountDownLatch.await();
System.out.println("3个子线程已经执行完毕");
System.out.println("继续执行主线程");
} catch (InterruptedException e) {
e.printStackTrace();
}
}

private static class ConsumeRunnable implements Runnable {
private String mName;

public ConsumeRunnable(String name) {
this.mName = name;
}
public void run() {
System.out.println("子线程" + mName + "正在执行");
try {
Thread.sleep(3000);// 模拟耗时操作
System.out.println("子线程" + mName + "执行完毕");
sCountDownLatch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

输入如下所示:

等待3个子线程执行完毕...
子线程two正在执行
子线程one正在执行
子线程three正在执行
子线程one执行完毕
子线程three执行完毕
子线程two执行完毕
3个子线程已经执行完毕
继续执行主线程