Я снова и снова сталкиваюсь с подобной проблемой: есть некоторый фрагмент кода, который обрабатывает данные, когда они поступают от пользователя / сети / производит какой-то вид. Из соображений эффективности я не хочу вызывать flush()
или commit()
для каждой части данных, которые я получаю, но только изредка.
Я обычно придумываю такой код:
class Processor {
private final static MAX_SAVE_PERIOD = 60000;
private final static MIN_SAVE_PERIOD = 20000;
private final static int MAX_BUFFER = 10000;
Arraylist<Data> dataBuffer = new Arraylist<Data>();
private long lastSave = 0;
public Saver() {
new Timer().schedule(new TimerTask() {
periodicSave();
}, MAX_SAVE_PERIOD, MAX_SAVE_PERIOD);
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
public void run() {
periodicSave();
}
}));
}
public synchronized void processData(Data data) {
dataBuffer.add(data);
if(dataBuffer.size() >= MAX_BUFFER) {
saveData();
}
}
private synchronzied void periodicSave() {
if(!dataBuffer.isEmpty()) {
saveData();
}
}
private void saveData() {
if (System.currentTimeMillis() - lastSave < MIN_SAVE_PERIOD) return;
...
lastSave = System.currentTimeMillis();
}
}
У меня появляется отчетливое ощущение, что я заново изобретаю колесо каждый раз, когда пишу это, и, более того, я продолжаю менять вещи каждый раз, когда пишу такой код, в зависимости от того, имеют ли различные части смысл в конкретном контексте.
Мне кажется, что это очень распространенный шаблон, но я не помню, чтобы он был назван или реализован как утилита библиотеки. Пока я должен реализовать это сам, я продолжаю сталкиваться с параличом анализа всякий раз, когда переопределяю его. Пожалуйста, помогите мне!
ОБНОВЛЕНИЕ : После того, как я написал это, я понял, что не учитывал очистку буфера до завершения работы JVM, поэтому я добавил в конструктор ловушку отключения. Теперь я понял, что этот код по-прежнему не будет работать должным образом, если завершение работы произойдет менее чем через MIN_SAVE_PERIOD
миллисекунд после последнего сохранения, поэтому мне, вероятно, следует выполнить рефакторинг saveData
. Это происходит снова.