很多時候需要周期性的執(zhí)行某些操作,就需要用到定時器。定時器有三種思路。
(資料圖片)
Sleep使用休眠,讓當前Goroutine休眠一定的時間來實現(xiàn)定時的效果,缺點是程序執(zhí)行速度不均勻,導(dǎo)致定時周期不均勻。
for{fmt.Println(time.Now())time.Sleep(time.Second*1)}Timer
Go語言的內(nèi)置包,指定一個時間開始計時,時間到之后會向外發(fā)送通知,發(fā)送通知的方式就是使用<-chan Time返回內(nèi)容。
第一種方式,直接在需要等待處使用,效果和Sleep一樣,一使用就卡在那了內(nèi)部就是使用了Timer。
fmt.Println(time.Now())<-time.After(1*time.Second)fmt.Println(time.Now())
也可以把他拆分開,在任意地方進行等待
timer:=time.NewTimer(1*time.Second)<-timer.Cfmt.Println(time.Now())
但是以上只是做到延遲一次性執(zhí)行,我們來改造一下,把他變成定時器。
done:=make(chanstruct{})timer:=time.NewTimer(1*time.Second)gofunc(){for{select{case<-timer.C:fmt.Println(time.Now())timer.Reset(1*time.Second)case<-done:return}}}()<-time.After(5*time.Second+time.Millisecond*100)done<-struct{}{}定義子Goroutine的目的是為了防止形成死鎖,讓定時器最終能退出,在實際項目中可能需要一個永久運行的定時器,一般為了不影響項目主邏輯也會這樣定義。如果你的項目就是定時任務(wù),我建議也這么寫,這樣可以注冊很多個定時器互不影響。done是為了判斷執(zhí)行是否結(jié)束,防止主Goroutine提前退出。這個示例只有兩個case,實戰(zhàn)中如果有加其他case需要給每個case內(nèi)都做一次Reset,保證重置定時器。Ticker
相比上述使用延遲執(zhí)行功能實現(xiàn)的定時器,Ticker本身就是一個定時器(內(nèi)部封裝了Timer),我們使用起來就非常簡單。
ticker:=time.NewTicker(1*time.Second)gofunc(){for{<-ticker.Cfmt.Println(time.Now())}}()<-time.After(5*time.Second+time.Millisecond*100)ticker.Stop()
在select 一節(jié)中講述的官方超時控制方案非常的實用,也是使用的此函數(shù)。還使用到timer.Stop和timer.Reset這兩個內(nèi)置函數(shù)這里就不展開講解了,建議進行復(fù)習(xí)。
小結(jié)定時器一般用來周期性執(zhí)行任務(wù),比如定時同步數(shù)據(jù)、計算報表、發(fā)送通知。
time.Sleep使用休眠,讓當前goroutine休眠一定的時間來實現(xiàn)定時的效果,缺點是內(nèi)部邏輯執(zhí)行的速度會影響到定時器的時間差,無法做到精確間隔。Timer類似于Sleep的延遲處理,通過channel來獲得通知,也可以改造成定時器。因為是延遲處理,所以要記得重置時間來實現(xiàn)定時執(zhí)行的效果。Ticker現(xiàn)成的定時器,內(nèi)部也是封裝了 Timer。標簽:
居家辦公工資支付問題,最高法明確! 全球快播報
2022-12-28重點聚焦!【創(chuàng)城時刻】商鋪垃圾“不落地” 環(huán)衛(wèi)工人上門收
2022-12-28每日快報!加快補齊農(nóng)村牧區(qū)疫情防控短板 孫紹騁調(diào)研農(nóng)村疫情防控工作
2022-12-28天天消息!呼和浩特市暫停市本級醫(yī)保政務(wù)服務(wù)大廳線下服務(wù) 線上辦理方法看這里
2022-12-28世界微頭條丨【新時代 新征程 新偉業(yè)】久泰新材料公司:為高質(zhì)量發(fā)展注入新動能
2022-12-27【辟謠】打過科興疫苗的人需警惕!接種科興疫苗的人憑接種證明點擊鏈接就可以領(lǐng)取每人2000元的補助?|快消息
2022-12-27不要浪費抗原了!啥時測才準,記住5點
2022-12-27【關(guān)注】入戶為老年人接種疫苗 為大家增添安全屏障
2022-12-27