实例讲解Java并发编程之闭锁
闭锁相当于一扇门,在闭锁到达结束状态之前,这扇门一直是关闭着的,没有任何线程可以通过,当到达结束状态时,这扇门才会打开并容许所有线程通过。它可以使一个或多个线程等待一组事件发生。闭锁状态包括一个计数器,初始化为一个正式,正数表示需要等待的事件数量。countDown方法递减计数器,表示一个事件已经发生,而await方法等待计数器到达0,表示等待的事件已经发生。CountDownLatch强调的是一个线程(或多个)需要等待另外的n个线程干完某件事情之后才能继续执行。
场景应用:
10个运动员准备赛跑,他们等待裁判一声令下就开始同时跑,当最后一个人通过终点的时候,比赛结束。10个运动相当于10个线程,这里关键是控制10个线程同时跑起来,还有怎么判断最后一个线程到达终点。可以用2个闭锁,第一个闭锁用来控制10个线程等待裁判的命令,第二个闭锁控制比赛结束。
importjava.util.concurrent.CountDownLatch; classAworkerimplementsRunnable{ privateintnum; privateCountDownLatchbegin; privateCountDownLatchend; publicAworker(intnum,finalCountDownLatchbegin,finalCountDownLatchend){ this.num=num; this.begin=begin; this.end=end; } @Override publicvoidrun(){ //TODOAuto-generatedmethodstub try{ System.out.println(num+"thpeopleisready"); begin.await();//准备就绪 }catch(InterruptedExceptione){ e.printStackTrace(); }finally{ end.countDown();//计数器减一,到达终点 System.out.println(num+"thpeoplearrive"); } } } publicclassRace{ publicstaticvoidmain(String[]args){ intnum=10; CountDownLatchbegin=newCountDownLatch(1); CountDownLatchend=newCountDownLatch(num); for(inti=1;i<=num;i++){ newThread(newAworker(i,begin,end)).start(); } try{ Thread.sleep((long)(Math.random()*5000)); }catch(InterruptedExceptione1){ //TODOAuto-generatedcatchblock e1.printStackTrace(); } System.out.println("judgesay:run!"); begin.countDown();//裁判一声令下开始跑 longstartTime=System.nanoTime(); try{ end.await();//等待结束 }catch(InterruptedExceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); }finally{ longendTime=System.nanoTime(); System.out.println("judgesay:allarrived!"); System.out.println("spendtime:"+(endTime-startTime)); } } }
输出
1thpeopleisready 2thpeopleisready 4thpeopleisready 6thpeopleisready 3thpeopleisready 10thpeopleisready 8thpeopleisready 5thpeopleisready 7thpeopleisready 9thpeopleisready judgesay:run! 1thpeoplearrive 4thpeoplearrive 10thpeoplearrive 5thpeoplearrive 2thpeoplearrive judgesay:allarrived! 9thpeoplearrive 7thpeoplearrive 8thpeoplearrive 3thpeoplearrive 6thpeoplearrive spendtime:970933