Go 1.23中Timer无buffer的实现方式是怎样的?

文章精选推荐

1 JetBrains Ai assistant 编程工具让你的工作效率翻倍

2 Extra Icons:JetBrains IDE的图标增强神器

3 IDEA插件推荐-SequenceDiagram,自动生成时序图

4 BashSupport Pro 这个ides插件主要是用来干嘛的 ?

5 IDEA必装的插件:Spring Boot Helper的使用与功能特点

6 Ai assistant ,又是一个写代码神器

7 Cursor 设备ID修改器,你的Cursor又可以继续试用了

文章正文

在 Go 1.23 中,Timer 的实现通常是通过 time 包提供的 time.Timer 类型来实现的。Timer 是一个用于在指定时间后触发一次事件的计时器。Timer 的实现并不依赖于缓冲区,而是通过 Go 的调度器和通道机制来实现的。

Timer 的基本实现

Timer 的核心是一个 time.Timer 结构体,它包含一个 time.Timer.C 通道,当计时器到期时,当前时间会被发送到这个通道。

以下是一个简单的 Timer 实现示例:

go 复制代码
package main

import (
	"fmt"
	"time"
)

func main() {
	// 创建一个 Timer,设置 2 秒后触发
	timer := time.NewTimer(2 * time.Second)

	// 等待 Timer 触发
	<-timer.C
	fmt.Println("Timer expired")

	// 如果你想要停止 Timer,可以使用 Stop() 方法
	// timer.Stop()
}

无缓冲区的实现

Timer 的实现并不依赖于缓冲区,而是通过 Go 的通道机制来实现的。Timer.C 是一个无缓冲的通道,当计时器到期时,当前时间会被发送到这个通道。由于通道是无缓冲的,发送操作会阻塞,直到有接收者准备好接收数据。

自定义无缓冲 Timer 实现

如果你想自己实现一个无缓冲的 Timer,可以使用 time.After 函数,它返回一个通道,当指定的时间到达时,通道会接收到一个时间值。

go 复制代码
package main

import (
	"fmt"
	"time"
)

func main() {
	// 使用 time.After 创建一个无缓冲的 Timer
	timerCh := time.After(2 * time.Second)

	// 等待 Timer 触发
	<-timerCh
	fmt.Println("Timer expired")
}

更复杂的 Timer 实现

如果你需要更复杂的 Timer 实现,比如可以重置或停止的 Timer,可以参考以下代码:

go 复制代码
package main

import (
	"fmt"
	"time"
)

type MyTimer struct {
	duration time.Duration
	timer    *time.Timer
	resetCh  chan time.Duration
	stopCh   chan struct{}
}

func NewMyTimer(duration time.Duration) *MyTimer {
	t := &MyTimer{
		duration: duration,
		resetCh:  make(chan time.Duration),
		stopCh:   make(chan struct{}),
	}
	t.timer = time.NewTimer(duration)
	go t.run()
	return t
}

func (t *MyTimer) run() {
	for {
		select {
		case <-t.timer.C:
			fmt.Println("Timer expired")
			return
		case newDuration := <-t.resetCh:
			if !t.timer.Stop() {
				<-t.timer.C
			}
			t.timer.Reset(newDuration)
		case <-t.stopCh:
			if !t.timer.Stop() {
				<-t.timer.C
			}
			return
		}
	}
}

func (t *MyTimer) Reset(duration time.Duration) {
	t.resetCh <- duration
}

func (t *MyTimer) Stop() {
	t.stopCh <- struct{}{}
}

func main() {
	timer := NewMyTimer(2 * time.Second)

	time.Sleep(1 * time.Second)
	timer.Reset(3 * time.Second)

	time.Sleep(2 * time.Second)
	timer.Stop()
	fmt.Println("Timer stopped")
}

在这个示例中,MyTimer 是一个自定义的 Timer 实现,它支持重置和停止操作。MyTimer 使用 time.Timer 作为底层实现,并通过通道来接收重置和停止的信号。

总结

Go 中的 Timer 实现依赖于无缓冲的通道和 Go 的调度器。你可以使用 time.Timertime.After 来创建简单的 Timer,或者通过自定义结构体来实现更复杂的 Timer 功能。

相关推荐
豆浆Whisky6 分钟前
深入剖析Go Channel:从底层原理到高阶避坑指南|Go语言进阶(5)
后端·go
写bug写bug11 分钟前
Lua语言教程:从基础到进阶
后端·lua
normaling13 分钟前
XML配置文件
后端
shepherd11125 分钟前
从零搭建高可用Kafka集群与EFAK监控平台:全流程实战总结
分布式·后端·kafka
_x_w26 分钟前
【12】数据结构之基于线性表的排序算法
开发语言·数据结构·笔记·python·算法·链表·排序算法
有诺千金29 分钟前
深入理解 Spring Boot 的@AutoConfiguration注解
java·spring boot·后端
代码吐槽菌30 分钟前
基于SpringBoot的律师事务所案件管理系统【附源码】
java·数据库·spring boot·后端·毕业设计
不爱学英文的码字机器33 分钟前
Rust 的征服:从系统编程到全栈开发的 IT 新宠
开发语言·后端·rust
flzjkl36 分钟前
【源码】【Java并发】【ReentrantLock】适合中学者体质的ReentrantLock源码阅读
java·后端
Victor35637 分钟前
Dubbo(49)如何排查Dubbo的集群容错问题?
后端