延迟加载参考实现

Pau*_*ora 12 java lazy-loading reference guava

由于Guava的计算地图功能给我留下了深刻印象,我正在寻找一种"计算参考" - 一种延迟加载参考实现,它与Guava的易用性并行,我的意思是它处理引擎盖下的所有锁定,加载和异常处理,只暴露一种get()方法.

经过短暂的搜索后,我迅速将自己作为概念证明:

public abstract class ComputingRef<T> implements Callable<T> {

   private volatile T referent = null;
   private Lock lock = new ReentrantLock();

   public T get() {
      T temp = referent;
      if (temp == null) {
         lock.lock();
         try {
            temp = referent;
            if (temp == null) {
               try {
                  referent = temp = call();
               }
               catch (Exception e) {
                  if (e instanceof RuntimeException) {
                     throw (RuntimeException)e;
                  }
                  else {
                     throw new RuntimeException(e);
                  }
               }
            }
         }
         finally {
            lock.unlock();
         }
      }
      return temp;
   }
}
Run Code Online (Sandbox Code Playgroud)

ComputingRef可以匿名扩展实现call(),它作为工厂方法:

ComputingRef<MyObject> lazySingletonRef = new ComputingRef<MyObject>() {
   @Override
   public MyObject call() {
      //fetch MyObject from database and return
   }
};
Run Code Online (Sandbox Code Playgroud)

我不满意这个实现是最佳的,但它证明了我所追求的.

我后来在T2框架中找到了这个例子,看起来更复杂.

现在我的问题是:

  • 我的上述代码如何改进?
  • 它与T2示例相比如何,该示例的复杂性有哪些优势呢?
  • 我在搜索中错过了其他延迟加载引用的实现吗?

编辑:更新我的实现以使用@ irreputable的答案建议的局部变量- 如果你发现上面的例子有用,请点它.

Ben*_*nes 24

看到Suppliers.memoize(Supplier)懒惰地初始化一个值.