zoukankan      html  css  js  c++  java
  • 构建高效可申缩的结果缓存

    摘自<<JAVA并发编程实战>>

    public interface Computable<A, V> {
        V comput(A arg);
    }
    import java.util.concurrent.*;
    
    /**
     * 构建高效可申缩的结果缓存
     * <p>
     * author: shiruiqiang
     * time: 31/01/2017 23:11
     **/
    public class Memoizer<A, V> implements Computable<A, V>{
        private final ConcurrentHashMap<A, Future<V>> cache = new ConcurrentHashMap<A, Future<V>>();
        private Computable<A, V> c;
        public Memoizer(Computable c) {
            this.c = c;
        }
        public V comput(A arg) {
            while(true) {
                Future<V> f = cache.get(arg);
                if (f == null) { // 检查是缓存中是否已经存在,如果没有就创建
                    Callable<V> task = new Callable<V>() {
                        @Override
                        public V call() throws Exception {
                            return c.comput(arg);
                        }
                    };
                    FutureTask<V> ft = new FutureTask(task);
                    f = cache.putIfAbsent(arg, ft); // 原子操作,不会重复计算
                    if (f == null) { // 如果缓存中原来没有这个结果则执行任务计算结果
                        f = ft;
                        ft.run();
                    }
                }
                try {
                    return f.get(); // 阻塞,等待结果.如果已经在缓存中则不会阻塞
                } catch(CancellationException e) {
                    cache.remove(arg, f);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    上述代码有多方面好处

    1:计算与缓存隔离,解偶

    2:线程安全

    3:支持并发

    4:并发时不会重复计算,高效

  • 相关阅读:
    第一次作业(2)
    第0次作业(2)
    最后一次作业—总结报告
    第八次作业
    第七周作业
    第六周作业
    第四周作业
    第4次作业
    2018c语言第3次作业
    2018c语言第2次作业
  • 原文地址:https://www.cnblogs.com/taixuyingcai/p/6359640.html
Copyright © 2011-2022 走看看