运用ForkJoin多线程框架实现归并排序

来源:互联网 发布:系统优化的方法论 编辑:程序博客网 时间:2024/06/07 08:50
一、普通归并排序
运行结果:

排序100000个随机数用了差不多5秒
 
二、ForkJoinPool实现归并排序
1
public class ConcurrentForkJoinMergeSort {
2
   private static int MAX = 100000;
3
4
    private static int inits[] = new int[MAX];
5
6
    // 同样进行随机队列初始化,这里就不再赘述了
7
    static {
8
        Random r = new Random();
9
        for(int index = 1 ; index <= MAX ; index++) {
10
            inits[index - 1] = r.nextInt(10000000);
11
        }
12
    }
13
14
    public static void main(String[] args) throws Exception {
15
        // 正式开始
16
        long beginTime = System.currentTimeMillis();
17
        ForkJoinPool pool = new ForkJoinPool();
18
        MyTask task = new MyTask(inits);
19
        ForkJoinTask<int[]> taskResult = pool.submit(task);
20
        try {
21
            taskResult.get();
22
        } catch (InterruptedException | ExecutionException e) {
23
            e.printStackTrace(System.out);
24
        }
25
        long endTime = System.currentTimeMillis();
26
        System.out.println("耗时=" + (endTime - beginTime));
27
    }
28
29
    /**
30
     * 单个排序的子任务
31
     */
32
    static class MyTask extends RecursiveTask<int[]> {
33
34
        private int source[];
35
36
        public MyTask(int source[]) {
37
            this.source = source;
38
        }
39
40
        /* (non-Javadoc)
41
         * @see java.util.concurrent.RecursiveTask#compute()
42
         */
43
        @Override
44
        protected int[] compute() {
45
            int sourceLen = source.length;
46
            // 如果条件成立,说明任务中要进行排序的集合还不够小
47
            if(sourceLen > 2) {
48
                int midIndex = sourceLen / 2;
49
                // 拆分成两个子任务
50
                MyTask task1 = new MyTask(Arrays.copyOf(source, midIndex));
51
                task1.fork();
52
                MyTask task2 = new MyTask(Arrays.copyOfRange(source, midIndex , sourceLen));
53
                task2.fork();
54
                // 将两个有序的数组,合并成一个有序的数组
55
                int result1[] = task1.join();
56
                int result2[] = task2.join();
57
                int mer[] = joinInts(result1 , result2);
58
                return mer;
59
            }
60
            // 否则说明集合中只有一个或者两个元素,可以进行这两个元素的比较排序了
61
            else {
62
                // 如果条件成立,说明数组中只有一个元素,或者是数组中的元素都已经排列好位置了
63
                if(sourceLen == 1
64
                        || source[0] <= source[1]) {
65
                    return source;
66
                } else {
67
                    int targetp[] = new int[sourceLen];
68
                    targetp[0] = source[1];
69
                    targetp[1] = source[0];
70
                    return targetp;
71
                }
72
            }
73
        }
74
75
        private int[] joinInts(int[] arr1, int[] arr2) {
76
77
            int left = 0;
78
            int right = 0;
79
            int[] mergeArr = new int[arr1.length + arr2.length];
80
            if(mergeArr.length == 0) return null;
81
            for (int i = 0; i < arr1.length + arr2.length; i++) {
82
                if(arr1.length == left) {
83
                    mergeArr[i] = arr2[right];
84
                    right++;
85
                    continue;
86
                }else if(arr2.length == right) {
87
                    mergeArr[i] = arr1[left];
88
                    left++;
89
                    continue;
90
                }
91
                if(arr1[left] <= arr2[right]){
92
                    mergeArr[i] = arr1[left];
93
                    left++;
94
                }else{
95
                    mergeArr[i] = arr2[right];
96
                    right++;
97
                }
98
            }
99
            return mergeArr;
100
        }
101
    }
102
}
运行结果:

 排序100000个随机数只用了28毫秒
原创粉丝点击