iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java定时任务原理详解
  • 998
分享到

Java定时任务原理详解

2024-04-02 19:04:59 998人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

目录序章一、Scheduled1.1 使用方法1.2 源码分析二、QUARTZ2.1 使用方法2.2 源码分析序章 定时任务实现方式 当下,java编码过程中,实现定时任务的方式主要

序章

定时任务实现方式

当下,java编码过程中,实现定时任务的方式主要以以下两种为主

网络上关于这两种框架的实践和配置相关的教程很多,这里不再赘述。

本文主要就二者的框架原理实现做一个入门引导,为了解深层实现细节做一定的铺垫。

本文源码版本

spring-context-3.2.18.RELEASE.jar

quartz-1.8.6.jar

一、Scheduled

1.1 使用方法

@EnableScheduling // @EnableScheduling 在配置类上使用,开启计划任务的支持
@Component(value="myClass")// 由spring管理
public class MyClass {
 
    @Scheduled(cron= "0 0 0 * * ?")//0 0 12 * * ? 每天12点触发0 0 0/1 * * ?  0 0 0 * * ?
    public void myTask() {
        // 业务逻辑
        ...
    }
}

1.2 源码分析

1.2.1 定时任务执行入口在哪?

org.springframework.scheduling.config.ContextLifecycleScheduledTaskReGIStrar
 
public void onApplicationEvent(ContextRefreshedEvent event) {
    if (event.getApplicationContext() != this.applicationContext) {
        return;
    }
    // 定时任务执行入口方法绑定到容器生命周期上
    scheduleTasks();
}

1.2.2 调用链路

1. 所有已注册task

org.springframework.scheduling.config.ScheduledTaskRegistrar
protected void scheduleTasks() {
    ...
    if (this.triggerTasks != null) {
        for (TriggerTask task : this.triggerTasks) {
            // 执行初始化完成的task和Trigger
            this.scheduledFutures.add(this.taskScheduler.schedule(
                    task.getRunnable(), task.getTrigger()));
        }
    }
    ...
}

2. 单个task

org.springframework.scheduling.TaskScheduler
ScheduledFuture schedule(Runnable task, Trigger trigger);

3. 线程池执行task

org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler
public ScheduledFuture schedule(Runnable task, Trigger trigger) {
    ScheduledExecutorService executor = getScheduledExecutor();
    try {
        ErrorHandler errorHandler =
                (this.errorHandler != null ? this.errorHandler : TaskUtils.getDefaultErrorHandler(true));
        // 调用具体的实现方法.schedule()
        return new ReschedulingRunnable(task, trigger, executor, errorHandler).schedule();
    }
    catch (RejectedExecutionException ex) {
        throw new TaskRejectedException("Executor [" + executor + "] did not accept task: " + task, ex);
    }
}

4. 这块是具体的线程实现细节,已经与schedul无关

private <V> ScheduledFuture<V> schedule(final ScheduledFutureTask<V> task) {
    if (task == null) {
        throw new NullPointerException("task");
    } else {
        if (this.inEventLoop()) {
            this.delayedTaskQueue.add(task);
        } else {
            // 此处就是真正的线程执行方法
            this.execute(new Runnable() {
                public void run() {
                    SingleThreadEventExecutor.this.delayedTaskQueue.add(task);
                }
            });
        }
 
        return task;
    }
}

1.2.3 @Scheduled注解的生效原理

org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor
 
// BeanPostProcessor生命周期方法,spring加载的时候会执行
public Object postProcessAfterInitialization(final Object bean, String beanName) {
        Class<?> targetClass = aopUtils.getTargetClass(bean);
    if (!this.nonAnnotatedClasses.containsKey(targetClass)) {
        final Set<Method> annotatedMethods = new LinkedHashSet<Method>(1);
        ReflectionUtils.doWithMethods(targetClass, new MethodCallback() {
            public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
                Scheduled scheduled = AnnotationUtils.getAnnotation(method, Scheduled.class);
                if (scheduled != null) {
                    // @Scheduled的真正解析方法,具体解析细节和参数参看源码
                    // 解析后添加到ScheduledTaskRegistrar里
                    // 全部任务解析完成,执行ScheduledTaskRegistrar,具体实现参看[1.2.2 调用链路]章节
                    processScheduled(scheduled, method, bean);
                    annotatedMethods.add(method);
                }
            }
        });
        if (annotatedMethods.isEmpty()) {
            this.nonAnnotatedClasses.put(targetClass, Boolean.TRUE);
        }
    }
    return bean;
}

二、QUARTZ

2.1 使用方法

// 实例化一个调度器工厂,每个应用只有唯一一个工厂实例
SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory();
// 实例化一个调度器
Scheduler sched = schedFact.getScheduler();
// 启动,只有启动了调度器Quartz才会去执行任务
sched.start();
 
// 实例化一个任务
JobDetail job = newJob(HelloJob.class)
  .withIdentity("myJob", "group1")
  .build();
 
// 实例化一个任务触发器,立刻触发,每40s执行一次
Trigger trigger = newTrigger()
  .withIdentity("myTrigger", "group1")
  .startNow()
  .withSchedule(simpleSchedule()
      .withIntervalInSeconds(40)
      .repeatForever())
  .build();
 
// 调度任务
sched.scheduleJob(job, trigger);

2.2 源码分析

2.2.1 启动入口

1. WEB.xml配置

<context-param>
   <param-name>quartz:config-file</param-name>
   <param-value>/some/path/my_quartz.properties</param-value>
</context-param>
<context-param>
   <param-name>quartz:shutdown-on-unload</param-name>
   <param-value>true</param-value>
</context-param>
<context-param>
   <param-name>quartz:start-on-load</param-name>
   <param-value>true</param-value>
</context-param>
 
<listener>
   <listener-class>
       org.quartz.ee.servlet.QuartzInitializerListener
   </listener-class>
</listener>

2. org.quartz.ee.servlet.QuartzInitializerListener

// 执行ServletContextListener.contextInitialized的容器生命周期方法
public void contextInitialized(ServletContextEvent sce) {
    ...
    // 根据自定义的配置文件加载SchedulerFactory
    if (configFile != null) {
        factory = new StdSchedulerFactory(configFile);
    } else {
        factory = new StdSchedulerFactory();
    }
    
    // 加载scheduler
    scheduler = factory.getScheduler();
    
    // 启动scheduler
    scheduler.start();
    log.info("Scheduler has been started...");
    ...
}   

2.2.2 核心方法详解

1. StdSchedulerFactory.getScheduler()
public Scheduler getScheduler() throws SchedulerException {
    if (cfg == null) {
        // 根据不同的配置方式加载对应配置
        initialize();
    }
    ... 
    // 加载实例(加载Scheduler整个上下文环境)
    sched = instantiate();
    return sched;
}

2. StdSchedulerFactory.getScheduler().instantiate()

具体实现代码很多,以下做伪代码描述

private Scheduler instantiate() throws SchedulerException {
 
    // 校验初始化
    if (cfg == null) {
        initialize();
    }
    
    // 获取 Scheduler
    // 加载 ThreadPool
    // 加载 JobStore
    // 加载 DataSources
    // 加载 SchedulerPlugins
    // 加载 JobListeners
    // 加载 TriggerListeners
    // 加载 ThreadExecutor
    
    // 构造QuartzScheduler
    qs = new QuartzScheduler(rsrcs, schedCtxt, idleWaitTime, dbFailureRetry);
    Scheduler scheduler = instantiate(rsrcs, qs);
    qs.initialize();
    
    // 返回实例化好的scheduler
    return scheduler;
}

到此这篇关于Java定时任务原理详解的文章就介绍到这了,更多相关Java定时任务内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Java定时任务原理详解

本文链接: https://www.lsjlt.com/news/165538.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java定时任务原理详解
    目录序章一、Scheduled1.1 使用方法1.2 源码分析二、QUARTZ2.1 使用方法2.2 源码分析序章 定时任务实现方式 当下,java编码过程中,实现定时任务的方式主要...
    99+
    2024-04-02
  • Java定时任务详解
    定时任务在项目中经常会使用到,本文主要根据博主自己使用定时的经验分如下几点介绍定时任务:1、Quartz定时任务简介及Spring配置Quartz定时任务2、SchedulerFactory对定时任务进行增删改查3、总结Quartz定时任务...
    99+
    2023-05-31
    java 定时任务 ava
  • Java spring定时任务详解
    目录一、定时任务1、cron表达式2、cron示例3、SpringBoot整合总结一、定时任务 1、cron表达式 语法:秒 分 时 日 月 周 年 (其中“年”Spring不支持...
    99+
    2024-04-02
  • SpringBoot定时任务设计之时间轮案例原理详解
    目录知识准备什么是时间轮(Timing Wheel)Netty的HashedWheelTimer要解决什么问题HashedWheelTimer的使用方式实现案例Pom依赖2个简单例子...
    99+
    2024-04-02
  • 一文详解Golang 定时任务库 gron 设计和原理
    目录 cron 简介gron定时参数源码解析CronEntry按照时间排序新增定时任务启动和停止Schedule扩展性经典写法-控制退出结语  cron 简介 在...
    99+
    2024-04-02
  • Java定时任务的实现原理是什么
    Java定时任务的实现原理是基于线程池和计时器的机制。在Java中,可以使用ScheduledExecutorService接口来创...
    99+
    2023-10-20
    Java
  • Java实现定时任务的方法详解
    目录前言定时任务是什么定时任务的有哪些是实现方式纯手写单线程循环Timer 和它的小伙伴ScheduledExecutorServiceSpring 提供的定时任务总结前言 学过定时...
    99+
    2022-11-13
    Java实现定时任务 Java定时任务
  • SpringBoot定时任务 @Scheduled详解
    博主在最近的开发中又遇到了关于定时调度的开发任务,在定时调度其实有很多的第三方平台可以接入,但是其实在SpringBoot有自带的定时任务注解@Scheduled。@Scheduled可以通过注解配置快速实现方法的定时调度,直接在方法加上@...
    99+
    2023-10-01
    spring boot java spring
  • Java-定时任务
    文章目录 补充:cron表达式基本知识方式一:使用sleep方法方式二:JDK Timer和TimerTask方式三:JDK ScheduledExecutorService方式四: Spri...
    99+
    2023-09-23
    java spring 开发语言 springboot
  • Redis定时任务原理的实现
    目录数据结构常见操作1. 创建定时事件2. 触发定时事件3. 执行定时事件总结本文主要是基于 redis 6.2 源码进行分析定时事件的数据结构和常见操作。 数据结构 在 redis...
    99+
    2024-04-02
  • JavaScript定时器原理详解
    目录一、 setTimeout() 定时器二、停止 setTimeout() 定时器三、setInterval() 定时器四、清除setInterval() 定时器五、电子时钟案例前...
    99+
    2024-04-02
  • 详解SpringBoot定时任务功能
    目录一 背景二 动态定时任务调度三 多节点任务执行问题四 后记一 背景 项目中需要一个可以动态新增定时定时任务的功能,现在项目中使用的是xxl-job定时任务调度系统,但是经过一番对...
    99+
    2024-04-02
  • 详解Gotorch多机定时任务管理系统
    目录前言cron+守护进程信号处理小结前言 先介绍下问题: 组内有十来台机器,上面用 cron 分别定时执行着一些脚本和 shell 命令,一开始任务少的时候,大家都记得哪台机器执行...
    99+
    2024-04-02
  • Java Scheduled定时任务
    开启定时任务步骤流程: 在启动类添加注解;(注意:千万不要忘记!) @EnableScheduling 在具体的方法上添加定时任务注解 @Scheduled(cron = “0 0 */3 * * ”) // 每3个小时触发一次 ...
    99+
    2023-08-20
    java
  • Java使用quartz实现定时任务示例详解
    目录正文配置文件pom定时任务和触发器定时任务的业务代码正文 最近新到了一个项目,用到定时任务的地方是真滴多。 就稍微研究了一下,来做个demo。 其实定时任务使用很广泛也很方便,之...
    99+
    2022-11-13
    Java quartz定时任务 Java quartz
  • Java 定时任务技术趋势详情
    目录Java 中自带的解决方案Spring 中自带的解决方案业务幂等解决方案开源任务调度中间件企业级解决方案定时任务技术趋势简介:定时任务是每个业务常见的需求,比如每分钟扫描超时支付...
    99+
    2024-04-02
  • SpringTask定时任务的实现详解
    目录Spring Task定时任务Cron表达式实现定时任务背景实现Spring Task定时任务 Cron表达式 以6-7位的一组数字,中间用空格间隔的字符串,表达一种时间 每位的...
    99+
    2022-11-13
    Spring Task定时任务 Spring定时任务
  • Python Celery定时任务详细讲解
    目录前言一、Celery定时任务是什么?二、使用步骤1.代码结构2.启动定时任务3.执行结果总结前言 Celery在python中的应用除了实现异步任务(async task)外也可...
    99+
    2024-04-02
  • 最新Python APScheduler 定时任务详解
    目录一、基本概念1.1、 触发器:triggers1.2、作业存储器:job stores1.3、执行器 executors1.4、调度器 schedulers二、调度器详解2.1、...
    99+
    2024-04-02
  • 怎么理解定时任务crontab
    这篇文章将为大家详细讲解有关怎么理解定时任务crontab,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。脚本目录:[oracle@tangjian ~]$ mkdir -p /u01/app...
    99+
    2023-06-06
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作