go語言中Timer和Ticker兩種計(jì)時(shí)器的使用
介紹
go語言中有Timer和Ticker這樣的兩種計(jì)時(shí)器,兩種計(jì)時(shí)器分別實(shí)現(xiàn)了不同的計(jì)時(shí)功能。
- Timer是單次時(shí)間事件,指在指定的單次時(shí)間過后觸發(fā),然后向自己channel中發(fā)送當(dāng)時(shí)時(shí)間,此后Timer不再計(jì)時(shí)。
- Ticker是多次時(shí)間事件,指每隔一段事件都觸發(fā)一次,并向自己channel發(fā)送當(dāng)前時(shí)間。
- 類似于javascript中的setTimeout()和setInterval()兩種計(jì)時(shí)器。
Timer計(jì)時(shí)及其方法
type Timer struct {
C <-chan Time
// 內(nèi)含隱藏或非導(dǎo)出字段
}
Timer類型代表單次時(shí)間事件。當(dāng)Timer到期時(shí),當(dāng)時(shí)的時(shí)間會(huì)被發(fā)送給C。
NewTimer
func NewTimer(d Duration) *Timer
NewTimer創(chuàng)建一個(gè)Timer,它會(huì)在最少過去時(shí)間段d后到期,向其自身的C字段發(fā)送當(dāng)時(shí)的時(shí)間。
使用:
package main
import (
"fmt"
"time"
)
func main() {
timer := time.NewTimer(10 * time.Second)
t1 := time.Now()
fmt.Printf("t1:%v\n", t1)
t2 := <-timer.C
fmt.Printf("t2:%v\n", t2)
}
輸出:
t1:2023-04-29 22:13:20.3142549 +0800 CST m=+0.002562901
t2:2023-04-29 22:13:30.328093 +0800 CST m=+10.016401001
程序輸出t1后,又計(jì)時(shí)了10秒輸出了t2
Stop
func (t *Timer) Stop() bool
Stop停止Timer的執(zhí)行。如果停止了t會(huì)返回真;如果t已經(jīng)被停止或者過期了會(huì)返回假。Stop不會(huì)關(guān)閉通道t.C,以避免從該通道的讀取不正確的成功。
使用:
package main
import (
"fmt"
"time"
)
func main() {
timer := time.NewTimer(10 * time.Second)
t1 := time.Now()
fmt.Printf("t1:%v\n", t1)
//停止計(jì)時(shí)器
timer.Stop()
t2 := time.Now()
fmt.Printf("t2:%v\n", t2)
t3 := <-timer.C
fmt.Printf("t3:%v\n", t3)
}
輸出:
t1:2023-04-29 22:25:05.921852 +0800 CST m=+0.002725901
t2:2023-04-29 22:25:05.9372012 +0800 CST m=+0.018075101
fatal error: all goroutines are asleep - deadlock!
可見,程序在timer使用了stop方法以后輸出t3就報(bào)出了all goroutines are asleep - deadlock! 錯(cuò)誤。
Reset
func (t *Timer) Reset(d Duration) bool
Reset使t重新開始計(jì)時(shí),(本方法返回后再)等待時(shí)間段d過去后到期。如果調(diào)用時(shí)t還在等待中會(huì)返回真;如果t已經(jīng)到期或者被停止了會(huì)返回假。
使用:
package main
import (
"fmt"
"time"
)
func main() {
timer := time.NewTimer(10 * time.Second)
t1 := time.Now()
fmt.Printf("t1:%v\n", t1)
//程序休眠2s
time.Sleep(2 * time.Second)
//重新設(shè)置時(shí)間間隔
timer.Reset(15 * time.Second)
t2 := time.Now()
fmt.Printf("t2:%v\n", t2)
t3 := <-timer.C
fmt.Printf("t3:%v\n", t3)
}
輸出:
t1:2023-04-29 22:33:53.4179209 +0800 CST m=+0.002563001
t2:2023-04-29 22:33:55.4452012 +0800 CST m=+2.029843301
t3:2023-04-29 22:34:10.4605181 +0800 CST m=+17.045160201
計(jì)時(shí)器被重新設(shè)置后會(huì)根據(jù)設(shè)置的時(shí)間段重新計(jì)時(shí),到時(shí)間后,計(jì)時(shí)結(jié)束,向其自身的C字段發(fā)送當(dāng)時(shí)的時(shí)間。
Ticker計(jì)時(shí)及其方法
type Ticker struct {
C <-chan Time // 周期性傳遞時(shí)間信息的通道
// 內(nèi)含隱藏或非導(dǎo)出字段
}Ticker保管一個(gè)通道,并每隔一段時(shí)間向其傳遞"tick"。
NewTicker
func NewTicker(d Duration) *Ticker
NewTicker返回一個(gè)新的Ticker,該Ticker包含一個(gè)通道字段,并會(huì)每隔時(shí)間段d就向該通道發(fā)送當(dāng)時(shí)的時(shí)間。它會(huì)調(diào)整時(shí)間間隔或者丟棄tick信息以適應(yīng)反應(yīng)慢的接收者。如果d<=0會(huì)panic。關(guān)閉該Ticker可以釋放相關(guān)資源。
func (t *Ticker) Stop()
Stop關(guān)閉一個(gè)Ticker。在關(guān)閉后,將不會(huì)發(fā)送更多的tick信息。Stop不會(huì)關(guān)閉通道t.C,以避免從該通道的讀取不正確的成功。
使用:
package main
import (
"fmt"
"time"
)
func main() {
ticker := time.NewTicker(1 * time.Second)
a := 10
for {
<-ticker.C
fmt.Println("a:", a)
a--
if a == 0 {
ticker.Stop()
break
}
}
}
輸出;
i: 10
i: 9
i: 8
i: 7
i: 6
i: 5
i: 4
i: 3
i: 2
i: 1
可見,程序中,每隔設(shè)置的1s時(shí)間就觸發(fā)一次定時(shí)器,并且向自帶的channel C中傳遞當(dāng)時(shí)時(shí)間。
到此這篇關(guān)于go語言中Timer和Ticker兩種計(jì)時(shí)器的使用的文章就介紹到這了,更多相關(guān)go語言 Timer和Ticker內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
golang DNS服務(wù)器的簡(jiǎn)單實(shí)現(xiàn)操作
這篇文章主要介紹了golang DNS服務(wù)器的簡(jiǎn)單實(shí)現(xiàn)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-04-04
Golang并發(fā)繞不開的重要組件之Channel詳解
Channel是一個(gè)提供可接收和發(fā)送特定類型值的用于并發(fā)函數(shù)通信的數(shù)據(jù)類型,也是Golang并發(fā)繞不開的重要組件之一,本文就來和大家深入聊聊Channel的相關(guān)知識(shí)吧2023-06-06

