Java多线程并发快速排序

1000W int 排序时间在 1000 毫秒以内

package pk;

import com.google.common.base.Stopwatch;

import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.*;

public class Sort_QuickSortParallel {

    private int[] arr;

    public Sort_QuickSortParallel(int[] arr) {
        this.arr = arr;
    }

    public static void main(String[] args) {

        for (int j = 0; j < 20; j++) {
            /********************************************************/


            /******************************************************************/

            int arrLen = 1000_0000;

            /******************************************************************/

            int[] arr = new int[]{10, -9, 321, 23, -909, 332, 12, 2222, 1, 0, 1, 12, 12, 23, 1980987, 32, -909};
            if (args.length > 0) {
                arrLen = Integer.parseInt(args[0]);
            }
            Random random = new Random();
            arr = new int[arrLen];
            for (int i = 0; i < arrLen; i++) {
                arr[i] = random.nextInt(Integer.MAX_VALUE);
            }

            Stopwatch stopwatch = Stopwatch.createStarted();
            new Sort_QuickSortParallel(arr).sort();
            System.out.println("并发快排,数据量 " + arrLen + " 耗时(毫秒) " + stopwatch.elapsed(TimeUnit.MILLISECONDS));

//        System.out.println(Arrays.toString(arr));

            for (int i = 1; i < arr.length; i++) {
                if (arr[i - 1] > arr[i]) {
                    System.out.println(i);
                    System.out.println(arr[i - 1]);
                    System.out.println(arr[i]);
                    throw new RuntimeException("算法错误");
                }
            }

            /********************************************************/
        }

    }

    private void sort() {

        int processors = Runtime.getRuntime().availableProcessors();

        processors *= 2;

        System.out.println("CPU核心数 " + processors);

        int parallelBeginDeep = 0;
        int parThreadCount;
        while (true) {
            parThreadCount = 1 << parallelBeginDeep;
            if (parThreadCount >= processors) {
                System.out.println("最大并发线程数 " + parThreadCount);
                System.out.println("并发起始深度 parallelBeginDeep (start with 0) " + parallelBeginDeep);
                break;
            } else {
                ++parallelBeginDeep;
            }
        }

        ExecutorService exec = Executors.newFixedThreadPool(parThreadCount);

        CountDownLatch downLatch = new CountDownLatch(parThreadCount);

//        DoSort doSort = new DoSort(downLatch, parallelBeginDeep, exec, arr, 0, arr.length - 1);
        QuickSortParallel quickSortParallel = new QuickSortParallel(arr, 0, arr.length - 1, downLatch, parallelBeginDeep, exec);

        exec.execute(quickSortParallel);

        try {
            downLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        exec.shutdown();
    }


    static class QuickSortParallel extends QuickSort {

        private int deep;
        private ExecutorService exec;

        public QuickSortParallel(int[] arr, int left, int right, CountDownLatch downLatch, int deep, ExecutorService exec) {
            super(arr, left, right, downLatch);
            this.deep = deep;
            this.exec = exec;
        }

        @Override
        public void run() {
            int nil = doSort(left, right);

            if (deep > 1) {
                if (nil - 1 > left)
                    exec.execute(new QuickSortParallel(arr, left, nil - 1, downLatch, deep - 1, exec));
                if (nil + 1 < right)
                    exec.execute(new QuickSortParallel(arr, nil + 1, right, downLatch, deep - 1, exec));
            } else {
                if (nil - 1 > left)
                    exec.execute(new QuickSort(arr, left, nil - 1, downLatch));
                if (nil + 1 < right)
                    exec.execute(new QuickSort(arr, nil + 1, right, downLatch));
            }

        }
    }

    static class QuickSort implements Runnable {

        protected int[] arr;
        protected int left, right;
        protected CountDownLatch downLatch;

        public QuickSort(int[] arr, int left, int right, CountDownLatch downLatch) {
            this.arr = arr;
            this.left = left;
            this.right = right;
            this.downLatch = downLatch;
        }

        @Override
        public void run() {
            doSort_(left, right);
            if (downLatch != null) {
                downLatch.countDown();
//                System.out.println(getClass().getName() + "  " + hashCode()  + "  >>>>>>>>>>>>>>>>>>>>>>>>>>>> downLatch.countDown();");
            }


//            for (int i = left + 1; i < right; i++) {
//                if (arr[i - 1] > arr[i]) {
//                    throw new RuntimeException("error");
//                }
//            }
        }

        private int doSort_(int lef, int rig) {
            int nil = doSort(lef, rig);

            if (nil - 1 > lef)
                doSort_(lef, nil - 1);

            if (nil + 1 < rig)
                doSort_(nil + 1, rig);

            return nil;
        }

        protected int doSort(int lef, int rig) {

            int mv = arr[lef];
            int nil = lef++;

            while (lef <= rig) {

                for (; rig > nil; rig--) {
                    if (arr[rig] < mv) {
                        arr[nil] = arr[rig];
                        nil = rig--;
                        break;
                    }
                }

                for (; lef < nil; lef++) {
                    if (arr[lef] > mv) {
                        arr[nil] = arr[lef];
                        nil = lef++;
                        break;
                    }
                }
            }

            arr[nil] = mv;

            return nil;

        }
    }
}

 

posted on 2021-01-28 22:03  五月の花  阅读(385)  评论(0编辑  收藏  举报

导航