重用对象而不阻止它被垃圾回收

时间:2016-01-24 19:03:12

标签: java garbage-collection synchronized volatile

我想编写一个类,其中一个实例字段包含大量创建成本高昂的数据。因为创建对象非常耗时,我希望单独的实例能够重用该对象(如果已经为不同的实例计算了它)。另一方面,如果该类的所有实例都被垃圾收集,我希望大对象也能够被垃圾收集。

我想出了以下代码。

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();
}

此代码似乎有效,但我不确定我是否正确使用volatilesynchronizedWeakReference和双重检查习惯用法。任何人都可以看到此代码有任何问题,或建议一种替代/更好的方法来实现这一目标吗?

1 个答案:

答案 0 :(得分:0)

对我来说很好,但我认为volatile不是必需的。至少如果您只是从synchronized块中分配,synchronization块应该阻止memory consistency errors