加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

golang cache 源码学习

发布时间:2020-12-16 19:13:14 所属栏目:大数据 来源:网络整理
导读:github源码地址 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

github源码地址

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
}

这段程序的关键点在于C := &Cache{c}* runtime.SetFinalizer(C,stopJanitor)*

首先,

func (j *janitor) Run(c *cache) {
    j.stop = make(chan bool)
    tick := time.Tick(j.Interval)
    for {
        select {
        case <-tick:
            c.DeleteExpired()
        case <-j.stop:
            return
        }
    }
}
func runJanitor(c *cache,ci time.Duration) {
    j := &janitor{
        Interval: ci,}
    c.janitor = j
    go j.Run(c)
}

可以看到runJanitor是启动了一个goroutine用于清除过期的缓存,这个goroutine是一直执行的,周期的检查c中有没有过期的缓存,所以c一直不会被垃圾回收。为了让程序停掉的时候该gorountine也能够停止,就需要利用C := &Cache{c}和runtime.SetFinalizer.

利用C := &Cache{c}, c虽然不会被垃圾回收,但是C会,那么当C被垃圾回收时,C变成unreachable 的状态,就会触发runtime.SetFinalizer,执行stopJanitor停止runJanitor启动的goroutine。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读