我有一个 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/