首页 > 系统服务 > 详细

go-cache使用

时间:2019-12-04 16:04:33      阅读:164      评论:0      收藏:0      [点我收藏+]

安装

1 go get github.com/patrickmn/go-cache

使用方法

import (
	"fmt"
	"github.com/patrickmn/go-cache"
	"time"
)

func main() {
	// Create a cache with a default expiration time of 5 minutes, and which
	// purges expired items every 10 minutes
     // 默认5分钟过期,每10分钟删除过期的项目 c := cache.New(5*time.Minute, 10*time.Minute) // Set the value of the key "foo" to "bar", with the default expiration time
// 设置缓存,使用默认过期时间 c.Set("foo", "bar", cache.DefaultExpiration) // Set the value of the key "baz" to 42, with no expiration time // (the item won‘t be removed until it is re-set, or removed using // c.Delete("baz")
// 使用不过期策略,除非重新设置了或者使用了Delete方法,否则数据将一直不会被删除,即使是每10分钟的清理也不会 c.Set("baz", 42, cache.NoExpiration) // Get the string associated with the key "foo" from the cache foo, found := c.Get("foo") if found { fmt.Println(foo) } // Since Go is statically typed, and cache values can be anything, type // assertion is needed when values are being passed to functions that don‘t // take arbitrary types, (i.e. interface{}). The simplest way to do this for // values which will only be used once--e.g. for passing to another // function--is: foo, found := c.Get("foo") if found { MyFunction(foo.(string)) } // This gets tedious if the value is used several times in the same function. // You might do either of the following instead: if x, found := c.Get("foo"); found { foo := x.(string) // ... } // or var foo string if x, found := c.Get("foo"); found { foo = x.(string) } // ... // foo can then be passed around freely as a string // Want performance? Store pointers! c.Set("foo", &MyStruct, cache.DefaultExpiration) if x, found := c.Get("foo"); found { foo := x.(*MyStruct) // ... } }

过期机制

过期有两种,一种是时间过期,一种是淘汰过期。Guava在构建Cache对象时,可以通过CacheBuilder类的expireAfterAccess和expireAfterWrite两个方法为缓存中的对象指定过期时间,过期的对象将会被缓存自动删除。其中,expireAfterWrite方法指定对象被写入到缓存后多久过期,expireAfterAccess指定对象多久没有被访问后过期。go-cache采用的是时间过期方法,且仅支持expireAfterWrite。

GC

go-cache使用了goroutine执行自动过期清理。当整个cache都不再被使用者需要了,应该被GC,但是由于后台清理goroutine的存在,整个cache将不会被回收掉。go-cache中使用了runtime.SetFinalizer,

func newCacheWithJanitor(de time.Duration, ci time.Duration, m map[string]Item) *Cache {
	c := newCache(de, m)
	// This trick ensures that the janitor goroutine (which--granted it
	// was enabled--is running DeleteExpired on c forever) does not keep
	// the returned C object from being garbage collected. When it is
	// garbage collected, the finalizer stops the janitor goroutine, after
	// which c can be collected.
	C := &Cache{c}
	if ci > 0 {
		runJanitor(c, ci)
		runtime.SetFinalizer(C, stopJanitor)
	}
	return C
}

对SetFinalizer的解释,我引用下别人的

对象可以关联一个SetFinalizer函数, 当gc检测到unreachable对象有关联的SetFinalizer函数时,会执行关联的SetFinalizer函数, 同时取消关联。 这样当下一次gc的时候,对象重新处于unreachable状态并且没有SetFinalizer关联, 就会被回收。--https://zhuanlan.zhihu.com/p/76504936

在这种场景下,往往需要一个wrapper来包一层。在go-cache的代码中,newCache()方法返回的是*cache,而绑定Setfinalizer的函数对象则是*Cache(注意大小写)。 

go-cache使用

原文:https://www.cnblogs.com/textworld/p/11936213.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!