「这是我参与2022首次更文挑战的第16天,活动详情查看:2022首次更文挑战」
Timer
java自带的Timer
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("Time's up!");
}
},3000L,1000);
解释:3000ms是延迟启动时间,1000ms是定时任务周期,每1s执行一次
Timer计时器可以定时(指定时间执行任务)、延迟(延迟5秒执行任务)、周期性地执行任务(每隔个1秒执行任务),但是,Timer存在一些缺陷。首先Timer对调度的支持是基于绝对时间的,而不是相对时间,所以它对系统时间的改变非常敏感。其次Timer线程是不会捕获异常的,如果TimerTask抛出的了未检查异常则会导致Timer线程终止,同时Timer也不会重新恢复线程的执行,他会错误的认为整个Timer线程都会取消。同时,已经被安排单尚未执行的TimerTask也不会再执行了,新的任务也不能被调度。故如果TimerTask抛出未检查的异常,Timer将会产生无法预料的行为。
ScheduledThreadPool-线程池
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(2);
scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println("=========================");
}
}, 1000, 2000, TimeUnit.MILLISECONDS);
scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println(System.currentTimeMillis()+"<><>"+System.nanoTime());
}
}, 1000, 2000, TimeUnit.MILLISECONDS);
使用注解的形式:@Scheduled
@Component
public class SpringScheduled {
@Scheduled(initialDelay = 2000,fixedDelay = 5000)
public void doSomething() {
System.out.println("Spring自带的Scheduled执行了=======================");
}
}
@SpringBootApplication
@EnableScheduling
public class DemoApplication {
public static void main(String[] args) throws InterruptedException {
SpringApplication application = new SpringApplication(DemoApplication.class);
application.addListeners(new ContextRefreshedEventListener());
application.run(args);
}
}
使用Quartz定时任务调度器
@Configuration
public class QuartzConfig {
@Resource
private ScheduleTask scheduleTask;
/**
* 配置定时任务1
* @return
*/
@Bean(name="firstJobDetail")
public MethodInvokingJobDetailFactoryBean firstJobDetail(){
MethodInvokingJobDetailFactoryBean method = new MethodInvokingJobDetailFactoryBean();
// 为需要执行的实体类对应的对象
method.setTargetObject(scheduleTask);
// 需要执行的方法
method.setTargetMethod("test");
// 是否并发执行
method.setConcurrent(false);
return method;
}
/**
* 配置触发器1
* @param firstJobDetail
* @return
*/
@Bean(name="firstTrigger")
public SimpleTriggerFactoryBean firstTrigger(JobDetail firstJobDetail){
SimpleTriggerFactoryBean simpleBean = new SimpleTriggerFactoryBean();
simpleBean.setJobDetail(firstJobDetail);
// 设置任务启动延迟
simpleBean.setStartDelay(1000);
// 每1秒执行一次
simpleBean.setRepeatInterval(1000);
//设置重复计数
//simpleBean.setRepeatCount(0);
return simpleBean;
}
/**
* 配置Scheduler
*/
@Bean(name = "scheduler")
public SchedulerFactoryBean schedulerFactoryBean(Trigger firstTrigger){
SchedulerFactoryBean factoryBean = new SchedulerFactoryBean();
factoryBean.setTriggers(firstTrigger);
return factoryBean;
}
}
@Component
public class ScheduleTask {
public void test() {
System.out.println("====================================");
}
}
总结
- Quartz是执行时间和间隔时间的最大值(比如;执行时间是3s,间隔是2s,则每3s执行一次;执行时间是3s,间隔是5s,则每5s执行一次。)
- Spring task是执行时间+间隔时间(比如;执行时间是3s,间隔是2s,则每5s执行一次;执行时间是3s,间隔是5s,则每8s执行一次。)
- timer有2中方法schedule和scheduleAtFixedRate,前者会等任务结束在开始计算时间间隔,后者是在任务开始就计算时间,有并发的情况
- ScheduledExecutorService的scheduleAtFixedRate类似Quartz,scheduleWithFixedDelay类似SpringTask