java - 懒加载引用实现

标签 java reference lazy-loading guava

Guava 的 computing map feature 给我留下了深刻的印象,我正在寻找一种“计算引用”——一种与 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;
   }
}

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

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

我不满意这个实现是最优的,但它展示了我所追求的。

后来我找到了 this example from the T2 Framework ,它看起来更复杂。

现在我的问题是:

  • 如何改进我的上述代码?
  • 它与 T2 示例相比如何,该示例的复杂性更高有哪些优势?
  • 是否有我在搜索中遗漏的延迟加载引用的其他实现?

编辑:按照 @irreputable's answer 的建议更新我的实现以使用局部变量 - 如果您觉得上面的示例有用,请点赞。

最佳答案

参见 Suppliers.memoize(Supplier)延迟初始化一个值。

关于java - 懒加载引用实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7524423/

相关文章:

java - 未报告的异常 ParseException;必须被捕获或声明被抛出——JAVA错误

java - 桌面应用程序和网络应用程序之间的通信?

c++ - 引用、 vector 、std::vector::at 和易于使用的接口(interface)

java - 使用 JPA 和 Hibernate 加载没有 N+1 笛卡尔积的递归对象图

java - 将接口(interface)作为方法中的参数传递

c - 将 16 位变量存储到取消引用的变量写入 32 位

c# - 如何在 Microsoft Azure 中的同一解决方案中引用项目

angular - 在 ngSwitch 中关闭延迟加载

c# - Entity Framework 已经有一个打开的 DataReader 与此命令关联,必须先将其关闭

java - 未识别 Android 手势,但正在调用 onGesturePerformed()。如何识别不同的手势?