一 背景
项目中需要一个可以动态新增定时定时任务的功能,现在项目中使用的是xxl-job定时任务调度系统,但是经过一番对xxl-job功能的了解,发现xxl-job对项目动态新增定时任务,动态删除定时任务的支持并不是那么好,所以需要自己手动实现一个定时任务的功能
二 动态定时任务调度
1 技术选择
Timer or ScheduledExecutorService
这两个都能实现定时任务调度,先看下Timer的定时任务调度
public class MyTimerTask extends TimerTask
{
private String name;
public MyTimerTask(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
@Override
public void run()
{
//task
Calendar instance = Calendar.getInstance();
System.out.println(new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”).format(instance.getTime()));
}
}
Timer timer = new Timer();
MyTimerTask timerTask = new MyTimerTask(“NO.1”);
//首次执行,在当前时间的1秒以后,之后每隔两秒钟执行一次timer.schedule(timerTask,1000L,2000L);
在看下ScheduledThreadPoolExecutor的实现
//org.apache.commons.lang3.concurrent.BasicThreadFactoryScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1, new BasicThreadFactory.Builder().namingPattern(“example-schedule-pool-%d”).daemon(true).build());executorService.scheduleAtFixedRate(new Runnable() { @Override public void run() { //do something }},
initialDelay,period, TimeUnit.HOURS);
两个都能实现定时任务,那他们的区别呢,使用阿里p3c会给出建议和区别
多线程并行处理定时任务时,Timer运行多个TimeTask时,只要其中之一没有捕获抛出的异常,其它任务便会自动终止运行,使用ScheduledExecutorService则没有这个问题。
从建议上来看,是一定要选择ScheduledExecutorService了,我们看看源码看看为什么Timer出现问题会终止执行
/** * The timer thread. */
private final TimerThread thread = new TimerThread(queue);
public Timer()
{
this(“Timer-” + serialNumber());
}
public Timer(String name)
{
thread.setName(name);
thread.start();
}
新建对象时,我们看到开启了一个线程,那么这个线程在做什么呢?一起看看
class TimerT