那么自然而然想到的问题就是,如果这一 接口已经做得不错了,我们为什么还需要Java 7的其他框架?使用ExecutorService和Callable的主要问题是,Callable实例在本质上是阻塞的。一旦一个Callable实例开始执行,其他所有Callable都会被阻塞。由于队列后面的Callable实例在前一实例未执行完成的时候不会被执行,因此许多资源无法得到利用。Fork/Join框架被引入来解决这一并行问题,可以处理更细粒度的并行计算,而Executor解决的是并发问题。(并发和并行的区别就是一个处理器同时处理多个任务和多个处理器或者是多核的处理器同时处理多个不同的任务)。ForkJoin是适用于多核环境的轻量级并行框架。目标是在多核系统下,通过并行运算,充分利用多处理器,提高效率与加速运行。
二、ForkJoin框架基本结构:
ForkJoinPool本身实现了ExecutorService接口,负责调度执行ForkJoinTask。ForkJoinTask是提交给ForkJoinPool 执行的任务,本身也实现了Future接口。ForkJoinTask有两个子类RecursiveAction和RecursiveTask。 RecursiveAction没有返回值(只需fork);RecursiveTask有返回值(需要合并)。类似于Runnable、Callable一样。没有返回值一般意味着所有子任务都执行完了即可,中间的子任务不需要join了。其实要不要返回值都可以实现,有返回值可以直接合并,没有返回值可以把结果保存在共享的数据上。而我们要做的是实现自己要完成的任务,只需要继承其一,并覆盖抽象方法compute()。在这个方法中实现自己的任务,递归分解任务。
ForkJoin框架的核心是ForkJoinPool类,实现了work-stealing算法,用于执行ForkJoinTask类型的任务(也就是按照该算法调度线程与任务,当然还负责解决好相关的一些其它问题)。
除了几个其他API方法以外,ForkJoinTask有两个主要的方法:
* fork () – 这个方法决定了ForkJoinTask的异步执行,凭借这个方法可以创建新的任务。
* join () – 该方法负责在计算完成侯返回结果,因此允许一个任务等待另一任务执行完成。分支/合并的完整过程如下:
if (my portion of the work is small enough)
do the work directly
else
split my work into two pieces
invoke the two pieces and wait for the results
四、work-stealing算法
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
public class ParallelMergeSort {
private static ForkJoinPool threadPool;
private static final int THRESHOLD = 16;
private static void sort(Comparable[] objectArray) {
Comparable[] destArray = new Comparable[objectArray.length];
threadPool.invoke(new SortTask(objectArray, destArray, 0,
objectArray.length - 1));
}
static class SortTask extends RecursiveAction {
private static final long serialVersionUID = 1L;
private Comparable[] sourceArray;
private Comparable[] destArray;
private int lowerIndex;
private int upperIndex;
public SortTask(Comparable[] sourceArray, Comparable[] destArray,
int lowerIndex, int upperIndex) {
this.sourceArray = sourceArray;
this.destArray = destArray;
this.lowerIndex = lowerIndex;
this.upperIndex = upperIndex;
}
@Override
protected void compute() {
if (upperIndex - lowerIndex < THRESHOLD) {
insertionSort(sourceArray, lowerIndex, upperIndex);
return;
}
int midIndex = (lowerIndex + upperIndex) >>> 1;
invokeAll(
new SortTask(sourceArray, destArray, lowerIndex, midIndex),
new SortTask(sourceArray, destArray, midIndex + 1,
upperIndex));
merge(sourceArray, destArray, lowerIndex, midIndex, upperIndex);
}
private void merge(Comparable[] sourceArray, Comparable[] destArray,
int lowerIndex, int midIndex, int upperIndex) {
if (sourceArray[midIndex].compareTo(sourceArray[midIndex + 1]) <= 0) {
return;
}
System.arraycopy(sourceArray, lowerIndex, destArray, lowerIndex,
midIndex - lowerIndex + 1);
int i = lowerIndex;
int j = midIndex + 1;
int k = lowerIndex;
while (k < j && j <= upperIndex) {
if (destArray[i].compareTo(sourceArray[j]) <= 0) {
sourceArray[k++] = destArray[i++];
} else {
sourceArray[k++] = sourceArray[j++];
}
}
System.arraycopy(destArray, i, sourceArray, k, j - k);
}
private void insertionSort(Comparable[] objectArray, int lowerIndex,
int upperIndex) {
for (int i = lowerIndex + 1; i <= upperIndex; i++) {
int j = i;
Comparable tempObject = objectArray[j];
while (j > lowerIndex
&& tempObject.compareTo(objectArray[j - 1]) < 0) {
objectArray[j] = objectArray[j - 1];
--j;
}
objectArray[j] = tempObject;
}
}
}
public static Double[] createRandomData(int length) {
Double[] data = new Double[length];
for (int i = 0; i < data.length; i++) {
data[i] = length * Math.random();
}
return data;
}
public static void main(String[] args) {
int processors = Runtime.getRuntime().availableProcessors();
System.out.println("No of processors: " + processors);
threadPool = new ForkJoinPool(processors);
Double[] data = createRandomData(1000);
System.out.println("Orginal unsorted data:");
int k = 0;
for (Double d : data) {
if (++k % 100 == 0) {
System.out.println();
}
System.out.printf("%3.2f ", (double) d);
}
sort(data);
System.out.println("\n\nSorted Array:");
for (Double d : data) {
if (++k % 100 == 0) {
System.out.println();
}
System.out.printf("%3.2f ", (double) d);
}
}
}
No of processors: 4
Orginal unsorted data:
498.57 517.40 971.53 831.27 812.89 235.02 692.14 998.85 693.03 79.25 805.36 222.89 658.93 284.86 98.20 77.10 523.99 159.91 257.43 201.68 820.57 862.75 990.14 443.81 732.19 685.80 834.08 359.13 839.29 450.15 84.23 488.96 513.66 588.37 993.48 130.19 981.20 373.06 293.03 22.35 913.56 534.71 121.88 491.02 906.21 204.65 655.24 106.85 353.75 717.98 78.02 846.63 43.14 315.58 62.08 75.51 250.87 196.06 575.27 408.94 252.66 685.47 675.01 658.34 932.17 516.52 921.01 616.23 610.17 338.59 179.17 394.61 306.02 616.43 882.75 394.67 390.74 17.25 267.10 756.31 994.13 235.12 700.59 312.76 587.88 956.02 997.26 658.70 882.57 328.23 515.45 929.35 548.51 870.16 921.96 283.63 298.57 221.27 732.78
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
331.82 80.82 52.01 791.17 576.10 8.15 329.17 412.28 564.97 32.58 837.01 105.83 454.05 330.94 433.35 184.36 594.98 988.70 377.10 962.70 529.03 494.03 966.69 533.98 993.06 939.03 612.46 102.32 446.33 606.82 514.29 373.80 928.90 808.10 995.73 394.98 769.77 671.36 331.86 272.38 777.70 88.08 600.64 406.18 67.87 167.51 685.99 228.14 604.34 365.31 65.94 946.36 871.38 916.13 430.03 468.39 825.76 322.06 487.87 499.32 428.04 427.58 553.97 793.28 602.01 45.85 624.44 673.90 430.22 192.29 696.48 233.88 756.98 728.17 24.88 73.42 141.41 620.62 857.50 44.14 279.49 84.68 947.38 227.52 597.12 589.02 799.56 296.14 705.58 79.04 178.61 480.75 806.17 799.37 876.22 598.22 932.67 782.16 118.12 982.55
128.04
Sorted Array:
0.57 0.81 1.07 6.44 6.45 8.15 10.27 10.84 11.01 14.64 14.98 17.12 17.25 17.92 18.43 18.65 21.12 21.39 22.22 22.35 22.92 24.88 25.35 26.87 28.02 32.58 34.71 35.45 35.69 37.78 39.34 40.24 40.91 42.58 42.77 42.97 43.14 43.93 44.14 44.49 44.91 45.85 47.44 47.63 52.01 52.43 53.51 54.80 55.33 59.02 60.55 61.38 62.08 63.72 64.20 64.81 65.94 66.95 67.87 69.90 71.55 71.68 71.87 73.42 74.41 75.51 77.10 78.02 79.04 79.25 80.71 80.82 81.11 81.35 81.43 84.23 84.68 86.91 87.42 88.08 91.04 94.95 96.15 96.45 97.00 98.20 99.60 100.50 100.58 101.08 102.09 102.32 105.54 105.83 106.85 107.54 107.61 114.78 116.52
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
917.31 917.51 917.64 917.75 918.93 918.96 920.18 920.78 921.01 921.67 921.96 924.36 924.70 924.74 928.41 928.90 928.95 929.35 931.55 932.17 932.67 935.71 936.45 936.65 937.74 939.03 939.21 939.37 940.55 940.66 941.01 941.39 942.73 944.34 944.88 945.30 946.36 947.38 948.32 949.26 949.44 950.40 950.86 951.13 953.02 953.86 954.12 955.79 956.02 956.89 957.69 959.43 959.75 960.26 961.79 962.70 963.08 964.18 964.49 965.01 966.21 966.69 967.62 969.98 971.53 971.94 972.79 973.62 974.46 974.68 975.85 976.57 978.54 979.41 979.52 981.20 981.64 982.36 982.55 984.24 984.66 985.77 986.44 987.94 988.70 989.47 990.14 992.77 992.87 993.06 993.48 993.92 994.13 995.39 995.73 995.73 996.55 997.26 998.33 998.85
999.25