简介
Fork 就是把一个大任务切分为若干个子任务并行地执行,Join 就是合并这些子任务的执行结果,最后得到这个大任务的结果。Fork/Join 框架使用的是工作窃取算法。
项目源码
https://gitee.com/smart_piggy/piggy-utils
ForkJoinPool 快速排序
package cn.piggy;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
public class PiggyQuickSort {
private final static ForkJoinPool forkJoinPool = new ForkJoinPool();
public static void piggyQuick(int []arr) {
if(arr==null||arr.length==1){
return;
}
QuickTask quicklyTask = new QuickTask(0, arr.length-1, arr);
ForkJoinTask<int[]> submit = forkJoinPool.submit(quicklyTask);
submit.join();
}
}
class QuickTask extends RecursiveTask<int[]> {
private final int left;
private final int right;
private final int[] array;
public QuickTask(int left, int right, int[] array) {
this.left = left;
this.right = right;
this.array = array;
}
private int number = 9;
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
@Override
protected int[] compute() {
if (right - left >= number) {
int i = sortCompare(left, right, array);
QuickTask one = new QuickTask(left, i-1, array);
QuickTask two = new QuickTask(i+1, right, array);
ForkJoinTask<int[]> fork1 = one.fork();
ForkJoinTask<int[]> fork2 = two.fork();
int[] join1 = fork1.join();
int[] join2 = fork2.join();
}else {
quickSort(array,left,right);
}
return array;
}
public void quickSort(int[] arr,int left,int right){
if(left<right){
int i = sortCompare(left, right, arr);
quickSort(arr, left, i-1);
quickSort(arr, i+1, right);
}
}
public int sortCompare(int low, int high, int[] arr) {
int tmp = arr[low];
while (low < high) {
while (low < high && arr[high] >= tmp) {
high--;
}
arr[low] = arr[high];
while (low < high && arr[low] <= tmp) {
low++;
}
arr[high] = arr[low];
}
arr[low] = tmp;
return low;
}
}
ForkJoinPool 归并排序
package cn.piggy;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
public class PiggyMergeSort {
private final static ForkJoinPool forkJoinPool = new ForkJoinPool();
public static void piggyMerge(int []arr) {
if(arr==null||arr.length==1){
return;
}
MergeTask countTask = new MergeTask(0, arr.length-1, arr);
ForkJoinTask<int[]> submit = forkJoinPool.submit(countTask);
submit.join();
}
}
class MergeTask extends RecursiveTask<int[]> {
private final int left;
private final int right;
private final int[] array;
private int number = 9;
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public MergeTask(int left, int right, int[] array) {
super();
this.left = left;
this.right = right;
this.array = array;
}
@Override
protected int[] compute() {
if (right - left >= number) {
int num = right+left;
int mid = num/2;
MergeTask one = new MergeTask(left, mid, array);
MergeTask two = new MergeTask(mid+1, right, array);
ForkJoinTask<int[]> fork1 = one.fork();
ForkJoinTask<int[]> fork2 = two.fork();
int[] join1 = fork1.join();
int[] join2 = fork2.join();
int middle = (right+left)/2;
merge(array,left,middle,right);
}else {
mergeSort(array,left,right);
}
return array;
}
public void mergeSort(int[] arr,int left,int right){
if(left<right){
int mid = (left+right)/2;
mergeSort(arr, left, mid);
mergeSort(arr,mid+1, right);
merge(arr, left, mid, right);
}
}
private void merge(int[] arr,int left,int mid,int right){
int[] temp = new int[right-left+1];
int i = left;
int j = mid+1;
int k = 0;
while (i<=mid && j<=right){
if(arr[i]<=arr[j]){
temp[k++] = arr[i++];
}else {
temp[k++] = arr[j++];
}
}
while(i<=mid){
temp[k++] = arr[i++];
}
while(j<=right){
temp[k++] = arr[j++];
}
// 将temp中的元素全部拷贝到原数组中
int z = 0;
while(left <= right){
arr[left++] = temp[z++];
}
}
}
测试代码
package cn.piggy;
import java.util.Arrays;
import java.util.Random;
public class TestMain {
public static void main(String[] args) {
int[] ints1 = randomArray();
long l1 = System.currentTimeMillis();
Arrays.sort(ints1);
long l2 = System.currentTimeMillis();
System.out.println(l2-l1);
int[] ints2 = randomArray();
long l3 = System.currentTimeMillis();
PiggyMergeSort.piggyMerge(ints2);
long l4 = System.currentTimeMillis();
System.out.println(l4-l3);
int[] ints3 = randomArray();
long l5 = System.currentTimeMillis();
PiggyQuickSort.piggyQuick(ints3);
long l6 = System.currentTimeMillis();
System.out.println(l6-l5);
}
private static int[] randomArray() {
int[] array = new int[100000000];
Random random = new Random();
for (int i = 0; i < array.length; i++) {
array[i] = random.nextInt(100000000);
}
return array;
}
}
测试结果
第一次
第二次
第三次