最近想做一个定时推送消息的功能,经过调研了解到DelayQueue,消息对象需实现Delayed接口里的getDelay(TimeUnit unit)方法,由于Delayed继承了Comparable故需要实现compareTo方法,可用于决定消息的推送次序。以考试为例,设置每个考生的交卷时间点。
学生对象:
/**
*
* @author peiyu
*/
public class Student implements Runnable,Delayed{
private String name; //姓名
private Date date; //交卷时间
private String id; //编号
public Student() {
}
public Student(String name, Date date, String id) {
super();
this.name = name;
this.date=date;
this.id=id;
}
@Override
public void run() {
System.out.println(name + " 设置时间=" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date) + ";执行时间="+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
}
@SuppressWarnings("static-access")
@Override
public long getDelay(TimeUnit unit) {
return unit.convert(date.getTime() - System.currentTimeMillis(), unit.NANOSECONDS);
}
@Override
public int compareTo(Delayed o) {
Student that = (Student) o;
return date.getTime()> that.getDate().getTime()?1:(date.getTime() < that.getDate().getTime() ? -1 : 0);
}
public static class EndExam extends Student{
private ExecutorService exec;
public EndExam(Date date,String id, ExecutorService exec) {
super(null,date, id);
this.exec = exec;
}
@Override
public void run() {
exec.shutdownNow();
}
}
@Override
public boolean equals(Object obj) {
Student student=(Student)obj;
return this.id.equals(student.getId());
}
/**
* 设置name.
* @return 返回name
*/
public String getName() {
return name;
}
/**
* 设置date.
* @return 返回date
*/
public Date getDate() {
return date;
}
/**
* 获取name.
* @param name 要设置的name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取date.
* @param date 要设置的date
*/
public void setDate(Date date) {
this.date = date;
}
/**
* 设置id.
* @return 返回id
*/
public String getId() {
return id;
}
/**
* 获取id.
* @param id 要设置的id
*/
public void setId(String id) {
this.id = id;
}
}
教师类
public class Teacher implements Runnable{
private DelayQueue<Student> students;
public Teacher(DelayQueue<Student> students,ExecutorService exec) {
super();
this.students = students;
}
@Override
public void run() {
try {
System.out.println("考试开始……");
while (!Thread.interrupted()) {
students.take().run();
}
System.out.println("考试结束……");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
测试类,开始考试
public class Exam {
public static void main(String[] args) throws ParseException {
//创建延迟队列
DelayQueue<Student> delayQueue = new DelayQueue<Student>();
ExecutorService exec = Executors.newCachedThreadPool();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:SS");
//将消息放入队列
delayQueue.put(new Student("学生1", dateFormat.parse("2016-11-10 16:02:10"), "1"));
delayQueue.put(new Student("学生2", dateFormat.parse("2016-11-10 16:09:10"), "2"));
delayQueue.put(new Student("学生3", dateFormat.parse("2016-11-10 16:08:10"), "3"));
delayQueue.put(new Student("学生4", dateFormat.parse("2016-11-10 16:06:10"), "4"));
delayQueue.put(new Student("学生5", dateFormat.parse("2016-11-10 16:03:10"), "5"));
delayQueue.put(new Student("学生6", dateFormat.parse("2016-11-10 16:05:10"), "6"));
exec.execute(new Teacher(delayQueue, exec));
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//将消息从队列中移除
Student remove = new Student();
remove.setId("6");
delayQueue.remove(remove);
delayQueue.put(new Student("学生7", dateFormat.parse("2016-11-10 16:02:10"), "7"));
// students.put(new Student("学生8", dateFormat.parse("2016-11-10 16:43:20"), "8"));
// students.put(new Student("学生9", dateFormat.parse("2016-11-10 16:43:01"), "9"));
// students.put(new Student("学生10", dateFormat.parse("2016-11-10 16:43:03"), "10"));
// students.put(new Student("学生11", dateFormat.parse("2016-11-10 16:43:11"), "11"));
// students.put(new Student("学生12", dateFormat.parse("2016-11-10 16:43:17"), "12"));
}
}
测试结果:
考试开始……
学生1 设置时间=2016-11-10 16:02:00;执行时间=2016-11-10 16:02:00
学生7 设置时间=2016-11-10 16:02:00;执行时间=2016-11-10 16:02:00
学生5 设置时间=2016-11-10 16:03:00;执行时间=2016-11-10 16:03:00
学生4 设置时间=2016-11-10 16:06:00;执行时间=2016-11-10 16:06:00
学生3 设置时间=2016-11-10 16:08:00;执行时间=2016-11-10 16:08:00
学生2 设置时间=2016-11-10 16:09:00;执行时间=2016-11-10 16:09:00
在考试的过程中,若有学生终止考试(不提交试卷),或有新的学生开始考试,确定交卷时间,最后学生的交卷时间都会按序。