Skip to content
Discussion options

You must be logged in to vote

Ah, looks like I misunderstood the proposed solution in the FAQ. So the trick is not to offload the computation, but only to postpone it and evaluate it outside the cache lock. The generalized solution (universal wrapper) could then be

fun get(key: K, compute: () -> V): V {
    val future = CompletableFuture<V>()
    cache.asMap().putIfAbsent(key, future)?.let { return it.join() /* computing or already cached, join and return */}
    return compute().also { future.complete(it) }
}

The tradeoff here is that the CompletableFuture is always instantiated, providing some overhead. So I might as well combine the two approaches, and use reentrancy detection, and create the future only when neede…

Replies: 1 comment 5 replies

Comment options

You must be logged in to vote
5 replies
@msevcenko
Comment options

@ben-manes
Comment options

@msevcenko
Comment options

Answer selected by ben-manes
@msevcenko
Comment options

@ben-manes
Comment options

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet
2 participants