我有一个带有 Guava 的 Java 类LoadingCache<String, Integer>
在该缓存中,我计划存储两件事:活跃员工当天工作的平均时间和他们的效率。我正在缓存这些值,因为每次收到请求时计算成本都会很高。此外,缓存的内容将被刷新(refreshAfterWrite
) 每一分钟。
我正在考虑使用CacheLoader
然而,对于这种情况,它的 load 方法只为每个键加载一个值。在我的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)。相反,请考虑定义存储此数据的适当值类型,并使用记忆Supplier https://google.github.io/guava/releases/23.0/api/docs/com/google/common/base/Suppliers.html#memoize-com.google.common.base.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()
or Suppliers.memoizeWithExpiration() https://google.github.io/guava/releases/23.0/api/docs/com/google/common/base/Suppliers.html#memoizeWithExpiration-com.google.common.base.Supplier-long-java.util.concurrent.TimeUnit-可以提供,考虑这个类似的模式,它隐藏了您正在使用的事实Cache
里面一个Supplier
:
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);
}};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)