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

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

相关文章:

  • 领域驱动设计总结——如何构造领域模型
  • video标签在h5中被劫持问题
  • R语言数据缩放-1到1
  • ElasticSearch之cat component templates API
  • 【JavaEE】多线程 (2) --线程安全
  • 【Docker】从零开始:6.配置镜像加速器
  • 超实用!Spring Boot 常用注解详解与应用场景
  • 一、用户管理
  • 【Java】循环语句练习
  • MIT 6.S081学习笔记(第三章)
  • 在vue或者react或angular中,模板表达式中的箭头函数是无效的吗?为什么无效?
  • Recovery介绍
  • Java 网络编程
  • 2023亚太杯数学建模C题思路分析 - 我国新能源电动汽车的发展趋势
  • EEG 脑电信号处理合集(2): 信号预处理
  • express + mock 让前后台并行开发
  • iOS帅气加载动画、通知视图、红包助手、引导页、导航栏、朋友圈、小游戏等效果源码...
  • Java 23种设计模式 之单例模式 7种实现方式
  • JAVA之继承和多态
  • js学习笔记
  • Linux后台研发超实用命令总结
  • Markdown 语法简单说明
  • MyEclipse 8.0 GA 搭建 Struts2 + Spring2 + Hibernate3 (测试)
  • Nginx 通过 Lua + Redis 实现动态封禁 IP
  • React的组件模式
  • spring boot下thymeleaf全局静态变量配置
  • SQLServer之索引简介
  • Vue2.x学习三:事件处理生命周期钩子
  • 阿里云前端周刊 - 第 26 期
  • 大型网站性能监测、分析与优化常见问题QA
  • 大主子表关联的性能优化方法
  • 发布国内首个无服务器容器服务,运维效率从未如此高效
  • 关于Android中设置闹钟的相对比较完善的解决方案
  • 检测对象或数组
  • 王永庆:技术创新改变教育未来
  • 主流的CSS水平和垂直居中技术大全
  • # 睡眠3秒_床上这样睡觉的人,睡眠质量多半不好
  • #常见电池型号介绍 常见电池尺寸是多少【详解】
  • $$$$GB2312-80区位编码表$$$$
  • (1)Android开发优化---------UI优化
  • (pt可视化)利用torch的make_grid进行张量可视化
  • (TipsTricks)用客户端模板精简JavaScript代码
  • (附源码)springboot猪场管理系统 毕业设计 160901
  • (剑指Offer)面试题41:和为s的连续正数序列
  • (九)c52学习之旅-定时器
  • (蓝桥杯每日一题)平方末尾及补充(常用的字符串函数功能)
  • (转)GCC在C语言中内嵌汇编 asm __volatile__
  • (转)iOS字体
  • . Flume面试题
  • .bat文件调用java类的main方法
  • .net core控制台应用程序初识
  • .net FrameWork简介,数组,枚举
  • .Net FrameWork总结
  • .NET 除了用 Task 之外,如何自己写一个可以 await 的对象?
  • .NET 回调、接口回调、 委托