golang定时器介绍(golang定时器实现)

1、time.After()

调用time.After(duration)之后,会返回一个time.Time类型的chan,不会阻塞程序的继续执行。等到指定duration时间后,会自动发送一个当前时间到chan,其底层是使用的NewTimer

// 函数原型 // After waits for the duration to elapse and then sends the current time // on the returned channel. // It is equivalent to NewTimer(d).C. // The underlying Timer is not recovered by the garbage collector // until the timer fires. If efficiency is a concern, use NewTimer // instead and call Timer.Stop if the timer is no longer needed. func After(d Duration) <-chan Time { return NewTimer(d).C }
// 示例 func main() { duration := time.Second * 5 t := time.After(duration) // 不阻塞,打印当前时间 fmt.Println(time.Now().Format("2006-01-02 15:04:05")) // 过了设定时间duration(5s)之后,往t中发送当前时间 fmt.Println((<-t).Format("2006-01-02 15:04:05")) } // 输出 2021-03-30 09:11:55 2021-03-30 09:12:00

#扩展(结合select实现超时处理)

select语句用来选择哪个case中的发送或接收操作可以被立即执行。它类似于switch语句,但是它的case涉及到channel相关的I/O操作

select语句不是循环,它只会选择一个case来处理,如果想一直处理channel,可以加一个无限的for循环

如果没有case需要处理,select语句就会一直阻塞。这时候就需要一个超时控制,用来处理超时的情况。

// 示例 func main() { c := make(chan string) go func() { // 3s后向channel c 中发送一条数据 time.Sleep(time.Second * 3) c <- "send" }() select { case res := <-c: fmt.Println(res) case <-time.After(time.Second): // select设置超时时间为1s,所以会先打印出timeout fmt.Println("timeout") } } // 输出 timeout

2、time.Tick()

Tick函数是使用channel阻塞当前的协程,用于完成定时任务的执行

// 函数原型 // Tick is a convenience wrapper for NewTicker providing access to the ticking // channel only. While Tick is useful for clients that have no need to shut down // the Ticker, be aware that without a way to shut it down the underlying // Ticker cannot be recovered by the garbage collector; it "leaks". // Unlike NewTicker, Tick will return nil if d <= 0. func Tick(d Duration) <-chan Time { if d <= 0 { return nil } return NewTicker(d).C }
// 示例 func main() { // 每隔1s向channel c 中发送当前时间 c := time.Tick(time.Second) for t := range c { fmt.Println(t.Format("2006-01-02 15:04:05")) } }

3、time.Sleep()

睡眠指定时间后继续执行下面的任务,Sleep会阻塞当前协程

// 函数原型 // Sleep pauses the current goroutine for at least the duration d. // A negative or zero duration causes Sleep to return immediately. func Sleep(d Duration)
// 示例 func { for { fmt.Println(time.Now().Format("2006-01-02 15:04:05")) time.Sleep(time.Second) } } // 输出 2021-03-30 11:08:53 2021-03-30 11:08:54 2021-03-30 11:08:55

4、time.Ticker

ticker是一个定时触发的计时器,它会以一个间隔往channel发送一条数据(当前时间),channel接收者可以固定的时间间隔从channel中读取数据

可以通过Stop方法来停止。一旦停止,接收者不会再从channel中接收数据了

// 函数原型 // A Ticker holds a channel that delivers `ticks' of a clock // at intervals. type Ticker struct { C <-chan Time // The channel on which the ticks are delivered. r runtimeTimer }
// 示例 func { ticker := time.NewTicker(time.Second) for t := range ticker.C { fmt.Println(t.Format("2006-01-02 15:04:05")) } } // 输出 2021-03-30 11:46:48 2021-03-30 11:46:49 2021-03-30 11:46:50 2021-03-30 11:46:51

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注