风一更--软件开发--Java 缓存
目的:基于Java 语言特性的本地缓存
1. FutureTask concurrencyHashMap, <JUC> p89
当缓存的是 Future 而不是值时,将导致 Cache Pollution 缓存污染问题. 在 取消和异常时要 remove
FutureTask 子类解决 缓存逾期问题.
缓存清理待解.
public class Memorization_4<A,V> implements Computable<A,V> { private final Map<A, Future<V>> cache = new ConcurrentHashMap<>(); private final Computable<A,V> computable; public Memorization_4(Computable<A,V> computable){ this.computable = computable; } @Override public V compute(A arg) throws InterruptedException { while(true){ Future<V> future = this.cache.get(arg); if(future == null){ Callable<V> eval = new Callable<V>() { @Override public V call() throws Exception { return computable.compute(arg); } }; FutureTask<V> futureTask = new FutureTask<>(eval); future = this.cache.putIfAbsent(arg,futureTask); if(future == null){ future = futureTask; futureTask.run(); } } try{ return future.get(); }catch (CancellationException ex){ this.cache.remove(arg,future); } catch (ExecutionException e){ throw launderThrowable(e.getCause()); } } } }
public class launderThrowable { public static RuntimeException launderThrowable(Throwable t){ if(t instanceof RuntimeException){ return (RuntimeException)t; }else if(t instanceof Error){ throw (Error)t; }else{ throw new IllegalStateException("unchecked", t); } } }
2. 不可变对象,final, volatile 发布, 缓存
父类 静态成员(字段和代码块取决于顺序) -》子类的静态代码
父类实例成员-》父类构造函数 ->子类 实例成员 -》子类构造函数
因此构造函数入参和类变量关联的,要在构造函数内初始化
操作涉及的不可变数据多于一个的,要用 不可变容器来包含它们,以维持原子操作。
public class OneValueCache {
private final BigDecimal lastNumber;
private final BigDecimal[] lastFactors;
public OneValueCache(BigDecimal lastNumber, BigDecimal[] lastFactors) {
this.lastNumber = lastNumber;
this.lastFactors = Arrays.copyOf(lastFactors, lastFactors.length);
}
public BigDecimal[] getFactors(BigDecimal input){
if(lastNumber == null || !lastNumber.equals(input)){
return null;
}else{
return Arrays.copyOf(lastFactors,lastFactors.length);
}
}
}
public class VolatileCacheFactorizer implements Servlet { private volatile OneValueCache cache = new OneValueCache(null,null); @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { BigDecimal input =extractFromRequest(servletRequest); BigDecimal[] factors = cache.getFactors(input); if(factors == null){ factors = calculateFactor(input); cache = new OneValueCache(input,factors); } // return response } // ---- omit others ---- }

浙公网安备 33010602011771号