網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
Sleep
很多時(shí)候需要周期性的執(zhí)行某些操作,就需要用到定時(shí)器。定時(shí)器有三種思路。
本節(jié)源碼位置 github.com/golang-mini…
使用休眠,讓當(dāng)前Goroutine
休眠一定的時(shí)間來(lái)實(shí)現(xiàn)定時(shí)的效果,缺點(diǎn)是程序執(zhí)行速度不均勻,導(dǎo)致定時(shí)周期不均勻。
for{ fmt.Println(time.Now()) time.Sleep(time.Second*1) }
Timer
Go
語(yǔ)言的內(nèi)置包,指定一個(gè)時(shí)間開(kāi)始計(jì)時(shí),時(shí)間到之后會(huì)向外發(fā)送通知,發(fā)送通知的方式就是使用<-chan Time
返回內(nèi)容。
第一種方式,直接在需要等待處使用,效果和Sleep
一樣,一使用就卡在那了內(nèi)部就是使用了Timer
。
fmt.Println(time.Now()) <-time.After(1*time.Second) fmt.Println(time.Now())
也可以把他拆分開(kāi),在任意地方進(jìn)行等待
timer := time.NewTimer(1 * time.Second) <-timer.C fmt.Println(time.Now())
但是以上只是做到延遲一次性執(zhí)行,我們來(lái)改造一下,把他變成定時(shí)器。
done := make(chan struct{}) timer := time.NewTimer(1 * time.Second) go func() { 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
的目的是為了防止形成死鎖,讓定時(shí)器最終能退出,在實(shí)際項(xiàng)目中可能需要一個(gè)永久運(yùn)行的定時(shí)器,一般為了不影響項(xiàng)目主邏輯也會(huì)這樣定義。如果你的項(xiàng)目就是定時(shí)任務(wù),我建議也這么寫(xiě),這樣可以注冊(cè)很多個(gè)定時(shí)器互不影響。 -
done
是為了判斷執(zhí)行是否結(jié)束,防止主Goroutine
提前退出。 - 這個(gè)示例只有兩個(gè)
case
,實(shí)戰(zhàn)中如果有加其他case
需要給每個(gè)case
內(nèi)都做一次Reset
,保證重置定時(shí)器。
Ticker
相比上述使用延遲執(zhí)行功能實(shí)現(xiàn)的定時(shí)器,Ticker
本身就是一個(gè)定時(shí)器(內(nèi)部封裝了Timer
),我們使用起來(lái)就非常簡(jiǎn)單。
ticker := time.NewTicker(1 * time.Second) go func() { for { <-ticker.C fmt.Println(time.Now()) } }() <-time.After(5 * time.Second + time.Millisecond*100) ticker.Stop()
在select 一節(jié)中講述的官方超時(shí)控制方案非常的實(shí)用,也是使用的此函數(shù)。還使用到timer.Stop
和timer.Reset
這兩個(gè)內(nèi)置函數(shù)這里就不展開(kāi)講解了,建議進(jìn)行復(fù)習(xí)。
小結(jié)
定時(shí)器一般用來(lái)周期性執(zhí)行任務(wù),比如定時(shí)同步數(shù)據(jù)、計(jì)算報(bào)表、發(fā)送通知。
-
time.Sleep
使用休眠,讓當(dāng)前goroutine
休眠一定的時(shí)間來(lái)實(shí)現(xiàn)定時(shí)的效果,缺點(diǎn)是內(nèi)部邏輯執(zhí)行的速度會(huì)影響到定時(shí)器的時(shí)間差,無(wú)法做到精確間隔。 -
Timer
類(lèi)似于Sleep
的延遲處理,通過(guò)channel
來(lái)獲得通知,也可以改造成定時(shí)器。因?yàn)槭茄舆t處理,所以要記得重置時(shí)間來(lái)實(shí)現(xiàn)定時(shí)執(zhí)行的效果。 -
Ticker
現(xiàn)成的定時(shí)器,內(nèi)部也是封裝了Timer
。
原文鏈接:https://juejin.cn/post/7178873205002600506
相關(guān)推薦
- 2021-12-10 linux系統(tǒng)文件共享samba配置教程_Linux
- 2023-06-13 C語(yǔ)言中如何通過(guò)指針參數(shù)返回值_C 語(yǔ)言
- 2022-04-23 排序會(huì)了遞歸,不學(xué)非遞歸太可惜了
- 2023-02-07 C++實(shí)現(xiàn)字符串和整數(shù)的相互轉(zhuǎn)換_C 語(yǔ)言
- 2022-07-26 討論nginx?location?順序問(wèn)題_nginx
- 2023-03-22 PyTorch中torch.tensor()和torch.to_tensor()的區(qū)別_python
- 2022-10-29 Android 開(kāi)發(fā) | API 指南- Content Provider 應(yīng)用程序的使用方法
- 2022-11-07 python中dot函數(shù)運(yùn)算過(guò)程總結(jié)_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門(mén)
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支