【问题标题】:What is the best way to cache single object within fixed timeout?在固定超时内缓存单个对象的最佳方法是什么?
【发布时间】:2011-12-13 11:00:57
【问题描述】:

Google Guava 的 CacheBuilder 允许使用过期键创建 ConcurrentHash,允许在固定 tiemout 后删除条目。但是我只需要缓存某个类型的一个实例。

使用 Google Guava 在固定超时内缓存单个对象的最佳方法是什么?

【问题讨论】:

    标签: java guava


    【解决方案1】:

    我会使用 Guava 的 Suppliers.memoizeWithExpiration(Supplier delegate, long duration, TimeUnit unit)

    public class JdkVersionService {
    
        @Inject
        private JdkVersionWebService jdkVersionWebService;
    
        // No need to check too often. Once a year will be good :) 
        private final Supplier<JdkVersion> latestJdkVersionCache
                = Suppliers.memoizeWithExpiration(jdkVersionSupplier(), 365, TimeUnit.DAYS);
    
    
        public JdkVersion getLatestJdkVersion() {
            return latestJdkVersionCache.get();
        }
    
        private Supplier<JdkVersion> jdkVersionSupplier() {
            return new Supplier<JdkVersion>() {
                public JdkVersion get() {
                    return jdkVersionWebService.checkLatestJdkVersion();
                }
            };
        }
    }
    

    使用 JDK 8 更新

    今天,我会以不同的方式编写这段代码,使用 JDK 8 方法引用和构造函数注入来获得更简洁的代码:

    import java.util.concurrent.TimeUnit;
    import java.util.function.Supplier;
    
    import javax.inject.Inject;
    
    import org.springframework.stereotype.Service;
    
    import com.google.common.base.Suppliers;
    
    @Service
    public class JdkVersionService {
    
        private final Supplier<JdkVersion> latestJdkVersionCache;
    
        @Inject
        public JdkVersionService(JdkVersionWebService jdkVersionWebService) {
            this.latestJdkVersionCache = Suppliers.memoizeWithExpiration(
                    jdkVersionWebService::checkLatestJdkVersion,
                    365, TimeUnit.DAYS
            );
        }
    
        public JdkVersion getLatestJdkVersion() {
            return latestJdkVersionCache.get();
        }
    }
    

    【讨论】:

    • 供应商抛出已检查异常的情况你知道解决办法吗?
    • @user2417480 我可能会将该异常包装在 RuntimeException 中。如果您真的想保留已检查的异常,也许稍后再打开它,但是跨多个层携带已检查的异常通常是一种反模式......这就是为什么例如spring-jdbc 有一个翻译层将检查的异常转换为运行时 DataAccessException。
    猜你喜欢
    • 1970-01-01
    • 2010-09-07
    • 2020-10-19
    • 1970-01-01
    • 2015-11-19
    • 2011-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多