//创建一个类,表示定时器
class MyTimer {
//创建一个静态内部类,用来表示任务
static class MyTask implements Comparable<MyTask> {
//类成员,表示任务内容
private Runnable runnable;
//类成员,表示任务执行时间
private long time;
//给定一个构造方法,在构造时需指定任务内容和多长时间后执行
public MyTask(Runnable runnable, long delay) {
this.runnable = runnable;
this.time = System.currentTimeMillis() + delay;
}
//类方法,获取该任务的执行时间
public long getTime() {
return time;
}
//类方法,执行该任务
public void run() {
runnable.run();
}
//任务需要组织在优先级队列中,故需要实现Comparable接口中的compareTo方法
@Override
public int compareTo(MyTask o) {
return (int)(this.time - o.time);
}
}
//创建一个阻塞优先级队列,用来组织定时器中的各个任务,由于时间小的任务排在前面,故使用带有优先级的队列组织任务
public PriorityBlockingQueue<MyTask> queue = new PriorityBlockingQueue<>();
//向优先级队列中添加任务
public void schedule(Runnable runnable, long delay) {
MyTask myTask = new MyTask(runnable, delay);
queue.offer(myTask);
//有新任务添加时,需要解除wait,让扫描线程重新检查队列中队首任务的触发时间
synchronized (locker) {
locker.notify();
}
}
//创建一个锁对象,借助这个对象解决扫描线程忙等问题,缓解CPU占用过高
private Object locker = new Object();
public MyTimer() {
//创建扫描线程
Thread t = new Thread(() -> {
while (true) {
try {
MyTask task = queue.take();
long curtime = System.currentTimeMillis();
//当前时间小于触发事件,则阻塞等待,并指定一个等待时间
if (curtime < task.time) {
queue.offer(task);
synchronized (locker) {
locker.wait(task.time - curtime);
}
} else {
//时间到了,就执行任务
task.run();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
}
}
public class Demo6 {
public static void main(String[] args) {
MyTimer timer = new MyTimer();
timer.schedule(() -> {
System.out.println("hello world!");
},3000);
System.out.println("hello main!");
}
}
|