使用的是spring的ThreadPoolTaskScheduler定时线程池,其有以下四种方法进行定时任务发布:

1. schedule(Runnable task, Date stateTime),在指定时间执行一次定时任务

2. schedule(Runnable task, Trigger trigger),动态创建指定表达式cron的定时任务

3. scheduleAtFixedRate(Runnable task, Date startTime, long period),从指定的时间开始以指定间隔时间(以毫秒为单位)执行一次任务,间隔时间为前一次执行开始到下一次任务开始时间

4. scheduleAtFixedRate(Runnable task, long period),从现在开始以指定间隔时间(以毫秒为单位)执行一次任务,间隔时间为前一次执行开始到下一次任务开始时间

5. scheduleWithFixedDelay(Runnable task, Date startTime, long delay),从指定的时间开始以指定间隔时间(以毫秒为单位)执行一次任务,间隔时间为前一次执行完成到下一次任务开始时间

6. scheduleWithFixedDelay(Runnable task, Duration delay),从现在开始以指定间隔时间(以毫秒为单位)执行一次任务,间隔时间为前一次执行完成到下一次任务开始时间

我这使用的是schedule(Runnable task, Trigger trigger),以cron表达式发布任务。

首先把ThreadPoolTaskScheduler作为bean注入到spring中

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;

/**
 * bean配置类
 * @author: yuhh
 * @create: 2019-06-25 13:50
 **/
@Configuration
public class BeanConfig {

    @Bean
    public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
        ThreadPoolTaskScheduler executor = new ThreadPoolTaskScheduler();
        // 线程池数量
        executor.setPoolSize(Runtime.getRuntime().availableProcessors());
        //设置好了之后可以方便我们定位处理任务所在的线程池
        executor.setThreadNamePrefix("charge-task-Executor-");
        //用来设置线程池关闭的时候等待所有任务都完成再继续销毁其他的Bean
        executor.setWaitForTasksToCompleteOnShutdown(true);
        //该方法用来设置线程池中任务的等待时间,如果超过这个时候还没有销毁就强制销毁,以确保应用最后能够被关闭,而不是阻塞住
        executor.setAwaitTerminationSeconds(60);
        return executor;
    }
}

然后在定时任务类中注入ThreadPoolTaskScheduler,如果需要在定时任务执行完一次后就关闭,则需要一个map用来存放每个定时任务的Future,Future可以关闭其线程

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;

/**
 * 定时任务类
 * @author: yuhh
 * @create: 2019-05-13 11:39
 **/
@Component
public class SchedulingTask {

    @Autowired
    private ThreadPoolTaskScheduler threadPoolTaskScheduler;

    /**
     * 存放动态定时任务结果,用于关闭定时任务
     */
    private Map<Integer, ScheduledFuture> futureMap = new HashMap<>();

    /**
     * 每天零点十分执行定时任务
     * @author yuhh
     * @date 2019/5/13 14:39
     */
    @Scheduled(cron = "0 10 0 * * ?")
    public void settleAccounts(){
        futureMap.put(
                mapKey,
                threadPoolTaskScheduler.schedule(
                        new MyRunnable(),
                        new CronTrigger(cron表达式)
                )
        )
    }


    /**
     * 内部类--定时任务线程
     */
    private class MyRunnable implements Runnable {

        @Override
        public void run() {
           // 业务代码
            todo
            // 执行完后要取消该定时任务
            ScheduledFuture future = futureMap.get(mapKey);
            future.cancel(true);
        }
    }
}

以上代码就可以根据给定的cron表达式动态的设定定时任务,并在执行完毕后关闭该定时任务