在运行多任务时,有多种策略,其中一种就是根据最早延迟时间优先运行期任务,接下来利用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