1. 程式人生 > 實用技巧 >springboot 定時任務問題

springboot 定時任務問題

1.springboot定時執行某個方法

2.springboot通過介面生成某個排程時間定時執行

  方法1: 網上好多案例不做詳細闡述

  方法2:業務場景:使用者配置一個活動,然後根據配置活動的時間定時推送訊息。

    1.配置一個每天凌晨的定時任務,去資料庫查詢資料,將符合條件的cron表示式放入定時任務中,依次執行,同時將結束時間是昨天的定時任務刪除。

    2.如果新新增定時任務,需要在當天執行定時任務,需要手動呼叫定時任務啟動方法,新增定時任務。

直接上程式碼:

@Autowired
    private ThreadPoolTaskScheduler threadPoolTaskScheduler;

    @Autowired
    RoomMembersService roomMembersService;

    @Autowired
    MongoTemplate mongoTemplate;

    private Map<String, ScheduledFuture<?>> taskMap = new HashMap<>();

    private ScheduledFuture<?> future;

    @Scheduled(cron = "0 0 0 * * ?")
    public void syncWxOnlineUsersAndGroupsMsg() {
        log.info("-------------> 凌晨排程開始");
        //獲取所有符合條件的cron表示式,新增排程
        List<GroupSignIn> signInCronList = roomMembersService.getSignInCronList();
        log.info("-------------> "+signInCronList.size());
        for (GroupSignIn groupSignIn : signInCronList){
            String cron = groupSignIn.getReminder_cron();
            String sign_id = groupSignIn.get_id().toString();
            String material_content = groupSignIn.getMaterial_content();
            startCron(cron,sign_id,material_content);
        }
        //獲取所有昨天結束的排程,刪除任務
        List<GroupSignIn> executeOverList = roomMembersService.executeOver();
        if (null != executeOverList && executeOverList.size() >0){
            for (GroupSignIn groupSignIn : executeOverList){
                String sign_id = groupSignIn.get_id().toString();
                log.info("刪除排程任務",sign_id);
                stop(sign_id);
            }
        }
        log.info("-------------> 凌晨排程結束");
    }


    @Bean
    public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
        return new ThreadPoolTaskScheduler();
    }

    public void startCron(String cron,String sign_id,String material_content) {
        log.info("-------------> 開始新增定時任務");
        String createTime = TimeUtils.getCurrentTimeInString(TimeUtils.DATETIME_FORMAT_DATE);
        ScheduledFuture<?> future = threadPoolTaskScheduler.schedule(new MyRunnable(cron,sign_id,material_content), new CronTrigger(cron));
//        stop(sign_id);
        taskMap.put(sign_id,future);
        SignInTask signInTask = new SignInTask();
        signInTask.setMaterial_content(material_content);
        signInTask.setSign_id(sign_id);
        signInTask.setReminder_cron(cron);
        signInTask.setCreated_date(createTime);
        mongoTemplate.insert(signInTask);
    }
    private class MyRunnable implements Runnable {
        private  String cron ;
        private  String sign_id ;
        private  String material_content ;
        public  MyRunnable(String cron,String sign_id,String material_content){
            this.cron = cron;
            this.sign_id = sign_id;
            this.material_content = material_content;
        }

        @Override
        public void run() {
            roomMembersService.sendSignMsg(sign_id,material_content);
        }
    }


    public boolean stop(String name) {
        log.info("-------------> 刪除排程開始"+name);
        if(null == taskMap.get(name)) {
            return false;
        }
        ScheduledFuture<?> scheduledFuture = taskMap.get(name);
        scheduledFuture.cancel(true);
        taskMap.remove(name);
        return true;
    }

  因為本人對多執行緒瞭解的少,所以還需要優化如何非同步跑排程。

對自己---》需要看定時任務原始碼,詳細理解為什麼這樣做,如何優化