前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java & Go 定时任务

Java & Go 定时任务

作者头像
FunTester
发布2024-07-30 16:26:30
1300
发布2024-07-30 16:26:30
举报
文章被收录于专栏:FunTester

定时任务概括

定时任务是软件开发中用于自动执行周期性任务的技术。它允许开发者设置特定的时间点或间隔来触发预定的操作,如数据备份、清理缓存、发送通知等。这种机制可以减少人工干预,提高系统效率和稳定性。定时任务在不同的操作系统和编程环境中有不同的实现方式,例如Linux的cron作业、Windows的任务计划程序,或是编程语言中的相关库。它们帮助自动化重复性工作,确保关键任务按时执行,是现代应用程序不可或缺的组成部分。

定时任务使用场景

定时任务在软件开发当中使用非常广泛。主要有以下场景:

  1. 数据备份。定时备份重要数据,防止丢失。
  2. 日志清理。定时归档和清理日志文件,释放磁盘空间
  3. 性能监控。定时收集、处理和上报性能数据。
  4. 数据同步。定时将最新数据同步给其他消费者。
  5. 资源管理。定时清理、回收系统资源,提升利用率和性能。

当然列举的这几个有些宽泛,在实际开发当中,会有多种多样的定时任务场景。下面我们先来看看 Java 语言都有哪些实现定时任务的类库。

Java 语言实现定时任务

相信很多小伙伴接触最多的定时任务就是定时自动化回归测试了。通常会有专门的开发和测试框架来完成具体的设置和执行定时任务。在 Java 语言中,实现定时任务有几种常用的方法:

  1. java.util.Timer:这是Java标准库提供的一个类,可以用来安排任务以后在后台线程中执行。使用Timer类,你可以创建一个TimerTask任务,然后使用schedulescheduleAtFixedRate方法来安排任务的执行。
  2. ScheduledExecutorService 接口:这是Java并发包中的一部分,提供了更灵活的定时任务调度能力。你可以使用Executors类创建一个ScheduledExecutorService实例,然后使用schedulescheduleAtFixedRate方法来安排任务。
  3. Spring框架的@Scheduled注解:如果你在使用Spring框架,可以利用@Scheduled注解来简化定时任务的配置。Spring的调度器会根据注解的参数来执行相应的方法。
  4. Quartz Scheduler:这是一个开源的作业调度库,提供了比Java标准库更强大的定时任务功能。Quartz允许你配置复杂的调度策略,如cron表达式,并支持集群。

java.util.Timer

利用 Spring 框架支持相对来说比较常见。下面我写了一个 java.util.Timer 实现每秒打印一次时间的定时任务的简单案例。可以按以下步骤编写代码:

  1. 创建一个继承自TimerTask的类,在其中实现run方法。
  2. 创建一个Timer对象。
  3. 使用Timer对象的schedule方法安排任务。

以下是具体的示例代码:

代码语言:javascript
复制

package com.funtest.temp;


import com.funtester.frame.SourceCode;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class FunTester extends SourceCode {

    public static void main(String[] args) {
        Timer timer = new Timer();// 实例化Timer类
        TimerTask task = new TimerTask() {
            @Override
            public void run() {// 实例化TimerTask类
                // 任务代码,打印当前时间,并指定线程名称
                SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
                Date date = new Date(System.currentTimeMillis());
                System.out.println(Thread.currentThread().getName() + "      " + formatter.format(date));
            }
        };
        // 0表示立即执行,1000表示每隔1秒执行一次
        timer.scheduleAtFixedRate(task, 0, 1000);
    }

}

下面是控制台打印的信息:

代码语言:javascript
复制
Timer-0      10:04:07
Timer-0      10:04:08
Timer-0      10:04:09
Timer-0      10:04:10

使用 java.util.Timer 实现定时任务,虽然具有简单易用优点,但在我的经验范围内极少,大多数都是包装成服务化,使用 Spring 自带的定时任务执行。其主要缺点就是:单线程执行、异常处理不够优雅、不支持并发。总体来讲不如 ScheduledExecutorService 功能强大。

ScheduledExecutorService

下面是 ScheduledExecutorService 的简单案例。

代码语言:javascript
复制
package com.funtest.temp;  
  
  
import com.funtester.frame.SourceCode;  
  
import java.text.SimpleDateFormat;  
import java.util.Date;  
import java.util.concurrent.Executors;  
import java.util.concurrent.ScheduledExecutorService;  
import java.util.concurrent.TimeUnit;  
  
public class FunTester extends SourceCode {  
  
    public static void main(String[] args) {  
        // 创建一个具有单个线程的调度程序  
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);  
        // 创建一个Runnable任务,每秒打印一次当前时间  
        Runnable task = new Runnable() {  
            @Override  
            public void run() {  
                SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");  
                System.out.println(Thread.currentThread().getName() + "      " + sdf.format(new Date()));  
            }  
        };  
        // 从现在开始1秒钟之后,每隔1秒钟执行一次  
        scheduler.scheduleAtFixedRate(task, 0, 1, TimeUnit.SECONDS);  
    }  
  
}

明显看到用到了线程池的使用,有点不用多说,简洁性我感觉不输 java.util.Timer

Go 语言定时任务

Go 语言定时任务实现,也是比较简单的也是利用 Go SDK 自带的 time 包。下面是简单的案例:

代码语言:javascript
复制

package main

import (
 "fmt"
 "time"
)

func main() {
 // 创建一个定时器,每隔1秒钟执行一次
 ticker := time.NewTicker(1 * time.Second)
 // 延迟关闭定时器
 defer ticker.Stop()
 // 无限循环
 for {
  // 从定时器的通道中接收数据
  select {
  case t := <-ticker.C:
   fmt.Println("Current time:", t)
  }
 }
}

这个案例基本是最佳实现,如果大家有需求都可以参考,而且 Go 语言 goroutine 的原因,不用很关心协程性能的问题,我自己就直接使用 goroutine 直接起定时任务了。这种对于复杂的定时任务,这种方式就显得力不从心了。

Go 语言 time 包里面还有一种方法实现:

代码语言:javascript
复制
package main  
  
import (  
    "fmt"  
    "time")  
  
func main() {  
    // 创建一个定时器,1秒后触发  
    timer := time.AfterFunc(1*time.Second, func() {  
       fmt.Println("Current time:", time.Now())  
    })  
  
    // 防止程序退出  
    select {  
    case <-timer.C:  
    }  
}

语法上看好像区别不是很大,各位自己选用吧。

cron 包

下面分享一下 Go 第三方包的实现。cron 是一个在 Go 语言中实现定时任务的流行库,它允许你使用 cron 表达式来定义任务的执行时间。PS:这个 cron 目测只支持了分钟级别的。

代码语言:javascript
复制
package main  
  
import (  
    "fmt"  
    "time"  
    "github.com/robfig/cron/v3")  
  
func main() {  
    // 创建一个定时任务  
    c := cron.New()  
    // 添加一个定时任务,每隔1分钟执行一次  
    c.AddFunc("0/1 * * * *", func() {  
       fmt.Println("Current time:", time.Now())  
    })  
    // 启动定时任务  
    c.Start()  
    // 防止程序退出  
    select {}  
}

AddFunc 方法参数 spec 不仅支持 cron 语法,为了方便使用还增加了一个 @every 语法,后面可以跟类似 @every 1m2stime.ParseDuration() 支持的格式都可以用在这里。除此之外 cron 预定义了一些时间规则:

  • @yearly:也可以写作@annually,表示每年第一天的 0 点。等价于0 0 1 1 *
  • @monthly:表示每月第一天的 0 点。等价于0 0 1 * *
  • @weekly:表示每周第一天的 0 点,注意第一天为周日,即周六结束,周日开始的那个 0 点。等价于0 0 * * 0
  • @daily:也可以写作@midnight,表示每天 0 点。等价于0 0 * * *
  • @hourly:表示每小时的开始。等价于0 * * * *

gocron包

还有一个更加灵活的库 gocron 功能更加强大,但使用起来存在一定门槛。下面是一个案例:

代码语言:javascript
复制
package main

import (
 "fmt"
 "time"

 "github.com/go-co-op/gocron"
)

func main() {
 // 定时任务
 s := gocron.NewScheduler(time.Local)
 // 每秒执行一次
 s.Every(1).Minutes().Do(func() {
  fmt.Println("Current time:", time.Now())
 })
 s.StartBlocking()
 fmt.Println("任务结束")
}

gocron 设置时间的话,都可以通过调用不同的 API 来组装实现。对于 API 学习需要一定的学习成本。同时 gocron 也支持 cron 语法的。下面是个例子:

代码语言:javascript
复制
package main

import (
 "fmt"
 "time"

 "github.com/go-co-op/gocron"
)

func main() {
 // 定时任务
 s := gocron.NewScheduler(time.Local)
 // 添加一个每周二上午10点每分钟执行一次的任务,使用 cron 表达式
 s.Cron("0 * 10 ? * 2").Do(func() {
  fmt.Println("Task executed at:", time.Now())
 })
 s.StartBlocking()
 fmt.Println("任务结束")
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-07-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FunTester 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 定时任务概括
  • 定时任务使用场景
  • Java 语言实现定时任务
    • java.util.Timer
      • ScheduledExecutorService
      • Go 语言定时任务
        • cron 包
          • gocron包
          相关产品与服务
          应用性能监控
          应用性能监控(Application Performance Management,APM)是一款应用性能管理平台,基于实时多语言应用探针全量采集技术,为您提供分布式性能分析和故障自检能力。APM 协助您在复杂的业务系统里快速定位性能问题,降低 MTTR(平均故障恢复时间),实时了解并追踪应用性能,提升用户体验。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档