用go写一个并发安全本地缓存的demo
时间: 2023-09-12 11:05:21 浏览: 146
缓存机制demo
### 回答1:
我可以给你一个用Go语言实现的并发安全本地缓存的demo,它可以确保在多个goroutine之间,缓存数据不会被污染:package main import (
"fmt"
"sync"
)// CacheStore is a simple key-value store that provides thread-safe access
type CacheStore struct {
store map[string]string
mux sync.Mutex
}// Set stores a key-value pair in the cache
func (c *CacheStore) Set(key, value string) {
c.mux.Lock()
defer c.mux.Unlock()
c.store[key] = value
}// Get retrieves a value for the given key from the cache
func (c *CacheStore) Get(key string) (string, bool) {
c.mux.Lock()
defer c.mux.Unlock() value, ok := c.store[key]
return value, ok
}func main() {
cache := &CacheStore{store: make(map[string]string)} // Set key-value pairs in the cache
cache.Set("foo", "bar")
cache.Set("baz", "qux") // Get values from the cache
val, ok := cache.Get("foo")
fmt.Println(val, ok) // bar true
}
### 回答2:
下面是一个使用Go语言编写的并发安全本地缓存的简单示例代码:
```go
package main
import (
"fmt"
"sync"
"time"
)
type Cache struct {
data map[string]string
mutex sync.RWMutex
}
func NewCache() *Cache {
return &Cache{
data: make(map[string]string),
}
}
func (c *Cache) Get(key string) (string, bool) {
c.mutex.RLock()
defer c.mutex.RUnlock()
value, ok := c.data[key]
return value, ok
}
func (c *Cache) Set(key, value string) {
c.mutex.Lock()
defer c.mutex.Unlock()
c.data[key] = value
}
func main() {
cache := NewCache()
// 启动多个goroutine同时读取和写入缓存
for i := 1; i <= 5; i++ {
go func(i int) {
key := fmt.Sprintf("key%d", i)
value := fmt.Sprintf("value%d", i)
cache.Set(key, value)
fmt.Printf("Goroutine %d: Set %s=%s\n", i, key, value)
time.Sleep(100 * time.Millisecond)
result, ok := cache.Get(key)
if ok {
fmt.Printf("Goroutine %d: Get %s=%s\n", i, key, result)
} else {
fmt.Printf("Goroutine %d: %s not found\n", i, key)
}
}(i)
}
time.Sleep(1 * time.Second)
}
```
这个示例代码定义了一个Cache结构体,它包含一个用于存储数据的map和一个用于并发读写操作的互斥锁sync.RWMutex。Cache提供了Get和Set方法,用于获取和设置缓存中的数据。在main函数中,多个goroutine同时对缓存进行读写操作。
运行上述示例代码,你会看到多个goroutine并发地读取和写入缓存。由于使用了互斥锁,保证了对缓存数据的并发访问的安全性。
### 回答3:
Go语言提供了一些内置的并发安全的数据结构,我们可以使用它们来实现一个并发安全的本地缓存的Demo。下面是一个简单的示例代码:
```go
package main
import (
"sync"
"time"
)
type Cache struct {
mu sync.RWMutex // 读写锁
items map[string]*cacheItem
}
type cacheItem struct {
value interface{}
expiration time.Time
}
func (c *Cache) Get(key string) (interface{}, bool) {
c.mu.RLock()
item, found := c.items[key]
c.mu.RUnlock()
if !found {
return nil, false
}
if time.Now().After(item.expiration) {
c.Delete(key)
return nil, false
}
return item.value, true
}
func (c *Cache) Set(key string, value interface{}, duration time.Duration) {
c.mu.Lock()
c.items[key] = &cacheItem{
value: value,
expiration: time.Now().Add(duration),
}
c.mu.Unlock()
}
func (c *Cache) Delete(key string) {
c.mu.Lock()
delete(c.items, key)
c.mu.Unlock()
}
func main() {
cache := &Cache{
items: make(map[string]*cacheItem),
}
cache.Set("key1", "value1", time.Minute)
cache.Set("key2", "value2", time.Hour)
value, found := cache.Get("key1")
if found {
println(value.(string)) // 输出"value1"
}
cache.Delete("key2")
}
```
上述代码中,我们使用`sync.RWMutex`来创建一个读写锁,保证对缓存的访问是并发安全的。`Cache`结构体中有一个`items`字段,它是一个`map[string]*cacheItem`,存储了缓存的键值对。`cacheItem`结构体包含了键对应的值和过期时间。
`Get`函数用于从缓存中获取指定键的值。它首先开始读锁定,以允许多个读操作同时进行。然后检查指定键是否存在,如果不存在则返回错误值。如果键存在,则检查该键对应的缓存项是否已过期,如果已过期则从缓存中删除该项并返回错误值。否则返回键对应的值。
`Set`函数用于向缓存中设置一个新的键值对,并指定该键值对的过期时间。
`Delete`函数用于从缓存中删除指定键的值。
在`main`函数中,我们首先创建了一个`Cache`实例,并使用`Set`函数向缓存中添加了两个键值对。然后使用`Get`函数获取了`"key1"`对应的值,并打印出来。最后使用`Delete`函数删除了`"key2"`对应的值。
这样,我们就实现了一个基于Go语言的并发安全的本地缓存Demo。它可以在多个goroutine之间安全地并发读写。
阅读全文