1.Thread.sleep(),让线程休眠挂起,等待一段时间后再执行,可参考如下代码:
// 提前的业务逻辑 xxx
try {
Thread.sleep(2000); // 睡眠2s
} catch(Exception e){
// ...
}
// 定时任务的业务逻辑
2.利用java.util包下的Timer和TimerTask, TimeTask抽象类实现了Runnable接口,只需要封装一下TimerTask类,再结合Timer类中schedule(....)方法,即可实现定时任务,可参考如下代码使用:
new Timer("schedued").schedule(new TimerTask(){
@Override
public void run() {
System.out.println("test Timer Task");
}
}, 100, 10000);
3.利用线程池:Executors提供几种创建线程池的方式,当然除了常见的创建固定大小的线程池之外,还有个就是通过ScheduledExecutorService来实现定时任务调度。
借助Executors#newScheduledThreadPool来实现定时任务非常简单,如下所示:
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1); // 获取线程池
executorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println("task: " + System.currentTimeMillis());
}
}, 100, 100, TimeUnit.MILLISECONDS); // 100ms后,首次执行,然后每个100ms执行一次
实际上和Timer的方法类似
4.借助spring,spring提供了强大的功能,支持注解的配置方式,配置完成后在对应的方法上加上注解即可实现定时任务,但是不得不提一下cron表达式,它是一个字符串,字符串以5或6个空格隔开,分开工6或7个域,每一个域都代表一个含义,是spring task的强大功能,常见的cron表达式可参考另一篇博客:定时任务实现(Spring注解),部分功能代码用法如下:
配置文件XML:
业务逻辑:
@Component
public class ScheduleDemo {
@Scheduled(cron = "0 0 5 * * ?")
public void checkData() {
System.out.println(" 校验: " + System.currentTimeMillis());
}
@Scheduled(cron = "0 0 6 * * ?")
public void alarm(){
System.out.println(" 报警: " + System.currentTimeMillis());
}
}
5.使用LTS任务调度,LTS主要用于解决分布式任务调度问题,支持实时任务,定时任务和Cron任务。有较好的伸缩性,扩展性。代码也很简单,参考如下:
配置好LTS的环境:
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@EnableLTSScheduling(configLocation = "classpath:/lts.properties")
public class JobConfig {
@Bean
public OneOffJobClient oneOffJobClient(){
return new OneOffJobClient();
}
}
引用提交任务:
@Scheduled(cron = "0 01 0 1 * ?") //每月的1号0点1分
@JobRunnerItem(shardValue = "efmt.company.savePositionHistoryRecords")
public void queryCompanyAssets(){
positionDomain.savePositionHistoryRecords();
}
使用小建议
不推荐使用 Thread#sleep的方式做定时任务
如指向利用jdk实现定时任务,可以考虑 Timer
和 ScheduledExecutorService
如项目本身就利用到了Spring,可以优先考虑优秀的框架提供的服务,如LTS
本文参考连接:https://my.oschina.net/u/566591/blog/1579950