Go定时器的三种实现方式示例详解

目录
  • Sleep
  • Timer
  • Ticker
  • 小结

Sleep

很多时候需要周期性的执行某些操作,就需要用到定时器。定时器有三种思路。

本节源码位置 github.com/golang-mini…

使用休眠,让当前Goroutine休眠一定的时间来实现定时的效果,缺点是程序执行速度不均匀,导致定时周期不均匀。

for{
		fmt.Println(time.Now())
		time.Sleep(time.Second*1)
	}

Timer

Go 语言的内置包,指定一个时间开始计时,时间到之后会向外发送通知,发送通知的方式就是使用<-chan Time 返回内容。

第一种方式,直接在需要等待处使用,效果和Sleep一样,一使用就卡在那了内部就是使用了Timer

	fmt.Println(time.Now())
	<-time.After(1*time.Second)
	fmt.Println(time.Now())

也可以把他拆分开,在任意地方进行等待

	timer := time.NewTimer(1 * time.Second)
	<-timer.C
	fmt.Println(time.Now())

但是以上只是做到延迟一次性执行,我们来改造一下,把他变成定时器。

    done := make(chan struct{})
	timer := time.NewTimer(1 * time.Second)
	go func() {
		for {
			select {
			case <-timer.C:
				fmt.Println(time.Now())
				timer.Reset(1 * time.Second)
			case <-done:
				return
			}
		}
	}()
	<-time.After(5*time.Second + time.Millisecond*100)
	done <- struct{}{}
  • 定义子Goroutine的目的是为了防止形成死锁,让定时器最终能退出,在实际项目中可能需要一个永久运行的定时器,一般为了不影响项目主逻辑也会这样定义。如果你的项目就是定时任务,我建议也这么写,这样可以注册很多个定时器互不影响。
  • done是为了判断执行是否结束,防止主Goroutine提前退出。
  • 这个示例只有两个case,实战中如果有加其他case需要给每个case内都做一次Reset,保证重置定时器。

Ticker

相比上述使用延迟执行功能实现的定时器,Ticker 本身就是一个定时器(内部封装了Timer),我们使用起来就非常简单。

ticker := time.NewTicker(1 * time.Second)
	go func() {
		for {
			<-ticker.C
			fmt.Println(time.Now())
		}
	}()
	<-time.After(5 * time.Second + time.Millisecond*100)
	ticker.Stop()

select 一节中讲述的官方超时控制方案非常的实用,也是使用的此函数。还使用到timer.Stoptimer.Reset这两个内置函数这里就不展开讲解了,建议进行复习。

小结

定时器一般用来周期性执行任务,比如定时同步数据、计算报表、发送通知。

  • time.Sleep 使用休眠,让当前goroutine休眠一定的时间来实现定时的效果,缺点是内部逻辑执行的速度会影响到定时器的时间差,无法做到精确间隔。
  • Timer 类似于Sleep的延迟处理,通过channel来获得通知,也可以改造成定时器。因为是延迟处理,所以要记得重置时间来实现定时执行的效果。
  • Ticker 现成的定时器,内部也是封装了 Timer

以上就是Go定时器的三种实现方式的详细内容,更多关于Go定时器实现方式的资料请关注我们其它相关文章!

(0)

相关推荐

  • Go编写定时器与定时任务详解(附第三方库gocron用法)

    目录 Go 编写定时器和定时任务 Timer Ticker gocron 安装 Demo 总结 Go 编写定时器和定时任务 在 项目开发当中,可能会遇到这样的场景: 1 A任务需要在多久之后执行一次(定时器) 2.B任务需要每隔多长时间执行一次 (定时任务) 谈到定时任务,离不开linux的crontab. 先简单了解下crontab // 每隔1秒执行一次 */1 * * * * ? // 每隔1分钟执行一次 0 */1 * * * ? // 每天0点执行一次 0 0 0 * * ? // 每

  • Golang 定时器的终止与重置实现

    昨日有读者对定时器的终止有疑问,今天我们来聊一聊定时器的终止与重置吧! 定时器是一种通过设置一项任务,在未来的某个时刻执行该任务的机制. 定时器的种类通常只有两种,一种是只执行一次的延时模式,一种是每隔一段时间执行一次的间隔模式. 在现代编程语言中,定时器几乎是标配.除了设置定时器外,还需要有提供定时器的方法. 比如在 JavaScript 中,提供了 setTimeout.setInterval.clearTimeout 和 clearInterval 四个 API,相比较而言是比较简单的.G

  • Golang 定时器(Timer 和 Ticker),这篇文章就够了

    定时器是什么 Golang 原生 time 包下可以用来执行一些定时任务或者是周期性的任务的一个工具 本文基于 Go 1.14,如果以下文章有哪里不对或者问题的地方,欢迎讨论学习 定时器的日常使用 Timer 相关 func NewTimer(d Duration) *Timer func (t *Timer) Reset(d Duration) bool func (t *Timer) Stop() bool func After(d Duration) <-chan Time func Af

  • go语言定时器Timer及Ticker的功能使用示例详解

    目录 定时器1-"*/5 * * * * *" 设置说明 定时器2-Timer-Ticker Timer-只执行一次 Ticker-循环执行 Timer延时功能 停止和重置定时器 定时器Ticker使用 定时器1-"*/5 * * * * *" package main import ( "fmt" "github.com/robfig/cron" ) //主函数 func main() { cron2 := cron.New

  • golang 一次性定时器Timer用法及实现原理详解

    目录 前言 Timer timer结构体 创建定时器 停止定时器 重置定时器 实现原理 数据结构 runtimeTimer 创建Timer 停止Timer 重置Timer 前言 定时器在Go语言应用中使用非常广泛,Go语言的标准库里提供两种类型的计时器,一种是一次性的定时器Timer,另外一种是周期性的定时器Ticker.本文主要来看一下Timer的用法和实现原理,需要的朋友可以参考以下内容,希望对大家有帮助. Timer Timer是一种单一事件的定时器,即经过指定的时间后触发一个事件,因为T

  • Go Ticker 周期性定时器用法及实现原理详解

    目录 前言 Ticker 应用示例 创建定时器 停止定时器 实现原理 数据结构 runtimeTimer 创建Ticker 停止Ticker Ticker 与 Timer 区别 小结 前言 定时器在Go语言应用中使用非常广泛,Go语言的标准库里提供两种类型的计时器,一种是一次性的定时器Timer,另外一种是周期性的定时器Ticker.本文主要来看一下Ticker的用法和实现原理,需要的朋友可以参考以下内容,希望对大家有帮助. Ticker Ticker是周期性定时器,即周期性的触发一个事件,它会

  • node运行js获得输出的三种方式示例详解

    一.通过console.log输出(我最喜欢的) 1.js脚本 1.js var arguments = process.argv.splice(2); //获得入参 var a= arguments[0]; 取第一个 console.log(a) //输出 2.python脚本 test_1.py import os print(os.popen('node 1.js fuck').read()) #打印结果fuck 二.通过文件读写获取 1.js脚本 1.js //npm环境别忘了装了 va

  • C#获取本地IP的四种方式示例详解

    1.第一种方式 采用System.Net.Dns的GetHostAddress的方式,具体请看代码: /// <summary> /// 网络不通畅可以获取 /// 不过能获取到具体的IP /// </summary> /// <returns></returns> public static List<IPAddress> GetByGetHostAddresses() { try { IPAddress[] adds = Dns.GetHos

  • python实现三壶谜题的示例详解

    前言 有一个充满水的8品脱的水壶和两个空水壶(容积分别是5品脱和3品脱).通过将水壶完全倒满水和将水壶的水完全倒空这两种方式,在其中的一个水壶中得到4品脱的水. 一.算法思想 算法分析 采用的算法思想是将某个时刻水壶中水的数量看作一个状态,用一个长度为3的数组表示. 初始状态便为[8,0,0],再拓展他的下一结点的可能结构. 若下一结点的结构已经被拓展过了便放弃,若没有拓展过则加入拓展列表(open_list)中.然后递归上述操作. 直到拓展列表(open_list)为空或者找到目标为止. 思想

  • JS中原始值和引用值的储存方式示例详解

    在ECMAscript中,变量可以存放两种类型的值,即原始值和引用值 原始值指的是代表原始数据类型的值,也叫基本数据类型,包括:Number.Stirng.Boolean.Null.Underfined 引用值指的是复合数据类型的值,包括:Object.Function.Array.Date.RegExp 根据数据类型不同,有的变量储存在栈中,有的储存在堆中.具体区别如下: 原始变量及他们的值储存在栈中,当把一个原始变量传递给另一个原始变量时,是把一个栈房间的东西复制到另一个栈房间,且这两个原始

  • java中常见的6种线程池示例详解

    之前我们介绍了线程池的四种拒绝策略,了解了线程池参数的含义,那么今天我们来聊聊Java 中常见的几种线程池,以及在jdk7 加入的 ForkJoin 新型线程池 首先我们列出Java 中的六种线程池如下 线程池名称 描述 FixedThreadPool 核心线程数与最大线程数相同 SingleThreadExecutor 一个线程的线程池 CachedThreadPool 核心线程为0,最大线程数为Integer. MAX_VALUE ScheduledThreadPool 指定核心线程数的定时

  • java线程池ThreadPoolExecutor的八种拒绝策略示例详解

    目录 池化设计思想 线程池触发拒绝策略的时机 JDK内置4种线程池拒绝策略 拒绝策略接口定义 AbortPolicy(中止策略) DiscardPolicy(丢弃策略) DiscardOldestPolicy(弃老策略) 第三方实现的拒绝策略 Dubbo 中的线程拒绝策略 Netty 中的线程池拒绝策略 ActiveMQ 中的线程池拒绝策略 PinPoint 中的线程池拒绝策略 谈到 Java 的线程池最熟悉的莫过于 ExecutorService 接口了,jdk1.5 新增的 java.uti

  • Android 中倒计时验证两种常用方式实例详解

    Android 中倒计时验证两种常用方式实例详解 短信验证码功能,这里总结了两种常用的方式,可以直接拿来使用.看图: 说明:这里的及时从10开始,是为了演示的时间不要等太长而修改的. 1.第一种方式:Timer /** * Description:自定义Timer * <p> * Created by Mjj on 2016/12/4. */ public class TimeCount extends CountDownTimer { private Button button; //参数依

  • bootstrap paginator分页插件的两种使用方式实例详解

    分页有两种方式: 1. 前台分页:ajax一次请求获取全部数据,适合少量数据(万条数据以下): $.ajax({ type: "GET", url: "",//后台接口地址 dataType: "json", success: function (msg) { var pages = Math.ceil(msg.data / 5);//data是数据总量 var element = $('#id');//对应ul的id element.boots

  • python中np.multiply()、np.dot()和星号(*)三种乘法运算的区别详解

    为了区分三种乘法运算的规则,具体分析如下: import numpy as np 1. np.multiply()函数 函数作用 数组和矩阵对应位置相乘,输出与相乘数组/矩阵的大小一致 1.1数组场景 A = np.arange(1,5).reshape(2,2) A array([[1, 2],        [3, 4]]) B = np.arange(0,4).reshape(2,2) B array([[0, 1],        [2, 3]]) np.multiply(A,B) #数

  • Python中三种花式打印的示例详解

    目录 1. 引言 2. 打印圣诞树 2.1 问题描述 2.2 问题分析 3. 打印字母版圣诞树 3.1 问题描述 3.2 问题分析 4. 打印字母版菱形 4.1 问题描述 4.2 问题分析 5. 总结 1. 引言 在Python中有很多好玩的花式打印,对厉害的高手来说可能是小菜一碟,对入门的小白来说往往让人望而退步,我们今天就来挑战下面三个常见的花式打印吧... 2. 打印圣诞树 2.1 问题描述 编码实现函数christmas_tree(height),该函数输入参数为一个整数表示圣诞树的高度

随机推荐