目录
定义:
类似于一个闹钟,达到设定的时间之后,就会执行某个指定的代码
标准库中的定时器:
标准库提供了Timer类,Timer类的核心方法为schedule(即将执行的代码,多长时间后执行)
mport java.util.Timer;
import java.util.TimerTask;
public class demo19 {
public static void main(String[] args) {
Timer timer = new Timer();
timer.schedule(new TimerTask()//本质就是runnable {
@Override
public void run() {
System.out.println("hello");
}
},2000);//表示2s后执行run
System.out.println("world");
}
}
执行结果:
定时器的实现
1.带优先级的阻塞队列(因为阻塞队列中的任务都有各自的执行时刻 (delay). 最先执行的任务一定是 delay 最小的. 使用带 优先级的队列就可以高效的把这个 delay 最小的任务找出来.)
2.队列中的每个元素是一个task对象
3.task中带有一个时间属性
4.有一个worker线程一直扫描队首元素,看队首元素是否需要执行
Task 类用于描述一个任务,因为要实现带优先级的队列,所以要实现comparable接口
class Task implements Comparable<Task>{
public Runnable runnable;
public long time;
public Task(Runnable runnable,long delay){
this.runnable=runnable;
//取当前时刻的时间戳++delay表示该任务实际执行的时间戳
this.time=System.currentTimeMillis()+delay;
}
@Override
public int compareTo(Task o) {
return (int)(this.time-o.time);//取出最小时间的元素
}
完整代码
package work;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.PriorityBlockingQueue;
public class demo19 {
public static void main(String[] args) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("hello");
}
}, 2000);
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("hello2");
}
}, 2000);
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("hello3");
}
}, 2000);
}
}
class Task implements Comparable<Task> {
public Runnable runnable;
public long time;
public Task(Runnable runnable, long delay) {
this.runnable = runnable;
//取当前时刻的时间戳++delay表示该任务实际执行的时间戳
this.time = System.currentTimeMillis() + delay;
}
@Override
public int compareTo(Task o) {
return (int) (this.time - o.time);//取出最小时间的元素
}
}
class MyTimer {
//带优先级的阻塞队列
private PriorityBlockingQueue<Task> queue = new PriorityBlockingQueue<>();
//创建一个锁对象
private Object locker = new Object();
//注册一个任务, 并指定这个任务多长时间后执行.
public void schedule(Runnable runnable, long delay) {
Task mytask = new Task(runnable, delay);
//构造Task,插入队列
queue.put(mytask);
locker.notify();
}
//构造线程
public MyTimer() {
Thread t = new Thread(() -> {
while (true) {
synchronized (locker) {
try {
//阻塞出队列
Task task = queue.take();
long curTime = System.currentTimeMillis();
if (task.time <= curTime) {
//时间到了,开始执行任务
task.runnable.run();
} else {
//阻塞入队列,把刚刚取出的任务放回队列中
queue.put(task);
locker.wait(task.time-curTime);
//取出队首元素,发现还没到时间就wait,但是有了新任务,就唤醒wait
//执行新任务,不像sleep那样死等
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t.start();
}
}
执行结果: