java常用的定時任務(wù)框架及相關(guān)代碼應(yīng)用示例
在Java中,實現(xiàn)定時任務(wù)的框架和工具較多,以下是常用的定時任務(wù)框架及代碼示例:
一、JDK自帶定時任務(wù)(基礎(chǔ))
1.Timer和TimerTask(簡單但功能有限)
Timer 是JDK早期提供的定時任務(wù)工具,通過單線程執(zhí)行任務(wù),存在任務(wù)阻塞風(fēng)險,適用于簡單場景。
import java.util.Timer;
import java.util.TimerTask;
public class TimerExample {
public static void main(String[] args) {
Timer timer = new Timer();
// 任務(wù):延遲1秒后執(zhí)行,之后每隔2秒執(zhí)行一次
TimerTask task = new TimerTask() {
@Override
public void run() {
System.out.println("TimerTask執(zhí)行:" + System.currentTimeMillis());
}
};
// schedule(任務(wù), 延遲時間(毫秒), 間隔時間(毫秒))
timer.schedule(task, 1000, 2000);
}
}
2.ScheduledExecutorService(推薦,線程池支持)
JDK 5+ 引入的線程池定時任務(wù),基于線程池實現(xiàn),避免單線程阻塞問題,功能更完善。
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ScheduledExecutorExample {
public static void main(String[] args) {
// 創(chuàng)建定時任務(wù)線程池(核心線程數(shù)為1)
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
// 任務(wù):延遲1秒后執(zhí)行,之后每隔2秒執(zhí)行一次
Runnable task = () -> System.out.println("ScheduledExecutor執(zhí)行:" + System.currentTimeMillis());
// scheduleAtFixedRate(任務(wù), 初始延遲, 間隔時間, 時間單位)
executor.scheduleAtFixedRate(task, 1, 2, TimeUnit.SECONDS);
}
}
二、Spring框架內(nèi)置定時任務(wù)
Spring提供了聲明式定時任務(wù)支持,通過注解簡化配置,依賴Spring上下文。
1. 基于@Scheduled注解(常用)
需在配置類中開啟定時任務(wù)支持(@EnableScheduling)。
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
// 開啟定時任務(wù)
@EnableScheduling
@Component
public class SpringScheduledExample {
// 固定延遲執(zhí)行:上一次任務(wù)結(jié)束后間隔2秒執(zhí)行
@Scheduled(fixedDelay = 2000)
public void fixedDelayTask() {
System.out.println("fixedDelay任務(wù)執(zhí)行:" + System.currentTimeMillis());
}
// 固定頻率執(zhí)行:每隔2秒執(zhí)行(無論上一次是否結(jié)束)
@Scheduled(fixedRate = 2000)
public void fixedRateTask() {
System.out.println("fixedRate任務(wù)執(zhí)行:" + System.currentTimeMillis());
}
// Cron表達式:每天12:00執(zhí)行(支持復(fù)雜時間配置)
@Scheduled(cron = "0 0 12 * * ?")
public void cronTask() {
System.out.println("Cron任務(wù)執(zhí)行:" + System.currentTimeMillis());
}
}
Cron表達式說明:
格式為 秒 分 時 日 月 周 [年],例如:
0 0/5 * * * ?:每5分鐘執(zhí)行一次0 30 10 ? * MON-FRI:每周一至周五10:30執(zhí)行
三、Quartz(強大的企業(yè)級框架)
Quartz是功能全面的定時任務(wù)框架,支持分布式、任務(wù)持久化、復(fù)雜調(diào)度策略等,適用于大型應(yīng)用。
1. 核心依賴(Maven)
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.2</version>
</dependency>
2. 代碼示例
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
// 定義任務(wù)
class MyJob implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("Quartz任務(wù)執(zhí)行:" + System.currentTimeMillis());
}
}
public class QuartzExample {
public static void main(String[] args) throws SchedulerException {
// 1. 創(chuàng)建調(diào)度器
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// 2. 創(chuàng)建任務(wù)詳情
JobDetail job = JobBuilder.newJob(MyJob.class)
.withIdentity("job1", "group1") // 任務(wù)ID和組
.build();
// 3. 創(chuàng)建觸發(fā)器(Cron表達式:每隔2秒執(zhí)行)
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1")
.withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?"))
.build();
// 4. 關(guān)聯(lián)任務(wù)和觸發(fā)器,啟動調(diào)度器
scheduler.scheduleJob(job, trigger);
scheduler.start();
}
}
3 SpringBoot 集成的Spring Boot Starter Quartz的應(yīng)用
3.1 核心概念
在使用前需了解 Quartz 的 3 個核心組件:
- Job:具體執(zhí)行的任務(wù)邏輯(實現(xiàn)
org.quartz.Job接口,重寫execute方法)。 - Trigger:觸發(fā)條件(何時執(zhí)行、執(zhí)行頻率等),支持
SimpleTrigger(簡單重復(fù))和CronTrigger(cron 表達式)。 - Scheduler:調(diào)度器,負責(zé)協(xié)調(diào) Job 和 Trigger 的關(guān)聯(lián),是 Quartz 的核心入口。
3.2 集成步驟
- 引入依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
- 配置 Quartz
Spring Boot 提供自動配置,可通過application.yml自定義 Quartz 行為,核心配置如下:
spring:
quartz:
# 任務(wù)存儲方式:memory(內(nèi)存,默認,非集群)、jdbc(持久化,支持集群)
job-store-type: jdbc
# 集群配置(僅 job-store-type: jdbc 時生效)
properties:
org:
quartz:
scheduler:
instanceName: myScheduler # 調(diào)度器實例名
instanceId: AUTO # 實例ID自動生成(集群中唯一)
jobStore:
class: org.quartz.impl.jdbcjobstore.JobStoreTX # 事務(wù)型存儲
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate # 數(shù)據(jù)庫適配器(根據(jù)數(shù)據(jù)庫選擇)
tablePrefix: QRTZ_ # 表前綴(Quartz 自帶表結(jié)構(gòu))
isClustered: true # 開啟集群
clusterCheckinInterval: 10000 # 集群節(jié)點心跳間隔(ms)
threadPool:
class: org.quartz.simpl.SimpleThreadPool # 線程池實現(xiàn)
threadCount: 10 # 線程數(shù)
threadPriority: 5 # 線程優(yōu)先級(1-10)
3、實戰(zhàn)示例
定義 Job 任務(wù)
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.stereotype.Component;
@Component
public class MyQuartzJob implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
// 任務(wù)邏輯:如打印日志、調(diào)用服務(wù)等
System.out.println("Quartz 任務(wù)執(zhí)行:" + System.currentTimeMillis());
// 從上下文獲取參數(shù)(可選)
String param = (String) context.getJobDetail().getJobDataMap().get("param");
System.out.println("接收參數(shù):" + param);
}
}
配置 JobDetail 和 Trigger
import org.quartz.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class QuartzConfig {
// 1. 定義 JobDetail(任務(wù)詳情)
@Bean
public JobDetail myJobDetail() {
// 綁定任務(wù)類,并設(shè)置持久化(即使沒有Trigger關(guān)聯(lián)也不刪除)
return JobBuilder.newJob(MyQuartzJob.class)
.withIdentity("myJob", "myJobGroup") // 任務(wù)唯一標(biāo)識(名稱+組名)
.usingJobData("param", "Hello Quartz") // 傳遞參數(shù)
.storeDurably() // 持久化
.build();
}
// 2. 定義 Trigger(觸發(fā)器)
@Bean
public Trigger myTrigger() {
// CronTrigger:基于cron表達式(此處為每5秒執(zhí)行一次)
CronScheduleBuilder cronSchedule = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");
return TriggerBuilder.newTrigger()
.forJob(myJobDetail()) // 關(guān)聯(lián)JobDetail
.withIdentity("myTrigger", "myTriggerGroup") // 觸發(fā)器唯一標(biāo)識
.withSchedule(cronSchedule) // 綁定調(diào)度策略
.build();
}
}
啟動測試
啟動 Spring Boot 應(yīng)用,控制臺會每隔5秒打印任務(wù)執(zhí)行日志,說明集成成功。
動態(tài)操作任務(wù)(增刪改查)
實際開發(fā)中常需動態(tài)管理任務(wù)(如通過接口添加/暫停任務(wù)),可注入 Scheduler 進行操作:
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/quartz")
public class QuartzController {
@Autowired
private Scheduler scheduler;
// 新增任務(wù)
@PostMapping("/add")
public String addJob() throws SchedulerException {
// 1. 構(gòu)建JobDetail
JobDetail jobDetail = JobBuilder.newJob(MyQuartzJob.class)
.withIdentity("dynamicJob", "dynamicGroup")
.usingJobData("param", "動態(tài)任務(wù)")
.storeDurably()
.build();
// 2. 構(gòu)建Trigger(每10秒執(zhí)行一次)
Trigger trigger = TriggerBuilder.newTrigger()
.forJob(jobDetail)
.withIdentity("dynamicTrigger", "dynamicGroup")
.withSchedule(CronScheduleBuilder.cronSchedule("0/10 * * * * ?"))
.build();
// 3. 注冊到調(diào)度器
scheduler.scheduleJob(jobDetail, trigger);
return "任務(wù)添加成功";
}
// 暫停任務(wù)
@PostMapping("/pause/{jobName}/{jobGroup}")
public String pauseJob(@PathVariable String jobName, @PathVariable String jobGroup) throws SchedulerException {
JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
scheduler.pauseJob(jobKey);
return "任務(wù)暫停成功";
}
// 恢復(fù)任務(wù)
@PostMapping("/resume/{jobName}/{jobGroup}")
public String resumeJob(@PathVariable String jobName, @PathVariable String jobGroup) throws SchedulerException {
JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
scheduler.resumeJob(jobKey);
return "任務(wù)恢復(fù)成功";
}
// 刪除任務(wù)
@PostMapping("/delete/{jobName}/{jobGroup}")
public String deleteJob(@PathVariable String jobName, @PathVariable String jobGroup) throws SchedulerException {
JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
// 先刪除觸發(fā)器,再刪除任務(wù)
scheduler.pauseTrigger(TriggerKey.triggerKey(jobName, jobGroup));
scheduler.unscheduleJob(TriggerKey.triggerKey(jobName, jobGroup));
scheduler.deleteJob(jobKey);
return "任務(wù)刪除成功";
}
}
通過 spring-boot-starter-quartz,Spring Boot 開發(fā)者可快速集成強大的定時任務(wù)能力,滿足從簡單定時到分布式復(fù)雜調(diào)度的各種需求。
四、分布式定時任務(wù)框架(集群環(huán)境)
在分布式系統(tǒng)中,需避免任務(wù)重復(fù)執(zhí)行,常用框架:
1. Elastic-Job(當(dāng)當(dāng)網(wǎng)開源,基于ZooKeeper)
// 定義任務(wù)
public class MyElasticJob implements SimpleJob {
@Override
public void execute(ShardingContext context) {
System.out.println("分片" + context.getShardingItem() + "執(zhí)行任務(wù)");
}
}
// 配置任務(wù)(Spring環(huán)境)
@Configuration
public class ElasticJobConfig {
@Bean
public SimpleJob myJob() {
return new MyElasticJob();
}
@Bean(initMethod = "init")
public JobScheduler jobScheduler(SimpleJob myJob, ZookeeperRegistryCenter regCenter) {
return JobSchedulerBuilder.newBuilder(myJob)
.registryCenter(regCenter)
.cron("0/2 * * * * ?") // 定時策略
.shardingTotalCount(2) // 分片數(shù)
.build();
}
}
2. XXL-Job(大眾點評開源,輕量級分布式任務(wù))
通過Admin控制臺配置任務(wù),代碼只需實現(xiàn)執(zhí)行邏輯:
@XxlJob("xxlJobDemo")
public void xxlJobDemo() throws Exception {
System.out.println("XXL-Job任務(wù)執(zhí)行:" + System.currentTimeMillis());
}
2.1 核心架構(gòu)
XXL-Job 采用“調(diào)度中心 + 執(zhí)行器”的分布式架構(gòu):
- 調(diào)度中心:集中管理任務(wù)調(diào)度,負責(zé)任務(wù)配置、觸發(fā)調(diào)度、監(jiān)控執(zhí)行結(jié)果等(基于 Spring Boot 開發(fā),可獨立部署)。
- 執(zhí)行器:部署在業(yè)務(wù)服務(wù)中,負責(zé)接收調(diào)度中心的任務(wù)指令并執(zhí)行具體邏輯(通過 HTTP 與調(diào)度中心通信)。
2.2 核心特性
- 分布式調(diào)度:支持集群部署,調(diào)度中心通過負載均衡策略(如輪詢、一致性哈希)向執(zhí)行器分發(fā)任務(wù),避免單點故障。
- 豐富的任務(wù)類型:支持 Cron 表達式定時任務(wù)、固定頻率任務(wù)、失敗重試、任務(wù)依賴等。
- 可視化管理:提供 Web 控制臺,可在線配置任務(wù)、啟停任務(wù)、查看執(zhí)行日志、監(jiān)控任務(wù)狀態(tài)。
- 彈性擴容:執(zhí)行器可動態(tài)增減節(jié)點,調(diào)度中心自動感知并調(diào)整負載。
- 失敗處理:支持任務(wù)失敗重試、失敗告警(郵件、短信等)。
- 日志追蹤:執(zhí)行日志集中存儲,支持在線查看和檢索。
2.3部署調(diào)度中心
- 從 GitHub 下載源碼,初始化調(diào)度中心數(shù)據(jù)庫(腳本
doc/db/tables_xxl_job.sql)。 - 配置調(diào)度中心
application.properties(數(shù)據(jù)庫連接、端口等),啟動xxl-job-admin模塊。
2.4 執(zhí)行器集成
(1)引入依賴
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>2.4.0</version> <!-- 版本與調(diào)度中心一致 -->
</dependency>
(2)配置執(zhí)行器
xxl:
job:
admin:
addresses: http://127.0.0.1:8080/xxl-job-admin # 調(diào)度中心地址
executor:
appname: my-executor # 執(zhí)行器名稱(唯一)
port: 9999 # 執(zhí)行器端口(默認9999,可選)
logpath: /data/xxl-job/logs # 日志路徑
(3)注冊執(zhí)行器并定義任務(wù)
// 配置執(zhí)行器客戶端
@Configuration
public class XxlJobConfig {
@Value("${xxl.job.admin.addresses}")
private String adminAddresses;
@Value("${xxl.job.executor.appname}")
private String appname;
@Bean
public XxlJobSpringExecutor xxlJobExecutor() {
XxlJobSpringExecutor executor = new XxlJobSpringExecutor();
executor.setAdminAddresses(adminAddresses);
executor.setAppname(appname);
return executor;
}
}
// 定義任務(wù)(@XxlJob注解指定任務(wù)標(biāo)識)
@Component
public class MyXxlJob {
@XxlJob("demoJobHandler") // 任務(wù)標(biāo)識,需與調(diào)度中心配置一致
public void execute() throws Exception {
String param = XxlJobHelper.getJobParam(); // 獲取任務(wù)參數(shù)
XxlJobHelper.log("任務(wù)執(zhí)行:" + param); // 日志記錄
// 業(yè)務(wù)邏輯...
}
}
2.5 調(diào)度中心配置任務(wù)
- 登錄調(diào)度中心 Web 控制臺(默認地址
http://localhost:8080/xxl-job-admin,賬號 admin/123456)。 - 新增執(zhí)行器(配置執(zhí)行器名稱
my-executor)。 - 新增任務(wù):選擇執(zhí)行器,填寫任務(wù)標(biāo)識
demoJobHandler、Cron 表達式(如0/5 * * * * ?),啟動任務(wù)。
適用場景
- 分布式定時任務(wù)(如定時數(shù)據(jù)同步、報表生成)。
- 需要統(tǒng)一管理和監(jiān)控的任務(wù)調(diào)度場景。
- 對任務(wù)失敗重試、告警有需求的業(yè)務(wù)。
相比 Quartz,XXL-Job 更側(cè)重分布式場景的易用性和可視化管理,簡化了集群部署和任務(wù)監(jiān)控的復(fù)雜度。
總結(jié)
到此這篇關(guān)于java常用的定時任務(wù)框架及相關(guān)代碼應(yīng)用的文章就介紹到這了,更多相關(guān)java定時任務(wù)框架及應(yīng)用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot集成Curator實現(xiàn)Zookeeper基本操作的代碼示例
Zookeeper是一個Apache開源的分布式的應(yīng)用,為系統(tǒng)架構(gòu)提供協(xié)調(diào)服務(wù),ZooKeeper的目標(biāo)就是封裝好復(fù)雜易出錯的關(guān)鍵服務(wù),將簡單易用的接口和性能高效、功能穩(wěn)定的系統(tǒng)提供給用戶,本文給大家介紹了SpringBoot集成Curator實現(xiàn)Zookeeper基本操作,需要的朋友可以參考下2024-05-05
詳解Java 序列化與反序列化(Serialization)
這篇文章主要介紹了Java 序列化與反序列化(Serialization),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí) 吧2019-03-03
詳解IntelliJ IDEA中TortoiseSVN修改服務(wù)器地址的方法
這篇文章主要介紹了詳解IntelliJ IDEA中TortoiseSVN修改服務(wù)器地址的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-12-12

