Чтобы ответить на ваш вопрос, нам нужно знать предполагаемый шаблон доступа к управляемым данным.
Как написано, ваш код обрабатывает шаблон доступа, где управляемые данные назначаются в некоторый момент времени после создания объекта, и где к управляемым данным можно получить доступ в любой момент времени после создания объекта, где присваивание происходит в одном потоке, а доступ происходит из других потоков. Это тот шаблон доступа, который вы намереваетесь поддерживать?
Вот небольшое обновление, помогающее прояснить код. Единственными отличиями являются синтаксические перестановки. Функция точно такая же.
Главное обновление, на которое следует обратить внимание, заключается в том, что присвоение «данным» производится в установщике. Это делает синхронизацию немного более понятной.
public class OuterClass {
// Some data to be managed. Centralize all explicit references.
private List<Data> data;
public synchronized List<Data> getData() { return data; }
public synchronized void setData(List<Data> data) { this.data = data; }
// An executor used to launch code which asynchronously
// compute and assigns the managed data.
private ScheduledExecutorService scheduledExecutorService;
// Tie into this instance lifecycle by launching
// a thread that computes and assigns managed data.
@PostConstruct
private void initialize(){
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
scheduledExecutorService.scheduleWithFixedDelay(new InnerClass(), // other configs);
}
// Code which computes the data ...
private List<Data> getDataFromOnlineDB() {/* some work */}
// A runnable used to asynchronously compute and assign the managed data.
private class InnerClass implements Runnable {
@Override
public void run() {
setData( getDataFromOnlineDB() );
}
}
}