java - 打算高效缓存多个值时,Guava缓存应该如何实现?

标签 java caching guava

我有一个 Java 类,它有一个 Guava LoadingCache<String, Integer>在该缓存中,我计划存储两件事:活跃员工一天的平均工作时间和他们的效率。我正在缓存这些值,因为每次收到请求时都要进行计算,成本很高。此外,缓存的内容将每分钟刷新一次 (refreshAfterWrite)。

我正在考虑使用 CacheLoader然而,对于这种情况,它的加载方法只为每个键加载一个值。在我的 CacheLoader ,我打算做类似的事情:

private Service service = new Service();

public Integer load(String key) throws Exception {
    if (key.equals("employeeAvg"))
        return calculateEmployeeAvg(service.getAllEmployees());

    if (key.equals("employeeEff"))
        return calculateEmployeeEff(service.getAllEmployees());

    return -1;
}

对我来说,我发现这非常低效,因为为了加载两个值,我必须调用 service.getAllEmployees()两次因为,如果我错了请纠正我,CacheLoader的应该是无状态的。

这让我想到使用 LoadingCache.put(key, value)方法,这样我就可以创建一个实用方法来调用 service.getAllEmployees()一次并即时计算值。但是,如果我确实使用 LoadingCache.put() , 我不会有 refreshAfterWrite功能,因为它依赖于缓存加载器。

如何提高效率?

最佳答案

您的问题似乎源于使用字符串表示值类型(Effective Java Item 50)。相反,考虑定义一个适当的值类型来存储这些数据,并使用 memoizing Supplier以避免重新计算它们。

public static class EmployeeStatistics {
  private final int average;
  private final int efficiency;
  // constructor, getters and setters
}

Supplier<EmployeeStatistics> statistics = Suppliers.memoize(
    new Supplier<EmployeeStatistics>() {
  @Override
  public EmployeeStatistics get() {
    List<Employee> employees = new Service().getAllEmployees();
    return new EmployeeStatistics(
        calculateEmployeeAvg(employees),
        calculateEmployeeEff(employees));
  }});

您甚至可以将这些计算方法移动到 EmployeeStatistics 中,只需将所有员工传递给构造函数并让它计算适当的数据。


如果您需要配置缓存行为超过 Suppliers.memoize()Suppliers.memoizeWithExpiration()可以提供,考虑这个类似的模式,它隐藏了你在 Supplier 中使用 Cache 的事实:

Supplier<EmployeeStatistics> statistics = new Supplier<EmployeeStatistics>() {
  private final Object key = new Object();
  private final LoadingCache<Object, EmployeeStatistics> cache =
      CacheBuilder.newBuilder()
        // configure your builder
        .build(
           new CacheLoader<Object, EmployeeStatistics>() {
             public EmployeeStatistics load(Object key) {
               // same behavior as the Supplier above
             }});

  @Override
  public EmployeeStatistics get() {
    return cache.get(key);
  }};

关于java - 打算高效缓存多个值时,Guava缓存应该如何实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31576136/

相关文章:

caching - 如何使 Apollo Server RESTDataSource 中的缓存失效

java - 如何使用 Firebase 1.0.2 忽略对象模型的新字段

java - 如何编写一个返回数组中给定列的总和的方法? java

caching - 直接映射缓存命中/未命中

java - EhCache缓存对象修改

java - 我的 ImmutableList 收集器不工作?

java - 处理来自多个平面文件的海量数据,并根据需求转换为 xml 格式

java - 按相反顺序对列表进行排序

java - 对android项目结构和MVC模式感到困惑

java - XMLHTTP 请求错误。带有 tomee 服务器的 Eclipse 项目。