风一更--软件开发--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());
            }
        }
    }
}
View Code
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);
        }
    }
}
View Code

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);
      }
  }

}
View Code
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 ----   
}
View Code

 

posted @ 2023-01-23 18:37  君子之行  阅读(9)  评论(0)    收藏  举报