JDK java.util.Timer 僅支持固定間隔調度,無法表達「每天 02:00」、「每周一 09:00」等 Cron 風格時間表達式。JDring(Olivier Dedieu 開源)填補此空白,提供類 Unix Cron 的聲明式定時調度 API,輕量零依賴,適合中小型項目快速接入。
AlarmListener:單方法接口 void handleAlarm(AlarmEntry entry)AlarmEntry:封裝觸發時間詳情(分、時、日、月、周、年)AlarmManager:中央調度器,addAlarm(...) 註冊任務import com.jalios.jdring.*;
public class Buzzing implements AlarmListener {
private final String message;
public Buzzing(String message) { this.message = message; }
@Override
public void handleAlarm(AlarmEntry entry) {
System.err.println("⏰ " + message);
System.err.println("觸發時間: " + entry.getDate());
}
}
import com.jalios.jdring.*;
import java.util.Calendar;
public class ScheduleDemo {
public static void main(String[] args) throws PastDateException {
AlarmManager mgr = new AlarmManager();
// 每小時第 20 分鐘觸發
mgr.addAlarm(20, -1, -1, -1, -1, -1, new Buzzing("每小時第 20 分報時"));
// 每周五 17:00 觸發
mgr.addAlarm(0, 17, -1, -1, Calendar.FRIDAY, -1, new Buzzing("周五下班提醒"));
// 固定日期:3月20日 12:00(周年紀念)
mgr.addAlarm(0, 12, 20, Calendar.MARCH, -1, -1,
new Buzzing("記住:明天是周年紀念日!"));
// 單次觸發:2025-12-25 09:00
mgr.addAlarm(0, 9, 25, Calendar.DECEMBER, -1, 2025,
new Buzzing("聖誕節快樂!"));
}
}
addAlarm(min, hour, dom, month, dow, year, listener)| 參數 | 含義 | 特殊值 | 示例 |
|---|---|---|---|
| min | 分鐘 (0-59) | -1 = 每分鐘 | 0 = 整點 |
| hour | 小時 (0-23) | -1 = 每小時 | 17 = 下午5點 |
| dom | 月中的日 (1-31) | -1 = 每天 | 1 = 每月1號 |
| month | 月 (Calendar.JANUARY...) | -1 = 每月 | Calendar.MARCH |
| dow | 周中的日 (Calendar.SUNDAY...) | -1 = 不按周限制 | Calendar.FRIDAY |
| year | 年 (如 2025) | -1 = 每年 | 2025 = 僅2025年 |
規則:-1 表示「不限制該維度」,組合形成 Cron 表達式語義。至少一個維度非 -1,否則每分鐘觸發。
| 維度 | 評價 |
|---|---|
| 依賴 | 零第三方依賴,單 JAR ~50KB |
| 線程模型 | 單獨調度線程輪詢,精度 ~秒級 |
| 持久化 | 無內建,需自行序列化 AlarmEntry 重啟恢復 |
| 集群/高可用 | 不支持,單機模式 |
| 動態增刪 | 支持運行時 addAlarm,無移除 API(可用標識位在 Listener 內控制) |
| Spring 整合 | 需自行封裝為 Bean,或改用 @Scheduled(cron="...") / Quartz |
<dependency>
<groupId>com.jalios</groupId>
<artifactId>jdring</artifactId>
<version>1.0</version>
</dependency>
JDring 以極簡 API 實現了 Java 世界缺失的「Cron 風格聲明式調度」,是工具箱裡值得收藏的輕量級利器。