鍍金池/ 問答/Java  Linux/ Java concurrent包中 DelayQueue 隊頭對象隊延遲到期時間

Java concurrent包中 DelayQueue 隊頭對象隊延遲到期時間最長怎么理解?

閱讀 Think in java 看到這么一種描述:我直接截圖吧

clipboard.png
隊頭對象延遲時間最長但是 我執(zhí)行代碼執(zhí)行結果是 延遲時間最短的先執(zhí)行的啊。以下是代碼:

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");
  }


}

以下是執(zhí)行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延遲時間最短的先執(zhí)行
[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

大家可以看以下,還是我哪里理解有問題?,F(xiàn)在繞在這兒解不開了 哈哈。

回答
編輯回答
任她鬧

首先我得承認,目前本人思維還沒有完全沉浸于多線程環(huán)境里。現(xiàn)在把這個過程重新描述一下:
1.創(chuàng)建單個任務實例時,傳遞的delayInMilliseconds值是從當前時間開始加上這個值得到的該任務最終應該執(zhí)行的時間。
2.這樣每個任務都會有一個自己的執(zhí)行時間點。接下來,Thread1開始執(zhí)行,那么剩下的 Thread2,Thread3 ……Thread 11 等一部分在Thread1執(zhí)行過程中 也已經(jīng)到期了。那么最緊急的在最前面,最緊急的當然是 到期時間最長的。這里是 已經(jīng)到期時間最長的意思。我之前理解錯了。
3.所以delay值最小的 一定是到期時間最長的了。

2017年11月17日 12:12