70行手搓一个定时任务
这里将定时任务的代码记录一下
参考视频地址:70行手搓一个定时任务
ScheduleService
package dhh.project.config.myschedule;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.locks.LockSupport;
/**
* 手写定时任务
*
* @since 2025/6/3 05:55
*/
public class ScheduleService {
Trigger trigger = new Trigger();
ExecutorService executorService = Executors.newFixedThreadPool(6);
public void schedule(Runnable task, long delay) {
Job job = new Job();
job.setTask(task);
job.setStartTime(System.currentTimeMillis() + delay);
job.setDelay(delay);
trigger.queue.offer(job);
trigger.wakeUp();
}
// 等待相应的时间,把任务添加到线程池中
class Trigger {
PriorityBlockingQueue<Job> queue = new PriorityBlockingQueue<>();
Thread thread = new Thread(() -> {
while (true) {
// 不能使用if判断,存在虚假唤醒问题,使用while解决
// Object
while (queue.isEmpty()) {
LockSupport.park();
}
Job latelyJob = queue.peek();
if (latelyJob.getStartTime() < System.currentTimeMillis()) {
latelyJob = queue.poll();
executorService.execute(latelyJob.getTask());
// 计算下一次执行的任务
Job nextJob = new Job();
nextJob.setTask(latelyJob.getTask());
nextJob.setDelay(latelyJob.getDelay());
nextJob.setStartTime(System.currentTimeMillis() + latelyJob.getDelay());
queue.offer(nextJob);
} else {
LockSupport.parkUntil(latelyJob.getStartTime());
}
}
});
{
thread.start();
System.out.println("触发器启动了!");
}
// 唤醒,当有更小的startTime的任务传进来的时候
void wakeUp() {
LockSupport.unpark(thread);
}
}
}
Job
package dhh.project.config.myschedule;
import lombok.Data;
/**
* 任务
*
* @since 2025/6/3 06:08
*/
@Data
public class Job implements Comparable<Job> {
private Runnable task;
private long startTime;
private long delay;
@Override
public int compareTo(Job o) {
return Long.compare(this.startTime, o.startTime);
}
}
ScheduleServiceTest
package dhh.project;
import dhh.project.config.myschedule.ScheduleService;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/**
* 手写定时任务测试类
*
* @since 2025/6/3 05:57
*/
public class ScheduleServiceTest {
public static void main(String[] args) throws InterruptedException {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss SSS");
ScheduleService scheduleService = new ScheduleService();
scheduleService.schedule(() -> {
System.out.println(LocalDateTime.now().format(formatter) + "这里100ms的");
}, 100);
Thread.sleep(1000);
System.out.println("添加一个每200ms执行的定时任务!");
scheduleService.schedule(() -> {
System.out.println(LocalDateTime.now().format(formatter) + "这里200ms的");
}, 200);
}
}
Changelog
6/3/25, 1:49 AM
View All Changelog
d3a6d
-on