GoLang之并发编程-定时器

GoLang之并发编程-定时器

1.time包

1.1Timer结构体

Timer结构体

Timer类型代表单次时间事件。当Timer到期时,当时的时间会被发送给C,除非Timer是被AfterFunc函数创建的。

type Timer struct {
    C <-chan Time
    // 内含隐藏或非导出字段
}
Reset方法

Reset使t重新开始计时,(本方法返回后再)等待时间段d过去后到期。如果调用时t还在等待中会返回真;如果t已经到期或者被停止了会返回假。

func (t *Timer) Reset(d Duration) bool
Stop方法

Stop停止Timer的执行。如果停止了t会返回真;如果t已经被停止或者过期了会返回假。Stop不会关闭通道t.C,以避免从该通道的读取不正确的成功。

func (t *Timer) Stop() bool

1.2NewTimer函数

NewTimer创建一个Timer,它会在最少过去时间段d后到期,向其自身的C字段发送当时的时间。

func NewTimer(d Duration) *Timer

1.3AfterFunc函数

AfterFunc另起一个go程等待时间段d过去,然后调用f。它返回一个Timer,可以通过调用其Stop方法来取消等待和对f的调用。

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

1.4Tricker结构体

Tricker结构体

Ticker保管一个通道,并每隔一段时间向其传递"tick"。

type Ticker struct {
    C <-chan Time // 周期性传递时间信息的通道
    // 内含隐藏或非导出字段
}
Stop方法

Stop关闭一个Ticker。在关闭后,将不会发送更多的tick信息。Stop不会关闭通道t.C,以避免从该通道的读取不正确的成功。

func (t *Ticker) Stop()

1.5NewTicker函数

NewTicker返回一个新的Ticker,该Ticker包含一个通道字段,并会每隔时间段d就向该通道发送当时的时间。它会调整时间间隔或者丢弃tick信息以适应反应慢的接收者。如果d<=0会panic。关闭该Ticker可以释放相关资源。

func NewTicker(d Duration) *Ticker

1.6Sleep函数

Sleep阻塞当前go程至少d代表的时间段。d<=0时,Sleep会立刻返回。

func Sleep(d Duration)

1.7After函数

After会在另一线程经过时间段d后向返回值发送当时的时间。等价于NewTimer(d).C。

func After(d Duration) <-chan Time

1.8Tick函数

Tick是NewTicker的封装,只提供对Ticker的通道的访问。如果不需要关闭Ticker,本函数就很方便。

func Tick(d Duration) <-chan Time

2.timer

2.1timer介绍

Timer:时间到了,执行只执行1次

2.2timer基本使用

func main() {
	// 1.timer基本使用
	timer1 := time.NewTimer(2 * time.Second)
	t1 := time.Now()
	fmt.Printf("t1:%v\n", t1) //t1:2022-06-14 20:00:31.647493 +0800 CST m=+0.024507301
	t2 := <-timer1.C
	fmt.Printf("t2:%v\n", t2) //t2:2022-06-14 20:00:33.647838 +0800 CST m=+2.024852301
}
func main() {
	// 1.timer基本使用
	timer1 := time.NewTimer(2 * time.Second)
	t1 := time.Now()
	fmt.Printf("t1:%v\n", t1)
	t2 := <-timer1.C
	fmt.Printf("t2:%v\n", t2)
	t3 := <-timer1.C
	fmt.Printf("t2:%v\n", t3)
	/*报错:
	t1:2022-06-14 20:17:43.8529544 +0800 CST m=+0.018502801
	t2:2022-06-14 20:17:45.8533066 +0800 CST m=+2.018855001
	fatal error: all goroutines are asleep - deadlock!

	goroutine 1 [chan receive]:
	main.main()
	        D:/all project/go/try/main.go:15 +0x169
	*/
}

2.3验证timer只能响应1次

func main() {
     // 2.验证timer只能响应1次
	timer2 := time.NewTimer(time.Second)
	for {
		<-timer2.C
		fmt.Println("时间到")
	}

	/*报错
	时间到
	fatal error: all goroutines are asleep - deadlock!

	goroutine 1 [chan receive]:
	main.main()
	        D:/all project/go/try/main.go:11 +0x30
	*/
}

2.4timer实现延时的功能

func main() {
	// 3.timer实现延时的功能
	//(1)
	time.Sleep(time.Second)

	//(2)
	timer3 := time.NewTimer(2 * time.Second)
	<-timer3.C
	fmt.Println("2秒到") //停顿3秒后输出

	//(3)
	<-time.After(2 * time.Second)
	fmt.Println("2秒到") //停顿两秒后输出
}
func main() {
	fmt.Println(time.Now()) //2022-06-14 20:29:16.1361797 +0800 CST m=+0.020503701
	time.Sleep(time.Second)
	fmt.Println(time.Now()) //2022-06-14 20:29:17.2873802 +0800 CST m=+1.171704201

	timer3 := time.NewTimer(2 * time.Second)
	<-timer3.C
	fmt.Println("2秒到")      //与一开始相差三秒
	fmt.Println(time.Now()) //2022-06-14 20:29:19.2877282 +0800 CST m=+3.172052201

	<-time.After(2 * time.Second)
	fmt.Println("2秒到")      //与上次相差两秒
	fmt.Println(time.Now()) //2022-06-14 20:29:21.2881651 +0800 CST m=+5.172489101
}
func main() {
	fmt.Println(time.Now()) //2022-06-14 20:26:40.570837 +0800 CST m=+0.031505001
	timer3 := time.NewTimer(2 * time.Second)
	<-timer3.C
	fmt.Println("2秒到")      //停顿两秒后输出
	fmt.Println(time.Now()) //2022-06-14 20:26:42.7248238 +0800 CST m=+2.185491801

	<-time.After(2 * time.Second)
	fmt.Println("2秒到")      //停顿两秒后输出
	fmt.Println(time.Now()) //022-06-14 20:26:44.7251656 +0800 CST m=+4.185833601
}

2.5停止定时器

func main() {
	// 4.停止定时器
	timer4 := time.NewTimer(2 * time.Second)
	go func() {
		<-timer4.C
		fmt.Println("定时器执行了")
	}()
	b := timer4.Stop()
	if b {
		fmt.Println("timer4已经关闭")
	}

	/*无论运行多少次,都输出以下
	timer4已经关闭
	*/
}

2.6重置定时器

func main() {
    // 5.重置定时器
	timer5 := time.NewTimer(3 * time.Second)
	timer5.Reset(1 * time.Second)
	fmt.Println(time.Now()) //2022-06-14 20:35:28.5337057 +0800 CST m=+0.029004901
	//以下会停顿会再输出
	fmt.Println(<-timer5.C) //2022-06-14 20:35:29.5338784 +0800 CST m=+1.029177601
	fmt.Println(time.Now()) //2022-06-14 20:35:29.5339321 +0800 CST m=+1.029231301
}

3.Ticker

3.1Ticker介绍

Ticker:时间到了,多次执行

3.2获取ticker对象

func main() {
	// 1.获取ticker对象
	ticker := time.NewTicker(1 * time.Second)
	i := 0
	// 子协程
	go func() {
		for {
			//<-ticker.C
			i++
			fmt.Println(<-ticker.C)
			if i == 5 {
				//停止
				ticker.Stop()
			}
		}
	}()
	for {

	}
	/*
			2022-06-14 20:42:28.3611397 +0800 CST m=+1.026178101
			2022-06-14 20:42:29.3613138 +0800 CST m=+2.026352201
			2022-06-14 20:42:30.3614882 +0800 CST m=+3.026526601
			2022-06-14 20:42:31.3616619 +0800 CST m=+4.026700301
			2022-06-14 20:42:32.3618361 +0800 CST m=+5.026874501
		    然后一直卡在这里
	*/
}

func main() {
	ticker := time.NewTicker(1 * time.Second)
	i := 0
	go func() {
		for {
			<-ticker.C
			i++
			fmt.Println(<-ticker.C)
			if i == 5 {
				ticker.Stop()
			}
		}
	}()
	for {

	}
	/*
		    2022-06-14 20:43:48.5040865 +0800 CST m=+2.018350901
			2022-06-14 20:43:50.5034351 +0800 CST m=+4.017699501
			2022-06-14 20:43:52.5032825 +0800 CST m=+6.017546901
			2022-06-14 20:43:54.5046309 +0800 CST m=+8.018895301
			2022-06-14 20:43:56.5039791 +0800 CST m=+10.018243501
					    然后一直卡在这里
	*/
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GoGo在努力

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值