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;包括目标的反射、杂波…

usr/bin/env: ‘bash\r‘: No such file or directory

执行docker报错 这种错误是由于windows下执行linux的shell文件&#xff0c;格式不对导致 去ubuntu下安装dos2unix sudo apt-get install dos2unix 切换到对应的目录下&#xff0c;对shell文件进行格式化 dos2unix xxx.sh

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

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

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

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

在linux上面使用shell脚本统计MYSQL数据情况

本公司涉及到一部分数据推送的业务&#xff0c;然后因为是配置数据传输任务的方式做的&#xff0c;但是有时候数据任务会出现问题&#xff0c;可能不推送等等情况&#xff0c;所以需要有个程序监控是否数据推送完成&#xff0c;简单就是检测规则就是定时跑源数据表和推送目标表…

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

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的原理&#…

“error LNK1169: 找到一个或多个多重定义的符号”的解决方法

问题描述如下&#xff1a; 有 三个源文件&#xff0c;A.h、B.cpp、C.cpp。 A.h是头文件&#xff0c;其中声明了三个变量a1、a2、 a3。 B.cpp是A.h中所声明的类的实现源代码&#xff0c;C.cpp是主程序文件。B.cpp和C.cpp中均包含头文件 A.h。 在编译时&#xff0c;编译能够通…

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

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

YoloV8改进策略:双动态令牌混合器(D-Mixer)的TransXNet,实现YoloV8的有效涨点

摘要 双动态令牌混合器(D-Mixer),一种输入依赖的方式聚合全局信息和局部细节。D-Mixer通过分别在均匀分割的特征片段上应用有效的全局注意力模块和输入依赖的深度卷积,使网络具有强大的归纳偏差和扩大的有效感受野。使用D-Mixer作为基本构建块设计了TransXNet,这是一种新…

STM32——超声波传感器

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

Java实现Leetcode题(栈和队列)

Leetcode232&#xff08;用栈实现队列&#xff09; package stack_queue;import java.util.Stack;public class Leetcode232 {public static void main(String[] args) {MyQueue myQueue new MyQueue();myQueue.push(1);myQueue.push(2);System.out.print(myQueue.peek());Sy…

基于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的…

uniapp微信小程序点击保存图片

一&#xff1a;需要用到的API 1.uni.uploadFile(OBJECT) 将本地资源上传到开发者服务器 uni.uploadFile(OBJECT) | uni-app官网 2. uni.saveImageToPhotosAlbum(OBJECT) 保存图片到系统相册。 uni.chooseImage(OBJECT) | uni-app官网 注意&#xff1a;微信小程序在2023年…

【参数汇总】mysql服务端/客户端常见优化参数

mysql服务端参数 1、innodb_buffer_pool_size &#xff08;innodb索引buffer pool缓冲区大小&#xff09; 默认大小为128M&#xff0c; 官方推荐其配置为系统内存的 50% 到 75% 。 一般innodb_buffer_pool_size要结合以下两个参数来设置&#xff1a; innodb_buffer_pool_ch…

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

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

本地部署 Qwen-Audio-Chat

本地部署 Qwen-Audio-Chat Qwen-Audio-Chat 介绍Qwen-Audio Github 地址部署 Qwen-Audio-Chat安装 ffmpeg克隆代码库创建虚拟环境使用 pip 安装 pytorch使用 pip 安装依赖使用 ModelScope运行 Web UI Qwen-Audio-Chat 介绍 Qwen-Audio-Chat是通用语音多模态大规模语言模型&…

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; 欢迎点赞…