当前位置:网站首页>Multi-threaded cases - timer
Multi-threaded cases - timer
2022-08-09 09:39: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);
}
}
边栏推荐
猜你喜欢
Summary of steps and methods for installing and uninstalling test cases that you must read
The div simulates the textarea text box, the height of the input text is adaptive, and the word count and limit are implemented
列表
BigDecimal用法常用操作记录
How much do you know about the mobile APP testing process specifications and methods?
软件测试面试中,面试官问你一些比较“刁难”的问题你会怎么回答
自动化测试框架有哪几种?搭建的思路是什么?一篇文章让你彻底了解自动化
安装torch_sparse失败解决方法
接口测试主要测试哪方面?需要哪些技能?要怎么学习?
m个样本的梯度下降
随机推荐
在anaconda环境中配置cuda和cudnn
恶意软件查杀工具分享
迭代
Sweet alert
3. Practice the Thread
常用的一些制表符号
关于SQL的SELECT查询语句的一般格式的描述2021-05-19
pycharm在创建py文件时如何自动注释
mysql 修改密码和忘记密码操作
.ts 音频文件转换成 .mp3 文件
2.Collection interface
2.线程创建
秒拍app分析
列表
unittest测试框架原理及测试流程解析,看完绝对有提升
BlockingQueue理论普
3.List interface and implementation class
记录一次被入侵5900端口经历
3.List接口与实现类
8.递归遍历和删除案例