我的计算代码繁重:
static class Computer {
public Single<String> compute() {
return Single.fromCallable(() -> {
Thread.sleep(1000);
System.out.println("Computation...");
return "3.14";
});
}
}
我要对多个订阅者(即缓存)进行一次评估。
Computer computer = new Computer();
Single<String> c = computer.compute().cache();
c.blockingGet();
c.blockingGet();
但是我想让缓存在一定时间后过期:
Thread.sleep(2000);
//This should trigger computation
c.blockingGet();
c.blockingGet();
有什么想法吗?
答案 0 :(得分:0)
尝试了一段时间后,无法使用内置的Observable
创建此设置。我认为这可能是可行的,但是IMO为此,您将需要Subject
,对于这种特定设置,我认为这太过分了。
我发现的解决方案是为此创建一个自定义运算符,该运算符将自己为给定功能执行缓存超时。
该类如下所示:
class TimeoutSingleCache<Downstream, Upstream> implements SingleOperator<Downstream, Upstream> {
private final Object LOCK = new Object();
// Cache
private long prevCallTime = -1;
@Nullable
private volatile Downstream cachedValue = null;
// Inputs
private final long invalidationTimeoutMillis;
private final Function<Upstream, Downstream> operation;
public TimeoutSingleCache(
long invalidationTimeoutMillis,
Function<Upstream, Downstream> operation
) {
this.invalidationTimeoutMillis = invalidationTimeoutMillis;
this.operation = operation;
}
@Override
public SingleObserver<? super Upstream> apply(SingleObserver<? super Downstream> observer) throws Exception {
return new SingleObserver<Upstream>() {
@Override
public void onSubscribe(Disposable d) {
observer.onSubscribe(d);
}
@Override
public void onSuccess(Upstream upstream) {
long currentTime = System.currentTimeMillis();
// Could be faster with double-check lock - not the point here
synchronized (LOCK) {
if (cachedValue == null || prevCallTime + invalidationTimeoutMillis < currentTime) {
prevCallTime = currentTime;
try {
cachedValue = operation.apply(upstream);
} catch (Exception e) {
observer.onError(e);
}
}
}
observer.onSuccess(cachedValue);
}
@Override
public void onError(Throwable e) {
observer.onError(e);
}
};
}
}
用法:
public static void main(String[] args) throws InterruptedException {
Single<String> cachedComputation = Single.just(1)
.lift(new TimeoutSingleCache<>(100L, input -> {
System.out.println("Computation!");
return "" + input + " : 3.14";
}));
System.out.println("1");
System.out.println(cachedComputation.blockingGet());
System.out.println("2");
System.out.println(cachedComputation.blockingGet());
Thread.sleep(200L);
System.out.println("3");
System.out.println(cachedComputation.blockingGet());
System.out.println("4");
System.out.println(cachedComputation.blockingGet());
}
输出:
1
Computation!
1 : 3.14
2
1 : 3.14
3
Computation!
1 : 3.14
4
1 : 3.14
希望有帮助。顺便问一句。