캐시에 개체를 저장해야하며 개체를 만드는 데 시간이 오래 걸릴 수 있습니다. ConcurrentHashMap<id, Future<Object>>
으로 시작하여 메모리 부족이 발생할 때까지 모든 것이 잘되었습니다. SoftReferences로 이동하고 더 좋았지 만 지금은 퇴거를 제어해야합니다. Ehcache로 이사 중입니다.값이 오랫동안 계산되는 캐시
확실한 라이브러리가있을 것이라고 확신하지만 모든 것을 일관되게 유지하면서 이미 계산되거나 처리중인 것을 다시 계산하지 않으면 서 캐시 스토리지와 계산을 2 단계로 수행하는 논리를 이해해야합니다. 계산 중입니다. 두 개의 레벨 캐시, 하나는 더 지속적인 결과를, 다른 하나는 계산 과정에 사용됩니다.
Callable.call()
메서드에서 동시성 문제가있는 다음 코드를 향상시키는 방법에 대한 힌트가 있습니까?
public class TwoLevelCache {
// cache that serializes everything except Futures
private Cache complexicos = new Cache();
private ConcurrentMap<Integer, Future<Complexixo>> calculations =
new ConcurrentHashMap<Integer, Future<Complexico>>();
public Complexico get(final Integer id) {
// if in cache return it
Complexico c = complexicos.get(id);
if (c != null) { return c; }
// if in calculation wait for future
Future f = calculations.get(id);
if (f != null) { return f.get(); } // exceptions obviated
// if not, setup calculation
Callable<Complexico> callable = new Callable<Complexico>() {
public Complexico call() throws Exception {
Complexico complexico = compute(id);
// this might be a problem here
// but how to synchronize without
// blocking the whole structure?
complexicos.put(id, complexico);
calculations.remove(id);
return complexico;
}
};
// store calculation
FutureTask<Complexico> task = new FutureTask<Complexico>(callable);
Future<Complexico> future = futures.putIfAbsent(id, task);
if (future == null) {
// not previosly being run, so start calculation
task.run();
return task.get(); // exceptions obviated
} else {
// there was a previous calculation, so use that
return future.get(); // exceptions obviated
}
}
private Complexico compute(final Integer id) {
// very long computation of complexico
}
}
Java 8의 ['Map.computeIfAbsent'] (https://docs.oracle.com/javase/8/docs/api/java/util/Map.html#computeIfAbsent-K-java.util)를 사용할 수 있습니다. function.Function-)을'ConcurrentHashMap'과 함께 사용하면 코드를 깔끔하게 정리할 수 있습니다. 'Callable.call'은 확실히 약간의 재난 지역입니다. –
미래를 만들고 그 결과를 얻는데 얼마나 걸리나요? –
@ R4J 그것은 0.1 초에서 10 초까지 걸립니다. – rmarimon