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个数组里面拿出第一个最小的,这十个进行比较,就可以得到目标数组中的第一个正整数。然后看这个正整数取自于哪个数组,于是这个数组当中的第二个数就充当了取出去的那个数的角色。
于是,又拿它与其他数组当中的最小数再进行比较得到次最小,如此反复。
时间: 2024-10-16 15:19:20