【JavaEE】定时器的简单实现
目录
定时器
实现定时器
描述任务
保存任务
扫描任务
执行任务
定时器
在实现定时器之前,先来简单的了解一下什么是定时器。
定时器是软件开发中一个重要的组件。比如到了什么时候,干一件什么样的事情;多少秒之后干什么。本篇文章介绍的多长时间后干什么事情。
Java标准库中的定时器,所提供的类——Timer 核心方法是schedule()。这里只演示多久之后执行任务这个方法。
import java.util.Timer;
import java.util.TimerTask;public class ThreadDemo25 {public static void main(String[] args) {Timer timer = new Timer();timer.schedule(new TimerTask() {@Overridepublic void run() {System.out.println("这是任务1, 1000ms后执行");}}, 1000);timer.schedule(new TimerTask() {@Overridepublic void run() {System.out.println("这是任务2, 2000ms后执行");}}, 2000);TimerTask task = new TimerTask() {@Overridepublic void run() {System.out.println("这是任务3,3000ms后执行");}};timer.schedule(task, 3000);}}
这里schedule中的两个参数
一个是TimeTask task 描述具体要执行的任务
一个是long time 描述time时间后执行该任务
其中TimeTask是一个抽象类,实现了Runnable接口。可以简单的理解为是堆Runnable接口的升级,实际上还是Runnable接口。
实现定时器
实现的是多久之后执行任务这一定时器。
描述任务
这里需要一个类是描述这个任务,因为除了任务之外,还需要时间。
// 使用Task类描述任务
// 因为存储该任务使用的是优先级阻塞队列,要比出优先级需要有比较器
// 这里直接实现Comparable接口
class Task implements Comparable<Task> {// 时间private long after;// 任务private Runnable runnable;public Task(Runnable runnable, long after) {this.runnable = runnable;this.after = after;}@Overridepublic int compareTo(Task task) {return (int)(this.after - task.after);}public long getAfter() {return after;}public void run(){this.runnable.run();}
}
保存任务
这里使用PriorityBlockingQueue来保存任务。因为保存进去的时候会按照时间来保存。带有优先级的阻塞队列完美符合这一点。检查是否要执行任务,只需要查看队首的元素时间是不是到了。
// 使用优先级阻塞队列保存任务private PriorityBlockingQueue<Task> queue = new PriorityBlockingQueue<>();
扫描任务
定时器创建时(所以需要在构造方法中),需要一个线程一直扫描检查里面的任务时间是否到了,到了就立马执行。
// 扫描线程时间private Thread scan = null;
执行任务
执行任务根据时间来判断是否要执行。如果时间还没到的时候,那么线程应该阻塞才好。其中时间是不固定的。可能随时会有新的任务添加进来,这样就会导致时间的不确定性。这里使用wait和notify来让任务阻塞还是执行。如果有新的任务添加进来,就唤醒以下正在阻塞的扫描线程,看看新的时间是否要执行,如果时间还不到,就继续阻塞,知道最早的时间到了,在执行任务。
public MyTimer() {// 创建一个线程扫描任务时间scan = new Thread(() -> {while (true) {try {long now = System.currentTimeMillis();Task task = queue.take();// 如果最快执行的任务的时间大于当前时间,就wait二者相差时间// 否则将会一直取出来在放进去if (task.getAfter() > now) {queue.put(task);synchronized (locker) {locker.wait(task.getAfter() - now);}} else {task.run();}} catch (InterruptedException e) {e.printStackTrace();}}});scan.start();}public void schedule (Runnable runnable, long after){Task task = new Task(runnable, System.currentTimeMillis() + after);queue.put(task);synchronized (locker) {locker.notify();}}
完整代码如下
// 实现一个定时器import java.util.concurrent.PriorityBlockingQueue;// 使用Task类描述任务
// 因为存储该任务使用的是优先级阻塞队列,要比出优先级需要有比较器
// 这里直接实现Comparable接口
class Task implements Comparable<Task> {// 时间private long after;// 任务private Runnable runnable;public Task(Runnable runnable, long after) {this.runnable = runnable;this.after = after;}@Overridepublic int compareTo(Task task) {return (int)(this.after - task.after);}public long getAfter() {return after;}public void run(){this.runnable.run();}
}class MyTimer {// 扫描线程时间private Thread scan = null;// 使用优先级阻塞队列保存任务private PriorityBlockingQueue<Task> queue = new PriorityBlockingQueue<>();// 时间还没有到的时候// 使用这个对象进行加锁和唤醒private Object locker = new Object();// 构造方法public MyTimer() {// 创建一个线程扫描任务时间scan = new Thread(() -> {while (true) {try {long now = System.currentTimeMillis();Task task = queue.take();// 如果最快执行的任务的时间大于当前时间,就wait二者相差时间// 否则将会一直取出来在放进去if (task.getAfter() > now) {queue.put(task);synchronized (locker) {locker.wait(task.getAfter() - now);}} else {task.run();}} catch (InterruptedException e) {e.printStackTrace();}}});scan.start();}public void schedule (Runnable runnable, long after){Task task = new Task(runnable, System.currentTimeMillis() + after);queue.put(task);synchronized (locker) {locker.notify();}}
}public class ThreadDemo26 {public static void main(String[] args) {MyTimer myTimer = new MyTimer();myTimer.schedule(new Runnable() {@Overridepublic void run() {System.out.println("这是任务1");}}, 6000);myTimer.schedule(new Runnable() {@Overridepublic void run() {System.out.println("这是任务2");}}, 2000);}
}
有什么问题评论区指出。希望可以帮到你。
【JavaEE】定时器的简单实现相关推荐
- MATLAB定时器的简单使用
MATLAB中无多线程机制,有时候需要实现多任务处理,可以用定时器实现. MATLAB Timer的详细用法见MATLAB help. 本文所用参数及函数解释: start(timer_id);%启动 ...
- Android定时器Timer简单使用
Android定时器Timer简单使用 Timer简介 Timer使用 总结 Timer简介 Timer(计时器)位于 java.util包下,可用于创建定时任务,任务可以安排为一次性执行,也可以定期 ...
- c语言定时器回调函数的参数,定时器的简单实现即回调函数的运用
这两天在 研究回调函数就想实现简单的定时器,如下是鄙人的程序望指教.ios #include #include using namespace std;app #define MAXNUM 25 ...
- python自己做个定时器_简单实现python定时器
下面介绍以threading模块来实现定时器的方法.(课课家) 使用前先做一个简单试验: import threading def sayhello(): print "hello worl ...
- [JavaEE]定时器
专栏简介: JavaEE从入门到进阶 题目来源: leetcode,牛客,剑指offer. 创作目标: 记录学习JavaEE学习历程 希望在提升自己的同时,帮助他人,,与大家一起共同进步,互相成长. ...
- linux ps le hrtime,Linux 高精度定时器hrtimers简单介绍和应用场景
hrtimer:high-resolution kernel timers: hrtimers的诞生是由于内核开发者在使用过程中发现,原始的定时器kernel/timers.c,已经可以满足所有场景的 ...
- 针对表单的事件;条件语句;定时器的简单介绍;
一.针对表单的事件: 1.表单的标签:form.input.select.textarea 2.表单的属性:type="radio/checked/password/button/text/ ...
- 《MFC游戏开发》笔记五 定时器和简单动画
本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9332377 作者:七十一雾央 新浪微博:http:// ...
- STM32 定时器的简单应用 1ms中断代码
引言:利用定时器TIM8产生1ms中断,每中断一次,全局变量+1,计数到10即10ms,使得输出引脚翻转一次.芯片采用STM32F103VCT6,系统输入时钟12MHz,完成代码并用示波器输出. 根据 ...
最新文章
- StaticFactoryMethod_Level4
- springboot redis
- IoC容器总结与简单模拟
- mysql查看在线用户
- Qt Creator设置调试器
- JS(去掉前后空格或去掉所有空格)的用法
- C语言指针详解----指针声明定义赋值
- 笔记本多硬盘win7下U盘安装Cnetos7引导问题!
- android 禁用dlsym_Android7.0对dlopen的改变——读取私有.so结果变化
- Android学习之网上商城(下)
- tushare pro接口_Python与交易策略分析amp;tushare/baostock库介绍(附代码)
- 阿里云迎来 2.0,重新定义软件系统应用开发方式
- 模仿QZONE挂图效果
- 比Everything、listary、DocFetcher还好用的桌面文档搜索软件 - bbdoc
- etree不能使用,etree.HTML()不能使用。
- W3Cschool菜鸟教程离线版下载链接
- 中兴C93E全光网配置
- linux删除ip地址的命令
- word批注怎么删除计算机名字,word批注删除不了,word怎么删除批注栏
- OriginPro2021安装注意事项(详细)
热门文章
- android阅读器长按选择文字功能实现代码
- 腾讯微信附近推广告推广,店铺周围黄金3-5公里推广,微信朋友圈广告
- scala中主构造器和辅助构造器
- mysql外键检查的作用_MySQL外键使用及说明详解
- HTML5+CSS大作业——中国风的元宵节专题(6页) 节专题活动页面滚动模板
- 微信小程序获取用户信息nickname为“微信用户”
- matlab %3c=运算符,Maximize 3x+y with constraints in Matlab
- Python 数组截取
- selenium中调用方法chrome maximize_window() 无法生效,截图的效果不完整
- Android O版本特性