对于定时器的设定,想必大家在不少网站或者文章中见到吧,但是所谓的定时器如何去用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
{ - 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
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();
- }
- }
- }
可参考: