以下来自 John Hann 的实现,这段代码引起了我的注意,它用巧妙的方法把方法调用的结果缓存起来了。
关于装饰器,书中用到的名字是 Memoizer,为啥是这个名字,也给了一个解释: 这个 Memoizer 装饰类应该长什么样呢?...首先 Memoizer 得实现 Computable 接口,然后重写其 compute 方法: public class Memoizer implements Computable<A,...所谓的“用装饰器”,不过就是这样的一行代码而已: Memoizer memoizer = new Memoizer(new ScoreQuery()); 用 Memoizer 这个通用类,来装饰了 ScoreQuery...所以,Memoizer 类里面还得搞一个缓存也就是 map,并且把它给用起来, public class Memoizer implements Computable {...memoizer = new Memoizer(new NucleicAcidTest()); 是不是扩展性一下就体现出来了。
ConcurrentHashMap下面我们进一步改进下,在 Memoizer2 中,通过 ConcurrentHashMap 代替 HashMap 来构建缓存,示例如下:public class Memoizer2...而言,Memoizer2 有着更好的并发性。...到目前为止,Memoizer3 在上述三个方案中属于最优方案。...ConcurrentHashMap + Future 改进版接下来我们继续改进下,在 Memoizer 中,使用 ConcurrentHashMap 中的原子方法 putIfAbsent,来避免 Memoizer3...因式分解Servlet应用结果缓存到目前为止,Memoizer 已经能够很好地满足高计算开销函数的要求。
使用函数的方式 在下面的代码片段中,我们创建了一个高阶的函数 memoizer。有了这个函数,将能够轻松地将缓存应用到任何函数。...从 memoizer 函数中,我们返回一个新函数,根据上面讨论的闭包原则,这个函数无论在哪里执行都可以访问 cache。...要将 memoizer 函数应用于最初递归的 fibonacci 函数,我们调用 memoizer 函数,将 fibonacci 函数作为参数传递进去。...const fibonacciMemoFunction = memoizer(fibonacciRecursive) 测试 memoizer 函数 当我们将 memoizer 函数与上面的例子进行比较时...,结果如下: memoizer 函数以 42,982,762 ops/sec 的速度提供了最快的解决方案,比之前考虑的解决方案速度要快 100%。
4 import java.util.Map; 5 6 /** 7 * Created by yulinfeng on 12/25/16. 8 */ 9 public class Memoizer1...final Map cache = new HashMap(); 11 private final Computable c; 12 13 public Memoizer1...> cache = new ConcurrentHashMap(); 11 private final Computable c; 12 13 public Memoizer2...= new ConcurrentHashMap>(); 12 private final Computable c; 13 14 public Memoizer3...= new ConcurrentHashMap>(); 10 private final Computable c; 11 12 public Memoizer
private final Map cache = new HashMap(); private final Computable c; public Memoizer1...* @param * @param */ class Memoizer2 implements Computable{ private final Map... cache = new ConcurrentHashMap(); private final Computable c; Memoizer2(Computable...final Map> cache = new ConcurrentHashMap(); private final Computable c; Memoizer3...} } /** * 使用ConcurrentHashMap的putIfAbsent解决原子问题 * 若计算取消则移除 * @param * @param */ class Memoizer
但又不能影响对象内容的情况下 三、应用案例 import functools def memoize(fn): known = dict() @functools.wraps(fn) def memoizer...if args not in known: known[args] = fn(*args) return known[args] return memoizer
以下是同步方法的实现方式: public class Memoizer1 implements Computable { @GuardedBy("this") private...final Map cache = new HashMap(); private final Computable c; public Memoizer1(Computable...} return result; }} 由于同步方法是对整个容器上锁,所以并发的效率不好,因此要使用并发容器作为计算结果的缓存,改进代码如下: public class Memoizer2...final Map cache = new ConcurrentHashMap(); private final Computable c; public Memoizer2...完善的代码如下: public class Memoizer implements Computable { // 记录那些结果的计算已经开始 private final
var memoizer=function(memo,fundamental){ var shell=function(n){ var result=memo[n];...memo[n]=result; } return result; }; return shell; }; var fibonacci=memoizer
例如: Supplier cachedValue = Memoizer.memoize(() -> expensiveDatabaseCall()); 上述代码中,Memoizer.memoize
return result; }; return fib; })(); fibonacci(10) //55 抽象的递归记忆函数 var memoizer...memo[n] = result; } return result; } return shell; }; var fibonacci = memoizer
不着急,下一小节说,我先把后半句话给解释了: 这个漏洞的发生概率要远小于 Memoizer2 中发生的概率。...Memoizer2 就是指前面用 ConcurrentHashMap 替换 HashMap 后的方案。 那么为什么引入 Future 之后的这个方案,触发刚刚说到的 bug 的概率比之前的方案小呢?
不过现在已经有一个解决方案Memoizer 其实很简单,就是用一个key来记录这次的Future,然后放在一个Map里,下次用到时再从Map里取出来。
classes/jdk/internal/jrtfs/SystemImage.class classes/jdk/internal/loader/AbstractClassLoaderValue$Memoizer...$RecursiveInvocationException.class classes/jdk/internal/loader/AbstractClassLoaderValue$Memoizer.class
领取专属 10元无门槛券
手把手带您无忧上云