定时器构成:
- 使用一个Task类来描述一段逻辑,同时记录该任务执行时间
- 使用一个阻塞优先队列,组织若干个Task
- 还需要一个扫描线程,检测队首元素是否需要执行
import java.util.concurrent.PriorityBlockingQueue;
public class Thread1 { //定时器
//Task类用来描述一段逻辑
static class Task implements Comparable<Task>{ //优先队列中的元素必须是可比较的
private Runnable command; //借助runnable的run方法来描述执行的具体任务
private long time; //表示执行command的时间(绝对时间)
public Task(Runnable command, long after) { //after表示多少毫秒之后执行(相对时间)
this.command = command;
this.time = System.currentTimeMillis()+after;
}
public void run(){ //run方法表示执行任务的具体逻辑
command.run();
}
@Override
public int compareTo(Task o) {
return (int) (this.time - o.time);
}
}
//扫描器
static class Worker extends Thread{
private PriorityBlockingQueue<Task> queen = null;
private Object mailBox = null;
public Worker(PriorityBlockingQueue<Task> queen,Object mailBox) {
this.queen = queen;
this.mailBox = mailBox;
}
@Override
public void run() { //实现具体线程执行内容
while(true){
try {
Task task = queen.take(); //1.取出队首元素
long curTime = System.currentTimeMillis(); //获取当前时间
if(task.time > curTime){ //2.检查当前任务时间是否到了
queen.put(task); //时间还没到,把任务再赛回去
synchronized (mailBox){
mailBox.wait(task.time - curTime);
}
}else{
task.run(); //时间到了,执行任务
}
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
}
}
//组织Task类
static class Timer{
private Object mailBox = new Object(); //为了避免忙等,使用wait方法
private PriorityBlockingQueue<Task> queen = new PriorityBlockingQueue<>();
public Timer(){ //创建线程
Worker worker = new Worker(queen,mailBox);
worker.start();
}
public void schedule(Runnable command,long after){ //提供一个方法,将任务安排进来
Task task = new Task(command,after);
queen.put(task);
synchronized (mailBox){
mailBox.notify();
}
}
}
}