1.定时器的介绍

人类最早使用的定时工具是沙漏或水漏,但在钟表诞生发展成熟之后,人们开始尝试使用这种全新的计时工具来改进定时器,达到准确控制时间的目的。定时器确实是一项了不起的发明,使相当多需要人控制时间的工作变得简单了许多。人们甚至将定时器用在了军事方面,制成了定时炸弹,定时雷管。不少家用电器都安装了定时器来控制开关或工作时间。

定时器是通信协议正常运行的基本要素之一,主要用于各种定时和帧重传的任务。通信协议在单片机系统上实现所使用的定时器,定时精度要求不高,但数量要求比较大。由于硬件资源有限,不可能为每一个单独任务分配一个硬件定时器,只能通过单个硬件定时器模拟多个软件定时器的方法,来满足协议中的定时应用需要。

用一定的数据结构将这些软件定时器组织起来,并提供统一的调用接口,称为“定时器管理”。定时器管理主要有2种实现方法:

①静态数组法。将定时器节点存储在数组中。优点是逻辑简单,占用ROM较少。但这种方案有明显的缺点:当硬件定时器中断发生时,要对所有定时器节点进行减法操作,时间开销很大,且时延不确定(与定时器数目相关)。

②delta链表法。按照定时器的定时值升序排列,形成链表。后一个定时器的定时值是前面所有定时器的值加上本节点的值。这样,在每次的时钟中断处理中,只需对第1个定时器节点进行减法操作,大大减少了时间开销。但是,该方案逻辑复杂,ROM用量大,需要频繁分配回收内存,容易形成内存碎片。

定时器管理模块的设计基于静态数组法。使用一个定时器节点数组来保存所有的定时请求,数组的每一项代表一个可用的定时器节点。每一个定时器节点都有一个状态项,表示该定时器正处于空闲、使用或溢出状态。定时器的定时值和定时器超时后要发送的消息也存储在定时器节点中,从而实现用一个硬件定时器为用户提供多个软件定时器。

为了解决中断处理时间开销大的问题,在模块中引入一个辅助定时器,辅助定时器的值总是等于所有定时器节点中的最小定时值。在硬件定时器中断处理中,仅对辅助定时器进行减法操作,从而大大缩短了中断处理的时间。

2.实现代码及测试用例

完整代码:

package practice;import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.LinkedList;
import java.util.List;public class MyTimeCall {public static void main(String[] args) throws ClassNotFoundException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException {MyTimeCall.getIns().addTask(2, "practice.TestNode", "music1", 0);MyTimeCall.getIns().addTask(4, "practice.TestNode", "music2", 0, "后来");}//实例化MyTimeCallprivate static final MyTimeCall ins = new MyTimeCall();//获取实例对象的方法public static MyTimeCall getIns() {return ins;}//任务类private static class Task {private long nextRunTime;private final long delayTime;private final Object obj;private final Method method;/*** 有参构造方法** @param nextRunTime 任务下一次的执行时间* @param delayTime   延迟间隔时间* @param obj         对象* @param method      方法*/public Task(long nextRunTime, long delayTime, Object obj, Method method) {this.nextRunTime = nextRunTime;this.delayTime = delayTime * 1000;this.obj = obj;this.method = method;}/*** 获取下一次任务执行的时间*/public void next() {this.nextRunTime = this.nextRunTime + this.delayTime;}/*** 判断当前任务能否执行** @param nowTime 当前时间* @return 布尔值*/public boolean needRun(long nowTime) {return this.nextRunTime < nowTime;}}//创建一个任务链表private final List<Task> tasks = new LinkedList<>();//标明当前任务是否已经被执行的标志private boolean running = false;/*** 增加任务的方法** @param delayTime    延迟间隔时间* @param className    类名* @param functionName 方法名* @param conPara      方法参数*/public synchronized void addTask(long delayTime, String className, String functionName, Object... conPara) throws ClassNotFoundException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException {//获取到整个类Class<?> c = Class.forName(className);//获取到方法参数的个数int paraCount = conPara.length;//遍历类的构造函数for (Constructor<?> constructor : c.getConstructors()) {if (constructor.getParameterCount() == paraCount) {//如果某个构造函数的参数与传入的方法参数个数一致Object o = constructor.newInstance(conPara);Method method = c.getMethod(functionName);//新建一个任务Task task = new Task(System.currentTimeMillis() + delayTime, delayTime, o, method);//将任务加入任务链表tasks.add(task);}}if (!this.running) {//任务未被执行Thread t = new Thread(this::run);t.setName("定时器线程");//更改任务状态this.running = true;t.start();}}public void run() {while (true) {//获取当前时间long currTime = System.currentTimeMillis();synchronized (this) {//遍历任务链表this.tasks.forEach((task -> {//判断任务当前是否可以执行if (task.needRun(currTime)) {//当前任务可以执行new Thread(() -> {try {task.method.invoke(task.obj);} catch (InvocationTargetException | IllegalAccessException e) {e.printStackTrace();}}).start();//设置下一次任务执行时间task.next();}}));}//每隔多久遍历一遍任务链表try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
}class Test {private int id;private String name;public Test(int id) {this.id = id;}public Test(int id, String name) {this.id = id;this.name = name;}public void music1() {id++;System.out.println("音乐第" + id + "次播放");}public void music2() {id++;name += "1";System.out.println(name + "第" + id + "次播放");}
}

测试用例结果:

定时器的实现到这里就结束啦!如果有任何问题可以在评论区留言,我会一一为你们解答。

Java实现定时器(Timer)相关推荐

  1. Java的定时器Timer和定时任务TimerTask应用以及原理简析

    记录:272 场景:Java JDK自带的定时器Timer和定时任务TimerTask应用以及原理简析.在JDK工具包:java.util中可以找到源码,即java.util.Timer和java.u ...

  2. java之定时器Timer

    文章目录 1 概览 2 终止Timer线程 3 反复执行一个任务 4 进一步分析schedule和scheduleAtFixedRate 5 一些注意的问题 1 概览 Timer是一种定时器工具,用来 ...

  3. java捕获定时器抛出的异常_详细了解Java中定时器Timer的使用及缺陷分析

    在需要定时并且周期执行任务时,在最初的JAVA工具类库中,Timer可以实现任务的定时周期执行的需求,不过有一定的缺陷,比如,Timer是基于绝对时间而非相对时间,因此Timer对系统时钟比较敏感,本 ...

  4. java之定时器任务Timer用法

    在项目开发中,经常会遇到需要实现一些定时操作的任务,写过很多遍了,然而每次写的时候,总是会对一些细节有所遗忘,后来想想可能是没有总结的缘故,所以今天小编就打算总结一下可能会被遗忘的小点: 1. pub ...

  5. Java定时器Timer

    Java定时器Timer 在JDK库中,Timer类主要负责计划任务的功能,也就是在指定的时开始执行某一个任务.Timer类的主要作用就是设置计划任务,但封装任务的类却是TimerTask类,执行计划 ...

  6. Java定时器Timer学习之一

    2019独角兽企业重金招聘Python工程师标准>>> 种类: 接通延时型定时器:接通延时型定时器是各种PLC(可编程控制器)中最常见最基本的定时器,这种定时器在Siemens的PL ...

  7. java定时器阻塞主线程_Java基础_死锁、线程组、定时器Timer

    一.死锁问题: 死锁是这样一种情形:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放.由于线程被无限期地阻塞,因此程序不可能正常终止. 比如,线程一需要第一把所,此时锁处于空闲状态,给了 ...

  8. Java定时器Timer和第三方定时器Quartz

    概述 定时器在应用广泛,比如定时统计数据生成报表.每隔设定的时间提醒用户等.Java.util包自带的定时器Timer提供简单的定点执行功能,而Quartz是一个第三方提供的定时器框架. 对比 Tim ...

  9. java定时器关闭再重启_Android定时器Timer的停止和重启实现代码

    本文介绍了Android定时器Timer的停止和重启实现代码,分享给大家,具体如下: 7月份做了一个项目,利用自定义控件呈现一幅动画,当时使用定时器来控制时间,但是当停止开启时总是出现问题.一直在寻找 ...

  10. java定时器timer_Java定时器Timer

    Java定时器Timer 在JDK库中,Timer类主要负责计划任务的功能,也就是在指定的时开始执行某一个任务.Timer类的主要作用就是设置计划任务,但封装任务的类却是TimerTask类,执行计划 ...

最新文章

  1. 这些建议需要竞赛组委会酌情考虑
  2. 6-第三方库离线安装法
  3. 井字棋小游戏c语言简单编码,C语言实现井字棋小游戏
  4. 【算法竞赛入门经典(第二版)】_要点提取(第三章)
  5. 关于layui分页组件layPage如何动态调整页数的使用
  6. Matlab与1stOpt多元非线性回归
  7. 远程控制软件编写--系列教程
  8. 大数据概述及电信大数据应用
  9. 那人立在侧边 水浒传
  10. 2019/04/12 华为通用软件开发工程师现场面试(offer到手)
  11. 项目管理学习笔记之二.工作分解
  12. android系统开机logo定制
  13. Python3 编写处理Excel表格数据筛选脚本用到的一些方法
  14. C语言 | Linux下的静态链接与动态链接
  15. 37所国家示范性软件学院
  16. 360网站卫士能防服务器吗,360网站卫士测评
  17. parametric bootstrap参数估计抽样方法的R实现
  18. 一本书,带你走出Spring新手村
  19. 2020年下半年教师资格中学《综合素质》真题与参考答案
  20. “千年之恋”注册页面制作

热门文章

  1. hive创建分区表 hive添加分区 hive删除分区
  2. 变革管理 | 四种类型项目管理办公室(PMO)及Activist PMO
  3. 小白的数字电路逻辑设计笔记(一)----绪论
  4. AD2S1205替代 国产旋变数字转换器—MS5905P
  5. 中国的外企之一瞥--与上海10万年薪外企职员谈
  6. 互联网VS央企,谈一谈我的选择
  7. mysql大数据量迁移方案
  8. 拘役两个月能去探视吗
  9. (转) Android应用Activity、Dialog、PopWindow、Toast窗口添加机制及源码分析
  10. ARM学习随笔(1) 位操作