当前位置: 首页 > article >正文

springboot集成常见定时任务

一、常见定时任务

原文转载

https://mp.weixin.qq.com/s/9GRxBCpeDss-llecrwo-lw

1、创建方式

  1. 使用线程创建
  2. 使用TimerTask创建
  3. 使用线程池创建
  4. 使用Quartz创建
  5. 使用springboot的@Scheduled注解

2、线程创建

public class CreatByThread {
    private static int count = 0;
    private static void timerTask(){
        Runnable runnable = new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                while (true){
                    Thread.sleep(1000);
                    count++;
                    System.err.println(count);
                }
            }
        };
        Thread thread = new Thread(runnable);
        thread.start();
    }
    public static void main(String[] args) {
        timerTask();//原生写法
        new Thread(()->{//lambda表达式
            while (true){
                try {
                    Thread.sleep(1000);
                    count++;
                    System.out.println(count);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

3、TimerTask创建

原文转载

https://blog.csdn.net/xieyuooo/article/details/8607220/
  1. 首先要明白:Timer是一个调度器,TimerTask只是一个实现了run方法的一个类(需要自己来实现)

  2. Timer和TimerTask的组合是一个单线程,如果创建多线程会使用:Executor.newScheduledThreadPool

  3. 常见的Timer类中的方法:

    • #调度一个task,经过dealy(ms)后开始调度,仅仅调度一次
          public void schedule(TimerTask task,long delay)
      
    • #调度一个task,在指定的时间点time上调度一次
          public void schedule(timertask task,Date t)
      
    • #调度一个task,在dealy(ms)后开始调度,每次调度完后,最少等待period(ms)后才开始调度
      	public void schedule(TimerTask task,long delay,long period)
      
    • #和上一个方法类似,唯一区别就是传入的第二个参数为第一次调度的时间
      	public void schedule(TimerTask task,Date firstTime,long period)
      
    • #调度一个task,在delay(ms)后开始调度,然后经过period(ms)再次调度,似乎和第三个方法类似,但不然,区别:
      #1、schedule在计算下一次执行时间的时候,是通过当前时间(在任务执行前得到)+时间片;
      #2、scheduleAtFixedRate方法是通过当前需要执行的时间(也就是现在需要执行的时间)+时间片;
      #3、schedule是运行时的实际时间,而scheduleAtFixedRate是理论时间。例如:schedule的时间片是5s,那么理论会在5101520这些时间片被调度,但如果由于某些cpu征用导致未调度,假如等到8s才被调度一次,那么schedule方法计算出来的下一次调度时间应该是13s,而不是10s,这样有可能下次越到20s后而被少调度一次或多次;而scheduleAtFixedRate就是每次理论计算出下一次需要调度的时间用以排序,若第8s被调度了,那么计算出应该是第10s,所以它距离当前时间是2s,那么在调度队列排序中,会优先调度;
      #4、scheduleAtFixedRate可以减少漏调度的情况;
      	public void scheduleAtFixedRate(TimerTask timer,long delay,long period)
      
    • #方法和上一个方法类似,唯一的区别是第一次调度的时间设置为Date,而不是当前时间的一个时间片
      	public void scheduleAtFixedRate(TimerTask timer,Date firstTime,long period)
      
public class CreatByTimerTask {
    private static int count = 0;
    private static void timerTask(){
        TimerTask timerTask = new TimerTask() {
            @SneakyThrows
            @Override
            public void run() {
                Thread.sleep(1000);
                count++;
                System.err.println(count);
            }
        };
        Timer timer = new Timer();
        timer.schedule(timerTask,0,1000);//每秒调度一次
    }
    public static void main(String[] args) {
        timerTask();//原生写法
        new Timer().schedule(new TimerTask() {
            @SneakyThrows
            @Override
            public void run() {
                Thread.sleep(1000);
                count++;
                System.out.println(count);
            }
        },0,1000);
    }
}

4、使用线程池创建

public class CreatByThreadPool {
    private static int count = 0;
    private static void timerTask(){
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                count++;
                System.err.println(count);
            }
        };
        ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
        //第二个参数为首次执行的延迟时间,第三个参数为定时执行的间隔时间
        service.scheduleAtFixedRate(runnable,1,1, TimeUnit.SECONDS);
    }
    public static void main(String[] args) {
        timerTask();
        Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(()->{
            count++;
            System.out.println(count);
        },1,1,TimeUnit.SECONDS);
    }
}

5、使用Quartz创建

  1. maven依赖

            <!--Quartz-->
            <dependency>
                <groupId>org.quartz-scheduler</groupId>
                <artifactId>quartz</artifactId>
                <version>2.2.1</version>
            </dependency>
            <dependency>
                <groupId>org.quartz-scheduler</groupId>
                <artifactId>quartz-jobs</artifactId>
                <version>2.2.1</version>
            </dependency>
    
  2. 实现了Quratz框架接口的类

    @Service
    public class QuartzServiceImpl implements Job {
        @Override
        public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
            System.err.println("this is a quartz method , now time:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        }
    }
    
  3. 启动类

    public class creatByQuartz {
        private static void timerTask() throws SchedulerException {
            //1、创建scheduler的工厂
            StdSchedulerFactory factory = new StdSchedulerFactory();
            //2、从工厂中获取调度器实列
            Scheduler scheduler = factory.getScheduler();
            //3、创建JobDetail
            JobDetail job = JobBuilder.newJob(QuartzServiceImpl.class)
                    //job描述
                    .withDescription("this is a quartz job")
                    //job的name和group
                    .withIdentity("quartzJob", "quartzGroup")
                    .build();
            //任务运行的时间,simpleSchedule类型触发器有效,3秒后启动任务
            long time = System.currentTimeMillis()+3*1000L;
            Date statTime = new Date(time);
            //4、创建Trigger(使用SimpleScheduleBuilder或者CronScheduleBuilder)
            CronTrigger trigger = TriggerBuilder.newTrigger()
                    .withDescription("this is trigger")
                    .withIdentity("quartzTrigger", "quartzTriggerGroup")
    //                .withSchedule(SimpleScheduleBuilder.simpleSchedule())
                    .withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?"))//两秒执行一次,采用cron表达式
                    .startAt(statTime)//默认当前时间启动
                    .build();
            //5、注册任务和定时器
            scheduler.scheduleJob(job,trigger);
            //6、启动调度器
            scheduler.start();
        }
        public static void main(String[] args) throws SchedulerException {
            timerTask();
        }
    }
    
1、Quartz相关builder
https://blog.csdn.net/yjltx1234csdn/article/details/105846493
https://www.cnblogs.com/sunset-red/p/13794009.html

6、springboot的@Scheduled注解

  1. 在启动类上添加注解:@EnableScheduling

    @Slf4j
    @SpringBootApplication(exclude = DataSourceAutoConfiguration.class)//排除连接数据库
    @EnableAspectJAutoProxy(proxyTargetClass = true)
    @EnableScheduling //开启定时任务
    public class IdempotencyApplication {
        public static void main(String[] args) throws UnknownHostException {
            ConfigurableApplicationContext applicationContext = SpringApplication.run(IdempotencyApplication.class, args);
            ConfigurableEnvironment env = applicationContext.getEnvironment();
            String ip = Inet6Address.getLocalHost().getHostAddress();
            String port = env.getProperty("server.port");
            String path = env.getProperty("server.servlet.context-path");
            log.info("----------------------------------\r\n{}","http://".concat(ip).concat(":").concat(port+path));
        }
    }
    
  2. 用注解:@Scheduled标识定时任务方法

    @Configuration
    @Component
    public class CreatByScheduled {
    //    @Scheduled(cron = "0/5 * * * * ?")//采用cron表达式执行一次定时任务
        @Scheduled(fixedRate = 5000)//指定时间5s执行一次定时任务
        public static void timerTask(){
            System.err.println("this is a timerTask:"+ LocalDate.now());
        }
    }
    
  3. 项目启动后,定时任务执行

  4. cron表达式说明

    https://blog.csdn.net/hu_dongyang/article/details/114270232
    
  5. springboot使用@Scheduled

    https://www.jianshu.com/p/c7492aeb35a1
    

http://www.kler.cn/a/153623.html

相关文章:

  • Leetcode—392.判断子序列【简单】
  • .net 8 发布了,试下微软最近强推的MAUI
  • 独立站的优势(代购网站)
  • webshell之其他免杀
  • 行内元素和块级元素分别有哪些?有何区别?怎样转换?
  • 计算机杂谈系列精讲100篇-【计算机应用】GPU 架构
  • 如何让企业报修、派单更高效!自动派单系统有什么用?
  • 负电源电压转换-TP7660H
  • wpf devexpress 使用IDataErrorInfo实现input验证
  • 鸿蒙(HarmonyOS)应用开发——容器组件(Grid组件)
  • 阿里云开源通义千问720亿参数模型,性能超越大部分商用闭源大模型
  • mysql使用--备份与恢复
  • 知识管理平台Confluence:win10安装confluence
  • XIAO ESP32S3之AI应用
  • TypeScript与JavaScript封装事件的防抖与节流
  • 如何本地搭建个人hMailServer邮件服务并实现远程发送邮件
  • pycharm中绘制一个3D曲线
  • 代数学笔记9: 群的直积,可解群,自由群,群表示
  • tmux工具--程序部署在服务器上持久化执行
  • mac安装elasticsearch