go Ticker使用

简介

Ticker是周期性定时器,即周期性的触发一个事件,通过Ticker本身提供的管道将事件传递出去。

数据结构

type Ticker struct {
	C <-chan Time
	r runtimeTimer
}

接口

  • 使用time.NewTicker()来创建一个定时器;
  • 使用Stop()来停止一个定时器;
  • 定时器使用完毕要释放,否则会产生资源泄露;

创建

使用NewTicker方法就可以创建一个周期性定时器,其中参数d即为定时器事件触发的周期。

func NewTicker(d Duration) *Ticker

停止

使用定时器对外暴露的Stop方法就可以停掉一个周期性定时器

func (t *Ticker) Stop()

使用场景

定时任务

有时,我们希望定时执行一个任务,这时就可以使用ticker来完成。

// TickerDemo 用于演示ticker基础用法
func TickerDemo() {
    ticker := time.NewTicker(1 * time.Second)
    defer ticker.Stop()
 
    for range ticker.C {
        log.Println("Ticker tick.")
    }
}

for range ticker.C会持续从管道中获取事件,收到事件后打印一行日志,如果管道中没有数据会阻塞等待事件,由于ticker会周期性的向管道中写入事件,所以上述程序会周期性的打印日志。

定时聚合任务

我们希望把一些任务打包进行批量处理。比如,公交车发车场景:

  • 公交车每隔5分钟发一班,不管是否已坐满乘客;
  • 已坐满乘客情况下,不足5分钟也发车;
// TickerLaunch用于演示ticker聚合任务用法
func TickerLaunch() {
    ticker := time.NewTicker(5 * time.Minute)
    maxPassenger := 30                   // 每车最大装载人数
    passengers := make([]string, 0, maxPassenger)
 
    for {
        passenger := GetNewPassenger() // 获取一个新乘客
        if passenger != "" {
            passengers = append(passengers, passenger)
        } else {
            time.Sleep(1 * time.Second)
        }
 
        select {
        case <- ticker.C:               // 时间到,发车
            Launch(passengers)
            passengers = []string{}
        default:
            if len(passengers) >= maxPassenger {  // 时间没到,车已座满,发车
                Launch(passengers)
                passengers = []string{}
            }
        }
    }
}

for循环负责接待乘客上车,并决定是否要发车。每当乘客上车,select语句会先判断ticker.C中是否有数据,有数据则代表发车时间已到,如果没有数据,则判断车是否已坐满,坐满后仍然发车。

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×