最早延迟时间优先运行的实现

在运行多任务时,有多种策略,其中一种就是根据最早延迟时间优先运行期任务,接下来利用Delayed接口和DelayQueue同步队列可以实现其功能。
代码例子:

//根据延迟时间来优先运行任务
class DelayedTask implements Runnable, Delayed {
      private static int counter = 0;
      private final int id = counter++;
      private final long delta;
      private final long trigger;
      protected static List<DelayedTask> sequence =
        new ArrayList<DelayedTask>();
      //设置延迟时间
      public DelayedTask(long delayInMilliseconds) {
        delta = delayInMilliseconds;
        trigger = System.currentTimeMillis()+delta;    
        sequence.add(this);
      }
      //告知延迟到期有多长时间
      public long getDelay(TimeUnit unit) {
        return
          trigger - System.currentTimeMillis();
      }
      //延迟时间的比较
      public int compareTo(Delayed arg) {
        DelayedTask that = (DelayedTask)arg;
        if(trigger < that.trigger) return -1;
        if(trigger > that.trigger) return 1;
        return 0;
      }
      //运行方法
      public void run() { System.out.println(this + " "); }
      public String toString() {
        return String.format("[%1$-4d]", delta) +
          " Task " + id;
      }
      public String summary() {
        return "(" + id + ":" + delta + ")";
      }
      //结束队列任务的终止类
      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.print(pt.summary() + " ");
          }
          System.out.println();
          System.out.println(this + " Calling shutdownNow()");
          exec.shutdownNow();
        }
      }
    }

    class DelayedTaskConsumer implements Runnable {
      private DelayQueue<DelayedTask> q;
      public DelayedTaskConsumer(DelayQueue<DelayedTask> q) {
        this.q = q;
      }
      public void run() {
        try {
          while(!Thread.interrupted())
              //用这个线程来运行任务
            q.take().run(); 
        } catch(InterruptedException e) {

        }
        System.out.println("Finished DelayedTaskConsumer");
      }
    }

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

运行结果:
[128 ] Task 11
[200 ] Task 7
[429 ] Task 5
[520 ] Task 18
[555 ] Task 1
[961 ] Task 4
[998 ] Task 16
[1207] Task 9
[1693] Task 2
[1809] Task 14
[1861] Task 3
[2278] Task 15
[3288] Task 10
[3551] Task 12
[4258] Task 0
[4258] Task 19
[4522] Task 8
[4589] Task 13
[4861] Task 17
[4868] Task 6
(0:4258) (1:555) (2:1693) (3:1861) (4:961) (5:429) (6:4868) (7:200) (8:4522) (9:1207) (10:3288) (11:128) (12:3551) (13:4589) (14:1809) (15:2278) (16:998) (17:4861) (18:520) (19:4258) (20:5000)
[5000] Task 20 Calling shutdownNow()
Finished DelayedTaskConsumer

你可能感兴趣的:(Delay接口用法,Delay队列用法,最早延迟时间优先)