多线程-闭锁CountDownLatch
闭锁相当于相当于一扇门,在闭锁到达结束状态之前,这扇门一直是关着的,所有的线程都不可以通过。它可以使一个或者一组线程等待某个时间发生。闭锁状态包括一个计数器,初始化的时候传入一个正数,这个数字表示等待的事件的个数。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