16-案例实现
案例实现
根据如下步骤来实现本案例。
1.创建一个 Event
类并实现一个 Delayed
接口:
public class Event implements Delayed {
2.声明一个 Date
类型的私有字段 startDate
:
private final Date startDate;
3.实现一个构造方法来初始化字段:
public Event (Date startDate) {
this.startDate=startDate;
}
4.实现 compareTo()
方法。该方法以 Delayed
对象作为参数,而且会返回一个当前对象与参数对象的对比值:
@Override
public int compareTo(Delayed o) {
long result=this.getDelay(TimeUnit.NANOSECONDS)-o.getDelay
(TimeUnit.NANOSECONDS);
if (result<0) {
return -1;
} else if (result>0) {
return 1;
}
return 0;
}
5.实现 getDelay()
方法。该方法会返回一个开始时间与激活时间的差值,并通过 TimeUnit
参数来将其转换为指定的时间单位:
public long getDelay(TimeUnit unit) {
Date now=new Date();
long diff=startDate.getTime()-now.getTime();
return unit.convert(diff,TimeUnit.MILLISECONDS);
}
6.创建一个 Task
类并实现一个 Runnable
接口:
public class Task implements Runnable {
7.声明一个私有的 int型
字段 id
。该字段用于代表该 Task
实例的身份:
private final int id;
8.声明一个私有的 DelayQueue<Event>
字段 queue
:
private final DelayQueue<Event> queue;
9.实现该类的构造方法,并初始化字段:
public Task(int id, DelayQueue<Event> queue) {
this.id=id;
this.queue=queue;
}
10.实现 run()
方法。首先,计算将要生成任务的事件的当前日期对象;其次,基于字段id和当前日期对象的时间戳来计算事件对象的实际激活时间:
@Override
public void run() {
Date now=new Date();
Date delay=new Date();
delay.setTime(now.getTime()+(id*1000));
System.out.printf("Thread %s: %s\n",id,delay);
11.把100个事件对象通过 add()
方法添加到队列中:
for (int i=0; i<100; i++) {
Event event=new Event(delay);
queue.add(event);
}
}
12.实现一个 Main
类和一个 main()
方法:
public class Main {
public static void main(String[] args) throws Exception {
13.创建一个 DelayQueue<Event>
类型的对象:
DelayQueue<Event> queue=new DelayQueue<>();
14.创建一个长度为5的线程数组,并用它存储即将要执行的任务:
Thread threads[]=new Thread[5];
15.创建5个 Task
对象并分别赋予不同的ID:
for (int i=0; i<threads.length; i++){
Task task=new Task(i+1, queue);
threads[i]=new Thread(task);
}
16.启动所有线程:
for (int i=0; i<threads.length; i++) {
threads[i].start();
}
17.用 join()
方法等待所有线程最终完成:
for (int i=0; i<threads.length; i++) {
threads[i].join();
}
18.在控制台打印队列长度。当队列长度大于0时,用 poll()
方法来获取一个 Event
对象;如果返回 null
,则阻塞当前线程500ms:
do {
int counter=0;
Event event;
do {
event=queue.poll()
if (event!=null) counter++;
} while (event!=null);
System.out.printf("At %s you have read %d events\n",
new Date(), counter);
TimeUnit.MILLISECONDS.sleep(500);
} while (queue.size()>0);
}
}