本文转自 Blog
Golang中time包有两个定时器,分别为 ticker 和 timer。两者都可以实现定时功能,但各自都有自己的使用场景。
Ticker定时器
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 
 | package main
 import (
 "fmt"
 "time"
 )
 
 func main() {
 
 
 
 
 ticker1 := time.NewTicker(5 * time.Second)
 
 defer ticker1.Stop()
 go func(t *time.Ticker) {
 for {
 
 <-t.C
 fmt.Println("Ticker:", time.Now().Format("2006-01-02 15:04:05"))
 }
 }(ticker1)
 
 time.Sleep(30 * time.Second)
 fmt.Println("ok")
 }
 
 | 
执行结果
| 12
 3
 4
 5
 6
 7
 8
 
 | 开始时间: 2020-03-19 17:49:41Ticker: 2020-03-19 17:49:46
 Ticker: 2020-03-19 17:49:51
 Ticker: 2020-03-19 17:49:56
 Ticker: 2020-03-19 17:50:01
 Ticker: 2020-03-19 17:50:06
 结束时间: 2020-03-19 17:50:11
 ok
 
 | 
可以看到每次执行的时间间隔都是一样的。
Timer定时器
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 
 | package main
 import (
 "fmt"
 "time"
 )
 
 func main() {
 
 
 timer1 := time.NewTimer(5 * time.Second)
 
 fmt.Println("开始时间:", time.Now().Format("2006-01-02 15:04:05"))
 go func(t *time.Timer) {
 times := 0
 for {
 <-t.C
 fmt.Println("timer", time.Now().Format("2006-01-02 15:04:05"))
 
 
 
 
 times++
 
 fmt.Println("调用 reset 重新设置一次timer定时器,并将时间修改为2秒")
 t.Reset(2 * time.Second)
 if times > 3 {
 fmt.Println("调用 stop 停止定时器")
 t.Stop()
 }
 }
 }(timer1)
 
 time.Sleep(30 * time.Second)
 fmt.Println("结束时间:", time.Now().Format("2006-01-02 15:04:05"))
 fmt.Println("ok")
 }
 
 | 
执行结果
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 
 | 开始时间: 2020-03-19 17:41:59timer 2020-03-19 17:42:04
 调用 reset 重新设置一次timer定时器,并将时间修改为2秒
 timer 2020-03-19 17:42:06
 调用 reset 重新设置一次timer定时器,并将时间修改为2秒
 timer 2020-03-19 17:42:08
 调用 reset 重新设置一次timer定时器,并将时间修改为2秒
 timer 2020-03-19 17:42:10
 调用 reset 重新设置一次timer定时器,并将时间修改为2秒
 调用 stop 停止定时器
 结束时间: 2020-03-19 17:42:29
 ok
 
 | 
可以看到,第一次执行时间为5秒以后。然后通过调用 time.Reset() 方法再次激活定时器,定时时间为2秒,最后通过调用 time.Stop() 把前面的定时器取消掉。
timer和ticker的区别
- ticker定时器表示每隔一段时间就执行一次,一般可执行多次。
- timer定时器表示在一段时间后执行,默认情况下只执行一次,如果想再次执行的话,每次都需要调用 time.Reset()方法,此时效果类似ticker定时器。同时也可以调用Stop()方法取消定时器
- timer定时器比ticker定时器多一个 Reset()方法,两者都有Stop()方法,表示停止定时器,底层都调用了stopTimer()函数。
注意事项
1. 这里需要注意的时,如果在调用 time.Reset() 或 time.Stop() 的时候,timer已经过期或者停止了,则会返回false。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 
 | func main() {
 timer := time.NewTimer(2 * time.Second)
 time.Sleep(3 * time.Second)
 ret := timer.Reset(2 * time.Second)
 fmt.Println(ret)
 
 
 timer = time.NewTimer(2 * time.Second)
 timer.Stop()
 ret = timer.Reset(2 * time.Second)
 fmt.Println(ret)
 
 fmt.Println("ok")
 }
 
 | 
执行结果
__2. 如果调用 time.Stop() 时,timer已过期或已stop,则并不会关闭通道。 __
3. 使用 time.NewTicker() 定时器时,需要使用 Stop() 方法进行资源释放,否则会产生内存泄漏,(Stop the ticker to release associated resources.)