闭锁相当于相当于一扇门,在闭锁到达结束状态之前,这扇门一直是关着的,所有的线程都不可以通过。它可以使一个或者一组线程等待某个时间发生。闭锁状态包括一个计数器,初始化的时候传入一个正数,这个数字表示等待的事件的个数。countDown方法递减计数器,表示一个事件已经发生。如果计数器的值为非0,await方法会一直阻塞到计数器为0。当计数器为0,表示等待的事件已经发生,这时候所有的线程才可以继续往下执行。
闭锁的实现有CountDownLatch,类似于我们生活的田径比赛,当运动员听到裁判员的哨声时,运动员才可以开始跑,未听到裁判的哨声运动员不可以跑。这个时候不管所有的运动员是否已经准备就绪了,只要哨声一响,就可以跑。这个跟后面的栅栏有区别,运动员只等待一个事件,就是听到裁判员的哨声响起。下面看一下实现的代码,如下:
package countDownLatch.countDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class CountDownLatchDemo { public static void main(String[]args) throws InterruptedException{
final CountDownLatch startGate=new CountDownLatch(1);
final CountDownLatch endGate=new CountDownLatch(5);
//线程池
ExecutorService exce=Executors.newCachedThreadPool();
//创建5个线程
for(int i=1;i<=5;i++){
final int num=i;
Thread thread =new Thread(new Runnable() {
public void run() {
try {
System.out.println(num+"号选手准备就绪,等待裁判员哨声响起..");
//相当于同步锁Synchronized中的await()方法
startGate.await();
try {
Thread.sleep((long) (Math.random()*10000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(num+"号选手到达终点..");
} catch (InterruptedException e) {
e.printStackTrace();
}
finally{
//相当于同步锁Synchronized中的notify()方法,区别在于countDown需要执行5次后才能唤醒await()
endGate.countDown();
}
}
});
exce.execute(thread);
}
long start=System.nanoTime();
System.out.println("裁判员哨声响起..");
Thread.sleep(10000);
//唤醒执行startGate.await()的线程,让线程往下执行
startGate.countDown();
//等待被唤醒,主程序才能继续往下执行,线程中每次执行endGate.countDown()就减1,当为零的时候,主程序往下执行
endGate.await();
long end=System.nanoTime();
System.out.println("所有运动员到达终点,耗时:"+(end-start));
//关闭线程池
exce.shutdown();
}
}
执行结果如下:
参考地址:JAVA并发编程实战
http://m.jb51.net/article/63973.htm