一、CountDownLatch(闭锁)
闭锁是一个同步工具类-它可以延迟线程的进度直到其到达终止状态。闭锁的作用相当于一扇门:在到达结束状态之前,这扇门是关闭的,并且不允许任何进程通过。当到达结束状态时,这扇门会打开并允许所有的线程通过。当闭锁到达结束状态后,将不会再改变状态,因此这扇门会一直打开。闭锁可以用来确保某些活动直到其它活动都完成后才继续执行。
CountDownLatch是一种灵活的闭锁实现。它可以使一个或多个线程等待一组事件的发生。闭锁状态包含一个计数器,它被初始化为正整数,表示需要等待的事件数量。countDown()方法递减计数器:表示一个事件已经发生。而await方法等待计数器达到零,这表示所有的事件都已经发生。如果计数器非零,那么await会一直阻塞知道计数器为零、或者中断、或者等待超时。
CountDownLatch提供了几个方法:
方法 | 说明 |
---|---|
public CountDownLatch(int count) | 初始化计数器为一个非负数 |
void await() throws InterruptedException | 阻塞直到计数器为0 |
boolean await(long timeout, TimeUnit unit) throws InterruptedException |
限时阻塞,超时则继续执行 |
void countDown() | 计数器递减1 |
long getCount() | 计数器数量 |
CountDownLatch(int count) 如果初始化计数器为0,那么所有线程都可以通过,也就起不到等待事件发生的作用了
await和await(timeout,unit)都是可中断的,当线程被中断时,这两个方法会抛出InterruptedException异常,并清除中断标志。
二、示例
基本使用
/**
* 测试你个线程并发执行某个任务需要的时间
*/
public class TestHarness {
public long timeTask(int nThread, Runnable runnable) throws InterruptedException {
final CountDownLatch beginGate = new CountDownLatch(1);
final CountDownLatch endGate = new CountDownLatch(nThread);
for(int i=0;i<nThread;i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
beginGate.await