Go语言standard package——time.Timer

本篇文章将对go语言的标准包time.Timer进行介绍,附带部分应用实例

1. time.Timer介绍

  • TImer的定义:
    	type Timer struct {
    		C <-chan Time
    		// contains filtered or unexported fields
    	}
    
  • 从上面的定义中可以看出,Timer是一个struct,内部包含有一个接受Time的的单向channel
  • Timer对应了一个驱动事件(a single event),Timer的创建方式只有两种:
    • NewTimer:func NewTimer(d Duration) *Timer,该方法接收一个Duration,返回一个Timer。当指定的时间间隔过去之后,返回的Timer会接收到一个Time。
    • AfterFunc:func AfterFunc(d Duration, f func()) *Timer,该方法接收一个Duration以及一个func,返回一个Timer;AfterFunc会在Duration指定的时间间隔结束之后,在一个独立的goroutine中调用传入的func,而返回的Timer包含一个stop方法,可以用于在duration期间内终止func的调用

2. time.Timer的方法

  • Reset:func (t *Timer) Reset(d Duration) bool,可以认为Reset方法是用于重定义一个已有Timer:
    • 对于用NewTimer方法定义的Timer,该方法只能够在该TImer处于stopped或expired(也就是初定义Duration已过,channel接受过时间的情况)下使用
      • 注意在调用Reset方法前,一定要判断该TImer是否处于对应的可执行状态,如下所示:注意,该过程不应该并发地与其他接受channel内容的操作并发执行
        if !t.Stop() {
        	<-t.C
        }
        t.Reset(d)
        
    • 对于用AfterFunc方法定义的Timer,Reset方法的返回值具有一下意义:
      • True:调用时Timer的func还没有执行,Reset会重调度该方法
      • False:调用时Timer的func已经在执行或执行完成,Reset会调度该方法并使其在此执行;注意:如果返回的是false,那么Reset不会保证上次执行的func已经执行完毕,也不会保证下次执行的func不与上次执行func并发执行;如果用户想要知道上次的func是否已经执行完毕,那么需要在func中设置对应的标志
  • Stop:func (t *Timer) Stop() bool,Stop方法会阻止Timer被“激活”:
    • 返回True:如果成果停止了Timer
    • 返回False:如果Timer已经被激活了或处于原来就处于Stop状态;注意:为了防止因度对应channel产生的错误,Stop方法不会关闭对应的channel
    • 为了保证在执行完Stop方法或TImer的channel是空的,可以对Stop方法的返回值进行检查,同时抽取channel的内容:
    	if !t.Stop() {
    		<-t.C
    	}
    
    • 对于一个由AfterFunc定义的Timer,如果Stop方法的返回值时false,那么说明该Timer已经被激活了,而其中的func已经在另一个goroutine中执行或执行完成;Stop方法不会等待func执行完毕之后才返回,如果用户想要确定func是否已经执行完成,那么需要通过在func中设定对应的标志

3. 示例

  • 示例一:Timer会在指定Duration之后接收到一个时间
  6 package main
  5 
  4 import "time"
  3 import "fmt" 
  2 
  1 func main() {
7           t := time.NewTimer(time.Duration(3*time.Second)) 
  1         time.Sleep(5*time.Second)
  2         if !t.Stop() { 
  3                 now := <-t.C
  4                 fmt.Println(now)
  5         }
  6 }

输出:2022-02-18 10:40:05.167702931 +0800 CST m=+3.002078547

  • 示例二:用AfterFunc定义的Timer不会在Duration结束之后接收到时间,而是会在另一个goroutine中执行指定的func
 18 package main
 17 
 16 import (
 15         "time"
 14         "fmt"
 13 )
 12 
 11 func main() {
 10         f := func() {
  9                 fmt.Println("function is invoked!")
  8         }
  7         t := time.AfterFunc(time.Duration(3*time.Second), f)
  6         time.Sleep(5*time.Second)
  5         if !t.Stop() {
  4                 // now := <-t.C 
  3                 // fmt.Println(now)
  2                 // 上述操作会陷入死锁
  1                 // 这也说明了用AfterFunc定义的Timer在指定的Duration结束之后并不会接收到时间
19          }
  1 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值