计时器用来定时执行任务,分享一段代码:

代码解读见注释。

最终输出结果为:

Timer 1 expired

Timer 2 stopped

因为Timer 2的处理线程在等到信号前已经被停止掉了,所以会打印出Timer 2 stopped而不是Timer 2 expired

附录:下面看下Go语言计时器的使用详解

Go语言计时器

GoTimerTickerTimerdurationchannelTimerTickerdurationchannelchannel

文章主要涉及如下内容:

TimerTickerTimerTickerReset

计时器的内部表示

Goruntime.timerrumtime.timer
rumtime.timer
whenperiodfargfnextWhentimerModifiedLater/timerModifiedEairlierwhenstatus
runtime.timertime.Timertime.Ticker
Timer.CTicker.Cchannel

Timer计时器

time.Timertime.NewTimertime.AfterFunctime.Afterchannelchannelgoroutine
TimerselectchannelchannelTimer
time.AfterFuncTimergoroutinef
AfterFuncffgoFuncgoFuncgoroutinefGogoroutinetimerproctimerprocgoroutine
NewTimerAfterTimersendTime
sendTimeTimerchanneltimerprocNewTimerchannelTimer.CchannelsendTimeTimer.CsendTimeselectTimer.CBuffer
TimerStopStoptrueStopStopfalse
GoMin HeapStop

Ticker计时器

Ticker
time.Tickertime.NewTickertime.Tick
time.Ticktime.Tickerchanneltime.Tick
time.TickTicker
time.Ticktime.NewTickerTicker
NewTickerNewTimerchannelchannelsendTimeTicker

Reset计时器时要注意的问题

Reset

重置计时器时必须注意不要与当前计时器到期发送时间到t.C的操作产生竞争。如果程序已经从t.C接收到值,则计时器是已知的已过期,并且t.Reset可以直接使用。如果程序尚未从t.C接收值,计时器必须先被停止,并且-如果使用t.Stop时报告计时器已过期,那么请排空其通道中值。

例如:

producer goroutinefalsetrueconsumer goroutinetrue

程序的输出如下:

2020-05-13 12:49:48.90292 +0800 CST m=+1.004554120 :recv false. continue
2020-05-13 12:49:49.906087 +0800 CST m=+2.007748042 :recv false. continue
2020-05-13 12:49:50.910208 +0800 CST m=+3.011892138 :recv false. continue
2020-05-13 12:49:51.914291 +0800 CST m=+4.015997373 :recv false. continue
2020-05-13 12:49:52.916762 +0800 CST m=+5.018489240 :recv false. continue
2020-05-13 12:49:53.920384 +0800 CST m=+6.022129708 :recv true. return

producer goroutinproducer goroutine6consumer gouroutine5
deadlock

2020-05-13 13:09:11.166976 +0800 CST m=+5.005266022 :timer expired

timer.Ctimer.C
producer goroutinecomsumer goroutinefortimer.Stoptruefalsetimer.Cdrain channelconsumer goroutine
Resetdrain channelselectdrain channelchanneldrain
true

2020-05-13 13:25:08.412679 +0800 CST m=+5.005475546 :timer expired
2020-05-13 13:25:09.409249 +0800 CST m=+6.002037341 :recv false. continue
2020-05-13 13:25:14.412282 +0800 CST m=+11.005029547 :timer expired
2020-05-13 13:25:15.414482 +0800 CST m=+12.007221569 :recv false. continue
2020-05-13 13:25:20.416826 +0800 CST m=+17.009524859 :timer expired
2020-05-13 13:25:21.418555 +0800 CST m=+18.011245687 :recv false. continue
2020-05-13 13:25:26.42388 +0800 CST m=+23.016530193 :timer expired
2020-05-13 13:25:27.42294 +0800 CST m=+24.015582511 :recv false. continue
2020-05-13 13:25:32.425666 +0800 CST m=+29.018267054 :timer expired
2020-05-13 13:25:33.428189 +0800 CST m=+30.020782483 :recv false. continue
2020-05-13 13:25:38.432428 +0800 CST m=+35.024980796 :timer expired
2020-05-13 13:25:39.428343 +0800 CST m=+36.020887629 :recv true. return

总结

Go
TimerTickerruntime.timertimerproctime.TickTickergcTimerTickerchanneltime.Aftertime.NewTimertime.NewTickersendTimesendTimeResetdrain channel