1. 程式人生 > >基於springboot ThreadPoolTaskScheduler類實現定時任務動態新增修改

基於springboot ThreadPoolTaskScheduler類實現定時任務動態新增修改

需求:有不定個的定時任務模板需要建立,定時任務在執行過程中,激發時間等屬性可能發生修改.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
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.text.SimpleDateFormat; import java.util.ArrayList; import
java.util.Date; import java.util.List; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Future; import java.util.concurrent.ScheduledFuture; @Componentpublic class ScheduledVm { @Autowired private ThreadPoolTaskScheduler threadPoolTaskScheduler; private ScheduledFuture<?> future
; private int taskSchedulerCorePoolSize=50; static boolean isinitialized=false; @Bean public ThreadPoolTaskScheduler threadPoolTaskScheduler() { threadPoolTaskScheduler=new ThreadPoolTaskScheduler(); threadPoolTaskScheduler.setPoolSize(taskSchedulerCorePoolSize);
/**需要例項化執行緒*/
        threadPoolTaskScheduler.initialize();
        isinitialized=true;
        return threadPoolTaskScheduler;
    }

    /**每隔1小時重新掃描構建定時任務*/
@Scheduled(fixedDelay = 3600000) private void getCron() { /**每次重新獲取任務模板的時候重構定時任務*/try{ if (isinitialized) {
/**設定為false,關閉執行緒池中的任務時,直接執行shutdownNow()*/
                threadPoolTaskScheduler.setWaitForTasksToCompleteOnShutdown(false);
                threadPoolTaskScheduler.shutdown();
        }catch (Exception e){
            
        }finally {
            threadPoolTaskScheduler();
        }

        List<Integer> types= new ArrayList<>();
Integer period=1;
       
/**根據不同的任務型別分別建立不同的任務,動態新增到執行緒池中*/
        for (Integer type: types) {
        if (type == 1) {

                    threadScheduler(new Runnable() {
                        @Override
public void run() {
                         System.out.println("型別:"+type);
                    },getCrons(startTime,period));
                } else if (type == 2){

                    threadScheduler(new Runnable() {
                        @Override
public void run() {                    
System.out.println("型別:"+type);  
},getCrons(startTime,period)); } else if (type == 3){ threadScheduler(new Runnable() { @Overridepublic void run() {
System.out.println("型別:"+type); 
},getCrons(startTime,period));
} } }
/**這種方式經過我的測試不能正常執行,每次重構任務池時都會把任務先執行一次*/

//    private ScheduledFuture<?> threadScheduler(Runnable runnable, Date startTime,long period){
//     //        return future = threadPoolTaskScheduler.scheduleWithFixedDelay(runnable,startTime,period);//    }
    /***使用cron表示式動態構建符合要求的表示式*/
private String getCrons(Date date,Integer period)
    {
//        String ss="*";
//        String mm="*";
//        String hh="*";
String dd="*";
        String MM="*";
        String yy="*";
        String []time=format.format(date).split("-");
        dd=time[2];
        MM=time[1];
        yy=time[0];
        /**每隔數月*/
if (period==1||period==2)
        {
            MM=MM+"/"+period;
        }else if (period==7||period==14)
        {
            /**每隔數天*/
dd=dd+"/"+period;
        }

/**每隔數月時,表示,在yyyy-MM-dd 8:30:00時執行一次,然後每隔MM月再執行
   每隔數天時,表示,再yyyy-MM-dd 8:30:00時執行一次,然後每隔dd天再執行*/
        return "0 30 8"+" "+dd+" "+MM+" ?"+yy;}

    private ScheduledFuture<?> threadScheduler(Runnable runnable, String cron){
        /**動態建立定時任務*/
return future = threadPoolTaskScheduler.schedule(runnable, new Trigger() {
            @Override
public Date nextExecutionTime(TriggerContext triggerContext) {
                return new CronTrigger(cron).nextExecutionTime(triggerContext);
            }
        });//new CronTrigger("0/5 * * * * *")
}



}