ScheduledExecutorService 和Timer的区别

一、本质区别

  1. Timer
  • JDK 1.3 就有的单线程定时任务
  • 内部只有一个线程轮流执行所有任务
  • 基于绝对系统时间 System.currentTimeMillis()
  1. ScheduledExecutorService
  • JDK 1.5 JUC 并发包提供
  • 线程池,多个线程执行任务
  • 基于相对时间(纳秒),不依赖系统时间
  • 任务之间完全隔离

二、核心缺陷对比

  1. Timer 单线程,一个任务卡死,全部任务卡死

  2. Timer 任务抛出未捕获异常 → 整个 Timer 直接死亡

  3. Timer 依赖系统时间,改时间会导致任务执行异常

  4. ScheduledExecutorService 完全解决以上所有问题


三、代码案例对比

① Timer 代码示例

复制代码
import java.util.Timer;
import java.util.TimerTask;

public class TimerTest {
    public static void main(String[] args) {
        Timer timer = new Timer();

        // 任务1:正常执行
        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                System.out.println("任务1执行");
            }
        }, 0, 1000);

        // 任务2:10秒后抛异常
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("任务2抛出异常");
                // Timer 只要有一个任务抛异常,整个Timer线程死亡!所有任务停止!
                throw new RuntimeException("异常"); 
            }
        }, 3000);
    }
}

运行结果:

任务 1 执行几次 → 任务 3 秒后抛异常 → 整个程序所有定时任务全部停止!

② ScheduledExecutorService 代码示例

复制代码
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ScheduledTest {
    public static void main(String[] args) {
        // 核心线程池2个
        ScheduledExecutorService executor = Executors.newScheduledThreadPool(2);

        // 任务1:正常执行
        executor.scheduleAtFixedRate(() -> {
            System.out.println("任务1执行");
        }, 0, 1, TimeUnit.SECONDS);

        // 任务2:3秒后抛异常
        executor.schedule(() -> {
            System.out.println("任务2抛出异常");
            throw new RuntimeException("异常");
        }, 3, TimeUnit.SECONDS);
    }
}

运行结果:

任务 2 抛出异常 只影响自己! 任务 1 永远继续执行!

ScheduledExecutorService

Java 1.5 提供的 **** 线程池风格的定时任务工具 ,用来替代旧的 Timer 。父接口是 ExecutorService,所以本质就是一个支持延迟 / 周期性执行的线程池

常用方法

  1. schedule(Runnable, delay, unit)

    延迟一段时间执行一次

  2. scheduleAtFixedRate(Runnable, initialDelay, period, unit)

    固定速率执行 ,每隔 period 执行一次,不关心任务执行时长

  3. scheduleWithFixedDelay(Runnable, initialDelay, delay, unit)

    固定间隔执行任务执行结束后,再等 delay 才执行下一次

  4. schedule(Callable...)

    延迟执行并带返回值


最核心区别

FixedRate:固定频率

每隔 固定时间 启动一次,任务执行时间长会导致任务挤堆、并发执行

FixedDelay:固定延迟

任务结束 → 等延迟 → 再执行下一次 任务之间一定有固定空闲时间


优点(对比 Timer)

  1. Timer 是单线程,一个任务卡死全部卡死
  2. ScheduledExecutorService 是线程池,任务之间隔离
  3. 任务抛出异常不会杀死整个调度器
  4. 更精确、更稳定

底层是什么?

**内部用的是:DelayedWorkQueue(延迟阻塞队列)**按执行时间排序,线程不断拿 "到时间" 的任务执行。


面试一句话总结

ScheduledExecutorService 是 JUC 提供的基于线程池的定时任务组件,用来替代 Timer,支持延迟执行、固定频率、固定间隔三种定时策略;任务隔离、异常安全,底层基于延迟队列实现。

相关推荐
白狐_79814 分钟前
408数据结构第8章:排序②——性质对比秒杀、场景选择与外部排序
java·数据结构·算法
zander25836 分钟前
LeetCode 84:柱状图中的最大矩形——单调栈如何确定左右边界
java·数据结构·算法
码匠许师傅1 小时前
【C++ 面试真题】聊聊 C++ 的拷贝构造与拷贝赋值
java·c++·面试
qq_448011161 小时前
C语言中的动态内存分配
c语言·开发语言·php
汉字萌萌哒2 小时前
2024CSP-J入门级C++真题详解
开发语言·c++
arbboter2 小时前
【网络工具】NetProxy网络代理用户手册
开发语言·网络·c#·网络代理·网络异常·代理工具
极创信息2 小时前
系统安全隐患全方位排查方案:标准化渗透测试全流程
java·opencv·struts·数据挖掘·eclipse·语音识别·hibernate
汉字萌萌哒3 小时前
2019CCF-CSP入门级C++试题解析
java·开发语言·c++
叠层归一研究院3 小时前
AGI 系统(十一):二阶网络 — 二阶递归 × 多主体 (元符号网络)
开发语言·人工智能·算法·php·agi
喜欢的名字被抢了3 小时前
程序出问题怎么查,以及如何让它不掉线
java·运维·数据库