介绍:在开发中,我们经常需要一些周期性就进行某一项操作。这时候我们就要去设置个定时器,Java中最方便、最高效的实现方式是用java.util.Timer工具类,再通过调度java.util.TimerTask任务的操作,例如每隔几分钟。
用途:主要应用在一些需要指定时间执行的任务操作,例如银行卡输错密码,游戏账号被封,公司统计数据等等,发生在我们周围,比较常用。
简介:Timer是一种工具,线程用其安排以后在后台线程中执行的任务。可安排任务执行一次,或者定期重复执行。实际上是个线程,定时调度所拥有的TimerTasks。
TimerTask是一个抽象类,它的子类由 Timer 安排为一次执行或重复执行的任务。实际上就是一个拥有run方法的类,需要定时执行的代码放到run方法体内。
常用的属性:
delay:延迟执行
cancel:关闭
period:固定频率
fixedRate:每隔多少毫秒执行一次该方法,如:@Scheduled(fixedRate=2000)
fixedDelay:当一次方法执行完毕之后,延迟多少毫秒再执行该方法。
cron:详细配置了该方法在什么时候执行。cron值是一个cron表达式
实现:
在JAVA中实现定时器功能要用的二个类是Timer,TimerTaskTimer类是用来执行任务的类,它接受一个TimerTask做参数Timer有两种执行任务的模式,最常用的是schedule,它可以以两种方式执行任务:
1:在某个时间(Data)
2:在某个固定的时间之后(int delay).
共同点:这两种方式都可以指定任务执行的频率,
还有一种是scheduleAtFixedRate
区别在于,如果指定开始执行的时间在当前系统运行时间之前,scheduleAtFixedRate会把已经过去的时间也作为周期执行,而schedule不会把过去的时间算上。
public static void ceshi(){
Timer t=new Timer();
SimpleDateFormat fTime = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date d1 = null;
try {
d1 = fTime.parse("2016/6/4 22:59:00");
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
schedule(new TimerTask(){
public void run()
{
System.out.println("this is task you do6");
}
},d1,3*60*1000);
}
schedule的时候如果时间超过设定时间的话,他只会立即执行一次然后按照规定的时间设置执行,而 scheduleAtFixedRate会将已过去的时间也计算在内,即超过多少次就执行多少次然后再按照规定时间执行
基于注解方式(简单,维护难):
xmlns 多加下面的内容、
xmlns:task="http://www.springframework.org/schema/task"
然后xsi:schemaLocation多加下面的内容
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd
最后是我们的task任务扫描注解
<task:annotation-driven/>
扫描位置是:
<context:component-scan base-package="com.test"/>
1. @Component //import org.springframework.stereotype.Component;
2. public class MyTestServiceImpl implements IMyTestService {
3. @Scheduled(cron="0/5 * * * * ? ") //每5秒执行一次
4. @Override
5. public void myTest(){
6. System.out.println("进入测试");
7. }
8. }
执行后控制台就会打印出 进入测试 了
注意:定时器的任务方法不能有返回值(如果有返回值,spring初始化的时候会告诉你有个错误、需要设定一个proxytargetclass的某个值为true)
秒0-59 , - * /分0-59 , - * /小时0-23 , - * /日1-31 , - * ? / L W C月1-12 or JAN-DEC , - * /周几1-7 or SUN-SAT , - * ? / L C #年(可选字段) empty, 1970-2099 , - * /
“*”——字符可以用于所有字段,在“分”字段中设为"*"表示"每一分钟"的含义。“?”——字符可以用在“日”和“周几”字段.它用来指定'不明确的值'.这在你需要指定这两个字段中的某一个值而不是另外一个的时候会被用到。在后面的例子中可以看到其含义。“-”——字符被用来指定一个值的范围,比如在“小时”字段中设为"10-12"表示"10点到12点"。“,”——字符指定数个值。比如在“周几”字段中设为"MON,WED,FRI"表示"the days Monday, Wednesday, and Friday"。“/”——字符用来指定一个值的的增加幅度.比如在“秒”字段中设置为"0/15"表示"第0, 15, 30,和45秒"。而"5/15"则表示"第5, 20, 35,和50".在'/'前加"*"字符相当于指定从0秒开始.每个字段都有一系列可以开始或结束的数值。对于“秒”和“分”字段来说,其数值范围为0到59,对于“小时”字段来说其为0到23,对于“日”字段来说为0到31,而对于“月”字段来说为1到12。"/"字段仅仅只是帮助你在允许的数值范围内从开始"第n"的值。“L”——字符可用在“日”和“周几”这两个字段。它是"last"的缩写,但是在这两个字段中有不同的含义。例如,“日”字段中的"L"表示"一个月中的最后一天" ——对于一月就是31号对于二月来说就是28号(非闰年)。而在“周几”字段中,它简单的表示"7" or "SAT",但是如果在“周几”字段中使用时跟在某个数字之后,它表示"该月最后一个星期×" ——比如"6L"表示"该月最后一个周五"。当使用'L'选项时,指定确定的列表或者范围非常重要,否则你会被结果搞糊涂的。“W”——可用于“日”字段。用来指定历给定日期最近的工作日(周一到周五)。比如你将“日”字段设为"15W",意为: "离该月15号最近的工作日"。因此如果15号为周六,触发器会在14号即周五调用。如果15号为周日,触发器会在16号也就是周一触发。如果15号为周二,那么当天就会触发。然而如果你将“日”字段设为"1W",而一号又是周六,触发器会于下周一也就是当月的3号触发,因为它不会越过当月的值的范围边界。'W'字符只能用于“日”字段的值为单独的一天而不是一系列值的时候。“L”和“W”可以组合用于“日”字段表示为'LW',意为"该月最后一个工作日"。“#”——字符可用于“周几”字段。该字符表示“该月第几个周×”,比如"6#3"表示该月第三个周五( 6表示周五而"#3"该月第三个)。再比如: "2#1" =表示该月第一个周一而"4#5" =该月第五个周三。注意如果你指定"#5"该月没有第五个“周×”,该月是不会触发的。“C”——字符可用于“日”和“周几”字段,它是"calendar"的缩写。它表示为基于相关的日历所计算出的值(如果有的话)。如果没有关联的日历,那它等同于包含全部日历。“日”字段值为"5C"表示"日历中的第一天或者5号以后",“周几”字段值为"1C"则表示"日历中的第一天或者周日以后"。对于“月份”字段和“周几”字段来说合法的字符都不是大小写敏感的。
基于XML
xml文件引入
xmlns:task=" http://www.springframework.org/schema/task
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd
指定要执行的类名称,地址i
<bean id="stuController" class="com.jk.controller.StuController"></bean>
指定要执行的方法时间
<task:scheduled-tasks>
<task:scheduled ref="stuController" method="selectStudentList" cron="0/9 * * * * ? "/>
</task:scheduled-tasks>
这是spring3.0版本之前的配置比较繁琐:
<bean id="timer" class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks">
<list>
<ref local="MyScheduledTimerTask" />
</list>
</property>
</bean>
<bean id="CleanEntryEventCacheTask" class="com.jk.controller.JobTest">
</bean>
<bean id="MyScheduledTimerTask" class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="timerTask">
<ref bean="CleanEntryEventCacheTask" />
</property>
<property name="delay">
<value>1000</value>
</property>
<property name="period">
<value>6000</value>
</property>
</bean>
注意:加入定时器的时候方法必须是无参,无返回值
加入maven项目时由于定时器使用的是spring3.0版本,而maven是4.0,所以如果在maven项目中使用需要将spring3.0版本jar包导入仓库repository中则可以直接使用