当前位置: 首页 > article >正文

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<MyTask>{

   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<MyTask> 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();
   }

}

http://www.kler.cn/a/145715.html

相关文章:

  • GPT 结束语设计 以nanogpt为例
  • HackTheBox靶机:Sightless;NodeJS模板注入漏洞,盲XSS跨站脚本攻击漏洞实战
  • 变频器硬件接线
  • ui文件转py程序的工具
  • JS宏进阶:正则表达式的使用
  • Taro+Vue实现图片裁剪组件
  • 机器学习【04重要】pycharm中关闭jupyter服务器
  • 交叉编译 和 软硬链接 的初识(面试重点)
  • 【面经八股】搜广推方向:常见面试题(五)
  • 流量主如何在广告收益和用户体验中找到平衡
  • 知识点小总结
  • 【单片机学习笔记】STC8H1K08参考手册学习笔记
  • 梦回吹角连营(超1e18的快速幂模板,两大数相乘处理)
  • stm32实现0.96oled图片显示,菜单功能
  • Gin 学习笔记02-参数获取
  • 定制手机套餐---python序列
  • 【Spring】Spring事务失效问题
  • MySQL进阶_10.锁
  • 《已解决: ImportError: Keras requires TensorFlow 2.2 or higher 问题》
  • Docker部署Nacos
  • ubuntu22.04安装swagboot遇到的问题
  • 【2023.11.26】Mybatis自定义映射规则学习
  • 手机APP-MCP走蓝牙无线遥控智能安全帽~执法记录仪~拍照录像,并可做基础的配置,例如修改服务器IP以及配置WiFi等
  • 开源博客项目Blog .NET Core源码学习(7:FluentValidation使用浅析)
  • 使用 Raspberry Pi、Golang 和 HERE XYZ 制作实时地图
  • 2023亚太杯数学建模思路 - 案例:粒子群算法