JavaEE之线程(9) _定时器的实现代码
前言
定时器也是软件开发中的一个重要组件. 类似于一个 “闹钟”。 达到一个设定的时间之后,就执行某个指定好的代码,比如:
在受上述场景中,当客户端发出去请求之后, 就要等待响应,如果服务器迟迟没有响应,也不清楚,这个请求就没发过去? 响应丢了?服务器出问题了?
对于客户端来说,不能无限的等,需要有一个最大的期限,到达这个最大的期限之后,是重新再发一遍,还是彻底放弃,还是什么其他的方式。
类似于以上场景就需要用到定时器。
一、标准库中的定时器
在标准库中提供了一个 Timer 类,它的核心方法为 schedule 。
schedule方法 包含两个参数:
- 第一个参数指定即将要执行的任务代码;
- 第二个参数指定多长时间之后执行 (单位为毫秒)。
参考代码如下:
Timer timer = new Timer();
timer.schedule(new TimerTask() {@Overridepublic void run() {System.out.println("hello");}
}, 3000);
二、实现一个定时器
在实现一个定时器(Timer)前,我们需要考虑三个问题
- Timer 中需要有一个线程,扫描任务是否到时间,可以执行了;
- 需要有一个数据结构,把所有的任务都保存起来;
- 还需要创建–人类,通过类的对象来描述一个任务(至少要包含任务内容和时间);
2.1 定时器的构成
1. 一个带优先级的阻塞队列;
为社么要带优先级呢?
因为阻塞队列中的任务都有各自的执行时刻 (delay)。最先执行的任务一定是 delay 最小的。使用带优先级的队列就可以高效的把这个 delay 最小的任务找出来。
2. 队列中的每个元素是一个 Task 对象;
3.Task 中带有一个时间属性, 队首元素就是即将要执行的对象;
4. 同时有一个 worker 线程一直扫描队首元素, 看队首元素是否需要执行。
2.2实现过程
定时器的完整实现代码:
package Timer9;import java.util.PriorityQueue;/*** @author Zhang* @date 2024/5/1016:43* @Description:*/
//通过这个类,描述了一个任务
class MyTimerTak implements Comparable<MyTimerTak>{//要有一个要执行的任务private Runnable runnable;//执行任务的时间private long time;// 此处的delay,就是schedule方法传入的相对时间public MyTimerTak(Runnable runnable, long delay ) {this.runnable = runnable;this.time = System.currentTimeMillis()+delay;}@Overridepublic int compareTo(MyTimerTak o) {//这样写,就是让队首元素是最小时间的值return (int)(this.time - o.time);}public long getTime(){return time;}public Runnable getRunnable(){return runnable;}
}//自己的定时器
class MyTimer{//使用一个数据结构,保存所有要安排的任务PriorityQueue<MyTimerTak> queue = new PriorityQueue<>();//使用这个ui想作为锁对象private Object locker = new Object();public void schedule(Runnable runnable,long delay){synchronized (locker){queue.offer(new MyTimerTak(runnable, delay));}}//扫描线程public MyTimer(){//创建一个线程Thread t = new Thread(()->{while (true){try{synchronized (locker){//不要使用if 作为wait的判定条件,应该使用while//使用 while 的目的是为了在 wait被唤醒的时候,再次确认一下条件while(queue.isEmpty()){//使用wait等待//这里的wait,需要另外的线程唤醒//添加了新任务,就会被唤醒locker.wait();}MyTimerTak tak = queue.peek();//比较当前的队首是否可以执行元素long curTime = System.currentTimeMillis();if (curTime >= tak.getTime()){//当前时间已经达到了人物事件,就可以执行任务了tak.getRunnable().run();//任务执行结束,就可以从队列中删除了queue.poll();}else {//当前时间还没达到任务时间,暂时不执行任务locker.wait(tak.getTime() - curTime);}}} catch(InterruptedException e){e.printStackTrace();}}});t.start();}}
定时器的调用和演示:
public class Demo2 {public static void main(String[] args) {MyTimer timer = new MyTimer();timer.schedule(new Runnable() {@Overridepublic void run() {System.out.println("3000");}},3000);timer.schedule(new Runnable() {@Overridepublic void run() {System.out.println("2000");}},2000);timer.schedule(new Runnable() {@Overridepublic void run() {System.out.println("1000");}},1000);}
}
总结
以上就是今天要讲的内容,本文仅仅简单介绍定时器的使用场景,标准库中的定时器,定时器的实现代码。
相关文章:

JavaEE之线程(9) _定时器的实现代码
前言 定时器也是软件开发中的一个重要组件. 类似于一个 “闹钟”。 达到一个设定的时间之后,就执行某个指定好的代码,比如: 在受上述场景中,当客户端发出去请求之后, 就要等待响应,如果服务器迟迟没有响应&…...
纯前端实现将页面数据下载word文档中【包括图片,echarts图,表格,和对话 内容】
亲测真实有效 导出word步骤 在Vue中导出Word文档,可以使用第三方库file-saver和html-docx-js。首先需要安装这两个库: npm install file-saver html-docx-js --save "html-docx-js": "0.3.1","file-saver": "2.0.5…...

JavaSE——类和对象(二)~~封装
目录 一.封装 二.封装扩展之包 三.static成员 四. 代码块 五. 内部类(重要) 大家好呀,我是北纬,接着上节我们继续讲解Java中关于类和对象的相关知识,今天着重给大家介绍一下关于面向对象程序的特性之一——封装。…...
头歌OpenGauss数据库-I.复杂查询第9关:交换性别
任务描述 本关任务:给定一张 tb_Salary 表,如下所示,有 m 男性 和 f 女性的值。交换所有的 f 和 m 值(例如,将所有 f 值更改为 m,反之亦然)。 idnamesexsalary1Elonf70002Donnyf80003Careym60…...

冷干机使用中的注意事项
冷干机使用中的注意事项 使用冷干机时,以下是几个注意事项: 安装位置:选择一个通风良好、温度适宜的位置安装冷干机。确保周围环境没有过多的灰尘、腐蚀性气体或其他污染物,以免对冷干机的正常运行和寿命产生不利影响。 电源要求…...

OpenFeign微服务调用组件使用
前言:OpenFeign是可以跨服务、跨进程的调用方式。 什么是Feign Feign是Netflix开发的声明式、模版化的HTTP客户端。 优势: Feign可以做到使用 HTTP 请求远程服务时就像调用本地方法一样的体验,开发者完全感知不到这是远程方法,更感知不到这…...

文心智能体,零代码构建情感表达大师智能体
前言 随着智能体技术的突飞猛进,各行各业正迎来前所未有的变革与机遇。智能体,作为人工智能领域的重要分支,以其自主性、智能性和适应性,正逐步渗透到我们生活的每一个角落,成为推动社会进步和科技发展的新动力。 为了…...
es6
# 一、变量提升性 let和const没有变量提升性 console.log(str) 》undefined var str 你好console.log(num) 报错 let num 你好console.log(a) 报错 const a 你好function demo (){ let n 2; if(true){ let n 1; } console.log(n) //2 const 也是一样 var 是1 } demo()const…...
「贪心算法」柠檬水找零
力扣原题链接,点击跳转。 假设你的手里没有钱。你要卖柠檬水,每杯5块钱。每个顾客有可能会给你5块钱、10块钱或20块钱,你要拿手中的钱找零。如何判断你能否成功找零呢? 如果一上来就有顾客花10块钱或20块钱,你手中没…...

ssm139选课排课系统的设计与开发+vue
选课排课系统的设计与开发vue 摘 要 互联网的普及,改变了人们正常的生活学习及消费习惯,而且也大大的节省了人们的时间,由于各种管理系统都再不断的增加,更方便了用户,也改良了很多的用户习惯。对于选课排课系统查询…...

Python使用virtualenv创建虚拟环境
目录 第一步:安装virtualenv 第二步:选择一个文件夹用来放所创建的虚拟环境 第三步:创建虚拟环境 第四步:激活虚拟环境 第五步:退出虚拟环境 第六步:测试安装django 前提:你得有个python环…...
LuatOS-Air二次开发学习
LuatOS简介 在介绍LuatOS-Air之前,先介绍下LuatOS。 LuatOS是合宙自研的嵌入式操作系统。覆盖各类物联网应用场景,可运行于4G Cat.1/MCU/NB-IoT/2G/Wi-Fi/蓝牙等等不同的物联网主控芯片。通过完善的嵌入式操作系统LuatOS,使得物联网主控CPU更…...

【Linux】关于获取进程退出状态中的core dump标志补充
通过 wait/waitpid 可以获取子进程的退出状态, 从而判断其退出结果. 记录退出状态的 int 变量 status 的使用情况如下图所示: 如果是收到信号终止的话, 低 7 位为收到的终止信号, 而低第 8 位为 core dump 标志, core dump 标志有什么用呢? core dump 标志只存 0/1, 表示是否…...

Vitis HLS 学习笔记--抽象并行编程模型-控制驱动与数据驱动
目录 1. 简介 2. Takeaways 3. Data-driven Task-level Parallelism 3.1 simple_data_driven 示例 3.2 分析 hls::task 类 3.3 分析通道(Channel) 3.4 注意死锁 4. Control-driven Task-level Parallelism 4.1 理解控制驱动的 TLP 4.2 simple_control_driven 示例 4…...

Python爬取B站视频:封装一下
📚博客主页:knighthood2001 ✨公众号:认知up吧 (目前正在带领大家一起提升认知,感兴趣可以来围观一下) 🎃知识星球:【认知up吧|成长|副业】介绍 ❤️如遇文章付费,可先看…...

Android Low Storage机制之DeviceStorageMonitorService
一、Android 版本 Android 13 二、low storage简介(DeviceStorageMonitorService) 设备存储监视器服务是一个模块,主要用来: 1.监视设备存储(“/ data”)。 2.每60秒扫描一次免费存储空间(谷歌默认值) 3.当设备的存储空间不足…...

1105: 交换二叉树的孩子结点
解法: #include<iostream> using namespace std; struct treeNode {char val;treeNode* left, * right;treeNode(char x) :val(x), left(NULL), right(NULL) {}; }; treeNode* buildtree() {char ch;cin >> ch;if (ch #) return NULL;treeNode* r ne…...
TensorFlow.js
什么是 TensorFlow.js? TensorFlow.js 是一个基于 JavaScript 的机器学习库,它是 Google 开发的 TensorFlow 的 JavaScript 版本。它使得开发者能够在浏览器中直接运行机器学习模型,而不需要依赖于后端服务器或云服务。TensorFlow.js 的主要…...

131. 面试中关于架构设计都需要了解哪些内容?
文章目录 一、社区系统架构组件概览1. 系统拆分2. CDN、Nginx静态缓存、JVM本地缓存3. Redis缓存4. MQ5. 分库分表6. 读写分离7. ElasticSearch 二、商城系统-亿级商品如何存储三、对账系统-分布式事务一致性四、统计系统-海量计数六、系统设计 - 微软1、需求收集2、顶层设计3、…...

Nodejs+Websocket+uniapp完成聊天
前言 最近想做一个聊天,但是网上的很多都是不能实现的,要么就是缺少代码片段很难实现websocket的链接,更别说聊天了。自己研究了一番之后实现了这个功能。值得注意的是,我想在小程序中使用socket.io,不好使࿰…...
MAC上怎么进入隐藏目录
在Mac上,由于系统保护的原因,一些系统目录如/usr默认是隐藏的,但可以通过以下方法进入: 方法一:使用Finder的“前往文件夹”功能 打开Finder。使用快捷键Command Shift G,或者在菜单栏中选择“前往”-“…...
kernel内核和driver驱动的区别
“kernel”和“driver”虽然都跟操作系统和硬件有关,但它们指的是不同的东西。 1. Kernel(内核) 定义:操作系统的核心组件,是操作系统中负责管理系统资源和硬件的最底层软件。 职责: 管理CPU调度ÿ…...
CSS篇-3
1. CSS 中哪些样式可以继承?哪些不可以继承? 可继承的样式: 与字体相关的样式,如:font-size、font-family、color 列表样式:list-style(如 UL、OL 的 list-style-type) 不可继承的样式: 与布局和尺寸相关的样式,如:border、padding、margin、width、height 总结: …...
Linux 中 m、mm、mmm 函数和 make 的区别
在 Linux 内核开发和 Android 开发中,构建系统通常使用 make 命令来编译和构建项目。而在 Android 开发环境中,还有 m、mm 和 mmm 等命令,这些命令是 Android 构建系统的一部分,提供了更高效和便捷的构建方式。以下将详细介绍这些…...

秋招Day12 - 计算机网络 - 网络综合
从浏览器地址栏输入URL到显示网页的过程了解吗? 从在浏览器地址栏输入 URL 到显示网页的完整过程,并不是一个单一的数据包从头到尾、一次性地完成七层封装再七层解析的过程。 而是涉及到多次、针对不同目的、与不同服务器进行的、独立的网络通信交互&a…...

输入ifconfig,发现ens33不见了,无法连接至虚拟机
输入ifconfig,发现ens33不见了,无法连接至虚拟机 输入ifconfig,发现ens33不见了,无法连接至虚拟机 输入ifconfig,发现ens33不见了,无法连接至虚拟机 当输入ifconfig,发现少了ens33,无…...

el-tree拖拽事件,限制同级拖拽,获取拖拽后节点的前后节点,同级拖拽合并父节点name且子节点加入目标节点里
node-drag-start:开始拖拽节点时触发(按下鼠标按钮),无论是否允许放置,此事件都会触发。 allow-drop 返回 true 才能触发@node-drag-end="handleDragend"、@node-drop="handleDrop"; (1)allow-drop:动态控制是否允许放置; (2)node-dr…...

pikachu靶场通关笔记08 XSS关卡04-DOM型XSS
目录 一、XSS原理 二、DOM型XSS 三、源码分析 1、进入靶场 2、XSS探测 3、源码分析 四、渗透实战 1、Payload1 2、Payload2 3、Payload3 本系列为通过《pikachu靶场通关笔记》的XSS关卡(共10关)渗透集合,通过对XSS关卡源码的代码审计找到XSS风…...

网络系统中安全漏洞扫描为何重要?扫描啥?咋扫描?
在网络系统中,安全漏洞扫描占据着极其重要的位置,这一环节有助于我们发现并消除潜在的安全隐患,进而提高网络安全防护的等级。下面,我将对此进行详尽的说明。 基本概念 漏洞扫描技术可以揭示并评估网站存在的安全风险࿰…...

基于51单片机的音乐盒汽车喇叭调音量proteus仿真
地址: https://pan.baidu.com/s/1l3CSSMi4uMV5-XLefnKoSg 提取码:1234 仿真图: 芯片/模块的特点: AT89C52/AT89C51简介: AT89C51 是一款常用的 8 位单片机,由 Atmel 公司(现已被 Microchip 收…...