前段时间做一个springMVC项目,有一个功能是要定时拉取数据。做法就是启动一个定时器,定时这行。java有自带的定时器,不过在springMVC中不好集成,而且由于使用springMVC,很

多都是注解,写起来效率较高。当然quart定时器很好用,而且功能强大。自己想偷懒,找到spring 自带了一个轻量级的定时器spring schedule,使用注解一行代码就能实现。代码是这样的:

在spring 注解中加一行,代表支持这个定时器的注解使用,然后再定时器类中的方法上加一行@Scheduled(cron = "0 55 23 * * ?") 注解,当然这个类必须加

入spring组件里面。很容易,一个定时器就实现了,而且修改也很容易,变更cron表达式就好。

由于功能的增加,需要定时器的地方有好几个,自己什么也没想,把原先的方法照搬过来,也不会想到会出什么问题。那天发布项目测试的时候,突然发现该运行的内容没有,关键是日志也

没报错。这种问题不知道原因,都不好去解决。只能回到项目,一个一个打日志,调试。后面发现定时器也不是全部没启动,启动了一个。后面发现如果就只是一个定时器,运行没问题,难道这

个只支持一个定时器?我举得不太可能,写个代码测试一下,发现几个是没问题。后面觉得有可能这个定时器是阻塞的,就是同时只能执行一个任务,果不然,项目中的几个任务是需要一直运行

的,就是说要占几个线程。开始想去看sprng schedule的源码,感觉里面类之间牵涉太多了。就先看了java自带的定时器的源码,发现两个在那个问题的处理上很相似,看了一下

java.util.timer,它的核心执行代码,其实就是一个线程在一直轮询扫描各个定时器,既然是一个线程,那么肯定是阻塞的。下面做一下简要的分析。

核心有三个类,Timer,TimeTask ,其中Timer中又包括两个重要的类TaskQueue,TimerThread.类图如下(只介绍主体功能)

首先看TimerTask,VIRGIN,SCHEDULED,EXECUTED,CANCELLED分别代表执行的状态:未执行,执行中,已执行完,已取消。

方法中,run指该任务执行,cancel,取消该任务,scheduledExecutionTime返回下次执行任务时间。

Timer 其实是一个外观接口,提供定时任务的访问接口schedule

TaskQueue 其实是一个TimerTask的容器,属性中包含一个TimerTask数组。

方法则是对任务的管理

add,加入新的定时任务

getMin,获取时间最近的定时任务

removeMin,移除最近的定时任务

rescheduleMin,重新调度时间

fixUp 吧定时任务往前移,

fixDown 把定时任务往后移

总体来说,这个既是对定时任务的管理与调度。

定时的主要实现部分是在TimerThread

TimerThread实现Thread接口,也就是说通过这个线程来实现定时功能,

主要代码在mainLoop 代码如下

该函数已知扫描TaskQueue中的TimerTask任务,每次取时间最近的定时任务,如果时间没到,那么线程等待,如果判断轮到某个定时器执行,那么线程阻塞,直到该线程完成。由于轮询的是单一线程,所以在时间点上,每次只能有一个定时任务执行。这样,如果一个任务执行时间过长,那么其他的任务就得等待,如果一个任务一直在执行,那么其余的任务就永远执行不了,被阻塞了。这个和我用spring schedule相像。可能我用到的那个功能和java 自带的timer实现差不多,用到是单一线程的阻塞模式。

后边有时间逐步分析spring schedule,quart

java timer 轮询_java 定时器分析相关推荐

  1. java 长轮询_java – Spring中的长轮询

    我们有一个独特的案例,我们需要与外部API接口,这需要我们长时间轮询他们的端点以获得他们所谓的实时事件. 问题是我们可能有多达80,000人/设备在任何给定时间点击此端点,监听事件,每个设备/人1个连 ...

  2. java 员工轮询值班排班 开发设计(mysql+redis)

    JAVA 员工轮询 值班 排班 1.设计一个值班历史纪录表 duty_employee_history(area_id,dept_id) 联合主键,存放已值班过的数据 area_id int(11) ...

  3. java timer线程结束_Java线程Timer定时器用法详细总结

    定时/计划功能主要使用的就是Timer对象,它在内部还是使用多线程的方式进行处理,所以它和线程技术还是有非常大的关联. Timer类主要作用就是设置计划任务,但封装任务的类却是TimerTask类.T ...

  4. java线程轮询_基于springboot实现轮询线程自动执行任务

    本文使用: Timer:这是java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务.使用这种方式可以让你的程序按照某一个频度执行, 但不能在指定 ...

  5. java定时轮询_RxJava应用场景之轮询定时任务

    Android开发中必不可少会遇到轮询或定时任务,在RxJava诞生之前,我们常常使用Handler+postDelay,或者Java中的Timer来实现,实际上RxJava也可以实现这类需求.下面, ...

  6. java ajax轮询_ajax轮询(ajax轮询实现聊天)

    最近一直在研究ajax长轮询连实现即时通信,但是到底是个怎么轮询法?难道. 一般最原始的作法就是在客户端搞个定时器一直向后台请求,而ajax的长轮询与一般的http连接不一样,它发送的是长连接,比如说 ...

  7. java ajax轮询_ajax轮询

    http://blog.csdn.net/qq_23412263/article/details/70260057 原理 普通的jquery ajax轮询的原理主要是,客户端通过定时器定时发送ajax ...

  8. java 长轮询_基于springboot 长轮询的实现操作

    springboot 长轮询实现 基于 @EnableAsync , @Sync @SpringBootApplication @EnableAsync public class DemoApplic ...

  9. java 十六进制转十进制_JAVA知识-分析JAVA中的重点和难点

    Java中有很多内容在开发项目的过程中并不常用,但是却是很重要的部分,为了避免忘记,今天重新温习了一遍Java中的重点和难点,借此机会记录一下方便以后查找. 本文主要分为以下几个部分: 1.进制的相互 ...

最新文章

  1. 【LeetCode OJ 136】Single Number
  2. Lambda使用——JDK8新特性
  3. C++数组与指针概念
  4. 原生JS获取地址了参数
  5. cpu消耗 pytorch_高效 PyTorch :如何消除训练瓶颈
  6. JS高效数据存取指南
  7. 在后台运行程序/软件的Linux命令
  8. HDU 3065 病毒侵袭持续中(AC自动机)题解
  9. 判断一个数是偶数还是素数 做相应处理并排序输出
  10. 电脑打印机print spooler服务总是自动停止的解决方法...
  11. 开源生产排程aps(Advanced Planning and Scheduling)软件介绍
  12. Adobe Flash Player不是最新版本的解决方法
  13. Android Studio 中集成 ASSIMP
  14. UTC(世界标准时间)/GMT(格林威治时间)/CST(北京时间)
  15. linux limits.conf 生效,linux修改limits.conf不生效
  16. node-red与西门子PLC通信
  17. Android 实现HTTPS自签名证书(非常详细)
  18. 从零开始学USB(二十四、最简单的USB驱动开始)
  19. 拥有10年编程经验的你,为什么还一直停留在原地
  20. 织梦dedecms仿CCTV门户资讯新闻类网站源码

热门文章

  1. 播放器基础--OpenSL ES音频播放
  2. 《可汗学院-线性代数小结》
  3. Java Web的面试复习
  4. python canvas画弧度_Python 小技之繁花曲线
  5. 功能键设置(命令模式实战)
  6. Linux系统中环境变量的设置,getEnv,putEnv, environ全局变量的使用
  7. 主动式和被动式电容笔哪个好用?第三方电容笔推荐
  8. 电子签章(SpringCloud写一个简单签章)
  9. 智能家居(7) —— 人脸识别 翔云平台编程使用(编译openSSL支持libcurl的https访问、安装SSL依赖库openSSL)
  10. 全球及中国水性固化剂行业研究及十四五规划分析报告