手搓一个定时器
目录
1.什么是定时器
2.计时器的使用
3.手搓定时器
3.1定义一个TimerTask类
3.2定义一个Timer类
3.3实现schedule方法
3.4实现Timer的构造方法
3.4.1随时随地查看优先级队列中是否有任务要执行
3.4.2获取队首任务,并判断是否到执行时间
3.4.3到达执行时间执行任务
4.整体的一个代码:

1.什么是定时器
在看警匪片时,经常会有匪徒在银行安装定时炸弹,而这里的定时炸弹就可以看成一个定时器,当设定的时间到时,炸弹就会爆炸,而我们这里的定时器是当时间到时,就会执行相应的任务
2.计时器的使用
在Java中,关于计时器的类时Timer
Timer类是java.util包提供的API。
Timer中最主要的方法是schedule方法,他是将我们的任务,和时间放进一个数组模拟的队列中,然后在指定时间执行指定的任务
代码示例:
import java.util.Timer;
import java.util.TimerTask;public class Main19 {public static void main(String[] args) {Timer timer=new Timer();timer.schedule(new TimerTask() {@Overridepublic void run() {System.out.println("hello 3000");}},3000);timer.schedule(new TimerTask() {@Overridepublic void run() {System.out.println("hello 2000");}},2000);timer.schedule(new TimerTask() {@Overridepublic void run() {System.out.println("hello 1000");}},1000);System.out.println("hello main");}
}
schedule的第一个参数类型是TimerTask,这个类他继承了Runnable类,然后第二个参数是,当前程序运行多少时间执行这个任务,单位是ms
3.手搓定时器
简单介绍完java中的Timer的使用,下面我们就来模拟实现一个定时器
整体的一个思路:
1.定义任务类(TimerTask):用来存储每一个任务的属性,如执行的时间,以及要执行的任务
2.定义一个Timer类(定时器):每一个任务执行的先后顺序,以及执行过程中的一些细节问题
3.1定义一个TimerTask类
class TimerTask{private Runnable task;private long time;public TimerTask(Runnable task, long time) {this.task = task;this.time = time;}
}
在这个类中成员属性分别为要执行的任务,以及任务执行的时间,还有一个构造方法
3.2定义一个Timer类
class Timer{private PriorityQueue<TimerTask>queue=new PriorityQueue<>();public void schedule(Runnable task,long time){}public Timer() {Thread t=new Thread(()->{});t.start(); }}
1.在这个类中有一个优先级队列,这个是用来给各个任务执行的先后顺序进行排序的
2.schedule是用来将我们要执行的任务添加到优先级队列当中的
3.Timer()这个构造方法,是我们在创建这个类时,他就开启了一个线程,这个线程是用来按时间执行我们队列中的任务的,如果线程中有任务他就在指定时间去执行,如果没有任务,他就阻塞等待
3.3实现schedule方法
锁对象:
Object lock=new Object();
schedule方法:
public void schedule(Runnable task,long delay){synchronized (lock){TimerTask timerTask=new TimerTask(task, System.currentTimeMillis()+delay);queue.offer(timerTask);}}
1.我们实例化一个TimerTask的对象,然后将schedule的参数作为任务,以及时间传递给TimerTask的构造方法作为参数(注意的是:这里构造方法接收的时间是任务执行的时间,而schedule参数的时间是任务距离调用schedule调用时相差的时间),所以构造方法参数的时间,我们要用当前时间加上延迟的时间(获取当前时间:System.currentTimeMillis());
2.得到TimerTask这个对象后,我们要将这个对象添加到优先级队列当中
3.在实例化Timer时,构造方法也会启动一个线程,所以我们这是一个多线程的程序,为了保证线程安全,我们给其加上一个锁
因为我们向优先级队列中添加的是我们自定义的类,他不知道该怎么对齐进行排序,所以我们要对TimerTask这个类定义一个比较规则
class TimerTask implements Comparable<TimerTask>{@Overridepublic int compareTo(TimerTask o) {return (int)(this.time-o.time);}
}
我们将TimerTask实现一个Comparable接口,并重写Comparaable接口里面的comparaeTo方法,又因为我们想让时间近的任务放在队首,所以我们的比较规则是为了实现一个小根堆,如果this.time-o.time是一个整数就会将小的任务放在前面,然而我们的时间是long类型,我们需要将this.time-o.time的值强转为int类型
3.4实现Timer的构造方法
3.4.1随时随地查看优先级队列中是否有任务要执行
public Timer() {Thread t=new Thread(()->{while(true){try {synchronized (lock){while(queue.isEmpty()){lock.wait();}}} catch (InterruptedException e) {throw new RuntimeException(e);}}});t.start();}
1.第一个while循环是当一次任务执行完毕,再次查看队列中是否有要执行的任务
2.第二个while循环是查看队列中是否有任务,如果没有任务,我们就阻塞等待,直到schedule被调用时,我们这里的wait被唤醒,然后进行接下来的操作
3.wait一般搭配synchronized来使用保证线程安全
为了在队列为空时,向队列中添加任务后,需要将wait唤醒,所以在schedule方法中要加上notify
public void schedule(Runnable task,long delay){synchronized (lock){TimerTask timerTask=new TimerTask(task, System.currentTimeMillis()+delay);queue.offer(timerTask);lock.notify();}}
3.4.2获取队首任务,并判断是否到执行时间
TimerTask task=queue.peek();if(System.currentTimeMillis()<task.getTime()){lock.wait(task.getTime()-System.currentTimeMillis());}
1.获取队首任务,使用peek,而不使用poll
2.如果未到达执行时间,我们就阻塞等待任务执行时间和当前时间之间的时差
3.如果在这个阻塞等待的时间段内,使用schedule向队列中添加了一个比当前任务更早的任务,schedule中的notify会将我们这里的带时间的wait唤醒,然后重新获取队列中的队首任务
3.4.3到达执行时间执行任务
if(System.currentTimeMillis()<task.getTime()){lock.wait(task.getTime()-System.currentTimeMillis());}else {task.run();queue.poll();}
1.这里使用else,也就是当当前系统时间大于等于任务执行的时间,执行任务
2.如果不使用else,当在等待过程中,新插入一条任务,那么就会解除阻塞,执行run和poll,从而导致程序出错
task.run方法需要我们在TimerTask类中进行实现
public void run(){task.run();}
4.整体的一个代码:
package Demo4;import java.util.PriorityQueue;class TimerTask implements Comparable<TimerTask>{private Runnable task;private long time;public TimerTask(Runnable task, long time) {this.task = task;this.time = time;}public void run(){task.run();}public long getTime() {return time;}@Overridepublic int compareTo(TimerTask o) {return (int)(this.time-o.time);}
}class Timer{private PriorityQueue<TimerTask>queue=new PriorityQueue<>();Object lock=new Object();public void schedule(Runnable task,long delay){synchronized (lock){TimerTask timerTask=new TimerTask(task, System.currentTimeMillis()+delay);queue.offer(timerTask);lock.notify();}}public Timer() {Thread t=new Thread(()->{while(true){try {synchronized (lock){while(queue.isEmpty()){lock.wait();}TimerTask task=queue.peek();if(System.currentTimeMillis()<task.getTime()){lock.wait(task.getTime()-System.currentTimeMillis());}else {
task.run();
queue.poll();}}} catch (InterruptedException e) {throw new RuntimeException(e);}}});t.start();}}public class Main10 {public static void main(String[] args) {Timer timer=new Timer();timer.schedule(new Runnable() {@Overridepublic void run() {System.out.println("hello 3000");}},3000);timer.schedule(new Runnable() {@Overridepublic void run() {System.out.println("hello 2000");}},2000);timer.schedule(new Runnable() {@Overridepublic void run() {System.out.println("hello 1000");}},1000);}
}
完结:
相关文章:
手搓一个定时器
目录 1.什么是定时器 2.计时器的使用 3.手搓定时器 3.1定义一个TimerTask类 3.2定义一个Timer类 3.3实现schedule方法 3.4实现Timer的构造方法 3.4.1随时随地查看优先级队列中是否有任务要执行 3.4.2获取队首任务,并判断是否到执行时间 3.4.3到达执行时间…...
AI提示词工程优化Prompt-GPT使用手册(科普一键收藏史上最强攻略)
Prompt(提示),最初是 NLP 研究者为下游任务设计出来的一种任务专属的输入形式或模板。在 ChatGPT 引发大语言模型新时代之后,Prompt 指与大模型交互输入的代称。 随着大模型的进展,Prompt Engineering是一个持久的探索过程。 目录 什么是提示…...
【数据结构】快速排序(三种实现方式)
目录 一、基本思想 二、动图演示(hoare版) 三、思路分析(图文) 四、代码实现(hoare版) 五、易错提醒 六、相遇场景分析 6.1 ❥ 相遇位置一定比key要小的原因 6.2 ❥ 右边为key,左边先走 …...
利用前向勾子获取神经网络中间层的输出并将其进行保存(示例详解)
代码示例: # 激活字典,用于保存每次的中间特征 activation {}# 将 forward_hook 函数定义在 upsample_v2 外部 def forward_hook(name):def hook(module, input, output):activation[name] output.detach()return hookdef upsample_v2(in_channels, o…...
CTF-RE 从0到N: S盒
S盒(Substitution Box) 是密码学中的一种替换表,用于对输入数据进行非线性变换,以增加加密过程的复杂性。它主要用于对称加密算法中(例如AES、DES),作为加密轮次的一部分,对输入字节…...
MT-Pref数据集:包含18种语言的18k实例,涵盖多个领域。实验表明它能有效提升Tower模型在WMT23和FLORES基准测试中的翻译质量。
2024-10-10,由电信研究所、里斯本大学等联合创建MT-Pref数据集,它包含18种语言方向的18k实例,覆盖了2022年后的多个领域文本。通过在WMT23和FLORES基准测试上的实验,我们展示了使用MT-Pref数据集对Tower模型进行对齐可以显著提高翻…...
【C++ 真题】B2099 矩阵交换行
矩阵交换行 题目描述 给定一个 5 5 5 \times 5 55 的矩阵(数学上,一个 r c r \times c rc 的矩阵是一个由 r r r 行 c c c 列元素排列成的矩形阵列),将第 n n n 行和第 m m m 行交换,输出交换后的结果。 输入格式 输入共 6 6 6 …...
AAPL: Adding Attributes to Prompt Learning for Vision-Language Models
文章汇总 当前的问题 1.元标记未能捕获分类的关键语义特征 如下图(a)所示, π \pi π在类聚类方面没有显示出很大的差异,这表明元标记 π \pi π未能捕获分类的关键语义特征。我们进行简单的数据增强后,如图(b)所示,效果也是如…...
MySQLDBA修炼之道-开发篇(一)
三、开发基础 1. 数据模型 1.1 关系数据模型介绍 关于NULL 如果某个字段的值是未知的或未定义的,数据库会提供一个特殊的值NULL来表示。NULL值很特殊,在关系数据库中应该小心处理。例如查询语句“select*from employee where 绩效得分<85 or>绩…...
Spring MVC 知识点全解析
Spring MVC 知识点全解析 Spring MVC 是一个基于 Java 的请求驱动的 Web 框架,属于 Spring 框架的一部分,广泛用于构建企业级 Web 应用程序。本文将详细阐述 Spring MVC 的核心知识点,包括其工作原理、关键组件、配置、请求处理、数据绑定、…...
python 基于FastAPI实现一个简易的在线用户统计 服务
简易在线用户统计服务 概述 这是一个基于Python的FastAPI框架实现的服务,用于统计客户端的心跳信息,并据此维护在线用户列表以及记录活跃用户数。 功能特性 心跳接收:接受来自客户端的心跳包,以更新客户端的状态。在线用户统计…...
glibc中xdr的一个bug
本人在64位linux服务器上(centos7),发现xdr_u_long这个函数有个bug,就是数字的范围如果超过unsigned int的最大值(4294967295)时,xdr_u_long失败。 这个场景主要用在unix时间戳上面,比如一款软件,设置有效期为100年。…...
Android Framework定制sim卡插入解锁pin码的界面
文章目录 手机设置SIM卡pin码一、安卓手机二、苹果手机 Android Framework中SIM卡pin码代码定位pin码提示文本位置定位pin码java代码位置 定制pin码framework窗口数字按钮 手机设置SIM卡pin码 设置 SIM 卡 PIN 码可以提高手机的安全性,防止他人在未经授权的情况下使…...
cc2530 Basic RF 讲解 和点灯讲解(1_1)
1. Basic RF 概述 Basic RF 是 TI 提供的一套简化版的无线通信协议栈,旨在帮助开发者快速搭建无线通信系统。它基于 IEEE 802.15.4 标准的数据包收发,但只用于演示无线设备数据传输的基本方法,不包含完整功能的协议。Basic RF 的功能限制包括…...
Android H5页面性能分析策略
文章目录 引言一、拦截资源加载请求以优化性能二、通过JavaScript代码监控资源下载速度三、使用vConsole进行前端性能调试四、使用Chrome DevTools调试Android端五、通过抓包分析优化网络性能六、总结 引言 在移动应用开发中,H5页面的性能直接影响到用户体验。本文…...
【前端面试】Typescript
Typescript面试题目回答 Typescript有哪些常用类型? Typescript的常用类型包括: 基本类型:boolean(布尔类型)、number(数字类型)、string(字符串类型)。特殊类型:nul…...
程序语言的内存管理:垃圾回收GC(Java)、手动管理(C语言)与所有权机制(Rust)(手动内存管理、手动管理内存)
文章目录 程序语言的内存管理:垃圾回收、手动管理与所有权机制引言一、垃圾回收机制(GC)(Java)1. 什么是垃圾回收机制2. 垃圾回收的工作原理3. 优点与缺点4. 示例代码 二、手动管理内存的分配和释放(C语言&…...
研究生论文学习记录
文献检索 检索论文的网站 知网:找论文,寻找创新点paperswithcode :这个网站可以直接找到源代码 直接再谷歌学术搜索 格式:”期刊名称“ 关键词 在谷歌学术搜索特定期刊的关键词相关论文,可以使用以下几种方法&#…...
毕业设计选题:基于Django+Vue的图书馆管理系统
开发语言:Python框架:djangoPython版本:python3.7.7数据库:mysql 5.7数据库工具:Navicat11开发软件:PyCharm 系统展示 系统首页 图书馆界面 图书信息界面 个人中心界面 后台登录界面 管理员功能界面 用户…...
#网络安全#NGSOC与传统SOC的区别
NGSOC是Next Generation Security Operation Center(下一代安全运营中心)的缩写。 NGSOC安全运营服务基于态势感知与安全运营平台来开展监测分析等一系列的服务工作,旨在通过专业、高效的运营服务工作,帮助用户尽可能发挥NGSOC作…...
别再手动算归一化了!用Origin9.1的‘列公式’功能一键搞定数据预处理
用Origin9.1列公式功能高效实现数据归一化:从原理到实战 科研数据处理中,归一化是消除量纲影响、提升分析结果可比性的关键步骤。传统手动计算不仅耗时费力,还容易因公式输入错误导致结果偏差。Origin9.1的"列公式"功能(…...
告别并行接口:手把手教你用Stm32F4的SPI高效读取AD7606八通道数据
告别并行接口:手把手教你用Stm32F4的SPI高效读取AD7606八通道数据 在嵌入式系统设计中,AD7606作为一款高性能八通道16位ADC芯片,常被用于电力监测、工业控制等需要多通道高精度采样的场景。传统方案往往依赖其并行接口实现数据读取ÿ…...
【音频精修】Melodyne 核心工具实战:从音高微调到节奏重塑
1. Melodyne入门:音频精修的瑞士军刀 第一次打开Melodyne时,我完全被它那些密密麻麻的音符块吓到了。这玩意儿看起来比钢琴卷帘窗还复杂,但用顺手后才发现,它简直是拯救车祸现场录音的神器。作为业内公认的音高校正标杆࿰…...
ABAP 7.40+新语法实战:从传统代码到现代编程范式的重构
1. ABAP 7.40新语法带来的编程革命 十年前我刚接触ABAP时,代码风格还停留在SAP R/3时代的传统写法。每次看到满屏的DATA声明、LOOP...ENDLOOP和APPEND语句,就像在看上世纪90年代的编程教科书。直到ABAP 7.40版本发布,这个被称为"ABAP语言…...
英雄联盟Akari助手:5大核心功能提升你的游戏体验终极指南
英雄联盟Akari助手:5大核心功能提升你的游戏体验终极指南 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power 🚀. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit 你是否厌倦了在英雄联盟对…...
5个关键技巧:让魔兽争霸III在现代Windows系统流畅运行
5个关键技巧:让魔兽争霸III在现代Windows系统流畅运行 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 还在为魔兽争霸III在Windows 10/11上…...
别再死记硬背了!用Python代码动画演示组合数11个核心性质(附完整源码)
用Python动画拆解组合数:11个核心性质的动态演绎 数学公式总是让人望而生畏?当组合数学遇上Python动画,抽象概念瞬间变得鲜活起来。这不是又一篇枯燥的公式推导文章,而是一场用代码演绎数学之美的视觉盛宴。我们将用matplotlib和…...
如何快速解锁中兴光猫:zteOnu工具的完整指南
如何快速解锁中兴光猫:zteOnu工具的完整指南 【免费下载链接】zteOnu A tool that can open ZTE onu device factory mode 项目地址: https://gitcode.com/gh_mirrors/zt/zteOnu 中兴光猫工厂模式解锁神器zteOnu是一款专为网络爱好者设计的开源工具ÿ…...
3分钟掌握清华PPT模板:免费打造专业学术演示文稿的终极方案
3分钟掌握清华PPT模板:免费打造专业学术演示文稿的终极方案 【免费下载链接】THU-PPT-Theme 清华主题PPT模板 项目地址: https://gitcode.com/gh_mirrors/th/THU-PPT-Theme 还在为学术汇报、毕业答辩或重要演讲的PPT设计而头疼吗?清华大学视觉设计…...
基于花镇电子与出门问问的第三方ASR语音识别算法在博通SOC上的实现
基于华镇电子与出门问问的第三方ASR语音识别算法在博通SOC上的实现1 ASR架构2...
