什么是定时器?

它就像是一个闹钟一样,提醒你在一定时间之后该去做什么~~

前面在线程池的时候提到过两种可以执行延迟任务的方法
  • 创建一个单线程可以执行延迟任务的线程池,Executors.newSingleThreadScheduledExecutor();
  • 创建多个可以执行延迟任务的线程池,Executors.newScheduledThreadPool

用惯了Java提供的定时器,那么如何自己去简单实现一个定时器?

实现步骤(先描述再组织):
1.如何描述:首先提供一个Timer用来描述任务,其次Timer类里面要有一个时间(什么时候去执行任务)和任务
2.如何组织:提供一个worker类进行组织, 而woeker里面要提供执行方法和添加任务
3.进行调用

具体步骤

Timer类
//Timer类
class Timer {//里面有两个属性,时间+任务long time;Runnable runnable;//任务就是Runnable类型的,因为它里面有自带run方法,更容易执行//赋初值public Timer(Runnable runnable, long after) {this.runnable = runnable;//这里的时间,我们就定义成多长时间之后去执行任务,也就是延迟时间 = 当前时间+要延迟的时间this.time = System.currentTimeMillis() + after;}
}
Worker类
//组织类(Worker)class Worker {//1.任务的扫描和执行//如何扫描,也就是当初始化Worker的时候就创建一个线程一直去扫描任务public Worker() {}//首先必须有任务,所以要写一个添加任务的方法,里面要传入任务和执行时间public void schedule(Runnable runnable, long after) {}}
**完整代码**
import java.util.Date;
import java.util.concurrent.PriorityBlockingQueue;//描述类(Timer)
class Timer implements Comparable<Timer> {//里面有两个属性,时间+任务long time;Runnable runnable;//任务就是Runnable类型的,因为它里面有自带run方法,更容易执行//赋初值public Timer(Runnable runnable, long after) {this.runnable = runnable;//这里的时间,我们就定义成多长时间之后去执行任务,也就是延迟时间 = 当前时间+要延迟的时间this.time = System.currentTimeMillis() + after;}//提供一个执行方法public void run() {runnable.run();}//优先级的排序方法@Overridepublic int compareTo(Timer o) {return (int) (this.time - o.time);//正序.正序的好处:把最紧急的任务排在最前面//return (int)(o.time-this.time);//倒叙}
}//组织类(Worker)class Worker {//1.创建一个优先级队列,但是不是所有的任务都能够放进这个队列,所有我们就指定只能够存放我们Timer类里面的任务//2.既然是一个优先级队列,那么肯定有它的优先级,也就是重写Comparable里面的compareTo()方法PriorityBlockingQueue<Timer> priorityBlockingQueue = new PriorityBlockingQueue<>();//创建一个锁Object lock = new Object();//1.任务的扫描和执行//如何扫描,也就是当初始化Worker的时候就创建一个线程一直去扫描任务public Worker() {Thread thread = new Thread(() -> {while (true) {//1.扫描任务,首先得要有一个容器去放任务,那就是得有优先级阻塞队列try {//2.获取到队首的任务,而且只要扫描到第一个任务就可以得到整个队列的(任务)检查Timer timer = priorityBlockingQueue.take();//当拿到任务之后就判断拿到任务的时间是否小于当前时间,如果小于,那么说明这个任务达到了当前时间,可以执行if (timer.time <= System.currentTimeMillis()) {//然后调用run方法执行该任务timer.run();} else {//假如拿到的是不具备执行的任务 那就将这个任务再放进阻塞队列priorityBlockingQueue.put(timer);System.out.println("不具备执行条件");//存在问题:如果它不具备执行条件,但是他还是会一直扫描//解决方法:如果他不具备执行条件,那么就让它等着,知道被唤醒synchronized (lock){//那么等待多久呢?就是等待时间= 任务的时间-当前时间lock.wait(timer.time - System.currentTimeMillis());}}} catch (InterruptedException e) {e.printStackTrace();}}});thread.start();}//首先必须有任务,所以要写一个添加任务的方法,里面要传入任务和执行时间public void schedule(Runnable runnable, long after) {priorityBlockingQueue.put(new Timer(runnable, after));synchronized (lock){lock.notify();}}}public class ThreadDemo32 {public static void main(String[] args) {//创建定时器Worker worker = new Worker();//创建一个任务Runnable runnable = new Runnable() {@Overridepublic void run() {//如果要执行一个循环的延迟任务worker.schedule(this,3*1000);System.out.println("执行任务的时间:"+new Date());}};//查看添加任务的时间System.out.println("添加任务的时间:"+new Date());//添加一个任务,然后间隔3秒worker.schedule(runnable,3*1000);}}

注意问题

如果想要了解更多关于定时器的,可以参考:
https://blog.csdn.net/ecjtuxuan/article/details/2093757?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161676484816780264034046%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=161676484816780264034046&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-1-2093757.pc_search_result_before_js&utm_term=java%E5%AE%9A%E6%97%B6%E5%99%A8%E7%9A%84%E4%BD%BF%E7%94%A8%28Timer%29

Java如何简单实现一个定时器相关推荐

  1. java定时任务中使用多线程_java项目中如何利用多线程实现一个定时器任务

    java项目中如何利用多线程实现一个定时器任务 发布时间:2020-11-10 16:04:03 来源:亿速云 阅读:86 作者:Leah 今天就跟大家聊聊有关java项目中如何利用多线程实现一个定时 ...

  2. java播放声音类和一个简单示例

    java播放声音类和一个简单示例 播放声音的类 复制代码 代码如下:  import java.io.File; import java.io.IOException; import javax.so ...

  3. java判断春夏秋冬,让大家一个java非常简单的编程:根据输入1到12之间的数字,判断是春夏秋冬哪个季节...

    让大家一个java非常简单的编程:根据输入1到12之间的数字,判断是春夏秋冬哪个季节 mip版  关注:95  答案:3  悬赏:70 解决时间 2021-01-26 04:37 已解决 2021-0 ...

  4. java swing 简单计算器_用java swing编写一个简单的计算器

    用java swing实现的一个简单的计算器:一些swing的基础应用. 注释里有详解,直接上代码: package 简易计算器; import java.awt.BorderLayout; impo ...

  5. java rmi 例子_RMI最简单的一个实例

    RMI最简单的一个实例 2008年06月21日 星期六 下午 07:30 1.    RMI最简单的一个实例,思路是你在服务器端创建一个方法addData(),该方法实现两个整数的相加,然从客户端远程 ...

  6. java 方法数统计_利用Java简单实现一个代码行数统计器方法实例

    前言 哈喽,我是小黑, 最近学了java的输入输出流后一直心痒痒,总想找一点事情来做,所以用java代码来实现了一下统计代码的所有行数,看一下我上大学以来到底打了多少行. 先附上实现代码吧! pack ...

  7. JAVA毕业设计vue开发一个简单音乐播放器计算机源码+lw文档+系统+调试部署+数据库

    JAVA毕业设计vue开发一个简单音乐播放器计算机源码+lw文档+系统+调试部署+数据库 JAVA毕业设计vue开发一个简单音乐播放器计算机源码+lw文档+系统+调试部署+数据库 本源码技术栈: 项目 ...

  8. 网友:Java岗,自学一个月跳槽计算机视觉,其实入门很简单

    笔者在脉脉上看到一条帖子:原来Java岗,自学一个月成功跳槽视觉算法岗. 这已经不是笔者第一次看到转行成功的程序员案例了,而大家的跳槽动机基本上都离不开,发展趋势.岗位高薪.职业兴趣. 计算机视觉 行 ...

  9. Java高并发编程:定时器、互斥、同步通信技术

    笔记摘要 这里分析了多线程的一些细节问题,并介绍了传统定时器的创建,同时实现了根据自己的调度计划的自定义定时器,对于传统互斥技术中发现的内部类问题,进行了分析,最后对于同步通信技术,是重点,分析了如何 ...

最新文章

  1. canvas基础-绘制矩形(1)
  2. Effective Objective-C 2.0 初读小结
  3. zookeeper使用及模拟注册中心原理
  4. 将某一位置1,将某一位置0,判断某一位是否为1
  5. Unity 移动端的复制这么写
  6. dubbo注入找不到bean_Dubbo配置参考手册之dubbo:reference
  7. c语言使用三种方法计算圆周率,求用三种方法计算圆周率(C语言)
  8. 判断输入的字符与已知字符相等_你会输入带圈字符吗?
  9. js获取当前url的ip+端口
  10. 一般进入服务器系统的密码,如何查看远程服务器的密码是什么
  11. 数据库表同义词mysql修改_SQLServer中同义词Synonym的用法
  12. java 正则表达式 去掉 文章头部和尾部的空格(全角,半角)、制表符、换页符
  13. 机器学习笔记(三)——归一化、KD树、数值型特征无量纲化、数值型特征分箱等
  14. PSP开发简明教程(2)
  15. ip-纯真库:批量获取ip归属地
  16. Idea 2021新建项目没有spring选项
  17. 写给自己的Java程序员学习路线图
  18. 前端面试题总结【持续更新···】
  19. 使用useState因异步导致数据不能及时更新的问题
  20. 我的年假2016-2017

热门文章

  1. 数据结构之基于Java的链接队列实现
  2. 红帽RHEL8和RHEL7有什么区别?
  3. Mysql学习总结(56)——MySQL用户管理和权限设置
  4. Maven学习总结(40)——Maven安装项目jar到本地和私服相关总结
  5. FastDFS学习总结(2)--Tracker与Storage配置详解
  6. python并列语句_Python基础_控制语句
  7. string字符串内容倒叙_面试官:string、stringbuffer和stringbuilder都不会,我招你干什么?...
  8. java登录验证技术,login_required -- 登录验证
  9. 三大主流软件负载均衡器对比(LVS VS Nginx VS Haproxy)
  10. vim表达式正则替换