阅读 Think in java 看到这么一种描述:我直接截图吧
队头对象延迟时间最长但是 我执行代码执行结果是 延迟时间最短的先执行的啊。以下是代码:
package com.practice.concurrent.DelayedQueue;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
import static sun.misc.Version.print;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Delayed;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
/**
* 2017/12/18.
*/
public class DelayedTask implements Runnable, Delayed{
private static int counter = 0;
private final int id = counter++;
private final int delat;
private final long trigger;
protected static List<DelayedTask> sequence =
new ArrayList<DelayedTask>();
public DelayedTask(int delayInMilliseconds){
delat = delayInMilliseconds;
trigger = System.nanoTime() +
NANOSECONDS.convert(delat, MILLISECONDS);
sequence.add(this);
}
@Override
public long getDelay(TimeUnit unit) {
return unit.convert(
trigger - System.nanoTime(), NANOSECONDS
);
}
@Override
public int compareTo(Delayed arg) {
DelayedTask that = (DelayedTask) arg;
if (trigger < that.trigger) return -1;
if (trigger > that.trigger) return 1;
return 0;
}
@Override
public void run() {
System.out.println(this + " ");
}
public String toString(){
return String.format("[%1$-4d]", delat) +
" Task" + id;
}
public String summary(){
return "(" + id + ":" + delat + ")" + "trigger + (" +trigger + ")";
}
public static class EndSentinel extends DelayedTask {
private ExecutorService exec;
public EndSentinel(int delay, ExecutorService e) {
super(delay);
exec = e;
}
public void run(){
for (DelayedTask pt : sequence){
System.out.println(pt.summary() + " ");
}
print();
System.out.println(this + "Calling shutdownNow()");
exec.shutdown();
}
}
}
package com.practice.concurrent.DelayedQueue;
import static jdk.nashorn.internal.objects.Global.print;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.ExecutorService;
/**
* 2017/12/18.
*/
class DelayedTaskConsumer implements Runnable{
private DelayQueue<DelayedTask> q;
private ExecutorService exec;
public DelayedTaskConsumer(DelayQueue<DelayedTask> q, ExecutorService exec){
this.q = q;
this.exec = exec;
}
@Override
public void run() {
try {
while (!exec.isShutdown()){
q.take().run();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Finished DelayedTaskConsumer");
}
}
以下是执行demo
package com.practice.concurrent.DelayedQueue;
import java.util.Random;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 2017/12/18.
*/
public class DelayQueueDemo {
public static void main(String[] args) {
Random rand = new Random(47);
ExecutorService exec = Executors.newCachedThreadPool();
DelayQueue<DelayedTask> queue =
new DelayQueue<DelayedTask>();
for (int i=0; i<20; i++){
queue.put(new DelayedTask(rand.nextInt(5000)));
}
queue.add(new DelayedTask.EndSentinel(5000, exec));
exec.execute(new DelayedTaskConsumer(queue, exec));
}
}
运行结果如下:
[128 ] Task11 // 128延迟时间最短的先执行
[200 ] Task7
[429 ] Task5
[520 ] Task18
[555 ] Task1
[961 ] Task4
[998 ] Task16
[1207] Task9
[1693] Task2
[1809] Task14
[1861] Task3
[2278] Task15
[3288] Task10
[3551] Task12
[4258] Task0
[4258] Task19
[4522] Task8
[4589] Task13
[4861] Task17
[4868] Task6
(0:4258)trigger + (22522182884813)
(1:555)trigger + (22518480003523)
(2:1693)trigger + (22519618020447)
(3:1861)trigger + (22519786024736)
(4:961)trigger + (22518886028495)
(5:429)trigger + (22518354031877)
(6:4868)trigger + (22522793035627)
(7:200)trigger + (22518125038618)
(8:4522)trigger + (22522447042259)
(9:1207)trigger + (22519132045068)
(10:3288)trigger + (22521213048113)
(11:128)trigger + (22518053054251)
(12:3551)trigger + (22521476063436)
(13:4589)trigger + (22522514066333)
(14:1809)trigger + (22519734069385)
(15:2278)trigger + (22520203074247)
(16:998)trigger + (22518923078353)
(17:4861)trigger + (22522786081360)
(18:520)trigger + (22518445084154)
(19:4258)trigger + (22522183087267)
(20:5000)trigger + (22522925605119)
[5000] Task20Calling shutdownNow()
Finished DelayedTaskConsumer
大家可以看以下,还是我哪里理解有问题。现在绕在这儿解不开了 哈哈。
首先我得承认,目前本人思维还没有完全沉浸于多线程环境里。现在把这个过程重新描述一下:
1.创建单个任务实例时,传递的delayInMilliseconds值是从当前时间开始加上这个值得到的该任务最终应该执行的时间。
2.这样每个任务都会有一个自己的执行时间点。接下来,Thread1开始执行,那么剩下的 Thread2,Thread3 ……Thread 11 等一部分在Thread1执行过程中 也已经到期了。那么最紧急的在最前面,最紧急的当然是 到期时间最长的。这里是 已经到期时间最长的意思。我之前理解错了。
3.所以delay值最小的 一定是到期时间最长的了。