The logic is pretty straightforward:
Foo foo = cache.get();
if (isUpToDate(foo)) {
return foo;
} else {
foo = getUpdatedFoo(); // slow or expensive
cache.put(foo);
return foo;
}
However, I want to make sure that
- only one thread calls
getUpdatedFoo()
at a time - if thread A is already calling
getUpdatedFoo()
, thread B doesn't call it, instead just waiting for thread A's results
I could probably cobble together something based on the Memoizer pattern from JCiP, but I suspect there's a simpler way -- possibly using Guava CacheBuilder? Not immediately obvious how, though.
Update: Implemented a double-checked locking pattern per FrankPL's answer below:
Foo foo = cache.get();
if (!isUpToDate(foo)) {
lock.lock(); // Will block if some other thread is refreshing
try {
// See if some other thread already refreshed for us
foo = cache.get();
if (!isUpToDate(foo)) {
// guess not, we'll refresh it ourselves
foo = getUpdatedFoo();
cache.put(foo);
}
} finally {
lock.unlock();
}
}
return foo;