1. Interface Definition
Import java. util. concurrent. ExecutionException;
Public interface Computable <A, V> {
V compute (A arg) throws InterruptedException, ExecutionException;
}
2. Class implementation
Import java. util. concurrent. Callable;
Import java. util. concurrent. CancellationException;
Import java. util. concurrent. ConcurrentHashMap;
Import java. util. concurrent. ExecutionException;
Import java. util. concurrent. Future;
Import java. util. concurrent. FutureTask;
Public class Memoizer <A, V> implements Computable <A, V> {
Private final ConcurrentHashMap <A, Future <V> cache = new ConcurrentHashMap <A, Future <V> (); // thread security class
Private final Computable <A, V> c; // private, final keywords can be used whenever possible
Public Memoizer (Computable <A, V> c ){
This. c = c;
}
Public V compute (final A arg) throws InterruptedException, ExecutionException {
While (true ){
Future <V> f = cache. get (arg );
If (f = null ){
Callable <V> eval = new Callable <V> (){
Public V call () throws Exception {
Return c. compute (arg );
}
};
FutureTask <V> ft = new FutureTask <V> (eval );
F = cache. putIfAbsent (arg, ft); // Add atomic operation if the value is missing
If (f = null ){
F = ft;
Ft. run (); // start the calculation result
}
}
Try {
Return f. get ();
} Catch (CancellationException e ){
Cache. remove (arg, f); // avoid adding contaminated data to the cache
} Catch (ExecutionException e0 ){
Throw e0;
}
}
}
}
3. Call in servlet
Import java. io. IOException;
Import java. util. concurrent. ExecutionException;
Import javax. servlet. ServletException;
Import javax. servlet. ServletRequest;
Import javax. servlet. ServletResponse;
Import javax. servlet. http. HttpServlet;
Public class Factorizer extends HttpServlet {
Private final Computable <Integer, Integer []> c = new Computable <Integer, Integer []> (){
Public Integer [] compute (Integer arg) throws InterruptedException, ExecutionException {
Return new Integer [arg. intValue ()];
}
};
Private final Computable <Integer, Integer []> cache = new Memoizer <Integer, Integer []> (c );
// Main method. multi-threaded shared variables are thread-safe cache.
Public void service (ServletRequest req, ServletResponse resp) throws ServletException, IOException {
Try {
Integer I = extractFromRequest (req );
EncodeIntoResponse (resp, cache. compute (I ));
} Catch (Exception e ){
// TODO: handle exception
}
}
// The following two methods are auxiliary methods:
Private void encodeIntoResponse (ServletResponse resp, Integer [] compute ){
Try {
Resp. getWriter (). write (compute [0]);
} Catch (IOException e ){
E. printStackTrace ();
}
}
Private Integer extractFromRequest (ServletRequest req ){
Return Integer. valueOf (100 );
}
}