在Go语言中,sync.Map
是一个内置的并发安全的map类型,它可以在多个goroutine之间安全地共享数据。但是,如果你需要更高级的缓存策略,比如设置过期时间或者更复杂的读写控制,你可能需要使用第三方库或者自己实现一个并发安全的缓存系统。
以下是一个简单的例子,展示了如何使用 sync.Map
来实现一个基本的缓存系统,并且包含了一个简单的读写锁来控制并发访问:
package main
import (
"fmt"
"sync"
"time"
)
type CacheItem struct {
Value interface{}
ExpireAt int64 // 过期时间戳
AccessTime int64 // 访问时间戳
}
type ConcurrentCache struct {
mu sync.RWMutex
items map[string]CacheItem
}
func NewConcurrentCache() *ConcurrentCache {
return &ConcurrentCache{
items: make(map[string]CacheItem),
}
}
func (c *ConcurrentCache) Get(key string) (interface{}, bool) {
c.mu.RLock()
defer c.mu.RUnlock()
item, ok := c.items[key]
if !ok || item.ExpireAt < time.Now().Unix() {
return nil, false
}
item.AccessTime = time.Now().Unix()
return item.Value, true
}
func (c *ConcurrentCache) Set(key string, value interface{}, ttl time.Duration) {
c.mu.Lock()
defer c.mu.Unlock()
expiration := time.Now().Add(ttl).Unix()
c.items[key] = CacheItem{
Value: value,
ExpireAt: expiration,
AccessTime: time.Now().Unix(),
}
}
func (c *ConcurrentCache) Delete(key string) {
c.mu.Lock()
defer c.mu.Unlock()
delete(c.items, key)
}
func main() {
cache := NewConcurrentCache()
// 设置一个键值对,有效期为5秒
cache.Set("mykey", "myvalue", 5*time.Second)
// 读取键值对
if value, ok := cache.Get("mykey"); ok {
fmt.Println("Value:", value)
} else {
fmt.Println("Key not found or expired")
}
// 等待5秒,键值对应该已经过期
time.Sleep(6 * time.Second)
// 再次尝试读取键值对,应该返回false
if value, ok := cache.Get("mykey"); ok {
fmt.Println("Value:", value)
} else {
fmt.Println("Key not found or expired")
}
}
在这个例子中,我们定义了一个 ConcurrentCache
结构体,它包含了一个 sync.RWMutex
来控制并发读写,以及一个 map[string]CacheItem
来存储缓存项。CacheItem
结构体包含了值、过期时间和访问时间。
Get
方法用于读取缓存项,如果键存在且未过期,则更新访问时间并返回值。Set
方法用于设置缓存项,包括过期时间。Delete
方法用于删除缓存项。
请注意,这个例子中的缓存没有持久化存储,它只在内存中存储数据。如果你需要一个持久化的缓存系统,你可能需要使用数据库或者其他存储介质来存储缓存数据,并且需要考虑数据的一致性和恢复问题。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。