百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

Java 中的定时任务 | 初级(java的定时任务怎么运行的)

ccwgpt 2024-10-16 08:08 28 浏览 0 评论

定时任务简单来说就是在指定时间,以指定的频率来执行一个方法,而在 Java 中我们又该如何实现呢?


今天介绍的都是最原始的方式,开启一个线程,让它睡一会跑一次这也就达到了定频率的执行 run 方法,我们只需要将业务逻辑写在 run 方法中即可。


import java.util.Date;
public class ThreadTest {
    public static void main(String[] args) {
        // 设置执行周期
        final long timeInterval = 3000;
        Runnable runnable = new Runnable() {
            public void run() {
                while (true) {
                    System.out.println("Task Run ... " + new Date());
                    try {
                        Thread.sleep(timeInterval);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        Thread thread = new Thread(runnable);
        thread.start();
    }
}


我想使用线程来执行定时任务应该是所有牛逼定时器的核心所在了吧,下面介绍一种用起来更加顺手的方式 Timer 定时器。


Timer 定时器可以简单的理解为有且仅有一个后台线程对多个业务方法进行定时定频率调度的工具。


实现 Timer 定时任务需要一个 Timer 工具类和 TimerTask 实现类,实现类中用于编写任务的逻辑代码。


Timer 定时器中包含一个 TimerTask 的队列和一个 TimerThread 后台线程。注意喽,Timer 中任务的执行都依赖于这一个后台线程呢。


下面看一段示例代码


public class MyTask extends TimerTask{
    private String name;
    public MyTask(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public void run() {
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String format = sf.format(new Date());
        System.out.println("exec MyTask ... 当前时间为:" + format);
        System.out.println(this.name +" 正在执行!" + sf.format(new Date()));
    }
    public static void main(String[] args) {
        Timer timer = new Timer();
        TimerTask task1 = new MyTask("Tasks 1");
        TimerTask task2 = new MyTask("Tasks 2");
        Calendar calendar1 = Calendar.getInstance();
        calendar1.add(Calendar.SECOND, 3);
        Calendar calendar2 = Calendar.getInstance();
        calendar2.add(Calendar.SECOND, 5);
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String format = sf.format(new Date());
        System.out.println("当前时间为:" + format);
        timer.schedule(task1, calendar1.getTime(), 3000L);
        timer.schedule(task2, calendar2.getTime(), 3000L);
    }
}


API 之间的大致关系 Timer - TimerThread - TaskQueue - MyTask - run 当然最终执行的方法肯定是我们自定义任务中的 run 方法。因为我们自定义的任务已经继承了 TimerTask ,而这个类已经实现了 Runnable 接口。


简单说一下定时器中启动任务方法的不同。即 schedule 和 scheduleAtFixedRate 方法的区别?


分为两种情况:


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


schedule:以当前时间为准,然后依次按照时间间隔执行任务。


scheduleAtFixedRate: 以首次执行的时间为准,过去的时间没有执行任务的次数会在首次执行的时候补上。


2 任务执行所需时间超过任务执行周期时间


schedule:下一次执行的时间以上一次执行完成的时间为准,会存在一直延后执行的情况。


scheduleAtFixedRate: 下一次执行的时间以上一次执行开始的时间为准,不会延后,但是会存在并发的情况。


还有两个锦上添花的方法。cancel 和 purge,其中 cancel 又分为 TimerTask 单个任务的取消和 Timer 整个定时器的取消。而 Timer 调用 purge 可以返回已经取消的任务数量。


Timer 的缺陷


1 并发操作时的缺陷,这是因为 Timer 的后台只有一个执行线程导致的。


2 当任务抛出异常时的缺陷。如果 TimerTask 抛出 RuntimeException,Timer 会停止所有任务的执行。


如何解决?Java 中提供了一个工具类 ScheduledExecutorService 这个类就可以解决上述的问题。


其实原理很简单,Timer 中只有一个执行线程,绑定了多个任务,所以容易出问题,那解决的方案就是创建一个线程池,多个线程来完成多个任务即可。


但是一般我们想使用定时器来完成某个工作,任务简单点的,使用 Timer 就行,我就看到过有的项目中使用这个。


若是真的非常复杂的定时任务,比方说对时间有要求、任务的数量和执行次数有限制的,可以使用较为复杂的一个定时器框架 Quartz 。关于 Quartz,请听下回分解……


多说一句,Quartz 拥有后台执行线程池能够使用多个线程执行任务,所以,你看,核心还是多线程。

相关推荐

如何高效实现API接口的自动化测试?

实现API接口的自动化测试是一个多步骤的过程,涉及需求分析、测试用例设计、环境搭建、脚本编写、执行测试、结果分析和持续集成等多个环节。选择合适的工具和框架也是成功的关键。嘿,咱来聊聊实现API接口自动...

总结100+前端优质库,让你成为前端百事通

1年多时间,陆陆续续整理了一些常用且实用的开源项目,方便大家更高效地学习和工作.js相关库js常用工具类「lodash」一个一致性、模块化、高性能的JavaScript实用工具库。「xij...

混合开发到底怎么个混法?(混合开发rn)

引言最近几年混合开发越来越火,从PhoneGap到Cordova到Ionic,再到ReactNative,到Flutter。同时在搜索引擎中诸如IonicVSReactNativeRN和Weex+...

无所不能,将 Vue 渲染到嵌入式液晶屏

该文章转载自公众号@前端时刻,https://mp.weixin.qq.com/s/WDHW36zhfNFVFVv4jO2vrA前言之前看了雪碧大佬的将React渲染到嵌入式液晶屏觉得很有意思,R...

【直接收藏】前端 VUE 高阶面试题(一)

说说vue动态权限绑定渲染列表(权限列表渲染)首先请求服务器,获取当前用户的权限数据,比如请求this.$http.get("rights/list");获取到权限数据之后,在列表中...

Vue采用虚拟DOM的目的是什么?(vue2 虚拟dom)

虚拟DOM更新其实效率并不像大家想象中的那么高,而且React官方也从来没说过虚拟DOM效率有多高,相反React虚拟DOM的实现也不是所有虚拟DOM产品中最好的。但是通过虚拟D...

什么是 JavaScript?(什么是党的旗帜)

本文首发自「慕课网」,想了解更多IT干货内容,程序员圈内热闻,欢迎关注!作者|慕课网精英讲师然冬JavaScript(JS)是一种具有函数优先的轻量级,解释型或即时编译型的编程语言。(MDN...

Weex在内涵发现页中的工程实践(weex唯客交易所官网)

React-Native和Weex是目前最为火热的两个客户端跨平台解决方案。从去年2016年9月份开始,IES在抖音产品中应用了ReactNative,中途遇到了很多的问题,尤其是长列表的性能问题一...

新恒汇:公司主要业务包括智能卡业务、蚀刻引线框架业务以及物联网eSIM芯片封测业务

证券日报网讯新恒汇7月3日在互动平台回答投资者提问时表示,公司主要业务包括智能卡业务、蚀刻引线框架业务以及物联网eSIM芯片封测业务。具体请关注公司公告和公开披露信息。(编辑王雪儿)...

“移”科普——什么是物联网?(移动设备物联网物联网应用实例)

物联网(InternetofThings,简称IoT)是指通过互联网将物理世界与数字世界相连接,实现物与物之间的智能互联的网络。它是一种新型的信息通信技术,通过传感器、嵌入式系统、网络技术等手段,...

如何自己搭建一个物联网平台?(自建物联网云平台)

自己搭建一个物联网(IoT)平台需要涉及多个关键步骤,包括硬件设备的选择、软件开发、网络通信、安全性设计以及数据管理。以下是搭建物联网平台的基本流程:1.确定物联网平台架构一个完整的物联网平台通常包...

物联网数据接入篇-应用层 Modbus(5)

前四篇文章讲述的是TCP/IP模型中的网络接口层、网络层、传输层、应用层一,这里到了第四层应用层二。由于协议比较多,就分开篇来介绍。这篇讲Modbus协议,后面再讲MQTT协议、CoAP协议、...

乐鑫ESP32-C5全面量产:行业首款双频Wi-Fi 6的RISC-V SoC

IT之家5月2日消息,乐鑫信息科技4月30日宣布,ESP32-C5现已全面进入量产。ESP32-C5宣称是行业首款2.4&5GHz双频Wi-Fi6的RISC-...

Vue Shop Admin:强大而易用的后台管理系统模板

VueShopAdmin是一个基于Vue.js框架的后台管理系统模板。它具有简洁、易用和美观的特点,非常适合开发人员用于快速构建各种类型的管理系统。这个模板使用了最新的技术,如Vue3、V...

基于Prometheus的自动化巡检(prometheus自动发现详解)

!!大家好,我是乔克,一个爱折腾的运维工程,一个睡觉都被自己丑醒的云原生爱好者。作者:乔克公众号:运维开发故事道路千万条,安全第一条。操作不规范,运维两行泪。前言目前,大部分公司都采用Promet...

取消回复欢迎 发表评论: