1.time.Sleep方法
for {
time.Sleep(3 * time.Second)
thisTime := time.Now().Format("2006-01-02 15:04:05")
fmt.Printf("我在定時執(zhí)行任務(wù)time=%s\n", thisTime)
}
2.time.Tick函數(shù):
t1 := time.Tick(3 * time.Second)
for {
select {
case <-t1:
thisTime := time.Now().Format("2006-01-02 15:04:05")
fmt.Printf("t1定時器time=%s\n", thisTime)
}
}
3.
var wg sync.WaitGroup
wg.Add(2)
//NewTimer 創(chuàng)建一個 Timer,它會在最少過去時間段 d 后到期状婶,向其自身的 C 字段發(fā)送當(dāng)時的時間
timer1 := time.NewTimer(2 * time.Second)
//NewTicker 返回一個新的 Ticker,該 Ticker 包含一個通道字段,并會每隔時間段 d 就向該通道發(fā)送當(dāng)時的時間旋廷。它會調(diào)
//整時間間隔或者丟棄 tick 信息以適應(yīng)反應(yīng)慢的接收者。如果d <= 0會觸發(fā)panic礼搁。關(guān)閉該 Ticker 可
//以釋放相關(guān)資源饶碘。
ticker1 := time.NewTicker(2 * time.Second)
go func(t *time.Ticker) {
defer wg.Done()
for {
<-t.C
fmt.Printf("what is %v", t.C)
fmt.Println("get ticker1", time.Now().Format("2006-01-02 15:04:05"))
}
}(ticker1)
go func(t *time.Timer) {
defer wg.Done()
for {
<-t.C
fmt.Println("get timer", time.Now().Format("2006-01-02 15:04:05"))
//Reset 使 t 重新開始計(jì)時,(本方法返回后再)等待時間段 d 過去后到期馒吴。如果調(diào)用時t
//還在等待中會返回真扎运;如果 t已經(jīng)到期或者被停止了會返回假瑟曲。
t.Reset(2 * time.Second)
}
}(timer1)
wg.Wait()
Tick,Sleep豪治,包括time.After函數(shù)洞拨,都使用的timer結(jié)構(gòu)體,都會被放在同一個協(xié)程中統(tǒng)一處理负拟,這樣看起來使用Tick烦衣,Sleep并沒有什么區(qū)別。實(shí)際上是有區(qū)別的掩浙,Sleep是使用睡眠完成定時任務(wù)花吟,需要被調(diào)度喚醒。Tick函數(shù)是使用channel阻塞當(dāng)前協(xié)程厨姚,完成定時任務(wù)的執(zhí)行衅澈。當(dāng)前并不清楚golang 阻塞和睡眠對資源的消耗會有什么區(qū)別,這方面不能給出建議谬墙。但是使用channel阻塞協(xié)程完成定時任務(wù)比較靈活矾麻,可以結(jié)合select設(shè)置超時時間以及默認(rèn)執(zhí)行方法,而且可以設(shè)置timer的主動關(guān)閉芭梯,以及不需要每次都生成一個timer(這方面節(jié)省系統(tǒng)內(nèi)存险耀,垃圾收回也需要時間)。所以玖喘,建議使用time.Tick完成定時任務(wù)甩牺。
time.after要比time.tick節(jié)省內(nèi)存