千家信息网

Java任务调度Timer定时器怎么实现

发表于:2025-02-02 作者:千家信息网编辑
千家信息网最后更新 2025年02月02日,这篇文章主要介绍"Java任务调度Timer定时器怎么实现",在日常操作中,相信很多人在Java任务调度Timer定时器怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家
千家信息网最后更新 2025年02月02日Java任务调度Timer定时器怎么实现

这篇文章主要介绍"Java任务调度Timer定时器怎么实现",在日常操作中,相信很多人在Java任务调度Timer定时器怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"Java任务调度Timer定时器怎么实现"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

Timer任务调用相关类的UML图如下(仅包含部分变量与方法):

使用时,需自己写一个类,继承TimerTask,重写run()方法,大致步骤如下:

1.Timer的成员变量thread初始化时会聚合queue

public class Timer {    /**     * The timer task queue.  This data structure is shared with the timer     * thread.  The timer produces tasks, via its various schedule calls,     * and the timer thread consumes, executing timer tasks as appropriate,     * and removing them from the queue when they're obsolete.     */    private final TaskQueue queue = new TaskQueue();    /**     * The timer thread.     */    private final TimerThread thread = new TimerThread(queue);

2.Timer构造方法有几个重载,最终会调用thread的start()方法,启动线程,调用run()方法

public Timer(String name) {    thread.setName(name);    thread.start();}

3.thread的run()方法核心逻辑为mainLoop()方法:如果queue中TimerTask[]为空 && newTasksMayBeScheduled = true,则queue.wait()进入阻塞状态

    private void mainLoop() {        while (true) {            try {                TimerTask task;                boolean taskFired;                synchronized(queue) {                    // Wait for queue to become non-empty                    while (queue.isEmpty() && newTasksMayBeScheduled)                        queue.wait();                    if (queue.isEmpty())                        break; // Queue is empty and will forever remain; die                    // Queue nonempty; look at first evt and do the right thing                    long currentTime, executionTime;                    task = queue.getMin();                    synchronized(task.lock) {                        if (task.state == TimerTask.CANCELLED) {                            queue.removeMin();                            continue;  // No action required, poll queue again                        }                        currentTime = System.currentTimeMillis();                        executionTime = task.nextExecutionTime;                        if (taskFired = (executionTime<=currentTime)) {                            if (task.period == 0) { // Non-repeating, remove                                queue.removeMin();                                task.state = TimerTask.EXECUTED;                            } else { // Repeating task, reschedule                                queue.rescheduleMin(                                  task.period<0 ? currentTime   - task.period                                                : executionTime + task.period);                            }                        }                    }                    if (!taskFired) // Task hasn't yet fired; wait                        queue.wait(executionTime - currentTime);                }                if (taskFired)  // Task fired; run it, holding no locks                    task.run();            } catch(InterruptedException e) {            }        }    }

4.阻塞状态下,调用Timer类的schedule方法开启定时任务,schedule有几个重载,最终都是调用sched方法

5.sched方法中,queue.add(task),然后queue.notify()唤醒thread的线程

private void sched(TimerTask task, long time, long period) {    if (time < 0)        throw new IllegalArgumentException("Illegal execution time.");    // Constrain value of period sufficiently to prevent numeric    // overflow while still being effectively infinitely large.    if (Math.abs(period) > (Long.MAX_VALUE >> 1))        period >>= 1;    synchronized(queue) {        if (!thread.newTasksMayBeScheduled)            throw new IllegalStateException("Timer already cancelled.");        synchronized(task.lock) {            if (task.state != TimerTask.VIRGIN)                throw new IllegalStateException(                    "Task already scheduled or cancelled");            task.nextExecutionTime = time;            task.period = period;            task.state = TimerTask.SCHEDULED;        }        queue.add(task);        if (queue.getMin() == task)            queue.notify();    }}

6.therad的run()继续执行,进行一系列判断,最后调用TimerTask的run()方法,执行定时任务(见mainLoop方法)

到此,关于"Java任务调度Timer定时器怎么实现"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

0