java中的定时任务, 使用java实现有3种方式:
1, 使用普通thread实现
@Testpublic voidtest1() {//单位: 毫秒
final long timeInterval = 1000;
Runnable runnable= newRunnable() {public voidrun() {while (true) {//------- code for task to run
System.out.println("Hello !!");//------- ends here
try{
Thread.sleep(timeInterval);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
};
Thread thread= newThread(runnable);
thread.start();
}
2, 使用timer实现: 可控制启动或取消任务, 可指定第一次执行的延迟
线程安全, 但只会单线程执行, 如果执行时间过长, 就错过下次任务了, 抛出异常时, timerWork会终止
@Testpublic voidtest2 () {
TimerTask task= newTimerTask() {
@Overridepublic voidrun() {
System.out.println("Hello !!!");
}
};
Timer timer= newTimer();long delay = 0;long intevalPeriod = 1 * 1000;//schedules the task to be run in an interval
timer.scheduleAtFixedRate(task, delay, intevalPeriod);
}
3, 使用 ScheduledExcecutorService 实现
ScheduledExecutorService 是java.util.concurrent种的额一个累, 用于实现定时任务
它可以: 1, 通过线程池的方式执行任务
2, 设定第一次的延迟事件
3, 提供良好的约定, 设定时间间隔
@Testpublic voidtest() {
Runnable runnable= newRunnable() {public voidrun() {
System.out.println("Hello !!");
}
};
ScheduledExecutorService service=Executors
.newSingleThreadScheduledExecutor();//第二个参数为首次执行的延时时间,第三个参数为定时执行的间隔时间
service.scheduleAtFixedRate(runnable, 10, 1, TimeUnit.SECONDS);
}
4, 使用spring的 spring-task 实现
第一种方式, 注解的方式实现
@Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documentedpublic @interfaceScheduled
{public abstractString cron();public abstract longfixedDelay();public abstract longfixedRate();
}
fixedDelay: 设定间隔时间为 5000ms
fixedRate: 设定固定速率, 以固定速率5s来执行
cron="0 0 2 * * ? ": 使用时间表达式
第二种方式, 配置文件配置的方式实现
/* taskJob 为执行任务类, job1 为执行的函数*/
2, 添加配置信息
3, 代码实现
@Scheduled(fixedDelay = 5000)public voiddoSomething() {//something that should execute periodically
}
时间表达式
一个cron表达式有至少6个(也可能7个)有空格分隔的时间元素。
按顺序依次为
秒(0~59)
分钟(0~59)
小时(0~23)
天(月)(0~31,但是你需要考虑你月的天数)
月(0~11)
天(星期)(1~7 1=SUN 或 SUN,MON,TUE,WED,THU,FRI,SAT)
年份(1970-2099)
常用的表达式为:
0 0 10,14,16 * * ?每天上午10点,下午2点,4点0 0/30 9-17 * * ?朝九晚五工作时间内每半小时0 0 12 ? *WED 表示每个星期三中午12点"0 0 12 * * ?"每天中午12点触发"0 15 10 ? * *"每天上午10:15触发"0 15 10 * * ?"每天上午10:15触发"0 15 10 * * ? *"每天上午10:15触发"0 15 10 * * ? 2005"2005年的每天上午10:15触发"0 * 14 * * ?"在每天下午2点到下午2:59期间的每1分钟触发"0 0/5 14 * * ?"在每天下午2点到下午2:55期间的每5分钟触发"0 0/5 14,18 * * ?"在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发"0 0-5 14 * * ?"在每天下午2点到下午2:05期间的每1分钟触发"0 10,44 14 ? 3 WED"每年三月的星期三的下午2:10和2:44触发"0 15 10 ? * MON-FRI"周一至周五的上午10:15触发"0 15 10 15 * ?"每月15日上午10:15触发"0 15 10 L * ?"每月最后一日的上午10:15触发"0 15 10 ? * 6L"每月的最后一个星期五上午10:15触发"0 15 10 ? * 6L 2002-2005"2002年至2005年的每月的最后一个星期五上午10:15触发"0 15 10 ? * 6#3" 每月的第三个星期五上午10:15触发
5, 使用 第三方插件 Quartz实现
maven依赖
org.quartz-scheduler
quartz
2.2.1
5. 1) 可以设置一个类, 继承自 QuartzJobBean
1, 配置文件:
2, 配置调度工厂:
3, 定义作业类:
public class Job1 extendsQuartzJobBean {private inttimeout;private static int i = 0;//调度工厂实例化后,经过timeout时间开始执行调度
public void setTimeout(inttimeout) {this.timeout =timeout;
}/*** 要调度的具体任务*/@Overrideprotected void executeInternal(JobExecutionContext context) throwsJobExecutionException {
System.out.println("定时任务执行中…");
}
}
5.2) 直接写一个普通类, 在配置中进行配置
任务类:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;/**
* 定时删除用户收听过的poi
* @author wenbronk
* @time 2017年3月28日 下午2:01:09 2017*/
public classDelListenerPOIScheduler {
@AutowiredprivateStringRedisTemplate redisTemplate;public voiddoCheck() {
System.out.println("定时任务执行了....");
}
}
配置文件:
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
6, 在springboot中实现定时任务:
package com.iwhere.base.scheduling;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;/**
* 整合定时任务
* EnableScheduling 实现spring中的task功能
* @Scheduled中配置时间表达式
* @author 231
**/@Configuration//相当于配置beans,
@EnableScheduling //, 让spring进行任务调度
public classSchedulingConfig {
@Scheduled(cron="0/20 * * * * ?") //20秒执行一次
public voidscheduler() {
System.out.println("定时任务执行了");
}
}
7, Springboot 集成 quartz
为什么非要集成呢, 因为quartz支持集群定时任务, 现在还用不到, 防止以后用到
1, 配置quartz的配置信息类
package com.iwhere.easy.travel.timeschedule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;/**
* quartz的配置信息
* @author wenbronk
* @time 2017年3月29日 下午5:20:29 2017*/@Configurationpublic classTimeScheduleConfig {
@Bean(name= "detailFactoryBean")publicMethodInvokingJobDetailFactoryBean detailFactoryBean(DelListenerPOIScheduler scheduledTasks) {
MethodInvokingJobDetailFactoryBean bean= newMethodInvokingJobDetailFactoryBean();//这儿设置对应的Job对象
bean.setTargetObject(scheduledTasks);//这儿设置对应的方法名 与执行具体任务调度类中的方法名对应
bean.setTargetMethod("doCheck");
bean.setConcurrent(false);returnbean;
}
@Bean(name= "cronTriggerBean")publicCronTriggerFactoryBean cronTriggerBean(MethodInvokingJobDetailFactoryBean detailFactoryBean) {
CronTriggerFactoryBean trigger= newCronTriggerFactoryBean();
trigger.setJobDetail(detailFactoryBean.getObject());try{
trigger.setCronExpression("0 0 1 * * ?");//每天1点执行一次
} catch(Exception e) {
e.printStackTrace();
}returntrigger;
}
@BeanpublicSchedulerFactoryBean schedulerFactory(CronTriggerFactoryBean cronTriggerBean) {
SchedulerFactoryBean schedulerFactory= newSchedulerFactoryBean();
schedulerFactory.setTriggers(cronTriggerBean.getObject());returnschedulerFactory;
}
}
2), 具体的作业类
package com.iwhere.easy.travel.timeschedule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Component;/**
* 定时删除用户收听过的poi
* @author wenbronk
* @time 2017年3月28日 下午2:01:09 2017*/@Component
@Configurable
@EnableSchedulingpublic classDelListenerPOIScheduler {private Logger LOGGER = LoggerFactory.getLogger(DelListenerPOIScheduler.class);
@AutowiredprivateStringRedisTemplate redisTemplate;public voiddoCheck() {try{
String key= "noteUserListenedPoi:*";
redisTemplate.delete(key);
LOGGER.info("redis中用户收听历史被清空");
}catch(Exception e) {
e.printStackTrace();
LOGGER.error("redis删除用户收听记录失败");
}
}
}
系列原创, 转载请注明出处, 谢谢 @Wenbronk: http://www.cnblogs.com/wenbronk/p/6433178.html