Cache里经常用到的两个功能就是:
1 当key对应的值不存在时,加载进来并可以访问。
2 达到cache的上限后,可以LRU清除。
开源包guava自带的cache就很好的满足了上面的需求。
依赖:
compile 'com.google.guava:guava:18.0'
下面的MemberCache只是guava cache里的一个使用案例:
@Slf4j public class MemberCache { static final String KEY_DELEMILTER = "#"; // cache trust set of every member, memberSrl --> trust set private LoadingCache<String, SortedSet<Activity>> cache; public MemberCache(int maxSize) { System.out.println("==> member cache max size: " + maxSize); cache = CacheBuilder.newBuilder() .maximumSize(maxSize) .removalListener(new RemoveListener()) .build(new TrustsetLoader()); } public SortedSet<Activity> getTrustset(String memberSrl, String trustType) throws ExecutionException { String key = memberSrl + KEY_DELEMILTER + trustType; return cache.get(key); } public LoadingCache<String, SortedSet<Activity>> getCache() { return cache; } /** * listen remove event of cache. */ class RemoveListener implements RemovalListener<String, SortedSet<Activity>> { @Override public void onRemoval(RemovalNotification<String, SortedSet<Activity>> notification) { long free = Runtime.getRuntime().freeMemory(); final long humanSize = 1024 * 1024; System.out.printf("=> up to cache max, system free %d m \n", free / humanSize); } } /** * load member's trust set if absent. */ class TrustsetLoader extends CacheLoader<String, SortedSet<Activity>> { @Override public SortedSet<Activity> load(String key) { String[] keys = key.split(KEY_DELEMILTER); String memberSrl = keys[0]; String trustType = keys[1]; SortedSet<Activity> set = new TreeSet<>(); try { String rowKey = LIMIT_CONTROL.getRowKey(memberSrl); Get get = new Get(Bytes.toBytes(rowKey)); get.addColumn(LIMIT_CONTROL.getCF(), HColumn.valueOf(trustType).getCol()); // !!! set version is important for limit control table get.setMaxVersions(DurationLimit.getLimit(trustType)); Result[] results = HBaseUtil.get(LIMIT_CONTROL, get); for (Result result: results) { CellScanner scanner = result.cellScanner(); while (scanner.advance()) { Cell cell = scanner.current(); String value = CellUtil.getValue(cell, String.class); long timestamp = cell.getTimestamp(); Activity act = Activity.builder() .memberSrl(memberSrl) .trustType(trustType) .value(value) .actTime(timestamp) .build(); set.add(act); } } } catch (Exception e) { log.error("load trust set for key: {}, error", key, e); } System.out.printf("load key: %s, set size: %d \n", key, set.size()); return set; } } }