Я хочу написать класс, в котором поле экземпляра содержит большой объем данных, который стоит создавать. Поскольку объект занимает много времени для создания, я хочу, чтобы отдельные экземпляры могли повторно использовать объект, если он уже был вычислен для другого экземпляра. С другой стороны, если все экземпляры класса собираются с мусором, я хочу, чтобы большой объект мог быть собран с помощью мусора.Повторное использование объекта, не мешая ему собирать мусор
Я придумал код, как показано ниже.
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
и двойной проверки идиомы правильно. Может ли кто-нибудь увидеть какие-либо проблемы с этим кодом или предложить альтернативный/лучший способ достичь этого?