我想编写一个类,其中一个实例字段包含大量创建成本高昂的数据。因为创建对象非常耗时,我希望单独的实例能够重用该对象(如果已经为不同的实例计算了它)。另一方面,如果该类的所有实例都被垃圾收集,我希望大对象也能够被垃圾收集。
我想出了以下代码。
public class Example {
private Example() {}
private static volatile Reference<List<Integer>> ref = new WeakReference<>(null);
public static List<Integer> get() {
List<Integer> list;
if ((list = ref.get()) != null)
return list;
synchronized (Example.class) {
if ((list = ref.get()) != null)
return list;
list = compute();
ref = new WeakReference<>(list);
return list;
}
}
private static List<Integer> compute() {
// Some expensive computation producing a List with millions of elements
}
}
然后,您可以通过执行
使此列表成为实例字段public class MyClass {
private final List<Integer> list = Example.get();
}
此代码似乎有效,但我不确定我是否正确使用volatile
,synchronized
,WeakReference
和双重检查习惯用法。任何人都可以看到此代码有任何问题,或建议一种替代/更好的方法来实现这一目标吗?
答案 0 :(得分:0)
对我来说很好,但我认为volatile
不是必需的。至少如果您只是从synchronized
块中分配,synchronization
块应该阻止memory consistency errors