値をキャッシュしようとしていint
ます (DB から何かを数えます)。このカウントにはかなりの時間がかかる可能性があるため、最初に 200 ミリ秒のタイムアウトで試してみたいと思います。しかし、それが失敗した場合、2 つのシナリオがあります。
- My
cache
が入力され、現在の値を返し、非同期で再入力します。 - は
cache
入力されていません。入力してブロックし、値を返します。
私は「キャッシュ」と言っていますが、それは実際には単なるint
値です。ここで本格的な機能cache
が必要かどうかはわかりません。Guava のSupplierを使用してみましたが、特定のユース ケースを統合する方法が見つかりません。
多くのスレッドがこの手順全体に入る可能性があることに注意してください。キャッシュが読み込まれない場合に備えて、最初のスレッドだけを待機させたいと思います。残りは待機せずに、キャッシュされた値をすぐに取得する必要があります。他のスレッドがキャッシュの再設定を完了した場合は、更新された値です。
これが私が今持っているもののサンプルコードです:
public class CountRetriever {
private Supplier<Integer> cache = Suppliers.memoize(countSupplier());
private Supplier<Integer> countSupplier() {
return new Supplier<Integer>() {
@Override
public Integer get() {
// Do heavy count from the DB
}
};
}
public int getCount() {
try {
return submitAsyncFetch();
} catch (Exception e) {
// It takes too long, let's use the cache
return cache.get();
}
}
private Integer submitAsyncFetch() {
return executor.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
// Do heavy count from the DB
}
}).get(200, TimeUnit.MILLISECONDS);
}
}