Java Concurrency In Practice by Brian Goetz provides an example of a efficient scalable cache for concurrent use. Here is the code for the class:
public clas
Here is an example which calculates factorials:
public static void main(String[] args) throws Exception {
//create a memoizer that performs factorials
final Memoizer<Integer, Integer> memo = new Memoizer<Integer, Integer> (new Computable<Integer, Integer>() {
@Override
public Integer compute(Integer a) {
int result = 1 ;
for(int i = 1 ; i < a ; i++){
result = result*i;
}
return result;
}
});
//now call the memoizer
System.out.println(memo.compute(10));
//call it with 10 threads concurrently
ExecutorService exec = Executors.newFixedThreadPool(10);
ExecutorCompletionService<Integer> compService = new ExecutorCompletionService<Integer>(exec);
for(int i = 0 ; i < 15 ; i++){
compService.submit(new Callable<Integer>(){
@Override
public Integer call() throws Exception {
return memo.compute(5);
}
});
}
exec.shutdown();
for(int i = 0 ; i < 15 ; i++){
System.out.println(compService.take().get());
}
}
So if two threads try to compute the same factorial at exactly the same time, only one of them will actually perform the computation, because putIfAbsent
is threadsafe. The second thread will simply get the future which was put in the map by the first thread and wait for it to finish.
I could imagine something like this:
class PrimeDetector implements Computable<BigInteger, Boolean> {
public Boolean compute(BigInteger number) {
// detect whether the number is prime and return true if it is
}
}
Memoizer<BigInteger, Boolean> primeMemoizer =
new Memoizer<BigInteger, BigInteger[]>(new PrimeDetector());
boolean isPrime = primeMemoizer.compute(
new BigInteger("5625945193217348954671586615478165774647538956473535"));
...