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

在Golang中实现并发安全的缓存,核心是确保多个goroutine同时读写时数据的一致性和性能。直接使用map配合sync.RWMutex是最常见且有效的方式,也可以借助sync.Map简化部分场景。
大多数情况下,推荐使用sync.RWMutex来保护一个普通的map。读操作频繁时,读锁允许多个goroutine同时访问,写锁则独占,兼顾性能与控制。
示例:
一个类似淘宝助理、ebay助理的客户端程序,用来方便的在本地处理商店数据,并能够在本地商店、网上商店和第三方平台之间实现数据上传下载功能的工具。功能说明如下:1.连接本地商店:您可以使用ShopEx助理连接一个本地安装的商店系统,这样就可以使用助理对本地商店的商品数据进行编辑等操作,并且数据也将存放在本地商店数据库中。默认是选择“本地未安装商店”,本地还未安
0
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是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操作。
真实缓存通常需要自动过期能力。可以在value中封装一个带过期时间的结构体,并启动清理协程定期扫描。
关键点:
time.Time)示例片段:
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中实现并发安全的缓存的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号