在实际开发中,我们难免要遇到需要定时去执行的服务,这时候我们首先想到的就是专业执行定时任务的框架Quartz,但是很明显,一个非常简单的任务,去使用一个框架,还是比较麻烦的,工作量也略大,那么有没有什么方式可以简单的帮我们执行定时任务呢?这里简单列举几个常用的执行定时任务的方案
一、jdk自带的Timer
public Timer timer() {
//创建TimerTask的匿名内部类,重写抽象方法,run方法中定义具体执行的任务
TimerTask t=new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"使用timer实现的定时任务1");
}
};
//创建timer对象,(执行定时任务的对象)
Timer timer=new Timer();
//在1秒之后开始每5秒执行一次t中run方法的任务
timer.schedule(t,1000,5000);
System.out.println("______");
return timer;
}
注意:次方法是单线程串行执行的定时任务,也就意味着一个任务异常另一个也就卡主了,或者停止了
二、jdk自带的ScheduledExecutorService执行定时任务
这方法与Timer比较类似,秉承了一贯的简单易用的风格,但我们可以选择是单线程串行执行还是多线程并行执行,这就很方便了!
public ScheduledExecutorService ses() {
//单线程串行执行定时任务,我们也可以使用newScheduledThreadPool()方法指定线程工厂对象和线程数,使定时任务在
//多线程并行执行
ScheduledExecutorService s=Executors.newSingleThreadScheduledExecutor();
//执行定时任务,1秒后每隔5秒执行一个任务
s.scheduleAtFixedRate(
//jdk1.8的新特性,lambda表达式,可以看做是runnable的一个匿名内部类对象
()->System.out.println(Thread.currentThread().getName()+"使用ScheduledExecutorService执行定时任务1")
,1, 5,
//单位
TimeUnit.SECONDS);
return s;
}
三、使用spring给我们提供的定时任务方法
该方法简单易用,第一步是在主启动类添加@EnableScheduling
注解,以提供对定时任务的支持
然后在执行定时任务的类添加@Component
注解,,最后在执行定时任务的方法上添加@Scheduled(fixedDelay = 5000)
注解就可以按照定义的时间定时执行方法中的代码了,是不是非常简单!
@Scheduled(fixedDelay = 5000)
public void ss() {
System.out.println(Thread.currentThread().getName()+"使用spring自带的定时任务执行1");
}
我们通过测试也会发现这个定时任务也是单线程串行执行的,那么如果我们需要多线程并行执行呢?spring当然也想到这个问题了!我们只需要另外在跑配置类中配置线程池对象,然后在配置类添加@EnableAsync
注解,再在定时任务方法上添加@Async
注解以开启对异步的支持就可以了
@EnableAsync
@Component
public class Timing {
@Bean
public Executor executor() {
ThreadPoolTaskExecutor e=new ThreadPoolTaskExecutor();
e.setCorePoolSize(5);
e.setMaxPoolSize(20);
e.setQueueCapacity(3);
e.initialize();
return e;
}
}
下面我把我的完成demo贴出来,测试用的,就简简单单把上面这些方法都写到一个类里面了,将就看哈……
package com.wwy.test.timing;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
/**
* 创建定时任务的demo
* @author wwy
* @date 2019年12月11日
* @version v0.0.1
*
*/
@EnableAsync
@Component
public class Timing {
@Bean
public Executor executor() {
ThreadPoolTaskExecutor e=new ThreadPoolTaskExecutor();
e.setCorePoolSize(5);
e.setMaxPoolSize(20);
e.setQueueCapacity(3);
e.initialize();
return e;
}
/**
* 使用jdk自带的Timer实现定时任务(单线程串行执行)
*/
@Bean
public Timer timer() {
//创建TimerTask的匿名内部类,重写抽象方法,run方法中定义具体执行的任务
TimerTask t=new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"使用timer实现的定时任务1");
}
};
TimerTask t2=new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"使用timer实现的定时任务2");
}
};
//创建timer对象,(执行定时任务的对象)
Timer timer=new Timer();
//在1秒之后开始每5秒执行一次t中run方法的任务
timer.schedule(t,1000,5000);
timer.schedule(t2,1000,5000);
System.out.println("______");
return timer;
}
/**
* 使用jdk自带的ScheduledExecutorService执行定时任务
* @return
*/
@Bean
public ScheduledExecutorService ses() {
//单线程串行执行定时任务,我们也可以使用newScheduledThreadPool()方法指定线程工厂对象和线程数,使定时任务在
//多线程并行执行
ScheduledExecutorService s=Executors.newSingleThreadScheduledExecutor();
//执行定时任务,1秒后每隔5秒执行一个任务
s.scheduleAtFixedRate(
//jdk1.8的新特性,lambda表达式,可以看做是runnable的一个匿名内部类对象
()->System.out.println(Thread.currentThread().getName()+"使用ScheduledExecutorService执行定时任务1")
,1, 5,
//单位
TimeUnit.SECONDS);
s.scheduleAtFixedRate(
//jdk1.8的新特性,lambda表达式,可以看做是runnable的一个匿名内部类对象
()->System.out.println(Thread.currentThread().getName()+"使用ScheduledExecutorService执行定时任务2")
,1, 5,
//单位
TimeUnit.SECONDS);
return s;
}
/**
* 使用spring自带的定时任务执行
*/
//单线程串行执行线程任务,如果需要在多线程并行执行则需要配置线程池
@Scheduled(fixedDelay = 5000)
@Async
public void ss() {
System.out.println(Thread.currentThread().getName()+"使用spring自带的定时任务执行1");
}
@Scheduled(fixedDelay = 5000)
@Async
public void ss2() {
System.out.println(Thread.currentThread().getName()+"使用spring自带的定时任务执行2");
}
}