目录
定时器
约定一定时间后,执行一段代码
import java.util.Timer;
import java.util.TimerTask;
public class Demo1 {
public static void main(String[] args) {
Timer timer=new Timer();
//给定时器指定任务,以及时间
timer.schedule(new TimerTask(){//使用匿名内部类,继承TimerTask,并创建实例(TimerTask implement Runnable)
//通过run描述任务详细情况
public void run(){
System.out.println("执行定时器的任务");
}
},2000);//以当前时刻为基准,往后推xx时间
System.out.println("程序启动");
}
}
主线程执行schedule方法的时候,其实就是把这个任务放到timer对象中了
timer中包含一个扫描线程,一旦时间到了,便会执行刚才安排的任务
仔细观察发现整个进程其实没有结束,就是因为Timer内部的线程阻止了进程结束
Timer里可以安排多个任务
如何自己实现一个定时器?
1.Timer中需要有一个线程,扫描任务是否到达时间
2.需要有一个数据结构,把所有的任务保存起来—>优先级队列(时间小的先执行)
3.还需要有一个类,通过类的对象描述一个任务(任务内容+时间)
import java.util.PriorityQueue;
class MyTask implements Comparable<MyTask> {
private long time;
private Runnable runnable;
public MyTask(Runnable runnable,long time){
this.time=time+System.currentTimeMillis();
this.runnable=runnable;
}
public long getTime(){
return time;
}
public Runnable getRunnable(){
return runnable;
}
@Override
public int compareTo(MyTask o) {
return (int)(this.time-o.time);
}
}
class MyTimer2{
PriorityQueue<MyTask> queue =new PriorityQueue<>();
Object locker =new Object();
public void schedule(Runnable runable,long delay){
synchronized (locker){
queue.offer(new MyTask(runable,delay));
locker.notify();}
}
public MyTimer2(){
Thread t=new Thread(()->{
while(true) {
synchronized (locker) {
while (queue.isEmpty()) {
try {
locker.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
MyTask task = queue.peek();
long currentTime = System.currentTimeMillis();
if (task.getTime() <= currentTime) {
task.getRunnable().run();
queue.poll();
} else {
try {
locker.wait(task.getTime() - currentTime);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
});
t.start();}
}
public class demo2 {
public static void main(String[] args) {
MyTimer2 timer = new MyTimer2();
timer.schedule(new Runnable() {
@Override
public void run() {
System.out.println("6000");
}
}, 6000);
timer.schedule(new Runnable() {
@Override
public void run() {
System.out.println("4000");
}
}, 4000);
timer.schedule(new Runnable() {
@Override
public void run() {
System.out.println("2000");
}
}, 2000);
System.out.println("程序开始执行");
}
}
执行结果 :
程序开始执行
2000
4000
6000
此处用priorityQueue而不是PriorityBolckingQueue是因为此处用了两处wiat
使用阻塞版本优先级队列则不好处理