使用Timer
package com.example.Scheduled;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
/**
* 使用Timer
*/
public class TimerTest {
public static void main(String[] args) {
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
System.out.println("task run:"+ new Date());
}
};
Timer timer = new Timer();
//安排指定的任务在指定的时间开始进行重复的固定延迟执行。这里是每3秒执行一次
timer.schedule(timerTask,10,3000);
}
}
task run:Sun Oct 07 17:12:14 CST 2018
task run:Sun Oct 07 17:12:17 CST 2018
task run:Sun Oct 07 17:12:20 CST 2018
task run:Sun Oct 07 17:12:23 CST 2018
task run:Sun Oct 07 17:12:26 CST 2018
task run:Sun Oct 07 17:12:29 CST 2018
task run:Sun Oct 07 17:12:32 CST 2018
使用ScheduledExecutorService
package com.example.Scheduled;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* 使用ScheduledExecutorService
* 与Timer类似
*/
public class ScheduledExecutorServiceTest {
public static void main(String[] args) {
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
// 参数:1、任务体 2、首次执行的延时时间 3、任务执行间隔 4、间隔时间单位
service.scheduleAtFixedRate(()->System.out.println("task ScheduledExecutorService "+new Date()), 0, 3, TimeUnit.SECONDS);
}
}
task ScheduledExecutorService Sun Oct 07 17:15:30 CST 2018
task ScheduledExecutorService Sun Oct 07 17:15:33 CST 2018
task ScheduledExecutorService Sun Oct 07 17:15:36 CST 2018
task ScheduledExecutorService Sun Oct 07 17:15:39 CST 2018
task ScheduledExecutorService Sun Oct 07 17:15:42 CST 2018
使用Spring Task
- 创建定时任务
package com.example.Scheduled;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
* 创建定时任务
* 单线程
*/
@Component
public class ScheduledTasks {
private Logger logger = LoggerFactory.getLogger(ScheduledTasks.class);
private int fixedDelayCount = 1;
private int fixedRateCount = 1;
private int initialDelayCount = 1;
private int cronCount = 1;
//fixedDelay = 5000表示当前方法执行完毕5000ms后,Spring scheduling会再次调用该方法
@Scheduled(fixedDelay = 5000)
public void testFixDelay() {
logger.info("===fixedDelay: 第{}次执行方法", fixedDelayCount++);
}
//fixedRate = 5000表示当前方法开始执行5000ms后,Spring scheduling会再次调用该方法
@Scheduled(fixedRate = 5000)
public void testFixedRate() {
logger.info("===fixedRate: 第{}次执行方法", fixedRateCount++);
}
//initialDelay = 1000表示延迟1000ms执行第一次任务
@Scheduled(initialDelay = 1000, fixedRate = 5000)
public void testInitialDelay() {
logger.info("===initialDelay: 第{}次执行方法", initialDelayCount++);
}
//cron接受cron表达式,根据cron表达式确定定时规则
@Scheduled(cron = "0 0/1 * * * ?")
public void testCron() {
logger.info("===initialDelay: 第{}次执行方法", cronCount++);
}
}
@Scheduled源码可以看出它支持多种参数:
- cron:cron表达式,指定任务在特定时间执行;
- fixedDelay:表示上一次任务执行完成后多久再次执行,参数类型为long,单位ms;
- fixedDelayString:与fixedDelay含义一样,只是参数类型变为String;
- fixedRate:表示按一定的频率执行任务,参数类型为long,单位ms;
- fixedRateString: 与fixedRate的含义一样,只是将参数类型变为String;
- initialDelay:表示延迟多久再第一次执行任务,参数类型为long,单位ms;
- initialDelayString:与initialDelay的含义一样,只是将参数类型变为String;
- zone:时区,默认为当前时区,一般没有用到。
- 开启定时任务
添加@EnableScheduling注解,其作用是发现注解@Scheduled的任务并由后台执行
package com.example.Scheduled;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
2018-10-07 17:31:05.359 INFO 15828 --- [pool-1-thread-1] com.example.Scheduled.ScheduledTasks : ===fixedRate: 第1次执行方法
2018-10-07 17:31:05.359 INFO 15828 --- [pool-1-thread-1] com.example.Scheduled.ScheduledTasks : ===fixedDelay: 第1次执行方法
2018-10-07 17:31:05.393 INFO 15828 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2018-10-07 17:31:05.397 INFO 15828 --- [ main] com.example.Scheduled.Application : Started Application in 4.692 seconds (JVM running for 6.607)
2018-10-07 17:31:06.361 INFO 15828 --- [pool-1-thread-1] com.example.Scheduled.ScheduledTasks : ===initialDelay: 第1次执行方法
2018-10-07 17:31:10.361 INFO 15828 --- [pool-1-thread-1] com.example.Scheduled.ScheduledTasks : ===fixedRate: 第2次执行方法
2018-10-07 17:31:10.361 INFO 15828 --- [pool-1-thread-1] com.example.Scheduled.ScheduledTasks : ===fixedDelay: 第2次执行方法
2018-10-07 17:31:11.361 INFO 15828 --- [pool-1-thread-1] com.example.Scheduled.ScheduledTasks : ===initialDelay: 第2次执行方法
2018-10-07 17:31:15.361 INFO 15828 --- [pool-1-thread-1] com.example.Scheduled.ScheduledTasks : ===fixedRate: 第3次执行方法
2018-10-07 17:31:15.362 INFO 15828 --- [pool-1-thread-1] com.example.Scheduled.ScheduledTasks : ===fixedDelay: 第3次执行方法
2018-10-07 17:31:16.360 INFO 15828 --- [pool-1-thread-1] com.example.Scheduled.ScheduledTasks : ===initialDelay: 第3次执行方法
多线程处理
package com.example.Scheduled;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import java.util.concurrent.Executors;
/**
* 多线程
*/
@Configuration
public class SchedulerConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
//设定一个长度10的定时任务线程池
taskRegistrar.setScheduler(Executors.newScheduledThreadPool(10));
}
}
2018-10-07 17:42:11.768 INFO 5880 --- [pool-1-thread-1] com.example.Scheduled.ScheduledTasks : ===fixedRate: 第1次执行方法
2018-10-07 17:42:11.768 INFO 5880 --- [pool-1-thread-2] com.example.Scheduled.ScheduledTasks : ===fixedDelay: 第1次执行方法
2018-10-07 17:42:11.801 INFO 5880 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2018-10-07 17:42:11.805 INFO 5880 --- [ main] com.example.Scheduled.Application : Started Application in 4.892 seconds (JVM running for 6.729)
2018-10-07 17:42:12.769 INFO 5880 --- [pool-1-thread-3] com.example.Scheduled.ScheduledTasks : ===initialDelay: 第1次执行方法
2018-10-07 17:42:16.770 INFO 5880 --- [pool-1-thread-1] com.example.Scheduled.ScheduledTasks : ===fixedRate: 第2次执行方法
2018-10-07 17:42:16.770 INFO 5880 --- [pool-1-thread-2] com.example.Scheduled.ScheduledTasks : ===fixedDelay: 第2次执行方法
2018-10-07 17:42:17.768 INFO 5880 --- [pool-1-thread-4] com.example.Scheduled.ScheduledTasks : ===initialDelay: 第2次执行方法
2018-10-07 17:42:21.769 INFO 5880 --- [pool-1-thread-5] com.example.Scheduled.ScheduledTasks : ===fixedRate: 第3次执行方法
2018-10-07 17:42:21.771 INFO 5880 --- [pool-1-thread-6] com.example.Scheduled.ScheduledTasks : ===fixedDelay: 第3次执行方法
2018-10-07 17:42:22.769 INFO 5880 --- [pool-1-thread-3] com.example.Scheduled.ScheduledTasks : ===initialDelay: 第3次执行方法
使用core表达式
- 单线程
package com.example.Scheduled;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
* 使用corn表达式
*/
@Component
public class ScheduledTest {
private static final Logger logger = LoggerFactory.getLogger(ScheduledTest.class);
@Scheduled(cron="0 0/2 8-20 * * ?")
public void executeFileDownLoadTask() {
// 间隔2分钟,执行工单上传任务
Thread current = Thread.currentThread();
System.out.println("定时任务1:"+current.getId());
logger.info("ScheduledTest.executeFileDownLoadTask 定时任务1:"+current.getId()+ ",name:"+current.getName());
}
@Scheduled(cron="0 0/1 8-20 * * ?")
public void executeUploadTask() {
// 间隔1分钟,执行工单上传任务
Thread current = Thread.currentThread();
System.out.println("定时任务2:"+current.getId());
logger.info("ScheduledTest.executeUploadTask 定时任务2:"+current.getId() + ",name:"+current.getName());
}
@Scheduled(cron="0 0/3 5-23 * * ?")
public void executeUploadBackTask() {
// 间隔3分钟,执行工单上传任务
Thread current = Thread.currentThread();
System.out.println("定时任务3:"+current.getId());
logger.info("ScheduledTest.executeUploadBackTask 定时任务3:"+current.getId()+ ",name:"+current.getName());
}
}
定时任务1:37
2018-10-07 17:52:00.001 INFO 2964 --- [pool-1-thread-1] com.example.Scheduled.ScheduledTest : ScheduledTest.executeFileDownLoadTask 定时任务1:37,name:pool-1-thread-1
定时任务2:37
2018-10-07 17:52:00.002 INFO 2964 --- [pool-1-thread-1] com.example.Scheduled.ScheduledTest : ScheduledTest.executeUploadTask 定时任务2:37,name:pool-1-thread-1
定时任务2:37
2018-10-07 17:53:00.006 INFO 2964 --- [pool-1-thread-1] com.example.Scheduled.ScheduledTest : ScheduledTest.executeUploadTask 定时任务2:37,name:pool-1-thread-1
- 多线程
package com.example.Scheduled;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import java.util.concurrent.Executors;
/**
* 多线程
*/
@Configuration
public class SchedulerConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
//设定一个长度10的定时任务线程池
taskRegistrar.setScheduler(Executors.newScheduledThreadPool(10));
}
}
定时任务2:37
2018-10-07 18:01:00.001 INFO 13836 --- [pool-1-thread-1] com.example.Scheduled.ScheduledTest : ScheduledTest.executeUploadTask 定时任务2:37,name:pool-1-thread-1
定时任务1:38
2018-10-07 18:02:00.000 INFO 13836 --- [pool-1-thread-2] com.example.Scheduled.ScheduledTest : ScheduledTest.executeFileDownLoadTask 定时任务1:38,name:pool-1-thread-2
定时任务2:38
2018-10-07 18:02:00.002 INFO 13836 --- [pool-1-thread-2] com.example.Scheduled.ScheduledTest : ScheduledTest.executeUploadTask 定时任务2:38,name:pool-1-thread-2