ScheduleIterator接口
import java.util.Date;

public interface ScheduleIterator


{
public Date next();//获取下一个触发的时间点
}

Scheduler类
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;


public class Scheduler


{
class SchedulerTimerTask extends TimerTask

{
private SchedulerTask schedulerTask;
private ScheduleIterator iterator;
public SchedulerTimerTask(SchedulerTask schedulerTask,ScheduleIterator iterator)

{
this.schedulerTask = schedulerTask;
this.iterator = iterator;
}
public void run()

{
schedulerTask.run();
reschedule(schedulerTask, iterator);
}
}

private final Timer timer = new Timer();

public Scheduler()

{
}
public void cancel()

{
timer.cancel();
}
public void schedule(SchedulerTask schedulerTask,ScheduleIterator iterator)

{
Date time = iterator.next();
if (time == null)

{
schedulerTask.cancel();
}
else

{
synchronized(schedulerTask.lock)

{
if (schedulerTask.state != SchedulerTask.VIRGIN)

{
throw new IllegalStateException("Task already scheduled " +
"or cancelled");
}
schedulerTask.state = SchedulerTask.SCHEDULED;
schedulerTask.timerTask = new SchedulerTimerTask(schedulerTask, iterator);
timer.schedule(schedulerTask.timerTask, time);
}
}
}

private void reschedule(SchedulerTask schedulerTask,ScheduleIterator iterator)

{
Date time = iterator.next();
if (time == null)

{
schedulerTask.cancel();
}
else

{
synchronized(schedulerTask.lock)

{
if (schedulerTask.state != SchedulerTask.CANCELLED)

{
schedulerTask.timerTask = new SchedulerTimerTask(schedulerTask, iterator);
timer.schedule(schedulerTask.timerTask, time);
}
}
}
}
}

SchedulerTask 类
import java.util.TimerTask;

public abstract class SchedulerTask implements Runnable


{//被调度器不断调度执行的任务

final Object lock = new Object();

int state = VIRGIN;//任务状态
static final int VIRGIN = 0;
static final int SCHEDULED = 1;
static final int CANCELLED = 2;

TimerTask timerTask;//底层的定时器任务
protected SchedulerTask()

{
}
public abstract void run();//调度任务执行的具体任务
public boolean cancel()

{
synchronized(lock)

{
if (timerTask != null)

{
timerTask.cancel();//取消任务
}
boolean result = (state == SCHEDULED);//任务已经被调度执行
state = CANCELLED;//设置任务状态为“取消”
return result;
}
}
public long scheduledExecutionTime()

{
synchronized(lock)

{
return timerTask == null ? 0 : timerTask.scheduledExecutionTime();//任务执行时间
}
}

}

DailyIterator类:
import java.util.Calendar;
import java.util.Date;


public class DailyIterator implements ScheduleIterator
{
private final int hourOfDay, minute, second;
private final Calendar calendar = Calendar.getInstance();

public DailyIterator(int hourOfDay, int minute, int second)

{
this(hourOfDay, minute, second, new Date());
}

public DailyIterator(int hourOfDay, int minute, int second, Date date)

{
this.hourOfDay = hourOfDay;
this.minute = minute;
this.second = second;
calendar.setTime(date);
calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, second);
calendar.set(Calendar.MILLISECOND, 0);
if (!calendar.getTime().before(date))

{
calendar.add(Calendar.DATE, -1);
}
}

public Date next()

{//获取下一个触发的时间点
calendar.add(Calendar.DATE, 1);
return calendar.getTime();
}

}


测试类:
import java.text.SimpleDateFormat;

import java.util.Date;

import org.tiling.scheduling.Scheduler;
import org.tiling.scheduling.SchedulerTask;
import org.tiling.scheduling.examples.iterators.DailyIterator;

public class AlarmClock


{

private final Scheduler scheduler = new Scheduler();//调度器
private final SimpleDateFormat dateFormat =
new SimpleDateFormat("dd MMM yyyy HH:mm:ss.SSS");
private final int hourOfDay, minute, second;//每天触发的时间点

public AlarmClock(int hourOfDay, int minute, int second)

{
this.hourOfDay = hourOfDay;
this.minute = minute;
this.second = second;
}

public void start()

{
scheduler.schedule(new SchedulerTask()

{
public void run()

{
soundAlarm();
}
private void soundAlarm()

{
System.out.println("Wake up! " +
"It's " + dateFormat.format(new Date()));
// Start a new thread to sound an alarm
}
}, new DailyIterator(hourOfDay, minute, second));//通过迭代器模式迭代遍历得到后面一系列的时间点
}

public static void main(String[] args)

{
AlarmClock alarmClock = new AlarmClock(22, 5, 0);
alarmClock.start();
}
}

参考资料
Scheduling recurring tasks in Java applications
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述