业务中,会有对某段逻辑在未来某一时刻执行或以一定时间间隔周期性执行的需求。golang使用timer及ticker来满足该需求场景。
1 Timers
Timer表示在未来某一刻执行仅一次的事件。如下代码中,第一个timer表示1s后执行,<-timer.C会一直阻塞,直至预定时间到达。第二个timer表示2s后执行,新启一个goroutine等待时间到达,主routine在时间未到达前即调用了Stop(),这样,新启的goroutine中的逻辑即不会被执行。
- package main
- import (
- "fmt"
- "time"
- )
- func main() {
- timer := time.NewTimer(time.Second)
- <-timer.C
- fmt.Println("hello")
- timer = time.NewTimer(2 * time.Second)
- go func() {
- <-timer.C
- fmt.Println("world")
- }()
- if timer.Stop() {
- fmt.Println("timer stoped")
- }
- }
- package main
- import (
- "fmt"
- "time"
- )
- func main() {
- done := make(chan bool)
- time.AfterFunc(time.Second, func() {
- fmt.Println("hello")
- done <- true
- })
- <-done
- }
- $ go run test.go 2>&1 | grep "^goroutine" | wc -l
- 4
- $ go run test.go hello 2>&1 | grep "^goroutine" | wc -l
- 5
- package main
- import (
- "os"
- "runtime/debug"
- "time"
- )
- func main() {
- debug.SetTraceback("system")
- if len(os.Args) <= 1 {
- panic("before")
- }
- for i := 0; i < 10000; i++ {
- time.NewTimer(time.Second)
- // time.AfterFunc(time.Second, func() {})
- }
- panic("after")
- }
2 Tickers
Ticker表示一个按一定时间间隔周期性执行的事件。其创建与Timer类似。如下代码中,创建一个每隔1s即触发执行的ticker,新启一个goroutine遍历其时钟chan打印时间,主routine等待5s后停止该ticker,新启的goroutine即不会再收到消息。
- package main
- import (
- "fmt"
- "time"
- )
- func main() {
- ticker := time.NewTicker(time.Second)
- go func() {
- for t := range ticker.C {
- fmt.Println(t)
- }
- }()
- time.Sleep(5 * time.Second)
- ticker.Stop()
- }
本文代码托管地址:https://github.com/olzhy/go-excercises/tree/master/timers_and_tickers
原文地址:https://leileiluoluo.com/posts/golang-timers-and-tickers.html
有疑问加站长微信联系(非本文作者))
