package org.example;
import java.util.PriorityQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
public class CustomTimer {
private final PriorityQueue<Task> taskQueue = new PriorityQueue<>();
private final Worker worker = new Worker();
private final AtomicBoolean running = new AtomicBoolean(true);
// 用于时间校准的基准时间
private static final long CALIBRATION_NANOS = TimeUnit.MILLISECONDS.toNanos(1);
public CustomTimer() {
// 设置线程优先级和名称
worker.setName("HighPrecisionTimer-Worker");
worker.setPriority(Thread.MAX_PRIORITY);
worker.setDaemon(true);
worker.start();
}
public void schedule(TimerTask task, long delayMillis) {
schedule(task, delayMillis, -1);
}
public void scheduleAtFixedRate(TimerTask task, long initialDelayMillis, long periodMillis) {
if (periodMillis <= 0) {
throw new IllegalArgumentException("Period must be positive");
}
schedule(task, initialDelayMillis, periodMillis);
}
private void schedule(TimerTask task, long delay, long period) {
if (!running.get()) {
throw new IllegalStateException("Timer already canceled");
}
if (delay < 0) {
throw new IllegalArgumentException("Delay must not be negative");
}
synchronized (taskQueue) {
taskQueue.offer(new Task(task, currentTimeNanos() + TimeUnit.MILLISECONDS.toNanos(delay),
period > 0 ? TimeUnit.MILLISECONDS.toNanos(period) : -1));
taskQueue.notify();
}
}
private static long currentTimeNanos() {
return System.nanoTime();
}
public void cancel() {
if (running.compareAndSet(true, false)) {
synchronized (taskQueue) {
taskQueue.clear();
taskQueue.notify();
}
worker.interrupt();
}
}
private class Worker extends Thread {
private final long SPIN_THRESHOLD_NANOS = TimeUnit.MILLISECONDS.toNanos(1);
private final long PARK_THRESHOLD_NANOS = TimeUnit.MICROSECONDS.toNanos(100);
private final long MIN_PARK_NANOS = TimeUnit.MICROSECONDS.toNanos(1);
@Override
public void run() {
while (running.get()) {
try {
Task task = null;
long waitTime = 0;
synchronized (taskQueue) {
while (running.get() && taskQueue.isEmpty()) {
taskQueue.wait();
}
if (!running.get()) {
break;
}
task = taskQueue.peek();
if (task != null) {
waitTime = task.executionTimeNanos - currentTimeNanos();
}
}
if (task == null) {
continue;
}
// 分层等待策略
if (waitTime > 0) {
if (waitTime > SPIN_THRESHOLD_NANOS) {
// 对于较长等待时间,先使用Thread.sleep
TimeUnit.NANOSECONDS.sleep(waitTime - SPIN_THRESHOLD_NANOS);
}
// 自旋等待阶段
long spinStartTime = currentTimeNanos();
while (running.get() && currentTimeNanos() - spinStartTime < SPIN_THRESHOLD_NANOS) {
// 短时间快速自旋
spinWaitHint();
// LockSupport.parkNanos(100);
}
}
synchronized (taskQueue) {
if (!running.get()) {
break;
}
task = taskQueue.peek();
if (task == null || task.executionTimeNanos > currentTimeNanos()) {
continue;
}
task = taskQueue.poll();
// 执行任务
long actualExecutionTime = currentTimeNanos();
task.timerTask.run();
if (task.periodNanos > 0 && !task.timerTask.cancelled) {
// 计算下次执行时间,包含时间补偿
long drift = actualExecutionTime - task.executionTimeNanos;
long nextExecutionTime;
if (drift > task.periodNanos) {
// 如果延迟超过一个周期,重新调整到下一个周期
nextExecutionTime = actualExecutionTime + task.periodNanos;
} else {
// 正常情况下,基于原计划时间计算下一次执行时间
nextExecutionTime = task.executionTimeNanos + task.periodNanos;
}
task.executionTimeNanos = nextExecutionTime;
taskQueue.offer(task);
}
}
} catch (InterruptedException e) {
if (!running.get()) {
break;
}
}
}
}
}
// 添加一个自旋等待的优化方法
private void spinWaitHint() {
// Java 8 中的自旋等待优化
// 1. 使用一些CPU时间以允许其他超线程使用这些周期
// 2. 防止过度优化
for (int i = 0; i < 10; i++) {
// 使用位运算来防止JIT完全优化掉循环
int dummy = i & 0xff;
}
}
private static class Task implements Comparable<Task> {
final TimerTask timerTask;
long executionTimeNanos;
final long periodNanos;
Task(TimerTask timerTask, long executionTimeNanos, long periodNanos) {
this.timerTask = timerTask;
this.executionTimeNanos = executionTimeNanos;
this.periodNanos = periodNanos;
}
@Override
public int compareTo(Task other) {
return Long.compare(this.executionTimeNanos, other.executionTimeNanos);
}
}
public static abstract class TimerTask implements Runnable {
private volatile boolean cancelled = false;
public void cancel() {
cancelled = true;
}
public boolean isCancelled() {
return cancelled;
}
}
}
自定义Java定时器,解决原生Timer周期调度精度不足问题,但由于是单线程执行,耗时任务可能会导致任务排队执行影响后续任务执行,可添加线程池避免任务阻塞。
于 2025-02-25 10:39:16 首次发布