当前位置: 首页 > news >正文

多线程新手村4--定时器

定时器是日常开发中很常见的组件,定时器大家可能不知道是干什么的,但是定时炸弹肯定都听过,定个时间,过一段时间后bomb!!!爆炸

定时器的逻辑和这个一样,约定一个时间,这个时间到达之后,执行某个代码逻辑;定时器的常见场景有网络通信,定时邮件发送等等。

计算机网络中的“超时重传”就用到了定时器。当客户端向服务器发送消息时,服务器可能由于某些问题一直不回复,此时该怎么办呢?肯定不能无限的等,需要有一个最大的期限,当到达这个最大期限时,该放弃呢?还是重传呢?或者想别的解决办法,这时就用到了定时器。

内部库Timer

当然,不光要学会怎么使用内部库提供的定时器,我们还要自己手写一个定时器出来。

怎么写呢?

1、需要一个线程,不断扫描是否有任务到达时间,可以执行了。

2、需要一个数据结构,存储所有的任务。

3、还需要创建一个类,通过类的对象来描述一个任务(至少要包含做什么和时间)。

那么又出现一个问题,该使用什么数据结构呢?

用数组吗?不行,用数组每次扫描都要遍历所有任务,时间开销太大;

想想我们学过的数据结构,每次执行时间最小的,是的,没错,就是它,它就是--优先级队列!

优先级队列每次放入元素时都会更新顺序,保证时间最小的一定在最前面,因为我们每次可以执行的一定是时间最小的,之后的元素都不需要搜索,所以时间复杂度是O(1)。

代码如下:

package Thread;import java.util.PriorityQueue;
import java.util.Timer;
import java.util.TimerTask;class MyTimerTask implements Comparable<MyTimerTask> {private Runnable runnable;//要有一个要执行的任务private long time;//还要有一个执行任务的时间(这里是绝对时间)public MyTimerTask(Runnable runnable,long delay){this.runnable = runnable;this.time = System.currentTimeMillis() + delay;}@Overridepublic int compareTo(MyTimerTask o){return (int)(this.time - o.time);//这样的写法,就是让队首元素是最小时间的值}public long getTime(){return time;}public Runnable getRunnable(){return runnable;}
}class MyTimer{private PriorityQueue<MyTimerTask> queue = new PriorityQueue<>();private Object locker = new Object();public void schedule(Runnable runnable,long delay){synchronized (locker){queue.offer(new MyTimerTask(runnable,delay));locker.notify();}}public MyTimer(){Thread t = new Thread(() -> {while(true){try{synchronized (locker){while(queue.isEmpty()){locker.wait();}MyTimerTask task = queue.peek();long curTime = System.currentTimeMillis();if(curTime >= task.getTime()){task.getRunnable().run();queue.poll();}else{locker.wait(task.getTime() - curTime);}}} catch (InterruptedException e) {e.printStackTrace();}}});t.start();}
}public class mtime {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);System.out.println("程序开始执行");}
}

这里为什么要用wait呢?用sleep可以吗?

答案是不可以!

当我们向队列中插入元素时,会调用notify方法,这里使用wait是为了当新插入队列中的元素的时间比当前队头的元素的时间小时,就需要进行更新,重新判定一下最早的任务以及此处的等待时间。

相关文章:

多线程新手村4--定时器

定时器是日常开发中很常见的组件&#xff0c;定时器大家可能不知道是干什么的&#xff0c;但是定时炸弹肯定都听过&#xff0c;定个时间&#xff0c;过一段时间后bomb&#xff01;&#xff01;&#xff01;爆炸 定时器的逻辑和这个一样&#xff0c;约定一个时间&#xff0c;这…...

如何衡量安全阀检测的价格与价值?一文揭晓答案

安全阀作为工业设备中的重要组件&#xff0c;其性能的稳定性和可靠性直接影响着整个系统的安全运行。因此&#xff0c;对安全阀进行定期检测和维护显得尤为重要。 那么&#xff0c;安全阀检测一个需要多少钱呢&#xff1f; 在这篇文章中&#xff0c;佰德将从检测费用构成、市…...

Sectigo证书介绍以及申请流程

Sectigo (原Comodo CA)是全球SSL证书市场占有率最高的CA公司&#xff0c;目前将近40%的SSL证书用户选择了Sectigo。由于其产品安全&#xff0c;价格低&#xff0c;受到大量站长的信任和欢迎。Sectigo旗下的SSL证书品牌包括Sectigo, Positive SSL, Sectigo Enterprise等。 品牌…...

网络安全-钓鱼篇-利用cs进行钓鱼

一、环境 自行搭建&#xff0c;kill&#xff0c;Windows10&#xff0c;cs 二、原理 如图所示 三、钓鱼演示 首先第一步&#xff1a;打开System Profiler-分析器功能 选择克隆www.baidu.com页面做钓鱼 之后我们通过包装域名&#xff0c;各种手段让攻击对象访问&#xff1a;h…...

机器学习-6-对随机梯度下降算法SGD的理解

参考一文带您了解随机梯度下降(Stochastic Gradient Descent):python代码示例 参考sklearn-SGDClassifier 1 梯度下降 在机器学习领域,梯度下降扮演着至关重要的角色。梯度下降是一种优化算法,通过迭代沿着由梯度定义的最陡下降方向,以最小化函数。类似于图中的场景,可以…...

windows 11 精简版下载

Optimum 11 24H2 家庭版和专业版版本在性能、响应能力和资源使用方面相同&#xff0c;因此请下载并安装适合您笔记本电脑的正确版本或在您的 PC 上获得终极 Windows 11 24H2 体验的许可证&#xff01; • 如果您熟悉我们的 22H2 和 23H2 Optimum 11 版本&#xff0c;此版本将…...

rpm与yum扩展、命令

目录 系统安装软件方式 1、rpm方式 命令 yum方式 安装 更新和升级 查找与显示 删除程序 清除缓存 仅下载 系统安装软件方式 1、rpm方式 优点&#xff1a;无需网络安装软件 缺点&#xff1a;无法解决软件依赖 命令 rpm -ivh 安装 --nodeps忽略依赖关系 --force强…...

SpringBoot实现接口防抖的几种方案,杜绝重复提交

插&#xff1a; AI时代&#xff0c;程序员或多或少要了解些人工智能&#xff0c;前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家(前言 – 人工智能教程 ) 坚持不懈&#xff0c;越努力越幸运&#xff0c;大家…...

了解VS安全编译选项GS

缓冲区溢出攻击的基本原理就是溢出时覆盖了函数返回地址&#xff0c;之后就会去执行攻击者自己的函数&#xff1b; 针对缓冲区溢出时覆盖函数返回地址这一特征&#xff0c;微软在编译程序时使用了安全编译选项-GS&#xff1b; 目前版本的Visual Studio中默认启用了这个编译选项…...

python 垃圾回收机制

简介 在Python中&#xff0c;垃圾回收是自动管理内存的一个重要方面。Python使用了一种称为引用计数的策略来跟踪对象的引用数目。当对象的引用计数降为零时&#xff0c;Python解释器就会自动释放该对象所占用的内存空间。 除了引用计数之外&#xff0c;Python还使用了其他一…...

深度学习设计模式之组合模式

文章目录 前言一、介绍二、详细分析1.核心组成2.实现步骤3.代码示例4.优缺点优点缺点 5.使用场景 总结 前言 组合模式是将对象组合成树形结构来表现"整体/部分"层次结构&#xff0c;可以更好的实现管理操作。 一、介绍 组合设计模式又叫部分整体模式&#xff0c;将…...

C++ 网络编程

一、Reactor 网络编程模型 reactor 是一个事件处理模型。网络处理:因为用户层并不知道 IO 什么时候就绪,所以将对 IO 的处理转化为对事件的处理。网络模型构成: 非阻塞 IO:操作 IO,如果 IO 未就绪,IO 函数会立刻返回。IO 多路复用:检测多路 IO 是否就绪。工作流程: 注册…...

服务案例|网络攻击事件的排查与修复

LinkSLA智能运维管家V6.0版支持通过SNMP Trap对设备进行监控告警&#xff0c;Trap是一种主动推送网络设备事件或告警消息的方式&#xff0c;与SNMP轮询&#xff08;polling&#xff09;不同&#xff0c;具有以下几点优势&#xff1a; 1. 实时监控与快速响应 SNMP Trap能够实时…...

如何使用宝塔面板搭建Tipask问答社区网站并发布公网远程访问

文章目录 前言1.Tipask网站搭建1.1 Tipask网站下载和安装1.2 Tipask网页测试1.3 cpolar的安装和注册 2. 本地网页发布2.1 Cpolar临时数据隧道2.2 Cpolar稳定隧道&#xff08;云端设置&#xff09;2.3 Cpolar稳定隧道&#xff08;本地设置&#xff09; 3. 公网访问测试4.结语 前…...

Git学习和使用指南简单篇

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…...

HTTPS单双向认证流程详解与联想

HTTPS单向认证 HTTPS在单向认证传输的过程中会涉及到三个密钥&#xff1a; 服务端的公钥和私钥&#xff0c;用来进行非对称加密交换密钥 客户端生成的随机密钥&#xff0c;用来进行对称加密传输数据 认证过程 1.客户端向服务器发起HTTPS请求&#xff0c;连接到服务器的443端…...

防止浏览器缓存了静态的配置等文件(例如外部的config.js 等文件)

防止浏览器缓存了静态的配置文件 前言1、在script引入的时候添加随机数1.1、引入js文件1.2、引入css文件 2、通过html文件的<meta>设置防止缓存3、使用HTTP响应头&#xff1a; 前言 在实际开发中浏览器的缓存问题一直是一个很让人头疼的问题&#xff0c;尤其是我们打包时…...

【Umi】umi-max 中使用 Dva

前置介绍 Umi 是一个基于 React 的可插拔企业级前端应用框架&#xff0c;Umi 提供了一系列的插件和约定&#xff0c;使得开发者能够以约定大于配置的方式进行开发&#xff0c;同时还支持丰富的功能扩展和插件机制。 Dva 是一个基于 Redux、Redux-Saga 和 React-Router 的数据…...

Inno Setup 深入浅出-文件的显示

【1】在需要打包的文件中&#xff0c;新建一个文本文件&#xff0c;如License.txt 注意&#xff1a;中文的编码格式需要GB2312&#xff0c;否则显示乱码 【2】读取、显示文本 [Code] procedure Init_ShowLicense(); var tmpFont:TFont; begin editLicense : TMemo.C…...

数据链路层协议——以太网协议

目录 一、认识以太网 二、以太网帧格式 三、MTU 四、ARP协议 ARP协议 ARP协议格式 ARP缓存表 一、认识以太网 前面&#xff0c;我们讲到了网络层的IP协议&#xff0c;它通过目的IP&#xff0c;子网划分&#xff0c;路由表查找及其算法等方式让IP报文能够从一个主机到另一…...

Figma全中文界面解决方案:从安装到精通的实战指南

Figma全中文界面解决方案&#xff1a;从安装到精通的实战指南 【免费下载链接】figmaCN 中文 Figma 插件&#xff0c;设计师人工翻译校验 项目地址: https://gitcode.com/gh_mirrors/fi/figmaCN 作为一名中文设计师&#xff0c;你是否曾因Figma全英文界面而在操作时频繁…...

手把手教你用Strongswan App通过IKEv2 EAP认证连接Freeradius(附调试技巧)

移动端安全连接实战&#xff1a;Strongswan与Freeradius的IKEv2 EAP认证深度配置指南 在移动办公日益普及的今天&#xff0c;企业级VPN解决方案需要兼顾安全性与易用性。Strongswan作为开源的IPsec实现&#xff0c;配合Freeradius进行EAP认证&#xff0c;能够为Android设备提供…...

OpenClaw技能开发入门:千问3.5-9B定制天气查询

OpenClaw技能开发入门&#xff1a;千问3.5-9B定制天气查询 1. 为什么需要自定义技能&#xff1f; 去年冬天&#xff0c;我经常需要同时查看多个城市的天气情况来安排出差行程。每次手动打开天气网站、输入城市名、截图保存的操作让我不胜其烦。直到发现OpenClaw支持自定义技能…...

LaTeX2Word-Equation:学术公式无缝迁移的终极解决方案

LaTeX2Word-Equation&#xff1a;学术公式无缝迁移的终极解决方案 【免费下载链接】LaTeX2Word-Equation Copy LaTeX Equations as Word Equations, a Chrome Extension 项目地址: https://gitcode.com/gh_mirrors/la/LaTeX2Word-Equation 在学术写作与科研工作中&#…...

AI写前端也看“审美”?我用GLM4.6、Kimi和Minimax-m2做了个设计实验,结果有点意外

AI写前端也看“审美”&#xff1f;GLM4.6、Kimi与Minimax-m2的设计实验报告 当我们在深夜调试CSS时&#xff0c;是否想过AI模型其实也在"暗中观察"我们的设计品味&#xff1f;这次实验让我发现了一个有趣现象&#xff1a;不同AI生成的前端代码&#xff0c;在视觉呈现…...

【通信】基于matlab MC-CDMA系统仿真【含Matlab源码 15245期】

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到海神之光博客之家&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49…...

OpenClaw自动化测试:Qwen3.5-9B-AWQ-4bit驱动UI截图比对

OpenClaw自动化测试&#xff1a;Qwen3.5-9B-AWQ-4bit驱动UI截图比对 1. 为什么需要自动化UI测试 作为个人开发者&#xff0c;每次前端代码修改后最头疼的就是手动检查各个页面的UI变化。传统做法要么是人工逐页比对&#xff0c;要么依赖复杂的测试框架配置。直到我发现OpenCl…...

Java服务在Istio中Metrics丢失、Tracing断链?OpenTelemetry + Istio Telemetry V2精准对齐配置

第一章&#xff1a;Java服务在Istio中Metrics丢失与Tracing断链的根因剖析当Java应用以Sidecar模式接入Istio时&#xff0c;常出现Prometheus采集不到服务间HTTP指标&#xff08;如istio_requests_total&#xff09;、Jaeger/Zipkin中Span链路在Java服务入口处中断等现象。这些…...

OpenClaw节日营销助手:gemma-3-12b-it自动生成祝福语与发送邮件

OpenClaw节日营销助手&#xff1a;gemma-3-12b-it自动生成祝福语与发送邮件 1. 为什么需要节日营销自动化&#xff1f; 去年端午节前夜&#xff0c;我盯着电脑屏幕上的200多个客户邮箱地址发呆。每个客户都需要个性化的节日祝福&#xff0c;但手动编写和发送至少需要6小时。当…...

数据库运维与数据安全:备份恢复、日志分析与故障排查

下面的内容大家根据实际情况&#xff0c;公司的业务还有重点择机选择&#xff0c;不是所有的蓝翔都有挖掘机 如果说之前的索引优化是“飙车”&#xff0c;那么今天的主题就是“系安全带”和“买保险”。 在运维的世界里&#xff0c;没有“如果”&#xff0c;只有“万一”。当…...