为什么80%的码农都做不了架构师?>>>   

简介

Timer实际上是一种单一事件的定时器,即经过指定的时间后触发一个事件,这个事件通过其本身提供的channel进行通知。之所以叫单一事件,是因为Timer只执行一次就结束,这也是Timer与Ticker的最重要的区别之一。

通过timer.NewTimer(d Duration)可以创建一个timer,参数即等待的时间,时间到来后立即触发一个事件。

源码包src/time/sleep.go:Timer定义了Timer数据结构:

type Timer struct { // Timer代表一次定时,时间到来后仅发生一个事件。C <-chan Timer runtimeTimer
}

Timer对外仅暴露一个channel,指定的时间到来时就往该channel中写入系统时间,也即一个事件。

本节我们介绍Timer的几个使用场景,同时再介绍其对外呈现的方法。

使用场景

设定超时时间

有时我们希望从一个管道中读取数据,在管道中没有数据时,我们不想让程序永远阻塞在管道中,而是设定一个超时时间,在此时间段中如果管道中还是没有数据到来,则判定为超时。

Go源码包中有大量类似的用法,比如从一个连接中等待数据,其简单的用法如下代码所示:

func WaitChannel(conn <-chan string) bool {timer := time.NewTimer(1 * time.Second)select {case <- conn:timer.Stop()return truecase <- timer.C: // 超时println("WaitChannel timeout!")return false}
}

WaitChannel作用就是检测指定的管道中是否有数据到来,通过select语句轮询conn和timer.C两个管道,timer会在1s后向timer.C写入数据,如果1s内conn还没有数据,则会判断为超时。

延迟执行某个方法

有时我们希望某个方法在今后的某个时刻执行,如下代码所示:

func DelayFunction() {timer := time.NewTimer(5 * time.Second)select {case <- timer.C:log.Println("Delayed 5s, start to do something.")}
}

DelayFunction()会一直等待timer的事件到来才会执行后面的方法(打印)。

Timer对外接口

创建定时器

使用方法func NewTimer(d Duration) *Timer指定一个时间即可创建一个Timer,Timer一经创建便开始计时,不需要额外的启动命令。

实际上,创建Timer意味着把一个计时任务交给系统守护协程,该协程管理着所有的Timer,当Timer的时间到达后向Timer的管道中发送当前的时间作为事件。详细的实现原理我们后面会单独介绍。

停止定时器

Timer创建后可以随时停止,停止计时器的方法是:

func (t *Timer) Stop() bool

其返回值代表定时器有没有超时:

  • true: 定时器超时前停止,后续不会再有事件发送;
  • false: 定时器超时后停止;

实际上,停止计时器意味着通知系统守护协程移除该定时器。详细的实现原理我们后面单独介绍。

重置定时器

已过期的定时器或者已停止的定时器,可以通过重置动作重新激活,重置方法如下:

func (t *Timer) Reset(d Duration) bool

重置的动作实质上是先停掉定时器,再启动。其返回值也即停掉计时器的返回值。

需要注意的是,重置定时器虽然可以用于修改还未超时的定时器,但正确的使用方式还是针对已过期的定时器或已被停止的定时器,同时其返回值也不可靠,返回值存在的价值仅仅是与前面版本兼容。

实际上,重置定时器意味着通知系统守护协程移除该定时器,重新设定时间后,再把定时器交给守护协程。详细的实现原理我们后面单独介绍。

简单接口

前面介绍了Timer的标准接口,time包同时还提供了一些简单的方法,在特定的场景下可以简化代码。

After()

有时我们就是想等指定的时间,没有需求提前停止定时器,也没有需求复用该定时器,那么可以使用匿名的定时器。

func After(d Duration) <-chan Time方法创建一个定时器,并返回定时器的管道,如下代码所示:

func AfterDemo() {log.Println(time.Now())<- time.After(1 * time.Second)log.Println(time.Now())
}

AfterDemo()两条打印时间间隔为1s,实际还是一个定时器,但代码变得更简洁。

AfterFunc()

前面我们例子中讲到延迟一个方法的调用,实际上通过AfterFunc可以更简洁。AfterFunc的原型为:

func AfterFunc(d Duration, f func()) *Timer

该方法在指定时间到来后会执行函数f。例如:

func AfterFuncDemo() {log.Println("AfterFuncDemo start: ", time.Now())time.AfterFunc(1 * time.Second, func() {log.Println("AfterFuncDemo end: ", time.Now())})time.Sleep(2 * time.Second) // 等待协程退出
}

AfterFuncDemo()中先打印一个时间,然后使用AfterFunc启动一个定器,并指定定时器结束时执行一个方法打印结束时间。

与上面的例子所不同的是,time.AfterFunc()是异步执行的,所以需要在函数最后sleep等待指定的协程退出,否则可能函数结束时协程还未执行。

总结

本节简单介绍了Timer的常见使用场景和接口,后面的章节再介绍Ticker、以及二者的实际细节。

Timer内容总结如下:

  • time.NewTimer(d)创建一个Timer;
  • timer.Stop()停掉当前Timer;
  • timer.Reset(d)重置当前Timer;

赠人玫瑰手留余香,如果觉得不错请给个赞~

本篇文章已归档到GitHub项目,求星~ 点我即达

转载于:https://my.oschina.net/renhc/blog/3026957

Go Timer使用方法相关推荐

  1. python定时器timer_python通过线程实现定时器timer的方法

    本文实例讲述了python通过线程实现定时器timer的方法.分享给大家供大家参考.具体分析如下: 这个python类实现了一个定时器效果,调用非常简单,可以让系统定时执行指定的函数 下面介绍以thr ...

  2. C# Timer使用方法示例

    实例化一个timer: // 每5分钟执行一次,每次执行的间隔毫秒时长 System.Timers.Timer timer = new System.Timers.Timer(5*60*1000); ...

  3. timer purge_Java Timer purge()方法与示例

    timer purge 计时器类purge()方法 (Timer Class purge() method) purge() method is available in java.util pack ...

  4. timer cancel_Java Timer cancel()方法与示例

    timer cancel 计时器类cancel()方法 (Timer Class cancel() method) cancel() method is available in java.util ...

  5. System.Timers.Timer的Enable、Start、Stop记录

    Timer的初始化,此时不执行theout3方法 System.Timers.Timer time = new System.Timers.Timer(); time.Interval = 1000; ...

  6. python定时器每月执行一次_python 定时器,实现每天凌晨3点执行的方法

    python 定时器,实现每天凌晨3点执行的方法 如下所示: ''' Created on 2018-4-20 例子:每天凌晨3点执行func方法 ''' import datetime import ...

  7. Android中几种常用的定时器和延时方法

    通过实际项目的练习,掌握了几种android基本定时器和延时的用法,这里我想总结一下作为自己的收获,下面列出的是比较简洁的模式,方便简单地在程序中直接调用.  一.三种常用的定时器  1.Handle ...

  8. web前端学习day_03:JavaScript:如何使用/ 语法/ 方法/ NaN/ js对象分类/ BOM浏览器相关/ 事件/ DOM文档对象模型

    JavaScript 给页面添加动态效果 JavaScript是一门编程语言,和Java没有关系,为了蹭热度. 语言特点: 属于脚本语言,不需要编译直接解析执行. 基于面向对象 属于弱类型语言, 强类 ...

  9. Java Swing 之Timer配合JProgressBar的使用

    Timer作为java开发中常用的一个定时工具,配合JProgressBar使用起来还真是方便,只需要调用timer.start()方法就能激活并运行,然后调用stop()方法便能停止,还可以再次通过 ...

最新文章

  1. ❤比较两种模糊特效❤filter: blur(10px)和backdrop-filter: blur(10px)的区别
  2. 一名大神的github
  3. 设计模式=相似模式区别
  4. Android 透明动画实现 详细概述
  5. WTL学习笔记(5)系统皮肤管理
  6. vue-cli mock
  7. 海康SDK设备信息NET_DVR_GET_DEVICECFG解析
  8. 内存取证-volatility工具的使用
  9. uni-app 极光推送
  10. 17分钟过桥,过桥最短时间问题
  11. 一建工程经济的关键数据推导及关键记忆点
  12. 企鹅号不更新会封_我们如何为企鹅基金会筹集60,000美元
  13. www.lthack.com php,[经验谈] PHP漏洞全解 ---文章转载自(十八哥,自学it网_公益IT培训)...
  14. 华为方舟编译器做了些什么,让安卓有了“丝滑”的感觉 ?
  15. `算法知识` 多边形, 凸多边形, 外接矩形
  16. python自动化脚本常用方法小结
  17. Django数据库学习——定义用户模型(实例)
  18. 基于Python个人博客系统设计与实现 开题报告
  19. 我不服!这开源项目居然才888个星!?
  20. 世界人工智能大赛OCR赛题方案!

热门文章

  1. 人生致命的8个经典问题,你也常常犯傻
  2. 关于MYSQL 的 AUTO-INC Locks
  3. 安装ORACLE 11G R2 +redhat es4遇到的问题
  4. 九、多表模型创建,一对一,一对多,基于对像的多表模型等
  5. 基于LSTM的序列预测: 飞机月流量预测
  6. kotlin学习笔记——重载操作符
  7. 6.2.2 二叉树的创建
  8. 在idea中把项目上传到GitHub库中
  9. c/c++ struct的大小以及sizeof用法
  10. java内部类的使用