线程 —— 定时器

devtools/2025/3/17 13:00:45/

什么是定时器

定时器是软件开发中的一个重要组件,类似于一个“闹钟”。达到一个设定的时间之后,就执行某个指定好的代码。

标准库中的定时器

  • 标准库中提供了一个 Timer 类。Timer 类的核心方法为 schedule。
  • schedule 包含两个参数。第一个参数指定即将要执行的任务代码,第二个参数指定多长时间之后执行(ms)。
    在这里插入图片描述

正常描述任务,是 Runnable。
在定时器这里稍微特殊一点,把 Runnable 封装了一下 TimerTask。
在这里插入图片描述

核心还是重写 run 方法。
在这里插入图片描述
在这里插入图片描述

我们发现,这个进程也没有结束,其实这个和线程池一样,Timer 中也包含前台线程,阻止进程结束。

模拟实现定时器

1.创建一个类,表示一个任务。
在这里插入图片描述
在这里插入图片描述

2.定时器中,能够管理多个任务。(必须使用一些集合类把这多个任务管理起来 -> 当管理多个任务的时候,需要确保,时间最早的任务,最先执行。通过遍历的方式,找到时间最早 -> 优先级队列)
在计算中,时间戳来表示时刻
在这里插入图片描述

3.实现 schedule 方法,把任务添加到队列中即可。

在这里插入图片描述

4.额外创建一个线程,负责执行队列中的任务。

在这里插入图片描述
在这里插入图片描述

按刚刚的思路写出来就是这样啦,通过测试案例,也能运行出来
在这里插入图片描述

但是,一旦各位按照这个代码运行这个程序,风扇就会疯狂转。->cpu温度升高 -> cpu在高负荷工作。
原因在于这里面还有一些细节没有注意。
在这里插入图片描述

  • 首先,咱们的队列,添加完 3 个元素后,队列就空了。这里的转,其实是在等待新的任务到来,明明是等,却需要消耗大量的cpu资源,不太科学的。
    有的人可能会想到在if代码块中添加sleep。
    在这里插入图片描述

但是,这里的sleep时间不好设定,如果设置的短,起不到解决忙等的效果。如果设置的长,万一有新的任务来了,又没法及时处理。
所以,同样是等待,我们这里采用 wait ,notify 来解决这个问题。
在这里插入图片描述

那什么时候唤醒 呢? -> 每当有新任务进入队列时,唤醒。
在这里插入图片描述

  • 另外,这一块代码也会使进程陷入忙等
    在这里插入图片描述

我们也是采用wait的方法解决问题。
在这里插入图片描述

但是,此处这个wait必须得有其他线程 schedule 才能唤醒,实际上,此处是因该时间到,就继续执行的。
在这里插入图片描述

可能还是有人想用sleep,那我们来举个例子:本来队首是 14:30分,咱们在14:10分添加一个新的任务 14:20来执行。如果刚才是sleep,sleep 30分钟 无法被唤醒,意味着14:20的任务(新任务)无法及时执行了,因为sleep的时候,不会释放锁的!另一个线程调用schedule阻塞在枷锁的逻辑上。

标准库提供的 Timer 和刚才写的 MyTimer 差不多,都是使用一个线程,负责扫描队首元素,并执行的。如果任务少或任务的时间分散都无所谓,如果任务特别多,时间非常集中,一个线程就可能执行不过来,那我们完全可以创建多个线程,负责执行这里的队列中的任务,一个线程负责扫描,扫描到需要执行的任务,添加到另一个线程池的任务队列中,由多个线程负责执行。
在这里插入图片描述

这样的操作,就创建了一个带有线程池的定时器。

定时器,除了基于 堆(优先级队列) 方式来实现的定时器之外。还有一种方案,基于“时间轮”。类似搞个循环队列(数组),每个元素是一个“时间单位”,每个元素是一个链表,每到一个时间单位,光标指向下一个元素,同时把这个元素对应链表中的任务都执行一遍。它的优势是性能高,但劣势是时间精度不如优先级队列(优先级队列,最大的问题是堆的调整,logN)。(这个是更适合任务特别多的情况)。在这我们就不自己实现了,想了解的话大家可以搜一搜。

由于定时器,是一个非常重要的组件,在分布式系统中,把定时器专门提取出来,封装成一个单独的服务器(和消息队列很像)。
分布式系统,有很多服务器
如果只是一个类,意味着所有的服务器都需要执行这一套同样的逻辑,比较复杂,如果进行调整,所有的都要改。
提取出来,独立的服务器,大家都去用,如果未来有升级调整,也便于分配给这个定时任务服务器单独的硬件资源。


http://www.ppmy.cn/devtools/167825.html

相关文章

如何用C#编写一个可以验证登录信息的简单登录页面?

要用C#编写一个简单的登录页面,可以按照以下步骤进行: 创建一个新的C#控制台应用程序项目。 创建一个名为Login.cs的类,该类包含用户名和密码作为属性。 class Login {public string Username { get; set; }public string Password { get;…

《基于超高频RFID的图书馆管理系统的设计与实现》开题报告

一、研究背景与意义 1.研究背景 随着信息化时代的到来,运用计算机科学技术实现图书馆的管理工作已成为优势。更加科学地管理图书馆会大大提高工作效率。我国的图书管理体系发展经历了三个阶段:传统图书管理模式、现代图书管理模式以及基于无线射频识别&…

python练习2

说明:本文档主要是记录,欢迎练习,适合初学者,附答案无解析。有任何异议还请私信或者评论区告知。 一、选择题(共 7 题,每题 4 分,共 28 分) 1. 下方代码运行后,用户输入了 23 ,请问输出结果应该是什么 ( D ) A. 823 B. 31 C. 8+23 D. 不会输出任何内容…

基于javaweb的SSM+Maven网上选课管理系统设计与实现(源码+文档+部署讲解)

技术范围:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论…

专业的IP干净度检测工具

目录 PING0 平台 IP 地址归属地查询 运营商信息查询 IP 类型判断 风控值评估 同机房 IDC 查询 历史记录查询 地图定位 PING0 平台 访问 PING0 平台官网:https://www.ping0.cc/。 在首页的输入框中输入要查询的 IP 地址。 点击查询按钮,平台将快…

list及其模拟实现

list其实就是一个带头双向链表 1 迭代器 按功能分iteratorreverse_iteratorconst_iteratorconst_reverse_iterator 按性质分支持结构支持操作单向forward_list/unordered_map双向list/map/set/--随机vector/string/deque / -- / / - 按性质分,决定可以使用那些算…

数字接龙 第十五届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组

数字接龙 题目来源 第十五届蓝桥杯大赛软件赛省赛C/C 大学 B 组 原题链接 蓝桥杯 数字接龙 https://www.lanqiao.cn/problems/19712/learning/ 问题描述 题目描述 小蓝最近迷上了一款名为《数字接龙》的迷宫游戏,游戏在一个大小为 n n n \times n nn 的格子…

SpringMVC-文件上传

文章目录 1. 前端表单2. 阿里云OSS2.1 什么是阿里云OSS2.2 实现阿里云OSS2.2.1 准备工作2.2.2 SpringBoot集成阿里云OSS 3. 使用SpringCloud Alibaba快捷操作4. 前端直传5. 临时URL访问文件 在实际的项目开发中,文件的上传和下载可以说是最常见的功能之一&#xff0…