package thread;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
public class Exercise30_13 {
public static void main(String[] args) {
final int SIZE = 10_000_000;
Integer[] integersList = new Integer[SIZE]; //整型数组
for (int i = 0; i < integersList.length; i++) //初始化赋值
integersList[i] = new SecureRandom().nextInt(SIZE);
//测试并行排序
long startTime = System.currentTimeMillis();
parallelMergeSort(integersList);
long endTime = System.currentTimeMillis();
System.out.println("The number of processors is " + Runtime.getRuntime().availableProcessors());
System.out.println("The time is " + (endTime - startTime) + " milliseconds");
//输出前100个值
for (int i = 0; i < 100; i++)
System.out.print(integersList[i] + " ");
System.out.println();
//------------------------------------------------
Double[] doublesList = new Double[SIZE]; //double型数组
for (int i = 0; i < doublesList.length; i++) //初始化赋值
doublesList[i] = new SecureRandom().nextDouble() * SIZE;
//测试并行排序
startTime = System.currentTimeMillis();
parallelMergeSort(doublesList);
endTime = System.currentTimeMillis();
System.out.println("The number of processors is " + Runtime.getRuntime().availableProcessors());
System.out.println("The time is " + (endTime - startTime) + " milliseconds");
//输出前100个值
for (int i = 0; i < 100; i++)
System.out.printf("%6.2f", doublesList[i]);
System.out.println();
}
/** 泛型并行合并排序 */
public static <E extends Comparable<E>> void parallelMergeSort(E[] list) {
RecursiveAction mainTask = new MergeTask<>(list);
ForkJoinPool pool = new ForkJoinPool();
pool.invoke(mainTask);
}
/** 内部类-合并排序任务类 */
private static class MergeTask<E extends Comparable<E>> extends RecursiveAction {
private static final int THRESHOLD = 500; //最小门槛
private E[] list; //列表
public MergeTask(E[] list) {
this.list = list;
}
@Override
protected void compute() {
if (list.length < THRESHOLD) //列表长度小于最小门槛,执行顺序排序
Arrays.sort(list);
else { //执行并行排序
E[] firstHalf = (E[])(new Comparable[list.length / 2]); //前一半子数组
System.arraycopy(list, 0, firstHalf, 0, firstHalf.length);
int secondHalfLength = list.length - list.length / 2;
E[] secondHalf = (E[])(new Comparable[secondHalfLength]); //后一半子数组
System.arraycopy(list, list.length / 2, secondHalf, 0, secondHalfLength);
//分解调用子数组
invokeAll(new MergeTask<>(firstHalf), new MergeTask<>(secondHalf));
merge(firstHalf, secondHalf, list); //合并数组
}
}
/** 合并数组 */
private void merge(E[] list1, E[] list2, E[] temp) {
int current1, current2, current3; //代表数组下标
current1 = current2 = current3 = 0;
//将 list1 和 list2 的值添加进 temp 数组
while (current1 < list1.length && current2 < list2.length)
temp[current3++] = list1[current1].compareTo(list2[current2]) < 0 ?
list1[current1++] : list2[current2++];
while (current1 < list1.length) //添加剩余的 list1 的元素
temp[current3++] = list1[current1++];
while (current2 < list2.length) //添加剩余的 list2 的元素
temp[current3++] = list2[current2++];
}
}
}