当前位置:网站首页>多线程案例——定时器
多线程案例——定时器
2022-08-01 12:46:00 【Living_Amethyst】
定时器是什么
定时器也是软件开发中的一个重要组件. 类似于一个 “闹钟”. 达到一个设定的时间之后, 就执行某个指定好的代码.
定时器是一种实际开发中非常常用的组件.
比如网络通信中, 如果对方 500ms 内没有返回数据, 则断开连接尝试重连.
比如一个 Map, 希望里面的某个 key 在 3s 之后过期(自动删除).
类似于这样的场景就需要用到定时器
标准库中的定时器
- 标准库中提供了一个 Timer 类. Timer 类的核心方法为 schedule .
- schedule 包含两个参数. 第一个参数指定即将要执行的任务代码, 第二个参数指定多长时间之后
执行 (单位为毫秒).
示例:
public static void main(String[] args) {
// java.util 里的一个组件
Timer timer = new Timer();
//schedule这个方法的效果 是 “安排一个任务”
//不是立刻执行 而是3000毫秒之后执行
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("这是一个要执行的任务");
}
},3000);
}
模拟实现定时器
很多细节的解析再注释中注明
//模拟实现 定时器
import java.util.PriorityQueue;
import java.util.concurrent.PriorityBlockingQueue;
class MyTask implements Comparable<MyTask>{
//任务要干啥
private Runnable command;
//任务啥时候干
private long time; //绝对时间
public MyTask (Runnable command,long after){
this.command = command;
//此处记录的时间是一个绝对的时间戳,不是多长时间后执行
this.time = System.currentTimeMillis()+after;
}
//执行任务的方法 直接在内部调用 Runnable 的 run 即可
public void run(){
command.run();
}
public long getTime() {
return time;
}
@Override
public int compareTo(MyTask o) {
//希望时间小的在前 大的在后
return (int) (this.time - o.time);
}
}
class MyTimer {
//用来阻塞等待的锁对象
private Object locker = new Object();
//使用优先级队列来保存若干个任务
private PriorityBlockingQueue<MyTask> queue = new PriorityBlockingQueue<>();
// command:要执行的任务是啥
// after:多长时间之后执行这个任务
public void schedule(Runnable command,long after) {
MyTask myTask = new MyTask(command,after);
// 防止 新插入的任务 比之前队首的任务的时间还早,需要唤醒
synchronized (locker){
queue.put(myTask); //把加入操作也加锁
locker.notify();
}
}
public MyTimer(){
// 启动一个线程
Thread t = new Thread(()->{
while (true){
//循环过程中 不断尝试从队列中获取到队首元素
//判定队首元素当时的时间是否就绪,就绪了就执行 不就绪就不执行
try {
synchronized (locker) {
MyTask myTask = queue.take();//取的是队首元素,时间最早的任务
long curTime = System.currentTimeMillis();
if (myTask.getTime() > curTime) {
//时间还没到
queue.put(myTask); //把任务再放回队列
//队首的(最早执行的)元素时间还没到,需要等待,不然一直循环 CPU空转 内耗
locker.wait(myTask.getTime() - curTime);
} else {
//时间到了 执行任务
myTask.run();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
}
}
public class Demo18 {
public static void main(String[] args) {
MyTimer myTimer = new MyTimer();
myTimer.schedule(new Runnable() {
@Override
public void run() {
System.out.println("111");
}
},2000);
myTimer.schedule(new Runnable() {
@Override
public void run() {
System.out.println("222");
}
},4000);
myTimer.schedule(new Runnable() {
@Override
public void run() {
System.out.println("333");
}
},6000);
}
}
边栏推荐
- windows IDEA + PHP+xdebug 断点调试
- formatdatetime函数 mysql(date sub函数)
- R语言ggplot2可视化:使用ggpubr包的ggdensity函数可视化密度图、使用stat_central_tendency函数在密度中添加均值竖线并自定义线条类型
- 为什么最大值加一等于最小值
- 并发编程10大坑,你踩过几个?
- MMF的初步介绍:一个规范化的视觉-语言多模态任务框架
- bat countdown code
- How do programmers solve online problems gracefully?
- This article will take you to thoroughly clarify the working mechanism of certificates in Isito
- (ES6 and above and TS) Map object to array
猜你喜欢

那些利用假期学习的职场人,后来都怎么样了?

芝加哥丰田技术学院 | Leveraging Natural Supervision for Language Representation Learning and Generation(利用自然监督进行语言表示学习和生成)

【StoneDB Class】Introduction Lesson 2: Analysis of the Overall Architecture of StoneDB

Programmer's self-cultivation

bpmn-process-designer基础上进行自定义样式(工具、元素、菜单)

Qt get all files in a folder

The four methods of judging JS data type

Beyond Compare 4 试用期到期

阿里云官方 Redis 开发规范

【公开课预告】:超分辨率技术在视频画质增强领域的研究与应用
随机推荐
Dapr 与 NestJs ,实战编写一个 Pub & Sub 装饰器
Grafana9.0发布,Prometheus和Loki查询生成器、全新导航、热图面板等新功能!
蔚来又一新品牌披露:产品价格低于20万
初级必备:单例模式的7个问题
[Open class preview]: Research and application of super-resolution technology in the field of video image quality enhancement
动态库、静态库浅析
What is MNIST (what does plist mean)
MVVM响应式
Deep understanding of Istio - advanced practice of cloud native service mesh
SQL function SQRT
SCHEMA solves the puzzle
formatdatetime函数 mysql(date sub函数)
达梦更换正式授权dm.key
并发编程10大坑,你踩过几个?
How do programmers solve online problems gracefully?
R language ggplot2 visualization: use ggpubr package ggscatter function visualization scatterplot, use xscale wasn't entirely specified X axis measurement adjustment function, set the X coordinate for
英特尔全方位打造算力基础,助推“算”赋百业
Fault 007: The dexp derivative is inexplicably interrupted
安装apex报错
bpmn-process-designer基础上进行自定义样式(工具、元素、菜单)