睡眠排序

睡眠排序

睡眠排序的思想就是利用线程休眠,对于给定的数n,睡眠n单位时间,按照醒来的顺序输出,就可以实现从大到小排序。

虽然看起来蠢到爆,但是时间复杂度可是o(n)的。然并卵。。。

看了一点编程实战后总感觉少了点什么,所以借机码几个代码。。

声明:本代码仅用来搞笑 && 熟悉JDK并发工具包

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by Administrator on 2017/4/7.
 */
public class SleepSort {

    public class Sleep implements Runnable {

        /**
         * 公平的重入锁,用它取代 synchronized,使能够公平的获得锁
         */
        private ReentrantLock reentrantLock = new ReentrantLock(true);

        /**
         * 闭锁,用来统计是否排序完毕
         */
        private CountDownLatch countDownLatch;

        /**
         * 用来存放结果
         */
        private volatile List result;

        /**
         * 这个Sleep对象对应的排序数
         */
        private int num;

        public Sleep(CountDownLatch countDownLatch, List result, int num) {
            this.countDownLatch = countDownLatch;
            this.result = result;
            this.num = num;
        }

        @Override
        public void run() {
            // 休眠指定时间
            try {
                Thread.sleep(num * 10 + 10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            // 将结果添加到结果集中
            reentrantLock.lock();
            result.add(num);
            reentrantLock.unlock();

            // 将闭锁的计数器减一
            countDownLatch.countDown();
        }
    }

    public Integer[] sleepSort(int[] a) {
        CountDownLatch countDownLatch = new CountDownLatch(a.length);

        // 手动创建线程池。实际上用线程池不是很合理,因为一定不能让线程复用,一旦发生了线程复用结果就错了。因为睡眠排序要靠时差。
        ThreadPoolExecutor executors = new ThreadPoolExecutor(100,10000,
                10, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(), new RejectedExecutionHandler() {
            /**
             * 自定义拒绝策略,将被丢弃的任务信息输出
             * @param r
             * @param executor
             */
            @Override
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                System.out.println(Thread.currentThread() + " was discarded");
            }
        });
        // 结果集
        List result = new LinkedList<>();

        // 加入线程池
        for(int i = 0; i < a.length; i++) {
            executors.submit(new Sleep(countDownLatch, result, a[i]));
        }

        // 禁止向线程池中增加线程
        executors.shutdown();

        // 等待排序完毕
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return result.toArray(new Integer[a.length]);
    }

    public SleepSort(int[] a) {
        Integer[] result = sleepSort(a);
        for(int i = 0; i < result.length; i++) {
            System.out.println(result[i]);
        }
    }

    public static void main(String[] args) {
        int[] numbers = {1, 5, 6, 9, 13, 16, 3, 15, 2, 22, 29};
        new SleepSort(numbers);
    }

}

你可能感兴趣的:(并发,线程,睡眠排序,闭锁,并发,JDK并发工具包)