Golang-定时器和断续器

Golang-定时器和断续器

个人博客网站:** https://www.sakurasss.top ( 最近打算把个人博客里的那些文章也慢慢移过来吧 )

1. 基本介绍

Timer&Ticker是 Go 标准包 time 中定义的类型,通过 Channel 与程序进行通信

// 定时器
time.Timer
// 断续器
time.Ticker

定时器 Timer 类似于一次性闹钟
断续器 Ticker 类似于重复性闹钟,也称为循环定时器

应用场景 : 定时任务 , 程序每隔多长时间执行一次 , 程序某个时间点开始结束

2. 定时器

使用语法

// time.NewTimer
func NewTimer(d Duration) *Timer

创建定时器 , 参数是 Duration 时间。返回为 *Timer。*Timer.C是用来接收到期通知的单向 Channel

type Timer struct {
    C <-chan Time
}

只要能从*Timer.c上接收数据 , 就意味着定时器到时了 , 接收到的元素是time.Time 类型的数据 , 为到时时间

2.1 定时器典型使用

func TimerAA() {
	// 创建定时器
	t := time.NewTimer(2 * time.Second)
	fmt.Println("定时器开始计时:", time.Now().String())

	end := <-t.C
	fmt.Println("定时器定时结束:", end.String())
}

2.2 定时器停止和重置

// 停止计时器
// 返回值bool类型,返回false,表示该定时器早已经停止,返回true表示由本次调用停止
func (t *Timer) Stop() bool

// 重置定时器
// 返回值bool类型,返回false,表示该定时器早已经停止,返回true表示由本次调用重置
func (t *Timer) Reset(d Duration) bool

注意:
停止和重置是定时器没有结束的时候才能调用的
一旦能从time.C 中拿到内容说明定时器以及结束了 , 此时调用Stop 和Reset没有意义

  • 猜数组游戏 , 一共猜五次 , 每次 3 秒
func TimerStop() {
	// 初始化数组
	ch := make(chan int)

	// 每隔0.4秒猜一次
	go func() {
		for {
			ch <- rand.Intn(10)
			time.Sleep(400 * time.Millisecond)
		}
	}()

	// 每一局时间
	t := time.NewTimer(3 * time.Second)
	// 统计猜中次数和未猜中次数
	GuessYes, GuessNo := 0, 0
	// 五轮猜数字游戏
	for i := 0; i < 5; i++ {
	Guess:
		for {
			select {
			case value := <-ch:
				fmt.Println("猜的数字为: ", value)
				if value == 5 {
					fmt.Println("猜中了数字")
					GuessYes++
					// 重置定时器,开始下一轮游戏
					t.Reset(time.Second * 3)
					break Guess
				}
			case <-t.C:
				fmt.Println("时间结束,没有猜中数字")
				GuessNo++
				// 重新创建定时器
				t = time.NewTimer(3 * time.Second)
				break Guess
			}

		}
	}
	fmt.Println("游戏结束,猜中次数为: ", GuessYes, "失败次数为", GuessNo)
}

2.3 不需要定时器的关闭和重置

func After(d Duration) <-chan Time

返回值是定时器到期的通知 Channel , 不需要从 t.c 中取数据

func TimerChannel() {
	ch := time.After(5 * time.Second)
	fmt.Println("设置定时器: ", time.Now().String())

	now := <-ch
	fmt.Println("定时器结束: ", now.String())
}

2.4 定时器结束执行特定函数

func AfterFunc(d Duration, f func()) *Timer

3. 断续器 ( 循环定时器 )

func NewTicker(d Duration) *Ticker

创建断续器。参数是 Duration 时间。返回为 *Ticker。*Ticker.C是用来接收到期通知的单向 Channel

type Ticker struct {
    C <-chan Time // The channel on which the ticks are delivered.
}

因此我们只要可从 *Ticker.C上接收数据,就意味着断续器时间到。接收到的元素是 time.Time 类型数据,为到时时间。当接收到到期时间后,间隔下一个Duration还会再次接收到到期时间。

// Ticket 方法
// 停止断续器
func (t *Ticker) Stop()
// 重置断续器间隔时间
func (t *Ticker) Reset(d Duration)
  • 模拟定期心跳检测的案例
func TickerHeart() {
	// 断续器,每隔两秒做一次心跳检测
	ticker := time.NewTicker(2 * time.Second)

	// 定时器,表示只执行五次10秒的心跳检测
	// 不用定时器就是一直执行每隔两秒的心跳检测
	timer := time.NewTimer(10 * time.Second)

	loop:
	for now := range ticker.C {
		// 心跳检测
		fmt.Println("心跳检测 , http://domain/ping , ", now.String())

		// 非阻塞读ticker
		select {
		case <-timer.C:
			ticker.Stop()
			fmt.Println("心跳检测结束")
			break loop
		default:
			// 无阻塞的接收操作
		}
	}
}
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值