1 import java.util.concurrent.RecursiveAction;
2 import java.util.concurrent.ForkJoinPool;
3
4 public class ParallelMergeSort {
5 public static void main(String[] args) {
6 final int SIZE = 7000000;
7 int[] list1 = new int[SIZE];
8 int[] list2 = new int[SIZE];
9
10 for (int i = 0; i < list1.length; i++)
11 list1[i] = list2[i] = (int)(Math.random() * 10000000);
12
13 long startTime = System.currentTimeMillis();
14 parallelMergeSort(list1);
15 long endTime = System.currentTimeMillis();
16 System.out.println("\nParallel time with "
17 + Runtime.getRuntime().availableProcessors() +
18 " processors is " + (endTime - startTime) + " milliseconds");
19
20 startTime = System.currentTimeMillis();
21 MergeSort.mergeSort(list2);
22 endTime = System.currentTimeMillis();
23 System.out.println("\nSequential time is " +
24 (endTime - startTime) + " milliseconds");
25 }
26
27 public static void parallelMergeSort(int[] list) {
28 RecursiveAction mainTask = new SortTask(list);
29 ForkJoinPool pool = new ForkJoinPool();
30 pool.invoke(mainTask);
31 }
32
33 private static class SortTask extends RecursiveAction {
34 private final int THRESHOLD = 500;
35 private int[] list;
36
37 SortTask(int[] list) {
38 this.list = list;
39 }
40
41 @Override
42 protected void compute() {
43 if (list.length < THRESHOLD)
44 java.util.Arrays.sort(list);
45 else {
46
47 int[] firstHalf = new int[list.length / 2];
48 System.arraycopy(list, 0, firstHalf, 0, list.length / 2);
49
50
51 int secondHalfLength = list.length - list.length / 2;
52 int[] secondHalf = new int[secondHalfLength];
53 System.arraycopy(list, list.length / 2,
54 secondHalf, 0, secondHalfLength);
55
56
57 invokeAll(new SortTask(firstHalf),
58 new SortTask(secondHalf));
59
60
61 MergeSort.merge(firstHalf, secondHalf, list);
62 }
63 }
64 }
65 }