目录

定时器

实现定时器

描述任务

保存任务

扫描任务

执行任务


定时器

在实现定时器之前,先来简单的了解一下什么是定时器。

定时器是软件开发中一个重要的组件。比如到了什么时候,干一件什么样的事情;多少秒之后干什么。本篇文章介绍的多长时间后干什么事情。

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】定时器的简单实现相关推荐

  1. MATLAB定时器的简单使用

    MATLAB中无多线程机制,有时候需要实现多任务处理,可以用定时器实现. MATLAB Timer的详细用法见MATLAB help. 本文所用参数及函数解释: start(timer_id);%启动 ...

  2. Android定时器Timer简单使用

    Android定时器Timer简单使用 Timer简介 Timer使用 总结 Timer简介 Timer(计时器)位于 java.util包下,可用于创建定时任务,任务可以安排为一次性执行,也可以定期 ...

  3. c语言定时器回调函数的参数,定时器的简单实现即回调函数的运用

     这两天在 研究回调函数就想实现简单的定时器,如下是鄙人的程序望指教.ios #include #include using namespace std;app #define MAXNUM 25 ...

  4. python自己做个定时器_简单实现python定时器

    下面介绍以threading模块来实现定时器的方法.(课课家) 使用前先做一个简单试验: import threading def sayhello(): print "hello worl ...

  5. [JavaEE]定时器

    专栏简介: JavaEE从入门到进阶 题目来源: leetcode,牛客,剑指offer. 创作目标: 记录学习JavaEE学习历程 希望在提升自己的同时,帮助他人,,与大家一起共同进步,互相成长. ...

  6. linux ps le hrtime,Linux 高精度定时器hrtimers简单介绍和应用场景

    hrtimer:high-resolution kernel timers: hrtimers的诞生是由于内核开发者在使用过程中发现,原始的定时器kernel/timers.c,已经可以满足所有场景的 ...

  7. 针对表单的事件;条件语句;定时器的简单介绍;

    一.针对表单的事件: 1.表单的标签:form.input.select.textarea 2.表单的属性:type="radio/checked/password/button/text/ ...

  8. 《MFC游戏开发》笔记五 定时器和简单动画

    本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9332377 作者:七十一雾央 新浪微博:http:// ...

  9. STM32 定时器的简单应用 1ms中断代码

    引言:利用定时器TIM8产生1ms中断,每中断一次,全局变量+1,计数到10即10ms,使得输出引脚翻转一次.芯片采用STM32F103VCT6,系统输入时钟12MHz,完成代码并用示波器输出. 根据 ...

最新文章

  1. StaticFactoryMethod_Level4
  2. springboot redis
  3. IoC容器总结与简单模拟
  4. mysql查看在线用户
  5. Qt Creator设置调试器
  6. JS(去掉前后空格或去掉所有空格)的用法
  7. C语言指针详解----指针声明定义赋值
  8. 笔记本多硬盘win7下U盘安装Cnetos7引导问题!
  9. android 禁用dlsym_Android7.0对dlopen的改变——读取私有.so结果变化
  10. Android学习之网上商城(下)
  11. tushare pro接口_Python与交易策略分析amp;tushare/baostock库介绍(附代码)
  12. 阿里云迎来 2.0,重新定义软件系统应用开发方式
  13. 模仿QZONE挂图效果
  14. 比Everything、listary、DocFetcher还好用的桌面文档搜索软件 - bbdoc
  15. etree不能使用,etree.HTML()不能使用。
  16. W3Cschool菜鸟教程离线版下载链接
  17. 中兴C93E全光网配置
  18. linux删除ip地址的命令
  19. word批注怎么删除计算机名字,word批注删除不了,word怎么删除批注栏
  20. OriginPro2021安装注意事项(详细)

热门文章

  1. android阅读器长按选择文字功能实现代码
  2. 腾讯微信附近推广告推广,店铺周围黄金3-5公里推广,微信朋友圈广告
  3. scala中主构造器和辅助构造器
  4. mysql外键检查的作用_MySQL外键使用及说明详解
  5. HTML5+CSS大作业——中国风的元宵节专题(6页) 节专题活动页面滚动模板
  6. 微信小程序获取用户信息nickname为“微信用户”
  7. matlab %3c=运算符,Maximize 3x+y with constraints in Matlab
  8. Python 数组截取
  9. selenium中调用方法chrome maximize_window() 无法生效,截图的效果不完整
  10. Android O版本特性