Java SE5中的CountDownLatch和CyclicBarrier类库

CountDownLatch

1)java.unit.concurrent.CountDownLatch用于同步一个或多个任务, 强制他们等待由其他任务执行的一组任务的完成
     使用一个初始计数值作为锁存器,通过调用countDownLatch,使锁存器递减;
     当一个Latch锁存器递减至0之前,所有调用CountDownLatch.await 的任务线程都会一直被阻塞;
     当该Latch锁存器 = 0 时,同时释放所有调用CountDownLatch.await 的任务线程对象;
    
2)CountDownLacth的2中典型用法:
①使一个线程在N个线程完成某项操作之前一直等待(或者在其某项工作完成N次之前一直等待);
    CountDownLatch(1)可以作为一个开/关锁存器,在通过调用countDown的线程打开入口之前,所有调用await的线程都一直在入口等待;
//startSignal是一个启动信号,为driver在为执行所有worker做好准备之前,阻止所有worker执行;
//doneSiganl时一个完后信号,允许dirver在所有worker完成之前一直等待;
class Driver{
     void main(){
          CountDownLatch startSiganl = new CountDownLatch(1);
          CountDownLatch doneSignal = new CountDownLacth(N);
          
          ExecuteService exec = new Executors.newCachedThreadPool();
          for(int i=0;i<N;i++)
               exec.execute(new Worker(stratSignal,doneSingal));
          
          <do some before all Worker tasks start running>
          startSignal.countDown();              //let all threads start running
          <do something while all Worker tasks are running>
          doneSignal.await();                    //wait for all to finish
          <do something when all finished>
     }
}
class Worker implements Runnable{
     private final CountDownLatch stratSignal;
     private final CountDownLatch doneSignal;
     public Worker(CountDownLatch strat,CountDownLatch done){ startSiganl = start;doneSignal = done;}
     public void run(){
          try{
               startSignal.await();      //let all worker wait;
               <do Work>
               doneSignal.countDown();    //count down latch;
          }catch(InterrupedException ex){
          }
     }




②将一个问题分成N个部分,每个部分由描述该部分任务并让锁存器倒计时的Runnable来完成,然后将所有Runnable加入Executor队列 ,当所有子部分完成后,协调线程就可以通过awiat;
(当线程需要使用这种方法反复计数时,可以改为使用 CyclicBarrier);
class Driver{
     void main(){
          CountDownLatch donwSignal = new CountDownLatch(N);
          ExecutorService exec = Executors.newFixedThreadPool(N);
          for(int i=0;i<N;i++)
               exec.execute(new Worker(doneSiganl,i);
          doneSiganl.await();    //wait for all to finish
     }
}
class Worker implements Runnable{
     private final CountDownLatch doneSiganl;
     private final int i;
     public Worker(CountDownLatch doneSignal,int i){this.doneSignal = doneSignal;this.i = i;}
     public void run(){
          try{
               doWork(i);
               doneSignal.countDown();
          }catch(InterruptedException ex){
          }
     }
     priavte void doWork(){
          .......
     }
}






CyclicBarrier

1)java.util.concurrent.CyclicBarrier 允许一组线程相互等待,直到到达某个公共屏障点(common barrier point),barrier在释放等待线程之后可以重用;
2)CyclicBarrier适用于并行分解设计,在涉及一组大小固定的线程的程序中,这些程序必须不时地相互等待( 即线程分布呈现为二维矩阵);
/*在这个例子中,每个worker单独处理矩阵的一行,在处理完所有的行之前,该线程会一直处于barrier处等待;
  处理完所有的行后,由Runnable的mergeRows提供屏障操作,并合并这些行;
  当合并者找到一个解决方案,done()返回true,所用Worker线程终止;
*/
class Solver{
     final int N;          //所有并行处理线程的数量
     final float[][] data;    //记录并行处理线程锁需要的数据,row:并行处理线程数量;col:每个线程在barrier执行块内需要的数据
     final CyclicBarrier barrier;   //记录并行线程共同的循环屏障对象
    
     public Solver(float[][] matrix){
          this.data = matrix;
          N = matrix.length;
          barrier = new CycilcBarrier(N,new Runnable(){  
               public void run(){    //每次启动barrier时执行的屏障操作,该操作由最后一个进入barrier的线程执行;
                    mergeRows();   
               }
          });
          ExectorService exec = Executors.newFixedThreadPool(N);
          for(int i=0;i<N;i++)
               exec.execute(new Worker(i));
         
          <waitUnitlDone>          
     }
     class Worker implements Runnable{
          int row;
          public Worker(int row){ this.row = row; }
          public void run(){
               while(!done()){   //判断合并者是否找到一个解决方案,当通过判断时,终止所有Worker线程
                    processRow(row);  //每一个线程被分配的处理过程
                    try{
                         barrier.await();
                    }catch(InterruptedException ex){  //提前执行的线程中断
                         return;
                    }catch(BrokenBarrierException ex){  //但done()通过判定时,barrier被打破,每个线程的处理代码
                         return;
                    }
               }
          }
     }
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值