对于定时器的设定,想必大家在不少网站或者文章中见到吧,但是所谓的定时器如何去用Java代码来bian'x呢??感兴趣的老铁,可以看一下笔者这篇文章哟~~
所谓的定时器就是闹钟!!
设定一个时间,当时间到,就可以执行一个指定的代码~
标准库提供的定时器Timer《——》在java.util包底下
Timer里内置了线程(前台线程),会阻止线程结束(代码运行后可见)
import java.util.Timer;
import java.util.TimerTask;
public class Main {
public static void main(String[] args) {
Timer timer =new Timer();//创建实列
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("hello4");
}
},4000);//4000毫秒后执行
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("hello3");
}
},3000);//3000毫秒后执行
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("hello2"
);
}
},3000);//2000毫秒后执行
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("hello1");
}
},3000);//1000毫秒后执行
System.out.println("hello ");
}
}
上述代码的运行结果为:
在上述用到的:schedule:安排,安排一个工作,但不是立即完成,而是在未来某个时间点执行~
定时器应用场景非常多!尤其是网络编程~
超时是504
那么,如何自己实现一个定时器呢??
定时器内部关联的不仅仅是一个任务,可以管理很多任务的!!(比如:上面的代码),虽然任务可能有很多,他们的触发时间是不同的~
只要有一个/一组工作线程,每次都找到这些认为有最先到达时间的任务,当一个线程,先执行最早的任务,等做完了之后,在执行第二早的!时间到了就执行,时间没到就先等等!
定时器可能有多个线程在执行schedule方法!!希望在多线程下操作优先级队列,还能线程安全哈!!
PriorityBlockingQueue<>带有优先级的阻塞队列!
<>这里的元素需要我们手动封装一下里面的元素!
创建个类:表示两方面信息:
- 执行的任务是啥??
- 任务啥时候结束??
//描述任务的类
class MyTask implements Comparable<MyTask>{
private Runnable runnable;//描述要执行的任务
private long time;//什么时间执行,用时间戳来表示
public MyTask(Runnable task,long delay){
this.runnable = task;
this.time = System.currentTimeMillis() + delay;
}
public Runnable getRunnable() {
return runnable;
}
public long getTime() {
return time;
}
@Override
public int compareTo(MyTask o) {
return (int) (this.getTime()-o.getTime());
}
}
//定时器
public class MyTimer {
private BlockingQueue<MyTask> queue = new PriorityBlockingQueue<>();
Object locker = new Object();
public MyTimer(){
Thread t = new Thread(() -> {
while (true){
synchronized (locker) {
try {
MyTask task = queue.take();//获取队首元素
long curTime = System.currentTimeMillis();//获取当前时间
//比较当前时间和队首元素的执行时间
if(curTime >= task.getTime()){
//时间到,执行任务
task.getRunnable().run();
}else {
//时间没到,把元素再放回到队列中
queue.put(task);
locker.wait(task.getTime() - curTime);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t.start();
}
public void schedule(Runnable task,long delay) throws InterruptedException {
MyTask myTask = new MyTask(task, delay);
//把任务放入队列中
queue.put(myTask);
synchronized (locker){
locker.notify();
}
}
}
可参考:
Java定时器_吃点橘子的博客-CSDN博客