【小家Spring】Spring任务调度核心接口(类)之---TaskScheduler(任务调度器)、Trigger(触发器)、ScheduledTask(调度任务)详解(下)

简介: 【小家Spring】Spring任务调度核心接口(类)之---TaskScheduler(任务调度器)、Trigger(触发器)、ScheduledTask(调度任务)详解(下)

ThreadPoolTaskScheduler


包装Java Concurrent中的ScheduledThreadPoolExecutor类,大多数场景下都使用它来进行任务调度。


除实现了TaskScheduler接口中的方法外,它还包含了一些对ScheduledThreadPoolExecutor进行操作的接口

public class ThreadPoolTaskScheduler extends ExecutorConfigurationSupport
    implements AsyncListenableTaskExecutor, SchedulingTaskExecutor, TaskScheduler {
  ...
  // 默认的size 是1
  private volatile int poolSize = 1;
  private volatile boolean removeOnCancelPolicy = false;
  @Nullable
  private volatile ErrorHandler errorHandler;
  // 内部持有一个JUC的ScheduledExecutorService 的引用
  @Nullable
  private ScheduledExecutorService scheduledExecutor;
  ...
  // 初始化线程池的执行器~~~~ 该方法的父类是ExecutorConfigurationSupport
  // 它定义了一些线程池的默认配置~~~~~
  @Override
  protected ExecutorService initializeExecutor(
      ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) {
    // 我们发现,如果set PoolSize,那么它的size就是1
    this.scheduledExecutor = createExecutor(this.poolSize, threadFactory, rejectedExecutionHandler);
    if (this.removeOnCancelPolicy) {
      if (this.scheduledExecutor instanceof ScheduledThreadPoolExecutor) {
        ((ScheduledThreadPoolExecutor) this.scheduledExecutor).setRemoveOnCancelPolicy(true);
      } else {
        logger.info("Could not apply remove-on-cancel policy - not a Java 7+ ScheduledThreadPoolExecutor");
      }
    }
    return this.scheduledExecutor;
  }
  // 就是new一个ScheduledThreadPoolExecutor  来作为最终执行任务的执行器
  protected ScheduledExecutorService createExecutor(
      int poolSize, ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) {
    return new ScheduledThreadPoolExecutor(poolSize, threadFactory, rejectedExecutionHandler);
  }
  ...
  //获取当前活动的线程数 委托给ScheduledThreadPoolExecutor来做得
  public int getActiveCount() {
    if (this.scheduledExecutor == null) {
      // Not initialized yet: assume no active threads.
      return 0;
    }
    return getScheduledThreadPoolExecutor().getActiveCount();
  }
  // 显然最终就是交给ScheduledThreadPoolExecutor去执行了~~~
  // 提交执行一次的任务
  // submit\submitListenable方法表示:提交执行一次的任务,并且返回一个Future对象供判断任务状态使用
  @Override
  public void execute(Runnable task) {
    Executor executor = getScheduledExecutor();
    try {
      executor.execute(errorHandlingTask(task, false));
    }
    catch (RejectedExecutionException ex) {
      throw new TaskRejectedException("Executor [" + executor + "] did not accept task: " + task, ex);
    }
  }
  ...
}


使用它前必须得先调用initialize()【初始化方法】,有shutDown()方法,执行完后可以关闭线程


Demo:

    public static void main(String[] args) {
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(2);
        taskScheduler.initialize(); // 务必调用此方法来启动
        // 执行任务
        // 执行一次
        taskScheduler.execute(() -> System.out.println(Thread.currentThread().getName() + "  我只会被执行一次~~~"));
        // 周期性执行
        taskScheduler.schedule(() -> System.out.println(Thread.currentThread().getName() + " 我会被多次执行~~~"), new CronTrigger("0/2 * * * * ?"));
        // 此处:若你有周期性的任务,这里不要shutdown()
        //taskScheduler.shutdown();
    }


输出:


ThreadPoolTaskScheduler-1  我只会被执行一次~~~
ThreadPoolTaskScheduler-1 我会被多次执行~~~
ThreadPoolTaskScheduler-2 我会被多次执行~~~
ThreadPoolTaskScheduler-2 我会被多次执行~~~
ThreadPoolTaskScheduler-2 我会被多次执行~~~
ThreadPoolTaskScheduler-1 我会被多次执行~~~
ThreadPoolTaskScheduler-2 我会被多次执行~~~
ThreadPoolTaskScheduler-2 我会被多次执行~~~


发现每次都可能被不同的线程去执行(当然我们这里只放了两个~~~)


ConcurrentTaskScheduler


以单个线程方式执行定时任务,适用于简单场景;(以当前线程执行任务。如果任务简单,可以直接使用这个类来执行。快捷方便。)


PS:这是单线程运行


Demo:


    public static void main(String[] args) {
        ConcurrentTaskScheduler taskScheduler = new ConcurrentTaskScheduler();
        // 执行任务
        // 执行一次
        taskScheduler.execute(() -> System.out.println(Thread.currentThread().getName() + "  我只会被执行一次~~~"));
        // 周期性执行
        taskScheduler.schedule(() -> System.out.println(Thread.currentThread().getName() + " 我会被多次执行~~~"), new CronTrigger("0/2 * * * * ?"));
        // 此处:若你有周期性的任务,这里不要shutdown()
        //taskScheduler.shutdown();
    }


输出:


pool-2-thread-1  我只会被执行一次~~~
pool-3-thread-1 我会被多次执行~~~
pool-3-thread-1 我会被多次执行~~~
pool-3-thread-1 我会被多次执行~~~
pool-3-thread-1 我会被多次执行~~~
pool-3-thread-1 我会被多次执行~~~


执行的线程都是一样的。都是Executors.newSingleThreadScheduledExecutor()这个执行的~~~


DefaultManagedTaskScheduler


它继承自ConcurrentTaskScheduler,在ConcurrentTaskScheduler基础上增加了JNDI的支持。它@since 4.0,这里不多说明


ScheduledTask


定时任务类,内部包装了一个Runnable。

// @since 4.3  发现这个类出现得还是比较晚得
public final class ScheduledTask {
  // 任务,其实就是很简单的包装了 Runnable。
  // 常见的子类有 TriggerTask、CronTask(主要是支持的CronTrigger、cron表达式)、
  // FixedDelayTask、FixedRateTask、IntervalTask(前两者得父类)
  private final Task task;
  @Nullable
  volatile ScheduledFuture<?> future;
  ScheduledTask(Task task) {
    this.task = task;
  }
   //@since 5.0.2
  public Task getTask() {
    return this.task;
  }
  // 取消任务
  public void cancel() {
    ScheduledFuture<?> future = this.future;
    if (future != null) {
      future.cancel(true);
    }
  }
  @Override
  public String toString() {
    return this.task.toString();
  }
}


总结


这篇文章主要是对Spring得调取系统进行一些重点接口、类进行盘点。其实底层大都是依赖JDK的实现的。

从很多方面可以看出,Spring对JDK底层可谓非常非常的熟悉,才能运用得这么自如。在后面讲解SpringBoot、SpringCloud时依然能体现到这一点。那就是Spring很重重复造轮子,除非它真心觉得你的实现不好~

相关文章
|
1月前
|
Java API 微服务
【Spring Boot系列】通过OpenAPI规范构建微服务服务接口
【4月更文挑战第5天】通过OpenAPI接口构建Spring Boot服务RestAPI接口
107 0
|
5天前
|
存储 Java 数据安全/隐私保护
Spring Boot中实现邮箱登录/注册接口
Spring Boot中实现邮箱登录/注册接口
|
3天前
|
前端开发 Java 开发者
在Spring框架中,`PathMatcher`是用于进行URL路径匹配的接口
在Spring框架中,`PathMatcher`是用于进行URL路径匹配的接口
22 6
|
3天前
|
算法 Java API
在Spring Boot中实现接口签名验证通常涉及以下步骤
在Spring Boot中实现接口签名验证通常涉及以下步骤
25 4
|
1月前
|
Java Spring
spring boot访问接口报500
spring boot访问接口报500
22 2
|
1月前
|
Java 数据库连接 数据库
spring+mybatis_编写一个简单的增删改查接口
spring+mybatis_编写一个简单的增删改查接口
24 2
|
1月前
|
监控 Java API
Spring Boot与异步任务:整合与应用场景
【4月更文挑战第29天】异步任务在现代应用程序开发中扮演着重要的角色,它们可以提高应用程序的性能和响应速度,尤其适用于处理长时间运行的任务或需要等待外部资源的场景。Spring Boot提供了强大的支持来简化异步任务的实现。
46 0
|
12天前
|
存储 SQL 关系型数据库
MySQL 进阶使用【函数、索引、视图、存储过程、存储函数、触发器】(2)
MySQL 进阶使用【函数、索引、视图、存储过程、存储函数、触发器】
|
12天前
|
存储 SQL 关系型数据库
MySQL 进阶使用【函数、索引、视图、存储过程、存储函数、触发器】(1)
MySQL 进阶使用【函数、索引、视图、存储过程、存储函数、触发器】
|
5天前
|
存储 SQL 关系型数据库
MySQL数据库进阶第四篇(视图/存储过程/触发器)
MySQL数据库进阶第四篇(视图/存储过程/触发器)

热门文章

最新文章