MyTask
类用于描述一个任务
(
作为
Timer
的内部类
).
里面包含一个
Runnable
对象和一个
time(
毫秒时间戳)
📝相对时间和绝对时间
//执行任务的时间(绝对时间) private long time;
此时记录的是一个“绝对的时间"(完整的时间戳)。
- 绝对时间:当前具体的时间
- 相对时间:时间间隔
schedule方法里面的第二个参数是相对时间,为什么构造的时候记录绝对时间呢?
后续扫描线程的时候,如何判定当前这个任务是否要执行?
- 获取到当前的时间戳 14:00
- 再获取到任务要执行的时间戳 14:05
- 对比俩个时间戳(时间没有到,不能执行)
当前的时间戳是利用到 System.currentTimeMillis()方法,现在我写的时间是20:02,此时时间戳转换成时间就是绝对时间。我们再扫描线程的时候,我们比较的是 当前的时间戳和我要执行的时候的绝对时间,所以我们最好是记录绝对时间。
public MyTask(Runnable runnable,long delay){ this.time=System.currentTimeMillis()+delay; this.runnable=runnable; }
构造方法中的俩个参数是 执行任务的对象以及相对时间。因为再调用schedule方法的时候传的第二个参数是相对时间。我们只需要将 相对时间+时间戳=绝对时间,就可以算出来。
比如现在是20:07的时候,调用的是schedule方法,执行delay是5分钟,那么再对应上面的 System.currentTimeMillis()就是14:00,delay是5分钟,那么绝对时间也就是要执行的时间是14:05分。
当我们创建好属性和获取当前的对象和时间的时候,我们再代码中还有一定的问题。
我们要想到,我们用优先级队列来保存任务,那么用到优先级队列,要求里面的元素务必是可以比较的。所以我们需要实现Comparable接口,继承compareTo方法。
@Override
public int compareTo(MyTask o) {
return (int)(this.time-o.time);
}
由于返回类型是int类型,而时间戳返回类型是long类型,所以我们需要强制类型转换。
我们所创建的任务类里面的成员属性(任务对象和绝对时间)还有构造方法,以及比较方法。为下面的扫描线程铺垫。
🎈构造MyTime类
实现计时器,首先我们要创建一个优先级队列,里面包含的元素是执行的任务,然后实现schedule方法,再调用schedule方法的时候,就插入队列中,而里面的扫描线程应该放在构造方法中,因为我们再创建MyTime类的时候,线程就启动。
class MyTime{
PriorityQueue<MyTask>queue=new PriorityQueue<