Go语言基础之定时器!

Go提供了两种方式的计时器:

  • 定时执行任务的计时器和周期性执行任务的计时器。

固定时间定时器

1
2
3
4
5
6
7
8
9
10
11
12
func main() {
// 创建两秒的定时器
timer := time.NewTimer(2 * time.Second)
fmt.Println("当前时间:", time.Now())
//当前时间: 2020-05-13 09:12:41.0018223 +0800 CST m=+0.006835901

//两秒后,从单向时间管道中读取内容(当前时间)
// timer.C是一个单向的时间管道
t := <- timer.C
fmt.Println("t = ",t)
// t = 2020-05-13 09:12:43.0313903 +0800 CST m=+2.006835901
}

上面的示例演示了如何使用定时器延时两秒执行一项任务。

上面的示例也可以写成下面的形式。

1
2
3
4
5
6
func main() {
fmt.Println("开始计时")
// 创建2秒的定时器,得到其单向输出时间管道,阻塞两秒后读出数据
<- time.After(2 * time.Second)
fmt.Println("时间到")
}

提前终止计时器

计时器被中途stop掉了,被延时的goroutine将永远得不到执行,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
func main() {
// 创建3秒的定时器
timer := time.NewTimer(3*time.Second)
// 3秒后从定时器时间管道中读取时间
go func(){
<- timer.C
fmt.Println("子goroutine可以打印了,因为定时器的时间到了")
}()

// 停止定时器,停止状态下,计时器失效,被timer.C锁阻塞的子goroutine永远读不出数据
timer.Stop()

// 主goroutien为子goroutine留出足够的时间
time.Sleep(6*time.Second)
fmt.Println("Game Over")
}

中途重置定时器

下面的例子中,timer在配置为延时10秒执行后

  • 又被重置为1秒,所以其时间延时为一秒。

需要注意的是:

如果在reset的一刹那,定时器已经到时或者已被stop掉,则reset是无效的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
func main() {
// 创建10秒的定时器
timer := time.NewTimer(10 * time.Second)

// 重置为1秒
// 如果已经到时,或者已经stop,则重置失败
ok := timer.Reset(1 * time.Second)
fmt.Println("OK = ", ok, time.Now())
// OK = true 2020-05-13 09:43:12.0831215 +0800 CST m=+0.073242201


// 1秒后即可读出时间
t := <- timer.C
fmt.Println("时间到", t)
// 时间到 2020-05-13 09:43:13.121344 +0800 CST m=+1.074218801
}