疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

Java的CyclicBarrier 循环屏障


 

        在读Java编程思想的时候,书中提到如果需要实现多个线程合并除了使用join方法,还可以使用CyclicBarrier。翻看CyclicBarrier的API的时候,发现对应的介绍中一个很使用的Demo就动手敲了一遍。这里发出来,便于以后参考。
 
   这个Demo实现了使用多个线程对一个float型的二维数组进行求和计算。每第一维度对应一个线程,每个线程计算自己对应子数组元素的和,然后使用cyclicBarrier进行等待(调用await方法),当最后一个线程执行结束后会进入CyclicBarrier的预定义操作线程(对应一个Runnable对象),对各个线程的计算结果进行合并。
 
   
[java]
import java.util.ArrayList; 
import java.util.List; 
import java.util.concurrent.BrokenBarrierException; 
import java.util.concurrent.CyclicBarrier; 
 
 
/**
 * 测试用cyclicBarrier实现多个线程执行结果的合并
 * @author alex
 *
 */ 
public class CyclicBarrierTest { 
 
    public static void main(String[] args) { 
        float[][] data = {{0.1f,0.2f},{0.3f,0.4f},{0.5f,0.5f}, 
                            {0.1f,0.2f},{0.3f,0.4f},{0.5f,0.5f}, 
                            {0.1f,0.2f},{0.3f,0.4f},{0.5f,0.5f}, 
                            {0.1f,0.2f},{0.3f,0.4f},{0.5f,0.5f}, 
                            {0.1f,0.2f},{0.3f,0.4f},{0.5f,0.5f}, 
                            {0.1f,0.2f},{0.3f,0.4f},{0.5f,0.5f}, 
                            {0.1f,0.2f},{0.3f,0.4f},{0.5f,0.5f}, 
                            {0.1f,0.2f},{0.3f,0.4f},{0.5f,0.5f}, 
                            {0.1f,0.2f},{0.3f,0.4f},{0.5f,0.5f}, 
                            {0.1f,0.2f},{0.3f,0.4f},{0.5f,0.5f}}; 
        new Solver(data); 
    } 
 
class Solver { 
    final int N; 
     
    final float[][] data; 
     
    final CyclicBarrier cb; 
     
    // 存储所有Runnable对象  
    List<Worker> workers ; 
     
    float value; 
     
    public Solver(float[][] matrix) { 
        data = matrix; 
        N = matrix.length; 
        cb = new CyclicBarrier(N,new Runnable(){ 
            // 最后一个worker执行结束之后会进入以下的合并计算逻辑中。  
            public void run() { 
                for(Worker woker : workers) { 
                    value += woker.getResult(); 
                } 
                System.out.println(" Final result: "+value+" "); 
            } 
        }); 
        workers = new ArrayList<Worker>(); 
         for (int i = 0; i < N; ++i){ 
             Worker worker = new Worker(i); 
             workers.add(worker); 
             new Thread(worker).start(); 
         }  
 
    } 
     
     
    class Worker implements Runnable { 
        int rowNum; 
        float result; 
        public Worker(int rowNum) { 
            this.rowNum = rowNum; 
        } 
         
        public void run() { 
            for(int i = 0; i < data[rowNum].length; ++i){ 
                result += data[rowNum][i]; 
            } 
            System.out.println("rowNum:" + rowNum +",result: " + result); 
            try { 
                cb.await(); 
            } catch (InterruptedException e) { 
                return; 
            } catch (BrokenBarrierException e) { 
                return; 
            } 
            System.out.println("rowNum:" + rowNum +" wake up..."); 
        } 
         
        float getResult() { 
            return result; 
        } 
         
    } 
     
    float getValue(){ 
        return this.value; 
    }