从源码角度学习Timer定时器

STM32F407 CubeMX定时器PWM驱动舵机:从原理到代码,一个公式搞定角度控制 本文详细介绍了如何使用STM32F407和CubeMX配置定时器PWM驱动舵机,从原理到代码实现,推导出角度控制的万能公式。通过分析舵机控制信号的标准参数(20ms周期、0.5-2.5ms脉宽),结合STM32定时器的时钟配置(PSC和ARR),提供了一套完整的解决方案,帮助开发者快速实现精确的角度控制。 阅读详情

Timer定时器

通过一个后台线程(成员变量thread)来执行任务调度,每个Timer对象对应的是一个单一的后台线程,用于执行所有的定时器的任务,所以,定时器的任务应该很快完成,如果某个任务执行花费过多时间,它会长时间占用该线程,导致其他任务延迟执行以及扎堆执行。

这个类是线程安全的,多个线程可以共享给一个Timer对象,而不需要外部进行同步。


Timer

1. 成员变量

任务队列,参考TaskQueue

 private final TaskQueue queue = new TaskQueue();

执行任务调度的线程,参考TimerThread

private final TimerThread thread = new TimerThread(queue);

这个对象可以理解为线程终结者。这个引用只是纯定义在Timer中,没有再次使用,目的就是在Timer回收之前,优先执行这个引用复写的finalize方法。方法的内容是将变量 newTasksMayBeScheduled (参考TimerThread)设定为false,同时唤醒timerthread线程。

    private final Object threadReaper = new Object() {
        protected void finalize() throws Throwable {
            synchronized(queue) {
                thread.newTasksMayBeScheduled = false;
                queue.notify(); // In case queue is empty.
            }
        }
    };

2. 构造方法

所有构造函数都会启动计时器内部线程thread,有4个构造方法,比较简单没什么说的

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

3. 核心方法

3.1 任务调度

6个schedule方法其实也没什么好说的,重点在于内部私有方法sched

 1.  // 延迟 delay 毫秒后执行 task 任务
   public void schedule(TimerTask task, long delay) {
        if (delay < 0)
            throw new IllegalArgumentException("Negative delay.");
        sched(task, System.currentTimeMillis()+delay, 0);
    }

 2.   // 指定时间点 time 执行 task 任务
    public void schedule(TimerTask task, Date time) {
        sched(task, time.getTime(), 0);
    }

 3.   // 延迟 delay 毫秒后,以间隔 period 为一个周期循环执行 task 任务
    public void schedule(TimerTask task, long delay, long period) {
        if (delay < 0)
            throw new IllegalArgumentException("Negative delay.");
        if (period <= 0)
            throw new IllegalArgumentException("Non-positive period.");
        sched(task, System.currentTimeMillis()+delay, -period);
    }

  4.   // 指定时间点 time 开始执行 task 任务,并且以 period 为周期循环执行
    public void schedule(TimerTask task, Date firstTime, long period) {
        if (period <= 0)
            throw new IllegalArgumentException("Non-positive period.");
        sched(task, firstTime.getTime(), -period);
    }

    
  5. // 对比3的区别在于AtFixedRate(以固定频率执行),在sched方法中传参period正值,而3传的是负
     // 值,正负值的区别涉及到TimerTask,参考下文
    public void scheduleAtFixedRate(TimerTask task, long delay, long period) {
        if (delay < 0)
            throw new IllegalArgumentException("Negative delay.");
        if (period <= 0)
            throw new IllegalArgumentException("Non-positive period.");
        sched(task, System.currentTimeMillis()+delay, period);
    }

 6. // 对比4的区别参考5和3
    public void scheduleAtFixedRate(TimerTask task, Date firstTime,
                                    long period) {
        if (period <= 0)
            throw new IllegalArgumentException("Non-positive period.");
        sched(task, firstTime.getTime(), period);
    }
// 这个方法的主要作用是完善任务信息,并将任务添加到任务队列中 
private void sched(TimerTask task, long time, long period) {
        if (time < 0)
            throw new IllegalArgumentException("Illegal execution time.");
       
        //  对period进行数值约束,防止后续用到period时出现数值溢出
        if (Math.abs(period) > (Long.MAX_VALUE >> 1))
            period >>= 1;

        synchronized(queue) {
            // 先判断任务线程thread是否还计划继续添加新任务
            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的相关信息
                task.nextExecutionTime = time;
                task.period = period;
                // 将任务的状态表位计划中(已添加至任务队列)
                task.state = TimerTask.SCHEDULED;
            }
            // 进行添加操作
            queue.add(task);
            if (queue.getMin() == task)
                queue.notify();
        }
    }

3.2 任务取消

// 取消该定时器,清空任务队列。唤醒等待线程。
public void cancel() {
        synchronized(queue) {
            thread.newTasksMayBeScheduled = false;
            queue.clear();
            queue.notify();  // In case queue was already empty.
        }
}

3.3 任务清除

// 源码中无调用,是提供给外部使用的一个方法
public int purge() {
         int result = 0;

         synchronized(queue) {
             for (int i = queue.size(); i > 0; i--) {
                 if (queue.get(i).state == TimerTask.CANCELLED) {
                     queue.quickRemove(i);
                     result++;
                 }
             }

             if (result != 0)
                 queue.heapify();
         }

         return result;
     }

快速移除任务队列中所有被取消的任务,并重新堆化队列,返回删除的任务个数。Timer中并没有定义删除子任务
的方法。而唯一可以删除的形式,就是设定子任务状态,然后调用purge()方法进行一次洗牌。这种做法和JVM GC
中标记回收有点异曲同工之处。倘若将回收的方法,公开出来,则Timer内部需要提供很健壮的任务管理机制,防
止在高并发的情况下,队列维持的堆不会出现数据错误,或性能问题(想一下如果有大量的移除操作,那么每个移
除操作都需要同步队列,然后重新堆化)。

 


TimerThread

1. 成员变量

字面义是“能否添加新任务”,默认为true,该字段为ture且任务队列中已经不存在任务时,我们可以优雅的结束定时器。注意,这个字段受到队列对象监视器的保护,当它被设置为false时(可能是任务取消也可能是线程被意外杀死)意味着当前Timer已经不存在实例对象,所以定时器在执行任务时,需要确保其值为true 

boolean newTasksMayBeScheduled = true;

任务队列

  private TaskQueue queue;

2. 构造方法

TimerThread(TaskQueue queue) {
        this.queue = queue;
    }

3. 核心方法

    public void run() {
        try {
            mainLoop();
        } finally {
            // 如果线程意外终止,则同样需要走取消逻辑,清空队列,并标记此timer不再允许添加任务
            synchronized(queue) {
                newTasksMayBeScheduled = false;
                queue.clear();  // Eliminate obsolete references
            }
        }
    }

  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) {
            }
        }
    }

TaskQueue 任务队列

1. 成员变量

优先级队列,它维护了一个最小堆结构(本文不具体介绍,可以简单理解为就是父节点都小于子节点的这样一棵树。而根节点就是下次运行时间最小的任务,注意,这个队列的起始下标为1,第一个任务被放在queue[1]的位置上,与我另一篇对堆结构的分析文章中有所不同,所以在算法逻辑上虽然无区别,但细节上有细微的差别。比如节点n的左右子节点为2n和2n+1,父节点为n>>1,如果不关注算法的话也可以不用细究)

 private TimerTask[] queue = new TimerTask[128];

任务的实际数量

 private int size = 0;

2. 主要方法

2.1 添加任务

    void add(TimerTask task) {
        // 扩容机制
        if (size + 1 == queue.length)
            queue = Arrays.copyOf(queue, 2*queue.length);
        // 注意,这里保证了第一个任务被添加时是放在下标1的位置上,下标0是不存放task的
        queue[++size] = task;
        // 确保将此任务按顺序放在合适的位置
        fixUp(size);
    }

2.2 获取优先级最高的任务

也就是下次预期执行时间最早的,在queue中排在首位的(下标0不存放task,优先级最高的是1)

   TimerTask getMin() {
        return queue[1];
    }

2.3 重新设定下一次执行时间

    void rescheduleMin(long newTime) {
        queue[1].nextExecutionTime = newTime;
        fixDown(1);
    }

2.4 调整堆结构

    //  以向上调整的方式调整顺序,以维持堆结构
    private void fixUp(int k) {
        while (k > 1) {  
            // 父节点j
            int j = k >> 1;
            // 判断是否需要交换
            if (queue[j].nextExecutionTime <= queue[k].nextExecutionTime)
                break;
            // 如果发生了交换,继续循环,以确保交换后以原先父节点的位置为子节点的结构也满足堆结构
            TimerTask tmp = queue[j];  queue[j] = queue[k]; queue[k] = tmp;
            k = j;
        }
    }

    // 以向下调整的方式调整顺序,以维持堆结构
    private void fixDown(int k) {
        int j;
        // 子节点j
        while ((j = k << 1) <= size && j > 0) {
            // 比较左右子节点,选出最小的
            if (j < size &&
                queue[j].nextExecutionTime > queue[j+1].nextExecutionTime)
                j++; // j indexes smallest kid
            // 跟父节点k进行比较,如果k较小,不需要交换,停止循环
            if (queue[k].nextExecutionTime <= queue[j].nextExecutionTime)
                break;
            // 如果进行了交换,则需要确保交换后,以原先子节点为父节点的结构也满足堆结构,继续循环直至完全满足
            TimerTask tmp = queue[j];  queue[j] = queue[k]; queue[k] = tmp;
            k = j;
        }
    }

2.5 重新堆化

 // 堆化  
 void heapify() {
        // 从最后一个父节点开始,遍历所有父节点,执行向下调整操作,以重新构建堆结构(在timer.purge中被调用,即堆中元素发生了大量删除时需要重新构建堆)
        for (int i = size/2; i >= 1; i--)
            fixDown(i);
    }

TimerTask 定时任务

public abstract class TimerTask implements Runnable {...}

这个类是一个继承自接口Runnable的抽象类,需要实现类自己去补充run方法,也就是自定义任务内容。

这个类比较简单,简单介绍一下

// 用于内部保证同步逻辑的一个锁变量
final Object lock = new Object();

// 状态变量,,初始状态为virgin。只有这个状态的任务才可以添加到queue中,子任务添加后,会改变子任务
// 的状态,所以子任务不会被反复多次添加到queue中
int state = VIRGIN;

static final int VIRGIN = 0;  // 初始化
static final int SCHEDULED = 1; // 任务被添加到queue中即会设置该状态
static final int EXECUTED = 2; // 被执行过,只有不反复循环的子任务会被设置该状态
static final int CANCELLED = 3; // 被取消

// 下次被执行的时间(维持最小堆的判断标准)
long nextExecutionTime;

// 周期,初始是0毫秒,即不被反复执行。注意,该值区分正负,负数表示,每执行完一次后,间隔指定时间再次
// 执行。正数,表示每次开始执行后,指定间隔再次执行,前者用的比较多。
// nextExecutionTime = task.period<0 ? currentTime - task.period : executionTime + task.period
long period = 0;
 // 取消任务  
 public boolean cancel() {
        synchronized(lock) {
            boolean result = (state == SCHEDULED);
            state = CANCELLED;
            return result;
        }
    }
    
  // 获取任务的下一次计划执行时间
  public long scheduledExecutionTime() {
        synchronized(lock) {
            return (period < 0 ? nextExecutionTime + period
                               : nextExecutionTime - period);
        }
    }


上面两个方法在JDK源码中都没有被调用,是供外部调用的。

此部分转载于https://www.cnblogs.com/jilodream/p/5887110.html

最后的最后,来谈谈Timer类的定位:

(1)前Timer时代。

Timer是jdk1.3的时候,添加进源码的。这个时候大概是2000年左右。具体java被推出,才仅仅过去5年,所以1.3的主要改进,表现在新增的大量类库上。而在此之前,想拥有一个如Timer般的定时功能,是非常麻烦的,基本都要手动去实现。

(2)后Timer时代

查看了Timer的源代码之后,我们发现Timer在使用中存在这么问题:

1、定时任务是顺序执行的,也就是说后续的任务,一定要等到前边的任务执行完毕后,才会执行,否则将会一直等待。(其实这一点说不上来好还是坏,因为有时候我们可能会希望尽管是定时任务,但是执行时是有顺序完成和开始的,是要保证先后顺序的)

2、对系统时间非常敏感,通过代码我们知道,在每次子任务被取出后(执行run前),都会计算一遍执行时间,同时在判定子任务的执行时间是否已经到来时,都是直接获取到系统时间。倘若系统时间发生了修改,而使用的计划时间仍然是使用上次修改前的时间段时,就会出现一些意想不到的结果。如计划是5秒后执行,主线程wait 5秒钟后,被唤醒,在这5秒钟内,系统时间向后推迟了1天,那么主任务,仍然会执行该子任务(其他的也都会依次迅速执行,因为时间已经过了)。而倘若向前调整一天,那么主线程判断的时间仍然是,调整时间前的时间点,所以需要再等待一天。因此会出(防盗连接:本文首发自http://www.cnblogs.com/jilodream/ )现很多人以为Timer在调整时间后,被挂起,但是查看线程状态,发现还存在的奇怪场景。

3、子任务之间存在依赖。其实子任务之间的依赖关系并不强,无非就是前边的子任务执行完后,后边的子任务才可以开始执行。但是倘若在执行某个子任务时,捕捉到了异常,那么线程会立刻结束执行,后续的子任务都不会执行了,这个问题有时会对我们造成很大的困扰。

为了解决以上种种在jdk1.5中提供了ScheduledExecutorService接口以供开发者使用。

这个接口的实现,主要是通过线程池的形式,解决了上述遇到的问题(线程池也是jdk 1.5时才推出的),很多人因此认为Timer已经过时了,我觉得完全没有必要这样认为,通过自己对比Timer的原理和ScheduledExecutorService的改进之后。我们发现很多地方Timer仍然是有自己存在的必要的,只是占用场景不如ScheduledExecutorService多罢了。关于ScheduledExecutorService的学习,此处不再罗列,有兴趣的同学可以自己学习。

OpenMV Cam硬件定时器pyb.Timer深度实战指南 嵌入式视觉系统中,精确时序控制是保障图像采集、传感器同步与执行器协同的基础。硬件定时器作为微控制器的脉搏发生器,其原理源于时钟树分频与计数器溢出中断机制,相比软件延时具备纳秒级精度与负载无关性。在OpenMV Cam平台,pyb.Timer直接映射STM32F765VG高级定时器外设,支持毫秒级帧率锁定、硬件PWM舵机驱动、输入捕获同步采样及多通道时序编排等关键能力。它不仅是MicroPython在OpenMV上的专属高阶接口,更是实现确定性实时视觉控制的技术支点。本文聚焦pyb.Timer在工业分拣、智能 阅读详情

相关推荐

相机标定原理与张氏标定法

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Mar

heeweii的博客 2281

Timer

一、Timer的定义: 有且仅有一个后台线程 对 多个业务线程 进行 定时定频率 的调度 二、timer和timerTask方法使用 任务方法对象TimerTask :cancel() 、scheduledExecutionTime() 、run() public class MyTimerTask extends TimerTask { private String name; ...

jue6628的博客 263

point transformer v3结构

分割结构: embedding->enc->dec embedding->enc0->enc1->enc2->enc3->enc4->dec3->dec2->dec1->dec0 embedding ->block0->block1 ->dow->block0->block1 ->dow->block0->block1 ->dow->block0->block1-&gt

weixin_45625419的博客 583

Java定时任务及常见框架

Java定时任务及常见框架

weixin_45734473的博客 3792

树莓派4B:控制步进电机

文章目录准备阶段接线阶段树莓派程序 准备阶段 准备以下物品,淘宝都可以买到: 57步进电机 电源开关(220v转24v,3A,72W) 步进电机驱动器 电源线 电线 杜邦线 树莓派4B一套 具体型号如下: 接线阶段 整体:接线效果如下图 电源开关起220v转24v作用,很好接线,输出24v接入步进电机驱动器 步进电机驱动器的 A+ A- B+ B- 按提示接步进电机四线,步进电机上就会有说...

学习路上的鸭子的博客 1万+

AI医疗影像诊断工具2025 完整教程

本教程所述工具均为辅助诊断设备,不可替代执业医师判断。部署使用需遵守当地医疗器械管理法规。推荐开源框架组合:代码太多打包上传网盘了 自行下载。2025年的AI医疗影像诊断工具将以。

m0_60084632的博客 2030

如何实现定时任务- Java Timer/TimerTask 源码原理解析

一、背景和使用     日常实现各种服务端系统时,我们一定会有一些定时任务的需求。比如会议提前半小时自动提醒,异步任务定时/周期执行等。那么如何去实现这样的一个定时任务系统呢? Java JDK提供的Timer类就是一个很好的工具,通过简单的API调用,我们就可以实现定时任务。     现在就来看一下java.util.Timer是如何实现这样的定时功能的。     首先,我们来看一下一个使用demo Timer timer = new Timer(); TimerTask task...

欢迎来到我的博客 1018

汽车电缆选型实战:基于ISO 19642-3~12的7类电缆电压/材料/场景对照表

本文详细解析了基于ISO 19642-3~12标准的7类汽车电缆选型实战,涵盖电压等级、导体材料和场景应用的对照表。通过全参数速查表和典型选型陷阱分析,帮助工程师快速掌握从低压信号线到高压动力电缆的选型逻辑,提升新能源汽车与智能驾驶技术的安全性和可靠性。

weixin_29043895的博客 366

个人使用MATLAB timer 心得

matlab timer使用心得,注意事项和多个timer之间的关系

zhanlu11110的专栏 1万+

【TC3xx芯片】TC3xx芯片STM介绍

TC3xx芯片STM介绍

qq_36056498的博客 2281

NX二次开发 计算多个体的最小包围盒

多个体的最小包围盒

weixin_72680115的博客 430

timer定时器_拾遗Timer定时器

一 Timer 介绍在开发中我们经常会遇到一些简单定时任务的需求,而不需要量级较重的定时任务就可以采取java定时器;java.util.Timer工具类中的Timer 是定时器,但定时任务写在java.util.TimerTask 中,由 Timer 执行 TimerTask ;Timer 的本质就是线程,构造方法如下publicTimer(Stringname){...

weixin_39744512的博客 111

安装Codex时出现无法下载此应用和Microsoft Store初始化失败的解决方案

本文主要介绍了安装Codex时出现无法下载此应用和Microsoft Store初始化失败的解决方案,希望能对使用codex的同学们有所帮助。 文章目录 1. 问题描述 2. Windows 解决方案 3. Mac解决方案

weixin_43178406的博客 7万+

java定时器_拾遗Timer定时器

一 Timer 介绍在开发中我们经常会遇到一些简单定时任务的需求,而不需要量级较重的定时任务就可以采取java定时器;java.util.Timer工具类中的Timer 是定时器,但定时任务写在java.util.TimerTask 中,由 Timer 执行 TimerTask ;Timer 的本质就是线程,构造方法如下public 从源码角度可知,如果这样创建定时器非守护线程,即使主线程运行结...

weixin_39747087的博客 107

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

拾遗Timer定时器

一 Timer 介绍 在开发中我们经常会遇到一些简单定时任务的需求,而不需要量级较重的定时任务就可以采取java定时器; java.util.Timer工具类中的Timer 是定时器,但定时任务写在java.util.TimerTask 中,由 Timer 执行 TimerTask ; Timer 的本质就是线程,构造方法如下 public Timer(String name) { thread.setName(name); thread.start(); } .

知识追寻者(Inheriting the spirit of open source, Spreading technology knowledge;) 334

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

OpenMV Cam硬件定时器pyb.Timer实战指南

硬件定时器是嵌入式视觉系统实现毫秒级精准时序控制的核心组件,其原理基于MCU专用计数单元与中断机制,具备微秒级精度、非阻塞特性和低功耗优势。相比软件延时(如time.sleep_ms),硬件定时器可保障确定性响应,支撑图像同步采集、PID闭环控制、光照自适应快门等关键场景。在OpenMV Cam平台中,pyb.Timer封装了STM32H7定时器资源(如TIM2/TIM5),支持PWM输出、中断回调和编码器输入三大模式,是打通视觉算法与实时执行链路的技术枢纽。

weixin_30443747的博客 381

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

源码解析 | Flink Timer(定时器)机制与实现

点击上方蓝色字体,选择“设为星标”回复”资源“获取更多资源大数据技术与架构点击右侧关注,大数据开发领域最强公众号!暴走大数据点击右侧关注,暴走大数据!Timer简介Timer(定时器)是...

微信搜:import_bigdata,大数据领域硬核原创作者 857

深入解析Java Timer源码机制

包中,用于在后台线程中安排任务执行。它允许开发者安排任务在特定时间执行一次或定期重复执行。下面将从源码角度详细解析。内部使用堆结构实现,确保每次取出的任务都是最早需要执行的。方法中循环检查队列并执行任务。的工作原理,并给出代码示例。方法定义具体任务逻辑。是一个抽象类,实现了。

CLj_8xy7的博客 288

java定时器的几种实现方式

1 前言 在开始正题之前,先闲聊几句。有人说,计算机科学这个学科,软件方向研究到头就是数学,硬件方向研究到头就是物理,最轻松的是中间这批使用者,可以不太懂物理,不太懂数学,依旧可以使用计算机作为自己谋生的工具。这个规律具有普适应,看看“定时器”这个例子,往应用层研究,有 Quartz,Spring Schedule 等框架;往分布式研究,又有 SchedulerX,ElasticJob 等分布式任务调度;往底层实现看,又有多种定时器实现方案的原理、工作效率、数据结构可以深究…简单上手使用一个框架,并不能体

手写代码 1万+

java定时任务_拾遗Timer定时器

一 Timer 介绍在开发中我们经常会遇到一些简单定时任务的需求,而不需要量级较重的定时任务就可以采取java定时器;java.util.Timer工具类中的Timer 是定时器,但定时任务写在java.util.TimerTask 中,由 Timer 执行 TimerTask ;Timer 的本质就是线程,构造方法如下public 从源码角度可知,如果这样创建定时器非守护线程,即使主线程运行结...

weixin_39620099的博客 172

Unity时钟定时器插件——Vision Timer源码分析之二

Unity时钟定时器插件——Vision Timer源码分析之二   By D.S.Qiu 尊重他人的劳动,支持原创,转载请注明出处:http.dsqiu.iteye.com          前面的已经介绍了vp_Timer(点击前往查看),vp_TimeUtility相对简单很多,vp_TimeUtility定义了个表示时间的结构Units: /// &lt;summary&g...

qiudesuo的专栏 325

定时器的几种实现方式

1 前言 在开始正题之前,先闲聊几句。有人说,计算机科学这个学科,软件方向研究到头就是数学,硬件方向研究到头就是物理,最轻松的是中间这批使用者,可以不太懂物理,不太懂数学,依旧可以使用计算机作为自己谋生的工具。这个规律具有普适应,看看“定时器”这个例子,往应用层研究,有 Quartz,Spring Schedule 等框架;往分布式研究,又有 SchedulerX,ElasticJob 等分布式任...

weixin_33699914的博客 6775

Linux虚拟化KVM-Qemu分析(七)之timer虚拟化

先从操作系统的角度来看一下timer的作用吧:定时器的维护,包括用户态和内核态,当指定时间段过去后触发事件操作,比如IO操作注册的超时定时器等;更新系统的运行时间、wall time等,此外还保存当前的时间和日期,以便能通过time()等接口返回给用户程序,内核中也可以利用其作为文件和网络包的时间戳;调度器在调度任务分配给CPU时,也会去对task的运行时间进行统计计算,比如CFS调度,Round-Robin调度等;资源使用统计,比如系统负载的记录等,此外用户使用top命令也能进行查看;

smart_an的专栏 1120

#定时器 tick_定时器有几种实现方式?

来源:《Fate/Unlimited Codes》Saber Lily1 前言在开始正题之前,先闲聊几句。有人说,计算机科学这个学科,软件方向研究到头就是数学,硬件方向研究到头就是物理,最轻松的是中间这批使用者,可以不太懂物理,不太懂数学,依旧可以使用计算机作为自己谋生的工具。这个规律具有普适应,再看看“定时器”这个例子,往应用层研究,有 Quartz,Spring Schedule 等...

weixin_29054399的博客 1045

libevent源码浅析: 定时器和信号

libevent源码浅析: 定时器和信号 http://godorz.info/2011/02/the-annotated-libevent-sources-about-timer-and-signal/ 上一篇文章介绍了libevent下基本的I/O事件,这篇文章将讲讲libevent对定时器和信号事件的处理. Timer事件 反应堆event

hintonic的专栏 1609

Linux内核下的定时器的应用与分析

定时器的概念 从大众的角度,定时器就是一个闹钟,到时间了就会工作,从程序员的角度,定一个时间,到时间了就会调用你写的函数事件 定时器在内核的实现机制 所谓实现机制,我觉得就是代码的追踪,一步一步的追踪,这其中大部分都是结构体的封装。逻辑上的定时器是正常的中断,即发生硬件中断,会去查看有没有软中断要处理,定时器通过软中断来实现,属于TIMER_SOFTIRQ软中断 void __init init_timers(void) { init_timer_cpus(); init_timer_stats();

m0_46217142的博客 919
上一篇: 最小堆与最大堆测试代码
下一篇: 1024
MrMoving
博客等级 码龄10年 54粉丝 145原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值