很多人喜欢Go语言,其实是因为Go语言有其独特的语言属性在支撑着其在编程语言界的发展,今天兄弟连Go语言+区块链培训老师给大家介绍一下关于Go语言并发技术3:定时器,下面我们一起来看一下吧。
定时器概述
· Go为我们提供了两种不同方式的计时器:
· 定时执行任务的计时器
· 周期性执行任务的计时器
固定时间定时器
下面的例子演示了如何使用定时器延时2秒执行一项任务
func main() {
//创建2秒的定时器
timer := time.NewTimer(2*time.Second)
//当前时间: 2018-09-25 19:17:16.8050379 +0800 CST m=+0.004010601
fmt.Println("当前时间:", time.Now())
//2秒后,从单向时间管道中读出内容(当前时间)
//timer.C是一个单向的时间管道
t := <-timer.C
//t = 2018-09-25 19:17:18.8051013 +0800 CST m=+2.004074101
fmt.Println("t = ", t)
}
上面的例子还可以写作
func main() {
fmt.Println("开始计时")
//创建2秒的定时器,得到其单向输出时间管道,阻塞2秒后读出时间数据
<- time.After(2 * time.Second)
fmt.Println("时间到")
}
提前终止计时器
下面的例子中,计时器被中途stop掉了,被延时的协程将永远得不到执行
func main() {
//创建3秒的定时器,3秒
timer := time.NewTimer(3 * time.Second)
//3秒后从定时器时间管道中读取时间
//这里子协程永远得不到执行,因为后面的代码会停掉这个计时器
go func() {
<-timer.C
fmt.Println("子协程可以打印了,因为定时器的时间到了")
}()
//停止定时器,停止状态下,计时器失效,被timer.C所阻塞的协程永远读不出数据
timer.Stop()
//主协程为子协程留出足够的执行时间
time.Sleep(6*time.Second)
fmt.Println("GAME OVER")
}
中途重置定时器
· 下面的例子中,timer在配置为延时10秒执行后,又被重置为1秒,所以其实际延时1秒
· 需要注意的是,如果在reset的一刹那,定时器已经到时或者已被stop掉,则reset是无效的
func main() {
//创建3秒的定时器
timer := time.NewTimer(10 * time.Second)
//重置为1秒
//如果已经到时,或者已经Stop掉,则重置失败
ok := timer.Reset(1 * time.Second)
fmt.Println("ok = ", ok, time.Now())
//1秒后即可读出时间
t := <-timer.C
fmt.Println("时间到", t)
}
周期性执行的定时器
下面的例子将每隔一秒输出一次当前时间,5次后程序结束
func main() {
//创建1秒的秒表
ticker := time.NewTicker(1 * time.Second)
//ticker := mytime.NewTimer(1 * mytime.Second)
i := 0
for {
//从秒表的管道中读出时间
t := <-ticker.C
i++
fmt.Println("i = ", i, t)
//停止秒表
if i == 5 {
ticker.Stop()
break
}
}
fmt.Println("Game Over")
}
本篇文章出自兄弟连区块链培训教程:更多区块链视频教程/源码/课件/学习资料-企鹅QUN:591-229-276
定时器概述
· Go为我们提供了两种不同方式的计时器:
· 定时执行任务的计时器
· 周期性执行任务的计时器
固定时间定时器
下面的例子演示了如何使用定时器延时2秒执行一项任务
func main() {
//创建2秒的定时器
timer := time.NewTimer(2*time.Second)
//当前时间: 2018-09-25 19:17:16.8050379 +0800 CST m=+0.004010601
fmt.Println("当前时间:", time.Now())
//2秒后,从单向时间管道中读出内容(当前时间)
//timer.C是一个单向的时间管道
t := <-timer.C
//t = 2018-09-25 19:17:18.8051013 +0800 CST m=+2.004074101
fmt.Println("t = ", t)
}
上面的例子还可以写作
func main() {
fmt.Println("开始计时")
//创建2秒的定时器,得到其单向输出时间管道,阻塞2秒后读出时间数据
<- time.After(2 * time.Second)
fmt.Println("时间到")
}
提前终止计时器
下面的例子中,计时器被中途stop掉了,被延时的协程将永远得不到执行
func main() {
//创建3秒的定时器,3秒
timer := time.NewTimer(3 * time.Second)
//3秒后从定时器时间管道中读取时间
//这里子协程永远得不到执行,因为后面的代码会停掉这个计时器
go func() {
<-timer.C
fmt.Println("子协程可以打印了,因为定时器的时间到了")
}()
//停止定时器,停止状态下,计时器失效,被timer.C所阻塞的协程永远读不出数据
timer.Stop()
//主协程为子协程留出足够的执行时间
time.Sleep(6*time.Second)
fmt.Println("GAME OVER")
}
中途重置定时器
· 下面的例子中,timer在配置为延时10秒执行后,又被重置为1秒,所以其实际延时1秒
· 需要注意的是,如果在reset的一刹那,定时器已经到时或者已被stop掉,则reset是无效的
func main() {
//创建3秒的定时器
timer := time.NewTimer(10 * time.Second)
//重置为1秒
//如果已经到时,或者已经Stop掉,则重置失败
ok := timer.Reset(1 * time.Second)
fmt.Println("ok = ", ok, time.Now())
//1秒后即可读出时间
t := <-timer.C
fmt.Println("时间到", t)
}
周期性执行的定时器
下面的例子将每隔一秒输出一次当前时间,5次后程序结束
func main() {
//创建1秒的秒表
ticker := time.NewTicker(1 * time.Second)
//ticker := mytime.NewTimer(1 * mytime.Second)
i := 0
for {
//从秒表的管道中读出时间
t := <-ticker.C
i++
fmt.Println("i = ", i, t)
//停止秒表
if i == 5 {
ticker.Stop()
break
}
}
fmt.Println("Game Over")
}
本篇文章出自兄弟连区块链培训教程:更多区块链视频教程/源码/课件/学习资料-企鹅QUN:591-229-276