实例讲解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