go语言设置定时器的方法:1、通过“time.NewTicker()”方法创建,其中ticker会按照设定的间隔时间触发;2、通过“time.NewTimer()”方法创建,其中timer只会执行一词;3、使用“After()”来创建。

本文环境:Windows7系统、Go1.11.2版,本文适用于所有品牌的电脑。

推荐:《golang教程

Go语言中定时器的使用

GO语言在time包中提供了三种定时器的使用方式:

1.第一种:ticker

// A Ticker holds a channel that delivers `ticks' of a clock// at intervals.type Ticker struct {C <-chan Time // The channel on which the ticks are delivered.r runtimeTimer}

通过 time.NewTicker() 创建,这种类型,ticker会不断的按照设定的间隔时间触发,除非主动终止运行。

2.第二种:timer

// The Timer type represents a single event.// When the Timer expires, the current time will be sent on C,// unless the Timer was created by AfterFunc.// A Timer must be created with NewTimer or AfterFunc.type Timer struct {C <-chan Timer runtimeTimer}

通过 time.NewTimer() 创建,这种类型,timer只会执行一次,当然,可以在执行完以后通过调用 timer.Reset() 让定时器再次工作,并可以更改时间间隔。

3.第三种:After()

// After waits for the duration to elapse and then sends the current time// on the returned channel.// It is equivalent to NewTimer(d).C.// The underlying Timer is not recovered by the garbage collector// until the timer fires. If efficiency is a concern, use NewTimer// instead and call Timer.Stop if the timer is no longer needed.func After(d Duration) <-chan Time {return NewTimer(d).C}

从代码可以看到,After()其实是Timer的一个语法糖。


下面通过代码演示一下三种方式的使用:

1.Ticker

ticker := time.NewTicker(time.Second * 1) // 运行时长    ch := make(chan int)    go func() {        var x int        for x < 10 {            select {            case <-ticker.C:                x++                fmt.Printf("%d\n", x)            }        }        ticker.Stop()        ch <- 0    }()    <-ch                                    // 通过通道阻塞,让任务可以执行完指定的次数。

该ticker每1秒触发一次,即ticker.C中每一秒会有一个内容加入,最后通过向ch中写入数字,让程序解除阻塞,继续执行。

2.Timer

timer := time.NewTimer(time.Second * 1) // timer 只能按时触发一次,可通过Reset()重置后继续触发。    go func() {        var x int        for {            select {            case <-timer.C:                x++                fmt.Printf("%d,%s\n", x, time.Now().Format("2006-01-02 15:04:05"))                if x < 10 {                    timer.Reset(time.Second * 2)                } else {                    ch <- x                }            }        }    }()    <-ch

3.After()

// 阻塞一下,等待主进程结束    tt := time.NewTimer(time.Second * 10)    <-tt.C    fmt.Println("over.")    <-time.After(time.Second * 4)    fmt.Println("再等待4秒退出。tt 没有终止,打印出 over 后会看见在继续执行...")    tt.Stop()    <-time.After(time.Second * 2)    fmt.Println("tt.Stop()后, tt 仍继续执行,只是关闭了 tt.C 通道。")

4.我们可以利用这些基本的方法,设计自己的定时任务管理。

type jobFunc2 func(j *job)type job struct {    jf     jobFunc2    params map[string]interface{}    ch     chan int}func NewJob() *job {    return &job{        params: make(map[string]interface{}),        ch:     make(chan int),    }}func (j *job) Run(t time.Duration) {    ticker := time.NewTicker(time.Second * t)    go func() {        for {            select {            case <-ticker.C:                j.jf(j)            case <-j.ch:                fmt.Println("收到结束指令")                ticker.Stop()                break            }        }    }()}func main() {    j := NewJob()    j.jf = func(jj *job) {        fmt.Println("定时任务执行...", time.Now().Format("15:04:05 2006-02-01"), jj.params)    }    j.params["p1"] = "第一个参数"    j.params["p2"] = 100    j.Run(1)    // 阻塞一下,等待主进程结束    tt := time.NewTimer(time.Second * 10)    <-tt.C    fmt.Println("over.")    <-time.After(time.Second * 4)    fmt.Println("再等待4秒退出。tt 没有终止,打印出 over 后会看见在继续执行...")    tt.Stop()    <-time.After(time.Second * 2)    fmt.Println("tt.Stop()后, tt 仍继续执行,只是关闭了 tt.C 通道。")}

部分执行结果截图:

最后补充一下,通过channel去终止任务的执行。

// 阻塞一下,等待主进程结束    tt := time.NewTimer(time.Second * 10)    <-tt.C    fmt.Println("over.")    <-time.After(time.Second * 4)    fmt.Println("再等待4秒退出。tt 没有终止,打印出 over 后会看见在继续执行...")    tt.Stop()    <-time.After(time.Second * 2)    fmt.Println("tt.Stop()后, tt 仍继续执行,只是关闭了 tt.C 通道。")    j.ch <- 0    <-time.After(time.Second * 2)    fmt.Println("又等了2秒钟...这两秒钟可以看到 tt 没干活了...")


在GO语言编写中,要熟练使用 channel

更多相关文章

  1. 摄像机通道号对接
  2. PHP多任务秒级定时器的实现方法
  3. 原理暂且不谈,定时器你当真会用?
  4. java任务调度(1)Timer定时器(案例和源码分析)
  5. Jquery---定时器(实现页面内定时弹出广告,定时退出)
  6. thinkphp5使用workerman定时器定时爬取某站点新闻资讯等内容
  7. 原生JavaScript利用setInterval的一个简单开始暂停的定时器
  8. 我需要一个django-芹菜守护进程来监听特定的rabbitmq通道
  9. Linux下的微秒级定时器: usleep, nanosleep, select, pselect

随机推荐

  1. golang最适合做什么项目
  2. golang如何编译
  3. golang导出csv乱码解决方法
  4. golang 乱码怎么解决
  5. golang判断字符串是否为空的方法
  6. golang怎么生成随机数
  7. golang 开源吗
  8. golang判断字符串是否数字的方法
  9. golang数组和切片的区别是什么
  10. golang用什么ide