简介
CountDownLatch 通过它的名字也能猜出一二来,Countdown 顾名思义倒计时,Latch可以理解为触发或者发射。也就是说当倒数到0时就可以发射火箭啦,在线程中就是一个等待的线程,当 countdown 到 0 就不用再等待了,可以向下执行任务了。
上面分析了一下 CountdownLatch 的概念,相信大家也能体会它的使用场景了。在多个线程中,如果某个线程需要等待其他几个线程执行某个操作后,才能向下执行动作的话,我们就可以使用 CountDownLatch 来实现多线程之间的同步。
说了这么多,我们还是来看下 CountDownLatch 提供了哪些使用方法。
方法
- public CountDownLatch(int count)
构造函数,需传入计数的总数。
- public void await()
阻塞线程,直到总计数值为0
- public void countDown()
当前总计数减一
- public long getCount()
当前总计数
通过上面 CountDownLatch 提供的几个方法,我们可以看出来 CountDownLatch 没有重新设置总计数的方法,也就是说这个类只有初始化的时候才设置一次,等计数完成后就不可再复用,需要重新创建一个新的 CountDownLatch 才可以再计数。
CountDownLatch 还有一个超时等待的 await 函数,这里就不多分析了。CountDownLatch 几个重要的方法我们已经知道了,现在来看看怎么使用这几个方法。
测试
先上实例代码,创建了5个线程,2个等待线程,3个执行 countdown 线程。
import java.util.concurrent.CountDownLatch;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
public class Test2Activity extends Activity {
private CountDownLatch mCountDownLatch;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_layout);
mCountDownLatch = new CountDownLatch(3);
new Thread(new Runnable() {
@Override
public void run() {
try {
Log.d("TAG", "Thread Main A start:"+mCountDownLatch.getCount());
mCountDownLatch.await();
Log.d("TAG", "Thread Main A end:"+mCountDownLatch.getCount());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
try {
Log.d("TAG", "Thread Main B start:"+mCountDownLatch.getCount());
mCountDownLatch.await();
Log.d("TAG", "Thread Main B end:"+mCountDownLatch.getCount());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
mCountDownLatch.countDown();
Log.d("TAG", "Thread A:"+mCountDownLatch.getCount());
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
mCountDownLatch.countDown();
Log.d("TAG", "Thread B:"+mCountDownLatch.getCount());
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
mCountDownLatch.countDown();
Log.d("TAG", "Thread C:"+mCountDownLatch.getCount());
}
}).start();
}
执行结果:
从打印的结果,我们可以看到,2 个等待线程都是在其他三个线程执行完 countDown() 再执行下一步的任务。CountDownLatch 使用起来也是挺简单的,没有过多的,复杂的方法。就像发射火箭,开始倒计时,然后发射,收工,不用考虑重复使用同一火箭。一次性使用,无后顾之忧!!!