定时器是一个闹钟,当时间到就可以执行一个指定代码。
标准库 提供的定时器:Timer
public static void main(String[] args) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {//new TimerTask 本质上就是一个Runnable
@Override
public void run() {
System.out.println("hello1");//这个方法的执行,依靠Timer内置的线程执行的,时间到执行,还是前台线程,会阻止进程结束。
}
}, 1000);//设定时间
}
一个定时器可以管理多个任务,每个定时器有一个或一组线程,每次都找到最先要执行的任务,时间到了就执行,没到时间就等等。
public static void main(String[] args) {
Timer timer = new Timer();
//定时器,内部管理不止一个任务
timer.schedule(new TimerTask() {//new TimerTask 本质上就是一个Runnable
@Override
public void run() {
System.out.println("hello1");//这个方法的执行,依靠Timer内置的线程执行的,时间到执行,还是前台线程,会阻止进程结束。
}
}, 1000);//设定时间
timer.schedule(new TimerTask() {//new TimerTask 本质上就是一个Runnable
@Override
public void run() {
System.out.println("hello2");//这个方法的执行,依靠Timer内置的线程执行的,时间到执行,还是前台线程,会阻止进程结束。
}
}, 2000);//设定时间
timer.schedule(new TimerTask() {//new TimerTask 本质上就是一个Runnable
@Override
public void run() {
System.out.println("hello3");//这个方法的执行,依靠Timer内置的线程执行的,时间到执行,还是前台线程,会阻止进程结束。
}
}, 3000);//设定时间
timer.schedule(new TimerTask() {//new TimerTask 本质上就是一个Runnable
@Override
public void run() {
System.out.println("hello4");//这个方法的执行,依靠Timer内置的线程执行的,时间到执行,还是前台线程,会阻止进程结束。
}
}, 4000);//设定时间
}
那我们怎么知道最谁是时间最短最先执行的呢?
采用(优先级队列)结构即可!
模拟实现定时器
//表示一个任务
class MyTask implements Comparable<MyTask>{
public Runnable runnable;
public long time;
public MyTask(Runnable runnable, long time) {
this.runnable = runnable;
this.time = System.currentTimeMillis()+time;//当前系统时间戳+定义的时间
}
@Override
public int compareTo(MyTask o) {
return (int)(this.time-o.time);
}
}
class MyTimer{
//带有优先级的阻塞队列
private PriorityBlockingQueue<MyTask> queue=new PriorityBlockingQueue<>();
public void schedule(Runnable runnable,long delay){
//根据参数,构造MyTask,插入队列
MyTask myTask=new MyTask(runnable,delay);
queue.put(myTask);
synchronized (obj){
obj.notify();
}
}
Object obj=new Object();
public MyTimer(){
Thread t=new Thread(()->{
while(true){
try {
synchronized (obj) {
MyTask myTask = queue.take();//取任务
long curTime = System.currentTimeMillis();//获取当前系统时间
if (curTime >= myTask.time) {
myTask.runnable.run();//到时间了!执行任务
} else {
queue.put(myTask);//时间没到,放回队列中
obj.wait(myTask.time-curTime);//放弃cpu阻塞等待
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
}
}