使用sync.RWMutex保护map或sync.Map实现并发安全缓存,结合TTL和定期清理机制,兼顾性能与一致性。

在Golang中实现并发安全的缓存,核心是确保多个goroutine同时读写时数据的一致性和性能。直接使用map配合sync.RWMutex是最常见且有效的方式,也可以借助sync.Map简化部分场景。
使用 sync.RWMutex 保护普通 map
大多数情况下,推荐使用sync.RWMutex来保护一个普通的map。读操作频繁时,读锁允许多个goroutine同时访问,写锁则独占,兼顾性能与控制。
示例:
type Cache struct { data map[string]interface{} mu sync.RWMutex}func NewCache() *Cache { return &Cache{ data: make(map[string]interface{}), }}func (c *Cache) Get(key string) (interface{}, bool) { c.mu.RLock() defer c.mu.RUnlock() val, exists := c.data[key] return val, exists}func (c *Cache) Set(key string, value interface{}) { c.mu.Lock() defer c.mu.Unlock() c.data[key] = value}func (c *Cache) Delete(key string) { c.mu.Lock() defer c.mu.Unlock() delete(c.data, key)}
这种方式清晰、可控,适合需要自定义过期机制、淘汰策略等扩展功能的场景。
立即学习“go语言免费学习笔记(深入)”;
使用 sync.Map(适用于简单场景)
sync.Map是Go为高并发读写设计的专用并发安全map,适用于读多写少或键集不断变化的场景。它自带原子操作,无需额外锁。
示例:
var cache sync.Map// 写入cache.Store("key", "value")// 读取if val, ok := cache.Load("key"); ok { fmt.Println(val)}// 删除cache.Delete("key")
注意:sync.Map不支持遍历删除或复杂操作,且一旦使用,应全程使用其方法,不能混合普通map操作。
添加过期时间(TTL)支持
真实缓存通常需要自动过期能力。可以在value中封装一个带过期时间的结构体,并启动清理协程定期扫描。
关键点:
每个value记录过期时间(如time.Time) Get时判断是否过期,过期则返回不存在 可选:后台goroutine定期清理过期项
示例片段:
type item struct { value interface{} expireTime time.Time}func (i *item) isExpired() bool { return time.Now().After(i.expireTime)}
在Get中加入判断:
func (c *Cache) Get(key string) (interface{}, bool) { c.mu.RLock() defer c.mu.RUnlock() item, exists := c.data[key] if !exists || item.isExpired() { return nil, false } return item.value, true}
基本上就这些。根据场景选择sync.RWMutex + map还是sync.Map,再按需加上TTL和清理机制,就能构建出高效又安全的并发缓存。不复杂但容易忽略细节,比如过期检查的时机和锁粒度。
以上就是如何在Golang中实现并发安全的缓存的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1412065.html
微信扫一扫
支付宝扫一扫