Timer定时任务(从数据库查询数据)

本文介绍了如何在Java中创建定时任务,强调了@Scheduled注解和@EnableScheduling的使用。讨论了避免频繁创建新线程的方法,建议在每次任务变更后更新定时任务,并探讨了ScheduledExecutorService在优化定时任务中的应用。

目录

创建一个定时任务类

引用这个方法

用ScheduledExecutorService优化定时任务类


创建一个定时任务类


@Component
public class MyScheduledTask {
   
    private static Timer timer = new Timer();
    //如果直接@Autowired为空,可尝试这种方式
    private static NoticeMapper noticeMapper;
    @Autowired
    public void setEmployeeServer(NoticeMapper noticeMapper) {
        MyScheduledTask.noticeMapper = noticeMapper;
    }

    //设置定时时间
    //即使长时间没有操作,也可自己执行
    @Scheduled(cron = "0 45 15 * * ? ")
    public  void n() throws ParseException {
        //查询数据库中想要的数据集合 这里可以自行修改
        List<String> str1 = new ArrayList<>();

        List<Notice> noticeList=noticeMapper.selectList(new QueryWrapper<>());
        for (Notice notice:noticeList) {
            str1.add(notice.getStartTime());
        }
        //每次调用先关闭前面的,再重新创建
        timer.cancel();
        timer = new Timer();
        for (String str:str1) {
            String[] arr=str.split(" ");
            a(arr[1]);//HH:mm:ss
        }
        

    }
    //如果执行的代码需要其他的,参数可以传入实体类
    public  void a(String str) throws ParseException {

        // 一天的毫秒数
        long daySpan = 24 * 60 * 60 * 1000;

        // 规定的每天时间某一时刻运行
        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd "+str);
        // 首次运行时间
        Date startTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(sdf.format(new Date()));
        System.out.println(sdf.format(new Date()));
        // 如果今天的已经过了 首次运行时间就改为明天
//        if(System.currentTimeMillis() > startTime.getTime()) {
//            startTime = new Date(startTime.getTime() + daySpan);
//
//        }
        // 如果今天的还没到
       if(System.currentTimeMillis() < startTime.getTime())
        {
        TimerTask task = new TimerTask(){
            @Override
            public void run() {
                // 要执行的代码
                Date date = new Date();
                SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String sendTime = dateFormat.format(date);
                System.out.println("xxxxxxxxx "+sendTime);
            }
        };
        // 以每24小时执行一次
        timer.scheduleAtFixedRate(task, startTime, daySpan);
        }
    }
}

注意@Scheduled注解需要在启动类上加@EnableScheduling

每次创建timer会创建一个线程,如果每次都new一个timer,就会有许多一起进行的线程,所以在开头定义一个timer 然后结束旧的timer,再创建新的timer

引用这个方法

在每次增删改后任务都需要重新进行创建定时任务,其实也可不重新创建,不创建即为此日执行。

如impl层

    public R updateNotice(NoticeDTO noticeDTO) throws ParseException {
        Notice notice = noticeMapper.selectById(noticeDTO.getId());
        notice.setStartTime(noticeDTO.getStartTime());
        notice.setContent(noticeDTO.getContent());
        noticeMapper.updateById(notice);
        //这里引用了定时任务
        MyScheduledTask.n();
        return R.ok("更新成功");
    }

用ScheduledExecutorService优化定时任务类

其实这里 Executors.newScheduledThreadPool() 还可以优化

@Component
public class MyScheduledTask {

    private static ScheduledExecutorService pool = Executors.newScheduledThreadPool(4);
    private static NoticeMapper noticeMapper;
    @Autowired
    public void setEmployeeServer(NoticeMapper noticeMapper) {
        MyScheduledTask.noticeMapper = noticeMapper;
    }
    @Scheduled(cron = "0 0 0 * * ? ")
    public static void n() {
        //查询想要的数据集合  
              ......
        pool.shutdownNow();
        pool = Executors.newScheduledThreadPool(4);
           ........    
        for (String str:str1) {
            String[] arr=str.split(" ");
            //HH:mm:ss
            a(arr[1]);
        }

    }

    public static void a(String str){

        // 一天的毫秒数
        long daySpan = 24 * 60 * 60 * 1000;

        // 规定的每天时间15:33:30运行
        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd "+str);
        // 首次运行时间
        SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date startTime = null;
        try {
            startTime = dateFormat.parse(sdf.format(new Date()));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        System.out.println(sdf.format(new Date()));

        // 如果今天的设定时间还没到
        assert startTime != null :"时间格式不正确";
        if(System.currentTimeMillis() < startTime.getTime())
        {
        // 以每24小时执行一次
            //当前时间需要延迟多久到执行时间
            long delay = startTime.getTime()-System.currentTimeMillis();
            pool.scheduleAtFixedRate(() -> {
                // 要执行的代码
                try {
                    String sendTime = dateFormat.format(new Date());
                    System.out.println("xxxxxxxxx "+sendTime);
                } catch (Exception e) {
                    System.out.println("定时任务出现异常");
                }
            }, delay, daySpan, TimeUnit.MILLISECONDS);
        }
    }
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值