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,支持延迟执行、固定频率、固定间隔三种定时策略;任务隔离、异常安全,底层基于延迟队列实现。

相关推荐
小江的记录本2 小时前
【Swagger】Swagger系统性知识体系全方位结构化总结
java·前端·后端·python·mysql·spring·docker
空太Jun2 小时前
Spring Security 自定义数据库认证(初尝试)
java·数据库·spring
报错小能手2 小时前
ios开发方向——swift内存基础
开发语言·ios·swift
minji...2 小时前
Linux 多线程(四)线程等待,线程分离,线程管理,C++多线程,pthread库
linux·运维·开发语言·网络·c++·算法
麦德泽特2 小时前
基于 Go 语言的 Modbus 项目实战:构建高性能、可扩展的工业通信服务器
服务器·开发语言·golang·modbus·rtu
sinat_255487812 小时前
泛型·学习笔记
java·jvm·数据库·windows·python
还是大剑师兰特2 小时前
pnpm format 什么作用
开发语言·javascript·ecmascript
QuZero2 小时前
Java Synchronized principle
java·开发语言
明灯伴古佛2 小时前
面试:Java中乐观锁的实现原理是什么
java·面试·职场和发展