定时器
定时器指的是设定一个时间去做xx事,大体上分为两种:
- 设定多少时间后,执行xx事,一次性的。
- 设定一个间隔时间,循环的提醒做xx事,循环的多次的。
定时器非常有用,可以用于延时任务、定时执行任务、设置任务超时,定时打印日志等等。
下面我们来一起看下。
1. 一次性提醒(Timer)
a. 最简单的xx时间后提醒
package main
import (
"log"
"time"
)
func main() {
log.Printf("starting logging")
// 返回的事一个通道 2后会有值进来 这里阻塞2s
<-time.After(2 * time.Second)
log.Printf("2s 到啦!")
}
// 2023/11/16 21:19:15 starting logging
// 2023/11/16 21:19:17 2s 到啦!
b. 设置超时
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int) // 初始化一个通道用于做任务
// 做任务
go DoTask(ch)
select {
case <-ch:
fmt.Println("任务顺利完成")
case <-time.After(2 * time.Second):
fmt.Println("超时啦!")
}
}
// 做任务
func DoTask(ch chan<- int) {
// 模拟耗时
time.Sleep(3 * time.Second)
ch <- 1
}
c.延时函数
package main
import (
"fmt"
"time"
)
func main() {
// 异步执行 延时多久后执行 函数
time.AfterFunc(2*time.Second, func() {
fmt.Printf("延时函数执行啦!")
})
// 给定一定时间 让它执行
time.Sleep(3 * time.Second)
}
d. 一次定时器
time.NewTimer
返回定时器,它有一个C
通道,在到时间后会有值弹出,在这之前可以Stop
取消定时器;
在定时触发后,可以通过Reset
重新设置定时时间;
通常用于构建复杂的定时场景。
package main
import (
"log"
"time"
)
func main() {
log.Printf("开始啦")
timer := time.NewTimer(3 * time.Second)
<-timer.C
log.Printf("首次设置的3s到啦")
timer.Reset(time.Second) // 再次1s的定时器
<-timer.C
log.Printf("再次设置的1s到啦")
timer.Reset(2 * time.Second) // 再再此设置定时器
if !timer.Stop() { // 取消定时 取消有可能不成功
<-timer.C // 取消不会close通道 因此如果stop成功后调用 timer.C会报deadLock
}
log.Printf("由于取消了,所以这里立马执行")
}
// 2023/11/16 21:46:20 开始啦
// 2023/11/16 21:46:23 首次设置的3s到啦
// 2023/11/16 21:46:24 再次设置的1s到啦
// 2023/11/16 21:46:24 由于取消了,所以这里立马执行
2. 循环多次提醒(Ticker)
很容易理解,它的主要特点就是定时提醒;需要注意的是一定要记得Stop
它,否则有资源泄漏;
package main
import (
"log"
"time"
)
func main() {
// 间隔1s提醒 它的时间提醒通道也是C
tick := time.NewTicker(time.Second)
defer tick.Stop() // 保证资源释放
i := 0
for {
i++
<-tick.C // 间隔1s有值弹出
log.Printf("第%d次打印日志", i)
}
}
// 2023/11/16 21:57:21 第1次打印日志
// 2023/11/16 21:57:22 第2次打印日志
// 2023/11/16 21:57:23 第3次打印日志
// 2023/11/16 21:57:24 第4次打印日志
// 2023/11/16 21:57:25 第5次打印日志
// 2023/11/16 21:57:26 第6次打印日志
网友评论