1.Java自带的定时器
public class Test9 {
public static void main(String[] args) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("1000");
}
},1000);
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("3000");
}
},3000);
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("2000");
}
},2000);
System.out.println("启动");
}
}
2.自己实现一个定时器
//用来描述任务的一个类
class MyTimerTask implements Comparable<MyTimerTask>{
private long time;//执行任务的时间
private Runnable runnable;//要执行的任务
public MyTimerTask(Runnable runnable,long delay) {
this.runnable = runnable;
this.time = System.currentTimeMillis()+delay;
}
public long getTime() {
return this.time;
}
public Runnable getRunnable() {
return runnable;
}
@Override
public int compareTo(MyTimerTask o) {//优先级队列要设定一个比较队列中元素的规则
return (int) (this.time-o.time);//这个写法是最小的元素位于队首
}
}
//自己要实现的计时器
class MyTimer{
PriorityQueue<MyTimerTask> queue = new PriorityQueue<>();//利用优先级队列存储任务
Object lock = new Object();//定义一把锁
public void schedule(Runnable runnable,long delay) {//执行任务的方法
synchronized (lock) {
queue.offer(new MyTimerTask(runnable,delay));
lock.notify();//这里可以唤醒队列为空的情况和有新的任务加入到队列当中
}
}
//再写一个扫描线程,去判断任务需不需要执行
public MyTimer() {
Thread t = new Thread(()->{
while (true) {
try {
synchronized (lock) {
while (queue.isEmpty()) {//如果队列为空则wait等待,所以要搭配synchronized
lock.wait();
}
long curTime = System.currentTimeMillis();
MyTimerTask task = queue.peek();
if (curTime >= task.getTime()) {//将当前的时间与队首任务的时间做对比
task.getRunnable().run();//执行任务
queue.poll();//执行完任务,从队列里面删除
}else {
lock.wait(task.getTime()-curTime);//当任务时间没到的时候,让其等待,
}
}
}catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
}
}
public class Test9 {
public static void main(String[] args) {
MyTimer myTimer = new MyTimer();
myTimer.schedule(new Runnable() {
@Override
public void run() {
System.out.println("1000");
}
}, 1000);
myTimer.schedule(new Runnable() {
@Override
public void run() {
System.out.println("3000");
}
},3000);
myTimer.schedule(new Runnable() {
@Override
public void run() {
System.out.println("2000");
}
},2000);
}
}