基于读写锁实现一个内存缓存器

上一个用java实现的版本,这里用go也实现了一遍:

type CacheDemo struct {
    CacheMap    map[string]*model.Config
    ConfigModel model.ConfigModel `inject:""`
    syncLock    *sync.RWMutex
}

func (c *CacheDemo) ReadConfig() (err error) {
    configList, err := c.ConfigModel.SelectAll()
    if err != nil {
        return
    }
    cacheMap := make(map[string]*model.Config)
    for _, config := range configList {
        key := config.Key
        cacheMap[key] = config
    }
    c.syncLock.Lock()
    defer c.syncLock.Unlock()
    c.CacheMap = cacheMap
    return
}

// 这里可以优化一下,
// 首先开启读锁,从缓存中取数据,
// 如果缓存中没取到数据,释放读锁,上写锁,然后查数据库
// 如果数据库中也没取到数据,返回空,否则写进缓存
// 最后释放写锁,再上读锁,最后再释放读锁(至于这里为啥要多此一举,自己想想!)
func (c *CacheDemo) GetConfig(key string) *model.Config {
    c.syncLock.RLock()
    defer c.syncLock.RUnlock()
    return c.CacheMap[key]
}

func (c *CacheDemo) Init() {
    c.CacheMap = make(map[string]*model.Config)
    c.syncLock = &sync.RWMutex{}
}

func (c *CacheDemo) Start() {
    err := c.ReadConfig()
    if err != nil {
        log.Errorf("load Config have err = %s", err.Error())
    }
    // 启动一个协程定时拉取数据库所有信息存进缓存
    go func() {
        tick := time.Tick(5 * time.Minute)
        for {
            select {
            case <-tick:
                err := c.ReadConfig()
                if err != nil {
                    log.Errorf("load Config have err = %s", err.Error())
                }
            }
        }
    }()
}

猜你喜欢

转载自blog.csdn.net/weixin_34212762/article/details/87485088