Sleep函数 time.Sleep(time.Duration)

表示睡多少时间,睡觉时,是阻塞状态

  1. fmt.Println("start sleeping...")
  2. time.Sleep(time.Second)
  3. fmt.Println("end sleep.")
  4. //【结果】打印start sleeping后,等了正好1秒后,打印了end sleep
  5. //会阻塞,Sleep时,什么事情都不会做

定时器执行过程 - 图1

After函数 time.After(time.Duration)

和Sleep差不多,意思是多少时间之后,但在取出管道内容前不阻塞

  1. fmt.Println("the 1")
  2. tc:=time.After(time.Second) //返回一个time.C这个管道,1秒(time.Second)后会在此管道中放入一个时间点(time.Now()) 时间点记录的是放入管道那一刻的时间值
  3. fmt.Println("the 2") //不阻塞
  4. fmt.Println("the 3") //不阻塞
  5. <-tc //阻塞中,直到取出tc管道里的数据
  6. fmt.Println("the 4")
  7. //【结果】立即打印123,等了1秒不到一点点的时间,打印了4,结束
  8. //打印the 1后,获得了一个空管道,这个管道1秒后会有数据进来
  9. //打印the 2,(这里可以做更多事情)
  10. //打印the 3
  11. //等待,直到可以取出管道的数据(取出数据的时间与获得tc管道的时间正好差1秒钟)
  12. //打印the 4

定时器执行过程 - 图2

  1. fmt.Println("the 1")
  2. tc:=time.After(time.Second * 2) //返回一个time.C这个管道,2秒(time.Second × 2)后会在此管道中放入
  3. //一个时间点(time.Now()),时间点记录的是放入管道那一刻的时间值
  4. fmt.Println("the 2")
  5. fmt.Println("the 3")
  6. time.Sleep(time.Second)//这里是假设这个Println动作执行了半秒钟
  7. fmt.Println("the 4")
  8. time.Sleep(time.Second)//这里是假设这个Println动作执行了半秒钟
  9. fmt.Println("the 5")
  10. fmt.Println("the 6")
  11. fmt.Println("the 7")
  12. <-tc //阻塞中,直到取出tc管道里的数据
  13. fmt.Println("the 8")
  14. //【结果】立即打印1和2和3,等了1秒打印了4,打完后又等了1秒打印了5,然后又立即打印了678,结束
  15. //这里的<-tc是立即能获得数据的
  16. //因为早在执行差不多Print 5的时候,管道内已经有数据了
  17. //当gorotine线把数据丢到管道中后,它自己阻塞了(具体请了解goroutine)

定时器执行过程 - 图3

AfterFunc函数 time.AfterFunc(time.Duration,func())

  1. f := func() {
  2. fmt.Println("Time out")
  3. }
  4. time.AfterFunc(1*time.Second, f)
  5. time.Sleep(2 * time.Second) //要保证主线比子线“死的晚”,否则主线死了,子线也等于死了
  6. //【结果】运行了1秒后,打印出timeout,又过了1秒,程序退出
  7. //将一个间隔和一个函数给AfterFunc后
  8. //间隔时间过后,执行传入的函数

定时器执行过程 - 图4
由于f函数不是在Main Line执行的,而是注册在goroutine Line里执行的
所以一旦后悔的话,需要使用Stop命令来停止即将开始的执行,如果已经开始执行就来不及了

  1. houhui := true
  2. f := func() {
  3. fmt.Println("Time out")
  4. }
  5. ta := time.AfterFunc(2*time.Second, f)
  6. time.Sleep(time.Second)
  7. if houhui {
  8. ta.Stop()
  9. }
  10. time.Sleep(3 * time.Second) //要保证主线比子线“死的晚”,否则主线死了,子线也等于死了
  11. //【结果】运行了3秒多一点点后,程序退出,什么都不打印
  12. //注册了个f函数,打算2秒后执行
  13. //过了1秒后,后悔了,停掉(Stop)它

Tick函数 time.Tick(time.Duration)

  1. fmt.Println("the 1")
  2. tc:=time.Tick(time.Second) //返回一个time.C这个管道,1秒(time.Second)后会在此管道中放入一个时间点,
  3. //1秒后再放一个,一直反复,时间点记录的是放入管道那一刻的时间
  4. for i:=1;i<=2;i++{
  5. <-tc
  6. fmt.Println("hello")
  7. }
  8. //每隔1秒,打印一个hello

定时器执行过程 - 图5