java 定时器分析

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

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

在spring 注解中加一行<task:annotation-driven />,代表支持这个定时器的注解使用,然后再定时器类中的方法上加一行@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

时间: 2024-07-28 13:05:44

java 定时器分析的相关文章

Java性能优化指南系列(二):Java 性能分析工具

进行JAVA程序性能分析的时候,我们一般都会使用各种不同的工具.它们大部分都是可视化的,使得我们可以直观地看到应用程序的内部和运行环境到底执行了什么操作,所以性能分析(性能调优)是依赖于工具的.在第2章,我强调了基于数据驱动的性能测试是非常重要的,我们必须测试应用的性能并理解每个指标的含义.性能分析和数据驱动非常类似,为了提升应用程序的性能,我们必须获取应用运行的相关数据.如何获取这些数据并理解它们是本章的主题.[本章重点介绍JDK中提供的性能分析工具] 操作系统工具及其分析 程序分析的起点并不

java定时器

以下内容根据 JavaTM Tutorial 和相关API doc和网上的资料翻译整理,以供日后查看和参考: 1.描述 Timer是一种定时器工具,用来在一个后台线程计划执行指定任务.它可以计划执行一个任务一次或反复多次. TimerTask一个抽象类,它的子类代表一个可以被Timer计划的任务. 简单的一个例程: import java.util.Timer; import java.util.TimerTask; /** * Simple demo that uses java.util.T

java定时器的使用

java定时器的使用(Timer) 1.在应用开发中,经常需要一些周期性的操作,比如每5分钟执行某一操作等. 对于这样的操作最方便.高效的实现方式就是使用java.util.Timer工具类. privatejava.util.Timer timer; timer = newTimer(true); timer.schedule( newjava.util.TimerTask() { public void run() {//server.checkNewMail(); 要操作的方法} }, 0

java代码分析及分析工具

java代码分析及分析工具 一个项目从搭建开始,开发的初期往往思路比较清晰,代码也比较清晰.随着时间的推移,业务越来越复杂.代码也就面临着耦合,冗余,甚至杂乱,到最后谁都不敢碰. 作为一个互联网电子商务网站的业务支撑系统,业务复杂不言而喻.从09年开始一直沿用到现在,中间代码经过了多少人的手,留下了多少的坑,已经记不清楚了,谁也说不清了. 代码的维护成本越来越高.代码已经急需做调整和改善.最近项目组专门设立了一个小组,利用业余时间做代码分析的工作,目标对核心代码进行分析并进行设计重构. 代码分析

Java 定时器使用

// 定时器 privateTimer timer; timer = new Timer(); timer.schedule(new TimerTask() { public void run() { task(); } }, new Date(), 60*1000); public void task() { } Java 定时器使用,布布扣,bubuko.com

整理:java定时器。

本文纯属个人思路,如有错误,请指正. java的Timer依赖Thread,每一个Timer实际上都是一个Thread. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 import java.util.TimerTask; /**  * 本类仅为实现TimerTask,意义不大.  * @author 9082046**@qq.com  *  */ public class Task  extends TimerTask {       public void run()

java定时器实现总结

前言:Java定时器目前主要有3种实现方式:JDK组件,Spring Task,Quartz框架. 1. JDK组件(1) java.util.TimerTask MyTimerTask.java: public class MyTimerTask extends TimerTask { @Override public void run() { System.out.println("MyTimerTask, now: " + new SimpleDateFormat("y

HDFS API的java代码分析与实例

HDFS API的java代码分析与实例 1.HDFS常用的方法,我已经写好,我们看一下 // Create()方法,直接在HDFS中写入一个新的文件,path为写入路径,text为写入的文本内容 public static void  Create(String path,String text) throws IOException {             Configuration conf=new Configuration();                  conf.set(

J2SE快速进阶——Java内存分析

程序的执行过程 要在Java中分析内存,我们先来了解一下程序的执行过程: 正如上图所示,大致分为3个步骤: 1.最开始,我们的程序是存在于硬盘中的,当启动运行时,程序会被加载(load)到内存中去,这里的内存可以看做我们的内存条: 2.此时,内存中除了存在刚加载的程序的代码,还存在操作系统本身的代码(好吧,此句可以当做废话→_→),操作系统会找到程序中的Main方法开始执行程序: 3.第三步就是本文的重点,系统在程序执行过程中对内存的管理.在Java中,内存大致会被分为四块--heap(栈).s