一、Timer定时器
Java中,Timer类
是用于计划和执行重复任务的类(Java标准库
中确实提供了java.util.Timer
类)。它可以在指定的时间间隔内重复执行一个任务,或者在指定时间点执行任务。
二、Timer定时器的设计
下面是一个简单的定时器程序,可以运行试试看:
import java.util.Timer;
import java.util.TimerTask;
public class Demo22 {
public static void main(String[] args) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("hello world!!!");
}
},3000);
System.out.println("程序开始执行喽!!!");
}
}
三、定时器的实现
代码实现如下:
import java.util.Comparator;
import java.util.PriorityQueue;
class MyTimerTask implements Comparable<MyTimerTask> {
private long time; // 表示任务什么时候开始执行
private Runnable runnable; // 表示具体任务是啥
public MyTimerTask(Runnable runnable,long delay) {
// delay是一个相对的时间差
time = System.currentTimeMillis() + delay;// 这里计算出任务执行的具体时间
this.runnable = runnable;
}
public long getTime() {
return time;
}
public Runnable getRunnable() {
return runnable;
}
@Override
public int compareTo(MyTimerTask o) {
// 时间最少的元素放在队首,即时间越少优先级越高
return (int)(this.time - o.time); // time是long类型
}
}
// 这是定时器类的本体
class MyTimer {
// 使用优先级队列来保存上面的N个任务
private PriorityQueue<MyTimerTask> queue = new PriorityQueue<>();
// locker是用来加锁的对象
private Object locker = new Object();
// 定时器的核心方法,即把要执行的任务添加到队列中
public void schedule(Runnable runnable,long delay) {
synchronized (locker) {
MyTimerTask task = new MyTimerTask(runnable,delay);
queue.offer(task);
// 每次来新的任务之后都会唤醒一下扫描线程,此时扫描线程就可以根据最新的任务情况来重新规划等待时间
locker.notify();
}
}
// MyTimer类中还需要一个扫描线程,一方面要负责检查队首元素是否是此时应该被执行的。
// 另一方面,当任务到点开始执行之后,需要调用Runnable中的run方法来完成任务
public MyTimer() {
// 扫描线程
Thread t = new Thread(() -> {
while(true) {
try {
synchronized(locker) {
while(queue.isEmpty()) {
// 队列为空时,此时不应该取这里的元素
locker.wait();
}
MyTimerTask task = queue.peek();
long curTime = System.currentTimeMillis();
if(curTime > task.getTime()) {
// 如果当前时间晚于任务的执行时间,就意味着我们要执行这个任务了
queue.poll();
task.getRunnable().run(); // 至此就可以执行该任务了
} else {
// 如果当前时间早于任务的执行时间,诶呀太早了,让这个线程(休眠)休息一会一会吧!!!
// Thread.sleep(task.getTime() - curTime);
locker.wait(task.getTime() - curTime);
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
}
}
public class Demo23 {
public static void main(String[] args) {
MyTimer timer = new MyTimer();
timer.schedule(new Runnable() {
@Override
public void run() {
System.out.println("hello world! 3");
}
},3000);
timer.schedule(new Runnable() {
@Override
public void run() {
System.out.println("hello world! 2");
}
},2000);
timer.schedule(new Runnable() {
@Override
public void run() {
System.out.println("hello world! 1");
}
},1000);
System.out.println("程序开始执行!!!");
}
}
运行结果如下:
四、总结
Timer类是Java中的定时工具类,它可以帮助我们实现在指定时间执行指定任务的功能。Timer类提供了一个方法即schedule方法
,我们可以通过schedule方法来注册一个任务并指定执行该任务的时间,当执行时间到的时候,Timer类内部的线程就会负责调用执行注册的任务。
另外我们可以通过优先级队列的方式来实现类似于Timer类这样的定时器。
本文到这里就结束了,希望友友们可以支持一下一键三连哈。嗯,就到这里吧,再见啦!!!