java - 定时器

一、什么是定时器

定时器是指可以通过 Java 中的 Timer 类和 TimerTask 类所提供的功能来实现定期执行某些任务的工具。

标准库中提供了一个 Timer . Timer 类的核心方法为 schedule .
schedule 包含两个参数 . 第一个参数指定即将要执行的任务代码 , 第二个参数指定多长时间之后执行 ( 单位为毫秒).

下面是一个示例代码,用于创建一个定时器, 5 秒钟后打印一条消息:

import java.util.Timer;
import java.util.TimerTask;

public class TimerExample {

    public static void main(String[] args) {
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            public void run() {
                System.out.println("5 秒钟已经过去了...");
            }
        }, 5000);
    }
}

在上述代码中,我们首先创建一个 Timer 对象,然后使用 schedule 方法安排一个 TimerTask 对象在 0 秒后开始运行, 5 秒钟后再次运行。在 TimerTask 的 run 方法中,我们打印了一条简单的消息。

总之,Java 中的定时器是一种可以用来实现定期执行某些任务的工具,在开发中,我们可以根据具体需求来设计和使用相应的定时器,来进行任务的调度和处理。

 二、实现定时器

定时器的构成 :
  • 一个带优先级的阻塞队列
    为啥要带优先级呢?
    因为阻塞队列中的任务都有各自的执行时刻 (delay). 最先执行的任务一定是 delay 最小的. 使用带优先级的队列就可以高效的把这个 delay 最小的任务找出来.
  • 队列中的每个元素是一个 MyTask 对象.
  • MyTask 中带有一个时间属性, 队首元素就是即将
  • 同时要创建线程一直扫描队首元素, 看队首元素是否需要执行

class MyTask implements Comparable{

   public Runnable runnable;
   public Long time;//为了方便后续判定,使用绝对的时间戳

   public MyTask(Runnable runnable, Long delay) {
      this.runnable = runnable;
      //取当前时刻的时间戳 + delay, 作为该任务实际执行的时间戳
      this.time = System.currentTimeMillis() + delay;
   }

   @Override
   public int compareTo(MyTask o) {
      return (int)(this.time-o.time);
   }
}
public class MyTimer {
   //带有优先级的阻塞队列
   private PriorityBlockingQueue priorityBlockingQueue = new PriorityBlockingQueue<>();

   private Object locker = new Object();
   public void schedule(Runnable runnable,long delay){
      MyTask task = new MyTask(runnable,delay);
      //放任务
      priorityBlockingQueue.put(task);
      synchronized (locker) {
         locker.notify();
      }
   }

   public MyTimer(){
      Thread t = new Thread(() -> {
            while(true){
               synchronized (locker) {
               try {
                  //取任务
                  MyTask take = priorityBlockingQueue.take();
                  //任务的时间
                  Long curTime = System.currentTimeMillis();
                  if(take.time <= curTime){
                     //时间到了,可以执行任务
                        take.runnable.run();
                  }else{
                     //时间没到,把任务重新放回到队列里
                     priorityBlockingQueue.put(take);
                     //
                     locker.wait(take.time-curTime);
                  }
               } catch (InterruptedException e) {
                  e.printStackTrace();
               }
            }
         }
      });
      t.start();
   }

}

你可能感兴趣的:(java,开发语言)