LoadingCache的使用


背景

LoadingCache是GuavaCache構建緩存實體的方法,是一個支持多線程並發讀寫、高性能、通用的in-heap(堆)本地緩存。
支持key不存在時按照給定的CacheLoader 的loader方法進行loading。如果有多個線程同時get一個不存在的key,那么會有一個線程負責load,其他線程阻塞wait等待。

CacheBuilder方法參數

  • maximumSize(): 最大緩存上限,快達到上限或達到上限,處理了時間最長沒被訪問過的對象或者根據配置的被釋放的對象
  • expireAfterAccess():設置時間對象沒有被讀/寫訪問則對象從內存中刪除,回收順序和基於大小回收一樣
  • expireAfterWrite(): 設置時間對象沒有被寫訪問則對象從內存中刪除
  • refreshAfterWrite():為緩存增加自動定時刷新功能。緩存項只有在被檢索時才會真正刷新,即只有刷新間隔時間到了再去get(key)才會重新去執行Loading,否則就算刷新間隔時間到了也不會執行loading操作。

CacheLoader

實現自動加載緩存。可以在其中自定義load方法和reload方法,根據需求加載緩存和刷新緩存。

Cache常用方法

  • get(key): 有值則返回緩存值,沒有則執行load方法加載緩存。
  • put(key, value): 顯式地向緩存中插入值,會直接覆蓋掉已有鍵之前映射的值。
  • invalidate(key): 顯式地清除個別緩存項。
  • invalidateAll(keys): 批量清除緩存項。
  • invalidateAll(): 清除所有緩存項。
  • refresh(key): (異步)主動刷新對應緩存值 。在刷新操作進行時,緩存仍然可以向其他線程返回舊值。

實例

@Slf4j
@Component
public class EntryCache {

    @Autowired
    EntryMapper entryMapper;

    /**
     * guava cache 緩存實體
     */
    LoadingCache<String, Entry> cache = CacheBuilder.newBuilder()
            // 緩存刷新時間
            .refreshAfterWrite(10, TimeUnit.MINUTES)
            // 設置緩存個數
            .maximumSize(500)
            .build(new CacheLoader<String, Entry>() {
                @Override
                // 當本地緩存命沒有中時,調用load方法獲取結果並將結果緩存
                public Entry load(String appKey) {
                    return getEntryFromDB(appKey);
                }

                // 數據庫進行查詢
                private Entry getEntryFromDB(String name) {
                    log.info("load entry info from db!entry:{}", name);
                    return entryMapper.selectByName(name);
                }
            });

    /**
     * 對外暴露的方法
     * 從緩存中取entry,沒取到就走數據庫
     */
    public Entry getEntry(String name) throws ExecutionException {
        return cache.get(name);
    }

    @PostConstruct
    public void initCache() {
        log.info("init entry cache start!");
        //讀取所有記錄
        List<Entry> list = entryMapper.selectAll();

        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        for (Entry entry : list) {
            try {
                this.getEntry(entry.getName());
            } catch (Exception e) {
                log.error("init cache error!,e:{}", e.getMessage());
            }
        }
        log.info("init entry cache end!");
    }
}

參考


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM