睡眠排序
睡眠排序的思想就是利用线程休眠,对于给定的数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<Integer> result;
/**
* 这个Sleep对象对应的排序数
*/
private int num;
public Sleep(CountDownLatch countDownLatch, List<Integer> 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<Integer> 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);
}
}