使用Guava中Cache的注意点

案例1:
 PriceSourceSwitchHandler priceSourceSwitchHandler = new PriceSourceSwitchHandler();
        Cache linkStatusMap = CacheBuilder.newBuilder()
                .expireAfterWrite(10, TimeUnit.SECONDS)
                .removalListener(priceSourceSwitchHandler::resetLinkStatus)
                .build();
        linkStatusMap.put("1","1");
        TimeUnit.SECONDS.sleep(12);
        //linkStatusMap.cleanUp();
        linkStatusMap.getIfPresent("1");
        
案例2:
 LoadingCache linkStatusMap = CacheBuilder.newBuilder()
                // .expireAfterAccess(10, TimeUnit.SECONDS)
                .expireAfterWrite(10, TimeUnit.SECONDS)
                .refreshAfterWrite(5, TimeUnit.SECONDS)
                .removalListener(priceSourceSwitchHandler::resetLinkStatus)
                .build(new CacheLoader() {
                    @Override
                    public String load(String s) throws Exception {
                        return "def";
                    }
                    
                    @Override
                    public ListenableFuture reload(String key, String oldValue) throws Exception {
                        return super.reload(key, oldValue);
                    }
                });
        linkStatusMap.put("1","1");
        TimeUnit.SECONDS.sleep(12);
        //linkStatusMap.cleanUp();
        linkStatusMap.get("1");
    
注意点:
    1.案例1中直接调用build()后得到的Cache接口,数据过期后在调用linkStatusMap.getIfPresent("1")发现removalListener不生效,但是数据确实删除了,缓存没了
    2.案例2中直接调用build()后得到的Cache接口,数据过期后在调用linkStatusMap.get("1")发现可以触发removalListener
    3.案例2中expireAfterAccess方法是在设置的时间内没有get、put相关操作,就会过期,但是数据还未删除,只有访问了(get、put)该数据才会真正删除该数据
    4.案例2中expireAfterWrite方法是在设置的时间内没有put相关操作,就会过期,但是数据还未删除,只有访问了(get、put)该数据才会真正删除该数据,其中put会把当前segment下的所有数据删除,可参考:guava的loadingcache什么时候删除过期的数据? - 简书 (jianshu.com)
    5.案例2中refreshAfterWrite方法是在设置的时间内没有put相关操作,就会重新reload,前提是该key必须调用过load方法;
        如案例2中: 比如开始get("key"),会触发load,加载默认值def存入缓存("key","def"),这里load一次之后,后面才能触发reload;
                   5秒-10秒时间段内,比如7秒没有put操作,就会reload; 如果超过时间段,比如12秒没有put操作,则直接过期
    6.过期数据不会自动删除,需要起个定时任务,调用    linkStatusMap.cleanUp()方法删除过期数据  ,会把所有segment下的所有数据删除         

你可能感兴趣的:(guava,java,map)