Skip to content

定时器与计时器 ​

在Go语言中,定时器和计时器都出自 time 包:定时器(time.Timer)管单次延迟,计时器(time.Ticker)管周期重复。名字相近,用途不同。

1. 定时器(Timer) ​

time.Timer 是 Go 的 time 包中的一个类型,用于在指定的时间后执行一次操作。它用于设置一个单次延迟。

  • 主要功能:

    • 延迟执行一次操作
    • 等待指定的时间间隔后触发事件
  • 创建定时器: time.NewTimer 函数用于创建一个新的定时器,定时器将在指定的时间间隔后触发。

  • 主要方法:

    • Stop():停止定时器。如果定时器还未触发,调用此方法将取消其触发。
    • Reset(d time.Duration):重置定时器,将其间隔时间设置为新的值。
  • 示例代码:

    go
    package main
    
    import (
        "fmt"
        "time"
    )
    
    func main() {
        // 创建一个定时器
        timer := time.NewTimer(2 * time.Second)
    
        // 等待定时器触发
        <-timer.C
        fmt.Println("定时器触发了")
    
        // 创建一个定时器并立即停止
        timer2 := time.NewTimer(1 * time.Second)
        timer2.Stop() // 立即停止定时器
    
        // 尝试接收定时器的触发信号
        select {
        case <-timer2.C:
            fmt.Println("定时器2触发了")
        default:
            fmt.Println("定时器2被停止了")
        }
    }

2. 计时器(Ticker) ​

time.Ticker 是 Go 的 time 包中的一个类型,用于周期性地执行操作。它在指定的时间间隔内重复触发事件,适合用于需要重复执行某个任务的场景。

  • 主要功能:

    • 按指定时间间隔重复触发操作
    • 可以用于定时任务和周期性事件
  • 创建计时器: time.NewTicker 函数用于创建一个新的计时器,计时器会在指定的时间间隔内重复触发。

  • 主要方法:

    • Stop():停止计时器,取消其后续触发事件。
  • 示例代码:

    go
    package main
    
    import (
        "fmt"
        "time"
    )
    
    func main() {
        // 创建一个计时器,每秒触发一次
        ticker := time.NewTicker(1 * time.Second)
        quit := make(chan struct{})
    
        go func() {
            for {
                select {
                case t := <-ticker.C:
                    fmt.Println("计时器触发时间:", t)
                case <-quit:
                    ticker.Stop()
                    return
                }
            }
        }()
    
        // 运行 5 秒钟后停止计时器
        time.Sleep(5 * time.Second)
        quit <- struct{}{}
        fmt.Println("计时器停止了")
    }

3. 定时器与计时器的区别 ​

  • 触发方式:

    • 定时器:只触发一次,在指定时间后执行操作。
    • 计时器:周期性地触发,按指定时间间隔重复执行操作。
  • 使用场景:

    • 定时器:适用于一次性任务,例如延迟执行某个操作。
    • 计时器:适用于周期性任务,例如定时刷新状态、定时轮询等。
  • 实现机制:

    • 定时器:通过 <-time.Timer.C 接收一次性触发信号。
    • 计时器:通过 <-time.Ticker.C 接收周期性触发信号,并通过 Stop() 停止触发。

4. 实际应用场景 ​

  • 定时器:

    • 延迟执行任务:例如,在请求超时后进行重试。
    • 延迟消息发送:例如,发送确认邮件的延迟。
  • 计时器:

    • 定时任务:例如,定期检查服务状态。
    • 周期性事件:例如,定时更新应用的用户界面或数据。

总结 ​

选哪个看节奏:等一次的用 Timer,到点从 <-timer.C 取信号,不想要了就 Stop();按固定间隔重复的用 Ticker,用完同样要 Stop(),否则事件会一直发。超时重试归 Timer,定时轮询、状态刷新归 Ticker。

参考资料 ​

同层页面 ​

相关页面 ​

Hello Golang