网站备案 太烦,wordpress网页的源代码在哪里,南京市浦口区城乡建设局网站,宿迁房产网58同城网在 Golang 中#xff0c;原生的 map 类型并不支持并发安全#xff0c;也没有内置的键过期机制。不过#xff0c;有一些社区提供的库和方案可以满足这两个需求#xff1a;线程安全和键过期。 1. 使用 sync.Map#xff08;线程安全#xff0c;但不支持过期#xff09;
Go…在 Golang 中原生的 map 类型并不支持并发安全也没有内置的键过期机制。不过有一些社区提供的库和方案可以满足这两个需求线程安全和键过期。 1. 使用 sync.Map线程安全但不支持过期
Golang 提供了线程安全的 sync.Map但它没有键过期功能。如果只需要线程安全可以直接使用
import (fmtsync
)func main() {var m sync.Mapm.Store(key1, value1) // 写入键值val, ok : m.Load(key1) // 读取键值if ok {fmt.Println(key1:, val)}m.Delete(key1) // 删除键值
}限制sync.Map 适用于高并发场景但需要自行实现键的过期功能。 2. 使用开源库 go-cache推荐支持线程安全和键过期
go-cache 是一个轻量级、高效的内存缓存库支持线程安全和键过期功能。
安装
go get github.com/patrickmn/go-cache使用示例
package mainimport (fmttimegithub.com/patrickmn/go-cache
)func main() {// 创建一个缓存对象默认过期时间为 5 分钟清理间隔为 10 分钟c : cache.New(5*time.Minute, 10*time.Minute)// 设置键值并指定过期时间c.Set(key1, value1, cache.DefaultExpiration) // 默认过期时间c.Set(key2, value2, 10*time.Second) // 自定义过期时间// 读取键值val, found : c.Get(key1)if found {fmt.Println(key1:, val)} else {fmt.Println(key1 has expired or not found)}// 检查键是否存在_, exists : c.Get(key2)fmt.Println(key2 exists:, exists)// 删除键c.Delete(key2)
}特点
线程安全。支持键过期自动清理。提供多种方法如读取、删除、批量操作等。 3. 使用 expiremap支持自动过期和并发安全
expiremap 是另一个简洁的库专门为自动过期的键值存储设计。
安装
go get github.com/zyedidia/expiremap使用示例
package mainimport (fmttimegithub.com/zyedidia/expiremap
)func main() {// 创建一个过期 map键值过期时间为 2 秒m : expiremap.New(time.Second * 2)// 设置键值m.Set(key1, value1)m.Set(key2, value2)// 读取键值val, ok : m.Get(key1)if ok {fmt.Println(key1:, val)} else {fmt.Println(key1 has expired or does not exist)}// 等待 3 秒后键值会自动过期time.Sleep(3 * time.Second)_, ok m.Get(key1)fmt.Println(key1 exists after 3 seconds:, ok)
}特点
键过期时间由 time.Duration 控制。自动清理过期键。支持线程安全。 4. 自己实现一个安全且支持过期的 map
如果你不想使用外部库可以结合 sync.RWMutex 和 time.Timer 自行实现
示例代码
package mainimport (fmtsynctime
)type SafeMap struct {data map[string]anymutex sync.RWMutex
}func NewSafeMap() *SafeMap {return SafeMap{data: make(map[string]any),}
}func (sm *SafeMap) Set(key string, value any, duration time.Duration) {sm.mutex.Lock()defer sm.mutex.Unlock()sm.data[key] value// 启动一个定时器删除键go func() {time.Sleep(duration)sm.mutex.Lock()delete(sm.data, key)sm.mutex.Unlock()}()
}func (sm *SafeMap) Get(key string) (any, bool) {sm.mutex.RLock()defer sm.mutex.RUnlock()val, ok : sm.data[key]return val, ok
}func (sm *SafeMap) Delete(key string) {sm.mutex.Lock()defer sm.mutex.Unlock()delete(sm.data, key)
}func main() {sm : NewSafeMap()sm.Set(key1, value1, 5*time.Second) // 设置 5 秒过期val, ok : sm.Get(key1)fmt.Println(key1 exists:, ok, value:, val)// 等待 6 秒确保键已过期time.Sleep(6 * time.Second)val, ok sm.Get(key1)fmt.Println(key1 exists after expiration:, ok)
}特点
sync.RWMutex 确保并发安全。使用 time.Timer 实现键过期。 总结
如果需要简单易用的解决方案推荐使用 go-cache。如果你需要更轻量的库expiremap 是一个好选择。对于特定需求可以自行实现线程安全的 map结合定时器实现过期功能。