golang中的定时器

定时器

定时器指的是设定一个时间去做xx事,大体上分为两种:

  1. 设定多少时间后,执行xx事,一次性的。
  2. 设定一个间隔时间,循环的提醒做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次打印日志
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容