springbootmybatis

缓存设计

2020-04-13  本文已影响0人  后来丶_a24d

目录


本地缓存设计需要考虑的地方

  1. 数据结构使用
  2. 对象上限
  3. 清除策略
  4. 过期时间
  5. 线程安全
  6. 是否持久化

本地缓存项目代码编写

public interface Cache<K, V> {
    V get(K key);

    Map<K, V> getAll(List<K> keys);

    void put(K key, V value);

    void refresh(K key);

    void refreshAll(List<K> keys);
}

public abstract class WrapLoadingCache<K, V> implements Cache<K, V>{

    private static final Logger log = LoggerFactory.getLogger(WrapLoadingCache.class);

    protected LoadingCache<K, Optional<V>> loaderCache;

    protected abstract Optional<V> load(K key);

   
    protected Map<K, Optional<V>> loadAll(List<K> keys){
        throw new UnsupportedOperationException();
    }

    protected void init(int time, TimeUnit unit, int maxSize) {

        loaderCache = CacheBuilder.newBuilder()
                .expireAfterWrite(time, unit)
                .maximumSize(maxSize)
                .build(new CacheLoader<K, Optional<V>>() {
                    @Override
                    public Optional<V> load(K key) {
                        return LoaderCache.this.load(key);
                    }

                    @Override
                    public Map<K, Optional<V>> loadAll(Iterable<? extends K> keys) throws Exception {
                        return LoaderCache.this.loadAll(Lists.newArrayList(keys));
                    }
                });
    }

    @Override
    public V get(K key) {
        Optional<V> opt = null;
        try {
            opt = loaderCache.get(key);
        } catch (ExecutionException e) {
            log.warn("WrapLoadingCacheget throw exception", e);
        }
        return opt != null && opt.isPresent() ? opt.get() : null;
    }

    @Override
    public Map<K, V> getAll(List<K> keys) {
        try {
            Map<K, V> result = new HashMap<>();
            ImmutableMap<K, Optional<V>> map = loaderCache.getAll(keys);
            map.forEach((key, opt) -> {
                V v = opt != null && opt.isPresent() ? opt.get() : null;
                result.put(key, v);
            });

            return result;
        } catch (ExecutionException e) {
            log.warn("WrapLoadingCache get throw exception", e);
        }

        return null;
    }

    @Override
    public void put(K key, V value) {
        loaderCache.put(key, Optional.ofNullable(value));
    }

    @Override
    public void refresh(K key) {
        loaderCache.refresh(key);
    }

    @Override
    public void refreshAll(List<K> keys) {
        loaderCache.putAll(loadAll(keys));
    }
}

mybaits缓存设计原理

缓存图
LruCache
BlockingCache
private final ConcurrentHashMap<Object, ReentrantLock> locks;
mybatis二级缓存导致的不可重复读问题

guava缓存设计原理

// CacheLoader形式的Cache
 private static final LoadingCache<String, String> LOADER_CACHE = CacheBuilder.newBuilder()
            .expireAfterAccess(1, TimeUnit.SECONDS)
            .maximumSize(1000)
            .build(new CacheLoader<String, String>() {
                @Override
                public String load(String key) throws Exception {
                    return key + new Date();
                }
            });

参考文章

上一篇 下一篇

猜你喜欢

热点阅读