一、什么是定时器?

Go定时器是并发编程中的关键组件,主要用于在指定时间点或定期执行任务。它采用高效的最小堆算法实现,并与调度器进行了深度集成。

二、定时器类型与基础用法

1)一次性定时器

(1)创建定时器

创建一次性定时器,代码示例如下:

func main() {timer1 := time.NewTimer(2 * time.Second)t1 := time.Now()fmt.Printf("timer1:%v\n", t1)t2 := <-timer1.Cfmt.Printf("timer2:%v\n", t2)
}

运行结果如下图所示:

Go定时器:高效并发编程的核心组件_#timer

(2)停止定时器

取消已启动但尚未触发的定时器。代码示例如下:

func main() {timer1 := time.NewTimer(2 * time.Second)t1 := time.Now()fmt.Printf("timer1:%v\n", t1)timer1.Stop()
}

(3)重置定时器

重置已启动但尚未触发的定时器,但是需要注意重置定时器时需要判断定时器是否未停止。代码示例如下:

func main() {timer1 := time.NewTimer(2 * time.Second)t1 := time.Now()fmt.Printf("timer1:%v\n", t1)if !timer1.Stop() {// 排除可能的事件<-timer1.C}timer1.Reset(3 * time.Second)t2 := <-timer1.Cfmt.Printf("timer2:%v\n", t2)
}

运行结果如下图所示:

Go定时器:高效并发编程的核心组件_#后端_02

(4)延时功能

提高代码延时的三种实现方式:

  1. 通过time.sleep()函数实现
  2. 使用time.NewTimer()方法实现
  3. 采用time.After()函数实现

代码示例如下:

func main() {time.Sleep(time.Second)fmt.Printf("1秒到:%v\n", time.Now())timer3 := time.NewTimer(2 * time.Second)<-timer3.Cfmt.Printf("2秒到:%v\n", time.Now())<-time.After(2 * time.Second)fmt.Printf("2秒到:%v\n", time.Now())
}

(5)异步回调

使用AfterFunc 方法异步回调,无需显式等待。代码示例如下:

func main() {t1 := time.Now()fmt.Printf("timer1:%v\n", t1)time.AfterFunc(2*time.Second, func() {fmt.Printf("timer2:%v\n", time.Now())})// 阻塞主进程不退出,为定时器执行提供执行时间time.Sleep(100 * time.Second)
}

2)周期性定时器

(1)创建定时器

使用NewTicker方法创建周期性定时器,代码示例如下:

func main() {ticker := time.NewTicker(1 * time.Second)for range ticker.C {fmt.Println(time.Now())}}

运行结果如下图所示:

Go定时器:高效并发编程的核心组件_#定时器_03

(2)结束定时器

周期性定时器必须显式结束,避免资源泄露。代码示例如下:

func main() {ticker := time.NewTicker(1 * time.Second)defer ticker.Stop()for range ticker.C {fmt.Println(time.Now())}}

 (3)重置定时器

重置已启动周期性定时器。代码示例如下:

func main() {ticker := time.NewTicker(1 * time.Second)defer ticker.Stop()go func() {for range ticker.C {fmt.Println(time.Now())}}()time.Sleep(2 * time.Second)ticker.Reset(2 * time.Second)for {}}

运行结果如下图所示:

Go定时器:高效并发编程的核心组件_#golang_04