自定义Java定时器,解决原生Timer周期调度精度不足问题,但由于是单线程执行,耗时任务可能会导致任务排队执行影响后续任务执行,可添加线程池避免任务阻塞。

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;
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值