В поисках наиболее правильного / элегантного способа блокирования / ожидания методов GET для объектов, пока объект сам обновляется.Пример кода для имитации ситуации ниже.
По сути, когда объект создается, он отправляется в источник данных и заполняет его элементы списка.Затем объект используется несколькими клиентами, которые регулярно вызывают различные методы GET для запроса списка элементов.
Внутренне объект обновляется и обновляется с использованием потока, который периодически обновляет списокitems.
Когда объект обновляется сам, все клиентские вызовы GET должны ждать / блокироваться до завершения обновления.И наоборот, обновление не должно начинаться, если в середине вызова метода GET находится клиент.
Я пробовал несколько различных способов достижения желаемой функциональности (например, уведомления / ожидания, а также защелки обратного отсчета).,Тем не менее, мне интересно, что люди считают «самым» правильным / лучшим / простым способом достижения этого?
Спасибо, Jab
public class MainResource {
private List<Item> items;
public MainResource() {
this.items = new ArrayList<Item>();
loadItems();
startRefreshTimer();
}
public Item getSpecificItem(int i) {
// This should wait if the items are being refreshed by the loadItems method
return this.items.get(i);
}
public List<Item> getAllItems() {
// This should wait if the items are being refreshed by the loadItems method
return this.items;
}
private void loadItems() {
// This should wait to execute if either the getSpecificItem() or getAllItems() methods are mid-execution
this.items.clear();
this.items.addAll(retrieveItems());
}
private List<Item> retrieveItems() {
List<Item> ret = new ArrayList<Item>();
// Do work to get all of the items.
// Typically takes a few seconds.
return ret;
}
private void startRefreshTimer() {
// Every few minutes, reload all of the items.
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
Runnable periodicTask = new Runnable() {
public void run() {
loadItems();
}
};
executor.scheduleAtFixedRate(periodicTask, 0, 120, TimeUnit.SECONDS);
}
}