Wrayの知识库 Wrayの知识库
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • MacOS
  • Linux
  • Windows
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • MacOS
  • Linux
  • Windows
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
  • Java基础

    • Java概述
    • Java语法
    • 面向对象编程
    • Java数组
    • String字符串
    • 异常处理
  • Java集合

    • Java集合概述
    • ArrayList
    • LinkedList
    • HashMap
    • LinkedHashMap
    • HashSet
    • TreeMap
    • Queue&Deque
  • Java并发

    • Java并发概述
    • 线程与进程
    • Thread类与线程生命周期
    • 线程安全
    • synchronized关键字
    • volatile关键字
    • Java内存模型(JMM)
    • 线程间通信
    • 线程池
    • 并发工具类
    • 原子操作类Atomic
    • 并发锁
    • 并发容器
    • ConcurrentHashMap
    • BlockingQueue
    • CopyOnWriteArrayList
    • ThreadLocal
    • Fork/Join框架
    • ScheduledThreadPoolExecutor
      • 1. ScheduledThreadPoolExecutor 的基本概念
      • 2. ScheduledThreadPoolExecutor 的常用方法
      • 3. ScheduledThreadPoolExecutor 的实现原理
        • 3.1 scheduleAtFixedRate 方法源码分析
        • 3.2 DelayedWorkQueue
      • 4. ScheduledThreadPoolExecutor 的应用场景
      • 5. 与 Timer 和 Executors 的比较
      • 6. 源码分析与内部机制
      • 7. ScheduledThreadPoolExecutor 的优缺点
      • 8. 总结
    • CompletableFuture
  • Java IO

    • Java IO概述
  • JVM

    • JVM概述
  • Java
  • Java并发
Wray
2024-10-31
目录

ScheduledThreadPoolExecutor

ScheduledThreadPoolExecutor 是 Java 并发编程中的一个重要工具类,主要用于在指定延迟后或周期性地执行任务。它继承自 ThreadPoolExecutor,并扩展了其功能,使得任务可以按计划执行。它是 java.util.concurrent 包的一部分,通常用于定时任务的调度。

# 1. ScheduledThreadPoolExecutor 的基本概念

  • 定时任务调度:ScheduledThreadPoolExecutor 可以用于在给定的延迟时间后执行任务,或周期性地执行任务。
  • 线程池管理:继承自 ThreadPoolExecutor,ScheduledThreadPoolExecutor 具有线程池的管理功能,可以高效地管理线程的创建与销毁,减少资源开销。
  • 替代 Timer:相比于传统的 java.util.Timer,ScheduledThreadPoolExecutor 提供了更为强大的功能和更好的灵活性,支持多个任务的并发执行,且不会因为某个任务的异常而导致其他任务失败。

# 2. ScheduledThreadPoolExecutor 的常用方法

  • schedule(Runnable command, long delay, TimeUnit unit):在指定的延迟后执行一次性任务。
  • scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit):以固定的频率执行任务,任务的开始时间之间保持固定的间隔(不考虑任务执行的时间)。
  • scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit):在任务执行完成后,等待指定的延迟时间后再执行下一次任务。

示例代码:

ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor(2);

Runnable task = () -> System.out.println(Thread.currentThread().getName() + " is executing at " + System.currentTimeMillis());

// 延迟 1 秒后执行任务
scheduler.schedule(task, 1, TimeUnit.SECONDS);

// 延迟 1 秒后开始执行任务,每隔 3 秒执行一次
scheduler.scheduleAtFixedRate(task, 1, 3, TimeUnit.SECONDS);

// 延迟 1 秒后开始执行任务,每次任务执行完成后等待 3 秒再执行
scheduler.scheduleWithFixedDelay(task, 1, 3, TimeUnit.SECONDS);

在这个例子中,ScheduledThreadPoolExecutor 用于执行单次任务、固定频率任务和固定延迟任务。

# 3. ScheduledThreadPoolExecutor 的实现原理

  • 工作队列:ScheduledThreadPoolExecutor 使用了一个优先级队列 DelayedWorkQueue,该队列按照任务的到期时间进行排序。任务的执行时间越早,优先级越高。
  • 任务调度机制:当任务被提交到 ScheduledThreadPoolExecutor 时,它会进入到 DelayedWorkQueue 中,并且只有到达指定时间点的任务才会从队列中取出并执行。内部使用了 ReentrantLock 保证任务队列的线程安全。
  • 定时线程管理:ScheduledFutureTask 是用于封装定时任务的类,它实现了 RunnableScheduledFuture 接口,提供了对任务状态(如是否到期、是否被取消等)的管理。

# 3.1 scheduleAtFixedRate 方法源码分析

  • scheduleAtFixedRate 方法:用于以固定频率执行任务。
    public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
                                                  long initialDelay,
                                                  long period,
                                                  TimeUnit unit) {
        if (command == null || unit == null)
            throw new NullPointerException();
        if (period <= 0)
            throw new IllegalArgumentException();
        long triggerTime = System.currentTimeMillis() + unit.toMillis(initialDelay);
        ScheduledFutureTask<Void> sft = new ScheduledFutureTask<>(command, triggerTime, unit.toMillis(period), 0L);
        delayedExecute(sft);
        return sft;
    }
    
    • triggerTime:表示任务的第一次执行时间。
    • ScheduledFutureTask:用于封装定时任务,包含了任务的具体执行逻辑和调度信息。
    • delayedExecute(ScheduledFutureTask<?> task):将任务添加到 DelayedWorkQueue 中,等待触发时间到达。

# 3.2 DelayedWorkQueue

  • 概念:DelayedWorkQueue 是一个基于堆的优先级队列,用于管理调度任务的队列,内部根据任务到期时间进行排序,确保最先到期的任务最先被执行。
  • 线程安全:DelayedWorkQueue 使用 ReentrantLock 来保证对任务队列的并发访问安全。

# 4. ScheduledThreadPoolExecutor 的应用场景

  • 定时任务调度:ScheduledThreadPoolExecutor 常用于定时任务调度,例如定期执行某些后台任务、定时发送通知或报告生成等。
  • 周期性数据同步:在分布式系统中,使用 ScheduledThreadPoolExecutor 可以定期同步数据,例如缓存同步、日志轮询等。
  • 重试机制:对于失败的任务,可以使用 ScheduledThreadPoolExecutor 实现重试机制,在一定的延迟后重新执行任务。

# 5. 与 Timer 和 Executors 的比较

  • 与 Timer:相比于传统的 Timer 类,ScheduledThreadPoolExecutor 更加灵活,可以处理多个并发任务,并且不会因为某个任务的异常而导致其他任务失败。Timer 在单线程情况下,某个任务执行过慢或抛出异常会影响整个定时任务的执行。
  • 与 Executors.newScheduledThreadPool:Executors.newScheduledThreadPool(int corePoolSize) 实际上是使用 ScheduledThreadPoolExecutor 实现的,方便用户快速创建定时任务线程池。

# 6. 源码分析与内部机制

  • 任务延迟计算:当任务被提交时,会计算任务的触发时间,并以此将任务添加到 DelayedWorkQueue 中。队列中的任务根据触发时间排序,确保最先到期的任务最先执行。
  • 线程池管理:ScheduledThreadPoolExecutor 继承自 ThreadPoolExecutor,因此具有线程池管理功能,如工作线程的复用、队列管理、任务拒绝策略等。
  • 任务取消:当任务被取消时,ScheduledThreadPoolExecutor 会从队列中移除对应的任务,并设置任务的状态为已取消,确保不会再执行该任务。

# 7. ScheduledThreadPoolExecutor 的优缺点

  • 优点:
    • 灵活性高:可以实现单次、固定频率和固定延迟的任务调度,适用于各种定时任务场景。
    • 多任务调度:支持多个任务的并发调度,不会因为某个任务的异常而导致其他任务的失败。
    • 线程池复用:通过线程池的方式复用工作线程,减少了线程的频繁创建和销毁带来的开销。
  • 缺点:
    • 任务积压风险:如果任务的执行时间超过了调度周期,可能会导致任务积压,尤其是在高并发和短周期调度的情况下。

# 8. 总结

ScheduledThreadPoolExecutor 是 Java 并发编程中强大的定时任务调度工具,通过线程池的方式执行定时任务,提供了更高的灵活性和可扩展性。相比于传统的 Timer,它不仅能高效地处理并发任务,还具备更完善的异常处理机制。理解 ScheduledThreadPoolExecutor 的原理及其使用场景,可以帮助开发者在多线程环境中更好地管理定时任务的执行。

上次更新: 2024/11/01, 13:45:14
Fork/Join框架
CompletableFuture

← Fork/Join框架 CompletableFuture→

Copyright © 2023-2024 Wray | 鄂ICP备2024050235号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式