一、Timer
API描述:对应于每个Timer对象是单个后台线程,用于依次执行所有定时器的任务。 计时器任务应该快速完成。 如果一个定时器任务需要花费很多时间来完成,它会“计时”计时器的任务执行线程。 这可能会延迟随后的任务的执行,这些任务在(和)如果违规任务最后完成时,可能会“束起来”并快速执行。(**Timer是单线程执行任务**,在执行任务期间可能出现前个任务未执行完毕,后个定时任务时间已经到了,但还是会等待前个任务执行完毕你)
1、项目启动初始化对象
@Component
public class Runner implements CommandLineRunner {
@Autowired
private TimerDemo timerDemo;
@Override
public void run(String... args) throws Exception {
timerDemo.test();
System.out.println("CommandLineRunner执行");
}
}
2、定时任务类
@Component
public class TimerDemo {
public void test(){
Timer timer = new Timer();
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
System.out.println("定时任务执行了"+new Date());
}
};
//执行timerTask内的run方法
//固定延迟1000后执行
timer.schedule(timerTask,0,1000);
/**timerTask - 要安排的任务。
delay - 执行任务之前以毫秒为单位的延迟。
period - 连续执行任务之间的时间(以毫秒为单位)。*/
//固定速率执行,包含了任务执行的时间
timer.scheduleAtFixedRate(timerTask,0,1000);
}
}
3、结果
CommandLineRunner执行
定时任务执行了Wed Oct 09 15:21:35 GMT+08:00 2019
定时任务执行了Wed Oct 09 15:21:36 GMT+08:00 2019
定时任务执行了Wed Oct 09 15:21:37 GMT+08:00 2019
二、ScheduledThreadPoolExecutor
API描述:一个并发实用程序是ScheduledThreadPoolExecutor ,它是用于以给定速率或延迟重复执行任务的线程池。 这实际上是对一个更灵活的替代Timer / TimerTask组合,因为它**允许多个服务线程**,接受各种时间单位,并且不需要子类TimerTask (只实现Runnable )。 使用一个线程配置ScheduledThreadPoolExecutor使其等同于Timer 。
**继承实现关系:public class ScheduledThreadPoolExecutor extends ThreadPoolExecutor
implements ScheduledExecutorService**
//创建定时任务
ScheduledThreadPoolExecutor scheduled = new ScheduledThreadPoolExecutor(2);
scheduled.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println("Timer"+ Thread.currentThread().getName());
System.out.println("time:");
}
}, 0, 1000, TimeUnit.MILLISECONDS);//0表示首次执行任务的延迟时间,40表示每次执行任务的间隔时间,TimeUnit.MILLISECONDS执行的时间间隔数值单位
//调用定时任务
@Autowired
private ThreadPoolTimer threadPoolTimer;
@Override
public void run(String... args) throws Exception {
ScheduledThreadPoolExecutor scheduled = new ScheduledThreadPoolExecutor(2);
scheduled.execute(new Runnable() {
@Override
public void run() {
System.out.println("222222"+Thread.currentThread().getName());
threadPoolTimer.timerMethod();
}
});
scheduled.purge();
System.out.println("CommandLineRunner执行");
System.out.println("主線程" + Thread.currentThread().getName());
控制台
CommandLineRunner执行
222222pool-1-thread-2
主線程main
Timerpool-2-thread-1
time: