Java学习笔记:定时任务调度工具之 Timer

简介: Java学习笔记:定时任务调度工具之 Timer

定时任务调度

定义:

基于给定的时间点,给定的时间间隔或者给定的执行次数自动执行的任务

Timer 和 Quartz

Timer: 有且仅有一个后台线程对多个业务线程进行定时定频率的调度

主要构件

Timer -定时调用-> TimerTask


image.png

定时函数的用法

// 延时执行一次
public void schedule(TimerTask task, long delay)
// 定时执行一次
public void schedule(TimerTask task, Date time)
// 延时间隔执行
public void schedule(TimerTask task, long delay, long period)
// 定时间隔执行
public void schedule(TimerTask task, Date firstTime, long period)
// 延时间隔执行
public void scheduleAtFixedRate(TimerTask task, long delay, long period)
// 定时间隔执行
public void scheduleAtFixedRate(TimerTask task, Date firstTime, long period)

代码实例

package timer;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
class Util {
    public static String getCurrentDateTime() {
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return dateFormat.format(calendar.getTime());
    }
}
class MyTimerTask extends TimerTask {
    @Override
    public void run() {
        System.out.println("MyTimerTask is Running " + Util.getCurrentDateTime());
    }
}
public class TimerDemo {
    public static void main(String[] args) {
        Timer timer = new Timer();
        // 延时0s之后,每隔1s执行一次
        timer.schedule(new MyTimerTask(), 0L, 1000L);
    }
}

执行结果

MyTimerTask is Running 2020-06-22 22:49:45
MyTimerTask is Running 2020-06-22 22:49:46
MyTimerTask is Running 2020-06-22 22:49:47
...

其他函数

TimerTask.cancel() 取消【当前】 TimerTask 里的任务
TimerTask.scheduledExecutionTime() 返回此任务最近实际执行的已安排执行的时间
Timer.cancel()终止此计时器,丢弃【所有】当前已安排的任务
Timer.purge() 从此计时器的任务队列中移除所有已取消的任务,返回移除数量

区别

schedule 和 scheduleAtFixedRate


1、首次计划执行的时间早于当前的时间


schedule fixed-delay


如果第一次执行时间被 delay 了,随后的执行时间按照上一次实际执行【完成的时间点】进行计算


scheduleAtFixedRate fixed-rate


如果第一次执行时间被 delay 了,随后的执行时间按照上一次【开始的时间点】进行计算,并且为了赶上进度会多次执行任务,因此 TimerTask 中的执行体需要考虑同步


代码示例

package timer;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class TimerDemo {
    public static void main(String[] args) {
        Timer timer = new Timer();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, -10);
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println(dateFormat.format(new Date()));
            }
        }, calendar.getTime(), 2000L);
    }
}

执行结果

timer.schedule
2020-06-22 23:16:56
2020-06-22 23:16:58
2020-06-22 23:17:00
timer.scheduleAtFixedRate
2020-06-22 23:18:19
2020-06-22 23:18:19
2020-06-22 23:18:19

2、任务执行所需时间超出任务的执行周期间隔

schedule

下次执行时间相对于上一次实际执行【完成的时间点】,因此执行时间会不断延后

scheduleAtFixedRate

下一次执行时间相对于上一次【开始的时间点】,因此执行时间一般不会延后,因此存在并发性

package timer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class TimerDemo {
    public static void main(String[] args) {
        Timer timer = new Timer();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                try {
                    Thread.sleep(3000L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(dateFormat.format(new Date()));
            }
        }, 0L, 1000L);
    }
}
timer.schedule
2020-06-22 23:24:08
2020-06-22 23:24:11
2020-06-22 23:24:14
timer.scheduleAtFixedRate
2020-06-22 23:25:18
2020-06-22 23:25:21
2020-06-22 23:25:24

Timer 综合应用

执行 5 次任务,就停止定时器,并退出程序

package timer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
// 自定义任务
class MyTimerTask extends TimerTask {
    private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private int count = 0;
    private Timer timer;
    public MyTimerTask(Timer timer) {
        this.timer = timer;
    }
    @Override
    public void run() {
        System.out.println(dateFormat.format(new Date()));
        // 判断执行满5次就停止
        this.count++;
        if (this.count >= 5) {
            // 停止当前任务
            this.cancel();
            // 停止定时器,并退出程序
            this.timer.cancel();
        }
    }
}
public class TimerDemo {
    public static void main(String[] args) {
        Timer timer = new Timer();
        timer.schedule(new MyTimerTask(timer), 0L, 1000L);
    }
}

打印结果

2020-06-23 20:46:11
2020-06-23 20:46:12
2020-06-23 20:46:13
2020-06-23 20:46:14
2020-06-23 20:46:15

Timer 缺陷

1、管理并发任务的缺陷

Timer 有且仅有一个线程去执行定时任务,如果存在多个任务,且任务时间过长,会导致执行效果与预期不符


2、当任务抛出异常时的缺陷

如果 TimerTask 抛出 RuntimeException,Timer 会停止所有任务的运行


3、以下场景不建议使用


对时效性要求较高的多任务并发作业

对复杂的任务的调度


相关文章
|
2月前
|
人工智能 监控 Java
Java与AI智能体:构建自主决策与工具调用的智能系统
随着AI智能体技术的快速发展,构建能够自主理解任务、制定计划并执行复杂操作的智能系统已成为新的技术前沿。本文深入探讨如何在Java生态中构建具备工具调用、记忆管理和自主决策能力的AI智能体系统。我们将完整展示从智能体架构设计、工具生态系统、记忆机制到多智能体协作的全流程,为Java开发者提供构建下一代自主智能系统的完整技术方案。
458 4
|
3月前
|
人工智能 Java API
Java AI智能体实战:使用LangChain4j构建能使用工具的AI助手
随着AI技术的发展,AI智能体(Agent)能够通过使用工具来执行复杂任务,从而大幅扩展其能力边界。本文介绍如何在Java中使用LangChain4j框架构建一个能够使用外部工具的AI智能体。我们将通过一个具体示例——一个能获取天气信息和执行数学计算的AI助手,详细讲解如何定义工具、创建智能体并处理执行流程。本文包含完整的代码示例和架构说明,帮助Java开发者快速上手AI智能体的开发。
1223 8
|
3月前
|
人工智能 缓存 监控
使用LangChain4j构建Java AI智能体:让大模型学会使用工具
AI智能体是大模型技术的重要演进方向,它使模型能够主动使用工具、与环境交互,以完成复杂任务。本文详细介绍如何在Java应用中,借助LangChain4j框架构建一个具备工具使用能力的AI智能体。我们将创建一个能够进行数学计算和实时信息查询的智能体,涵盖工具定义、智能体组装、记忆管理以及Spring Boot集成等关键步骤,并展示如何通过简单的对话界面与智能体交互。
1095 1
|
3月前
|
Java
Java 数组学习笔记
本文整理Java数组常用操作:遍历、求和、查找、最值及二维数组行求和等典型练习,涵盖静态初始化、元素翻倍、去极值求平均等实例,帮助掌握数组基础与应用。
|
3月前
|
小程序 Java 知识图谱
Java 学习笔记 —— BMI & BMR 计算器
这是一个使用 Java 编写的 BMI 与 BMR 计算器小程序,可输入年龄、性别、身高和体重,计算身体质量指数(BMI)和基础代谢率(BMR),并输出健康评估结果。通过该项目,掌握了 Java 的输入处理、数据验证、条件判断、数学运算及格式化输出等基础知识,是 Java 初学者的理想练习项目。
|
6月前
|
Java 数据安全/隐私保护
银行转账虚拟生成器app,银行卡转账截图制作软件,java实现截图生成工具【仅供装逼娱乐用途】
本项目提供了一套基于Java的图片处理教学方案,包含自定义图片生成、图像水印添加及合法电子凭证生成技术示例。
|
6月前
|
Java 数据安全/隐私保护 计算机视觉
银行转账虚拟生成器app,银行卡转账截图制作软件,java实现截图生成工具【仅供装逼娱乐用途】
本内容提供Java生成自定义图片的示例代码,涵盖基础图像创建、文本添加及保存功能,适合学习2D图形编程。包括教学示例图片生成、文本图层处理和数字水印技术实现方案。
|
6月前
|
Java API 微服务
2025 年 Java 从入门到精通学习笔记全新版
《Java学习笔记:从入门到精通(2025更新版)》是一本全面覆盖Java开发核心技能的指南,适合零基础到高级开发者。内容包括Java基础(如开发环境配置、核心语法增强)、面向对象编程(密封类、接口增强)、进阶技术(虚拟线程、结构化并发、向量API)、实用类库与框架(HTTP客户端、Spring Boot)、微服务与云原生(容器化、Kubernetes)、响应式编程(Reactor、WebFlux)、函数式编程(Stream API)、测试技术(JUnit 5、Mockito)、数据持久化(JPA、R2DBC)以及实战项目(Todo应用)。
391 5
|
6月前
|
安全 Java 编译器
JD-GUI,java反编译工具及原理: JavaDecompiler一个Java反编译器
Java Decompiler (JD-GUI) 是一款由 Pavel Kouznetsov 开发的图形化 Java 反编译工具,支持 Windows、Linux 和 Mac Os。它能将 `.class` 文件反编译为 Java 源代码,支持多文件标签浏览、高亮显示,并兼容 Java 5 及以上版本。JD-GUI 支持对整个 Jar 文件进行反编译,可跳转源码,适用于多种 JDK 和编译器。其原理基于将字节码转换为抽象语法树 (AST),再通过反编译生成代码。尽管程序可能带来安全风险,但可通过代码混淆降低可读性。最新版修复了多项识别错误并优化了内存管理。
3513 1
|
7月前
|
机器学习/深度学习 消息中间件 存储
【高薪程序员必看】万字长文拆解Java并发编程!(9-2):并发工具-线程池
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发编程中的强力并发工具-线程池,废话不多说让我们直接开始。
285 0