10、CyclicBarrier

java.util.concurrent

Class CyclicBarrier

使得一系列的线程相互等待,直到全部线程都到达一个公共的屏障点。这个屏障之所以称为Cyclic(循环的),是因为它能够在等待线程释放后重复使用。

 

CyclicBarrier支持一个可选Runnable的参数,在每个屏障点运行一次(只有当所有的线程都到达时,才会执行)。

 

 1 class Solver {
 2        final int N;
 3        final float[][] data;
 4        final CyclicBarrier barrier;
 5 
 6        class Worker implements Runnable {
 7          int myRow;
 8          Worker(int row) { myRow = row; }
 9          public void run() {
10            while (!done()) {
11              processRow(myRow);
12 
13              try {
14                barrier.await();
15              } catch (InterruptedException ex) {
16                return;
17              } catch (BrokenBarrierException ex) {
18                return;
19              }
20            }
21          }
22        }
23 
24        public Solver(float[][] matrix) {
25          data = matrix;
26          N = matrix.length;
27          barrier = new CyclicBarrier(N,
28                                      new Runnable() {
29                                        public void run() {
30                                         // mergeRows(...);
31                                        }
32                                      });
33          for (int i = 0; i < N; ++i)
34            new Thread(new Worker(i)).start();
35 
36          waitUntilDone();
37        }
38 }

程序分析:

这个程序的框架在实际应用中还是很好用的,比如这么一个应用场景:将10个文件的正整数按从小到达的顺序进行合并。按照这个框架的思路,我们可以先将十个文件的数据放到一个二维数组当中来。

每一行就是一个文件当中的数据。首先我们使用十个线程分别对十个数组进行排序,当然,采用的排序方式不同或者别的原因,排序时长有先有后,只有当所有的数组都排完序以后,就可以处理CyclicBarrier

里面初始化的Runnable。要不然先排完序的线程就会阻塞等待其他排好序的线程。当然,这个应用场景的真正算法还是在Runnable里面,也就是当数组排好序了,如何按从小到大的顺序合并它们。

可以这样,先从10个数组里面拿出第一个最小的,这十个进行比较,就可以得到目标数组中的第一个正整数。然后看这个正整数取自于哪个数组,于是这个数组当中的第二个数就充当了取出去的那个数的角色。

于是,又拿它与其他数组当中的最小数再进行比较得到次最小,如此反复。

 

posted on 2015-05-29 16:55  飞机说之代码也疯狂  阅读(178)  评论(0编辑  收藏  举报