美文网首页
构建高效且可伸缩的结果缓存

构建高效且可伸缩的结果缓存

作者: zlcook | 来源:发表于2017-08-20 16:51 被阅读19次
    • 使用ConcurrentMap而不使用HashMap可以提高并发性,即避免下面问题:

      • 使用HashMap需要对整个compute加锁,synchronized


        并发性降低
    • 缓存Map中存放Future而不使用最终的结果,可以避免同一个key被计算多次情况。如下:

    相同值计算两次
    • 使用ConcurrentMap接口的putIfAbsent方法(“先检查再执行”的原子性操作)而不是put,可以避免重复计算问题,如下:
    相同值计算2次
    package net.jcip.examples;
    import java.util.concurrent.*;
    public class Memoizer <A, V> implements Computable<A, V> {
        private final ConcurrentMap<A, Future<V>> cache
                = new ConcurrentHashMap<A, Future<V>>();
        private final Computable<A, V> c;
    
        public Memoizer(Computable<A, V> c) {
            this.c = c;
        }
    
        public V compute(final A arg) throws InterruptedException {
            while (true) {
                Future<V> f = cache.get(arg);
                if (f == null) {
                    Callable<V> eval = new Callable<V>() {
                        public V call() throws InterruptedException {
                            return c.compute(arg);
                        }
                    };
                    FutureTask<V> ft = new FutureTask<V>(eval);
                    f = cache.putIfAbsent(arg, ft);
                    if (f == null) {
                        f = ft;
                        ft.run();  //将会调用c.compute(arg)
                    }
                }
                try {
                    return f.get();
                } catch (CancellationException e) {
                    cache.remove(arg, f);
                } catch (ExecutionException e) {
                    throw LaunderThrowable.launderThrowable(e.getCause());
                }
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:构建高效且可伸缩的结果缓存

          本文链接:https://www.haomeiwen.com/subject/amotdxtx.html