網站首頁 編程語言 正文
Sleep
很多時候需要周期性的執行某些操作,就需要用到定時器。定時器有三種思路。
本節源碼位置 github.com/golang-mini…
使用休眠,讓當前Goroutine
休眠一定的時間來實現定時的效果,缺點是程序執行速度不均勻,導致定時周期不均勻。
for{ fmt.Println(time.Now()) time.Sleep(time.Second*1) }
Timer
Go
語言的內置包,指定一個時間開始計時,時間到之后會向外發送通知,發送通知的方式就是使用<-chan Time
返回內容。
第一種方式,直接在需要等待處使用,效果和Sleep
一樣,一使用就卡在那了內部就是使用了Timer
。
fmt.Println(time.Now()) <-time.After(1*time.Second) fmt.Println(time.Now())
也可以把他拆分開,在任意地方進行等待
timer := time.NewTimer(1 * time.Second) <-timer.C fmt.Println(time.Now())
但是以上只是做到延遲一次性執行,我們來改造一下,把他變成定時器。
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
的目的是為了防止形成死鎖,讓定時器最終能退出,在實際項目中可能需要一個永久運行的定時器,一般為了不影響項目主邏輯也會這樣定義。如果你的項目就是定時任務,我建議也這么寫,這樣可以注冊很多個定時器互不影響。 -
done
是為了判斷執行是否結束,防止主Goroutine
提前退出。 - 這個示例只有兩個
case
,實戰中如果有加其他case
需要給每個case
內都做一次Reset
,保證重置定時器。
Ticker
相比上述使用延遲執行功能實現的定時器,Ticker
本身就是一個定時器(內部封裝了Timer
),我們使用起來就非常簡單。
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 一節中講述的官方超時控制方案非常的實用,也是使用的此函數。還使用到timer.Stop
和timer.Reset
這兩個內置函數這里就不展開講解了,建議進行復習。
小結
定時器一般用來周期性執行任務,比如定時同步數據、計算報表、發送通知。
-
time.Sleep
使用休眠,讓當前goroutine
休眠一定的時間來實現定時的效果,缺點是內部邏輯執行的速度會影響到定時器的時間差,無法做到精確間隔。 -
Timer
類似于Sleep
的延遲處理,通過channel
來獲得通知,也可以改造成定時器。因為是延遲處理,所以要記得重置時間來實現定時執行的效果。 -
Ticker
現成的定時器,內部也是封裝了Timer
。
原文鏈接:https://juejin.cn/post/7178873205002600506
相關推薦
- 2022-10-21 K8s解決主機重啟后kubelet無法自動啟動問題(推薦)_云其它
- 2022-05-04 Python?GUI編程之tkinter?關于?ttkbootstrap?的使用詳解_python
- 2022-09-04 Go語言指針用法詳解_Golang
- 2022-09-22 求解器選擇與收斂性問題(OR-Tools)
- 2022-10-17 Go?WaitGroup及Cond底層實現原理_Golang
- 2022-10-04 C語言實現倒置字符串的兩種方法分享_C 語言
- 2022-08-05 Winform窗體中打開PDF文件的三種方式_C#教程
- 2022-06-11 docker安裝elastic?search和kibana的實現_docker
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支