JavaEE07 定时器的使用和模拟实现

前言

前面我们聊了很多关于阻塞队列,单例模式等的应用,今天我们就来聊聊定时器的功能和模拟实现,其实定时器的实现在我们的日常生活中也很常见,比如说平常创建一些定时任务,定时开关机,定时去发表一篇qq空间等等,今天我们就来简单实现一个定时器.

1.JVM提供的定时器的使用

在自己实现之前,让我们先去看看JVM给我们提供好的定时器是如何使用的吧

以下是一个简单的实例

我们首先创建了一个定时器对象,定时器对象里面有一个schedule方法,这个方法最常用的是有两个参数组成的,一个是task任务,另一个是delay:相对现在的时间延迟多久发生这个事件,单位是毫秒,我们发现定时任务做完这个进程并没有结束,这是因为你没有让他结束,只能手动结束

timer也提供了一个cancel方法来执行这个操作.

其实这是因为定时器内部存在一个扫描线程会扫描任务队列,这个线程属于前台线程,会阻止进程的结束.

下面附上执行代码

public static void main(String[] args) {Timer timer = new Timer();TimerTask task = new TimerTask() {@Overridepublic void run() {System.out.println("确实挺不错的");}};timer.schedule(task,2000);TimerTask task1 = new TimerTask() {@Overridepublic void run() {System.out.println("你们觉得怎么样");}};timer.schedule(task1,1000);}

2.定时器的模拟实现

首先MyTimer中应该有一个阻塞队列,一个扫描线程和一个schedule方法

private Thread t = null;
private PriorityQueue<MyTimerTask> queue = new PriorityQueue<>();
public void schedule(Runnable runnable,long delay){synchronized (lock){MyTimerTask task = new MyTimerTask(runnable,delay);queue.offer(task);lock.notify();}}

然后我们再想一下task的实现,首先应该有一个执行时间,由于要放入优先级队列里来实现定时器的功能,所以我们的task也需要实现compareable接口或compartor接口,我们这里使用compareable接口来实现.

然后我们是要使用扫描线程来操作和执行这个任务,所以我们应该实现Runnable接口或者持有这个接口.此时你可以理解runnable的实现就是我的任务需要做什么

我们还要提供一个run方法给下面的扫描线程来执行

class MyTimerTask implements Comparable<MyTimerTask>{//什么时间运行这个任务  -- ms级别的时间戳private long time;private Runnable runnable;//delay期望是相对时间public MyTimerTask(Runnable runnable,long delay){this.runnable = runnable;this.time = System.currentTimeMillis() + delay;}public void run(){runnable.run();}//实现比较,这个地方记不得o1-o2 就去试一试@Overridepublic int compareTo(MyTimerTask o) {return (int)(this.time - o.time);}public long getTime(){return time;}}

下面我们继续实现我们的定时器,我们在构造方法内部实现扫描线程对阻塞队列的拿取任务执行任务的操作,取到任务就执行,遇见空队列我们就进行阻塞,又加入任务我们就进行唤醒,于是就有了一把锁来完成对阻塞队列的执行和添加任务的操作

这里也是先获取一下距离当前时间最短的任务,看是否到时间,到达就立即取出并执行,没到就阻塞(最多阻塞时间为预计时间减去当前时间,这是因为在阻塞的期间也可能有更新的任务添加进来)

public  MyTimer(){//扫描线程t = new Thread(()->{while(true){//引入锁目的是保护队列,所以得把队列的操作保护起来synchronized (lock){while(queue.isEmpty()){try {lock.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}}MyTimerTask task =  queue.peek();//获取当前时间long curTime = System.currentTimeMillis();if(curTime >= task.getTime()){queue.poll();task.run();}else{//时间还没到也需要等待,一直执行while循环判断,称之为忙等//这一般是一个不太好的做法//使用sleep也不太合适//万一在sleep过程中有线程调用了schedule//而且sleep也不能解锁try {//新任务来被唤醒一次//根据新的任务重新计算等待时间//或者是wait过程中没有新的任务,但是时间到了lock.wait(task.getTime() - curTime);} catch (InterruptedException e) {throw new RuntimeException(e);}}}}});t.start();

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/217993.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

现代雷达车载应用——第2章 汽车雷达系统原理 2.3节

经典著作&#xff0c;值得一读&#xff0c;英文原版下载链接【免费】ModernRadarforAutomotiveApplications资源-CSDN文库。 2.3 信号模型 雷达的发射机通常发出精心设计和定义明确的信号。然而&#xff0c;接收到的返回信号是多个分量的叠加&#xff0c;包括目标的反射、杂波…

数字化转型对企业有什么好处?

引言 数字化转型已经成为当今商业领域中的一股强大力量&#xff0c;它不仅仅是简单的技术更新&#xff0c;更是企业发展的重要战略转变。随着科技的迅猛发展和全球化竞争的加剧&#xff0c;企业们正在积极探索如何将数字化的力量融入到他们的运营和战略中。 数字化转型不仅是传…

9:00面试,9:05就出来了,问的问题有点变态。。。

从小厂出来&#xff0c;没想到在另一家公司又寄了。 到这家公司开始上班&#xff0c;加班是每天必不可少的&#xff0c;看在钱给的比较多的份上&#xff0c;就不太计较了。没想到12月一纸通知&#xff0c;所有人不准加班&#xff0c;加班费不仅没有了&#xff0c;薪资还要降40…

抖音发布最新公告,清退所有全国本地生活服务商.

11月27日&#xff0c;抖音发布最新公告&#xff0c;一文公告让本地生活服务商行业鬼哭狼嚎&#xff0c;公告很明确&#xff0c;只保留了区域服务商&#xff0c;全国性的所有服务商被清退。 我们再来看看抖音本地生活的前世今生&#xff0c;最开始的时候抖音本地生活全部是自己部…

QT用户管理效果预览

用户管理效果 QT 用户管理 GITHUB网站 QT版本 CMakeList.txt find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Sql REQUIRED) target_link_libraries(tableView PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Sql)GitHub代码获取链接 GitHub代码获取链接

Java stream流toMap使用过程中空指针问题

Java8中stream操作list时常见的一个错误&#xff1a; 排查原因&#xff1a; 定位到代码中发现从数据查询是存在数据的 排查stream前对象为null的情况&#xff0c;那问题只能出现在toMap这里了 我们需要知道toMap是怎么帮我们封装数据的&#xff0c;先搞明白toMap的原理&#…

用在半导体CST材料搬运AGV小车的RFID

RFID&#xff08;RadioFrequencyIdentification&#xff09;&#xff0c;又称无线射频识别技术&#xff0c;可通过射频信号进行非接触式的识别目标&#xff0c;近些年来被广泛应用在半导体制造业中&#xff0c;用于半导体行业的晶圆存储柜、电子货架、硅晶片清洗、半导体天车等…

STM32——超声波传感器

需求&#xff1a; 使用超声波测距&#xff0c;当手离传感器距离小于 5cm 时&#xff0c; LED1 点亮&#xff0c;否则保持不亮状态 接线&#xff1a; 定时器配置&#xff1a; 使用 TIM2 &#xff0c;只用作计数功能&#xff0c;不用作定时。 将 PSC 配置为 71 &#xff0c;…

基于K-means与CNN的遥感影像分类方法

基于K-means与CNN的遥感影像分类 一、引言 1.研究背景 航天遥感技术是一种通过卫星对地观测获取遥感图像信息数据的技术&#xff0c;这些图像数据在各领域都发挥着不可或缺的作用。遥感图像分类主要是根据地面物体电磁波辐射在遥感图像上的特征&#xff0c;判断识别地面物体的属…

推荐算法:HNSW【推荐出与用户搜索的类似的/用户感兴趣的商品】

HNSW算法概述 HNSW&#xff08;Hierarchical Navigable Small Word&#xff09;算法算是目前推荐领域里面常用的ANN&#xff08;Approximate Nearest Neighbor&#xff09;算法了。其目的就是在极大量的候选集当中如何快速地找到一个query最近邻的k个元素。 要找到一个query的…

【1.计算机组成与体系结构】浮点数的表示

目录 1.浮点数的表示2.运算过程3.特点 1.浮点数的表示 N尾数*基数(指数/也称为阶码) 例如&#xff1a;1.25x105 ; 1.255x103 2.运算过程 对阶>尾数计算>结果格式化 3.特点 1、一般尾数用补码&#xff0c;阶码用移码 2、阶码的位数决定数的表示范围&#xff0c;位数越…

Spring Boot 3 整合 Mybatis-Plus 动态数据源实现多数据源切换

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…

什么是循环依赖,如何解决

目录 什么是循环依赖&#xff1f; 循环依赖的原因&#xff1a; 如何解决循环依赖问题&#xff1f; 最佳实践和注意事项&#xff1a; 结论&#xff1a; 当在使用 Spring Boot 进行开发时&#xff0c;循环依赖&#xff08;Circular Dependency&#xff09;可能会成为一个常见…

广东省工业和信息化厅工业互联网处一行莅临科东软件考察调研

近日&#xff0c;广东省工业和信息化厅工业互联网处副处长郑华、广东省科学院智能制造研究所副所长曹永军等一行领导、专家莅临科东软件&#xff0c;就聚焦工业数字化转型&#xff0c;助推新型工业化高质量发展进行考察调研。 科东软件陪同郑华副处长一行参观科东软件展厅&…

学习笔记——GDB调试器

感谢B站up主 xiaobing1016 的学习视频&#xff1a;基于VSCode和CMake实现C/C开发 | Linux篇_哔哩哔哩_bilibili

Redis缓存异常问题,常用解决方案总结

前言 Redis缓存异常问题分别是&#xff1a;1.缓存雪崩。2.缓存预热。3.缓存穿透。4.缓存降级。5.缓存击穿&#xff0c;以 及对应Redis缓存异常问题解决方案。 1.缓存雪崩 1.1、什么是缓存雪崩 如果缓存集中在一段时间内失效&#xff0c;发生大量的缓存穿透&#xff0c;所有…

Appium 自动化测试 —— Appium的环境搭建与设置流程!

1、Appium 环境搭建&#xff1a; 学习 appium 最大的难处之一在于环境的安装&#xff0c;安装流程比较繁琐&#xff0c;安装的工具和步骤也较多&#xff0c;以下是基于 Windows 系统下的 Android 手机端的安装流程。就像我们在用 Selenium 进行 web 自动化测试的时候一样&…

Python键鼠控制之PyAutoGUI方法

前言 PyAutoGUI 是一个 Python 库&#xff0c;用于在桌面应用程序中自动化鼠标和键盘操作。它提供了一组简单而强大的方法&#xff0c;使得开发者可以编写脚本来模拟用户的鼠标点击、键盘输入以及屏幕截图等操作。PyAutoGUI 可以用于自动化重复性任务、测试 GUI 应用程序、创建…

如何通过3D人脸扫描设备制作一个3D超写实虚拟人?

随着虚拟技术的快速发展&#xff0c;现如今的虚拟人逐渐逼真&#xff0c;比二次元虚拟偶像更接近真人形象的3D超写实虚拟人&#xff0c;拥有着更逼真的面部表情&#xff0c;更完美地融入于虚实画面。 随着3D人脸扫描设备不断发展&#xff0c;大大降低了高难度的3D超写实虚拟人…

Django 模型操作(六)

Django通过Model操作数据库, 不管你数据库的类型是MySql或者Sqlite, Django自动帮你生成相应数据库类型的SQL语句,所以不需要关注SQL语句和类型,对数据的操作Django帮我们自动完成。只要会写Model就可以了。 django使用对象关系映射 (Object Relational Mapping, 简称ORM)框…