Дождитесь завершения следующего запуска задания.JAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Дождитесь завершения следующего запуска задания.

Сообщение Anonymous »

TL;DR
Как получить результат следующего запуска задания, которое может быть отменено?
Настройка
У меня есть тяжелый org.eclipse.core.runtime.jobs.Job, который обрабатывает данные из «Источника» и сохраняет их в «Результате».

Код: Выделить всё

private volatile Object source, result;
private static final class SyncJob extends Job {
@Override
public void run(IProgressMonitor monitor) {
result = process(source, monitor);
}
}
Внешний субъект меняет «Источник» через нерегулярные промежутки времени. Поскольку предполагается, что «Источник» и «Результат» в конечном итоге будут согласованными, задание перепланируется при каждом изменении «Источника». Поскольку старые данные из «Источника» уже не актуальны, я отменяю обработку предыдущего значения.

Код: Выделить всё

void handleEvent() {
source = data;
syncJob.cancel();
syncJob.schedule();
}
Это работает хорошо, и «Результат» в конечном итоге соответствует «Источнику».
Проблема
А новое требование — получить «Результат» для определенного «нового события» (в том смысле, что нам нужен результат процесса (источник, монитор) для заданного значения источника или для значения, которое было ему присвоено позже заданного значения, точное значение не важно, но оно должно быть «новее», чем то, которое создается в «newEvent»). Дополнительная сложность заключается в том, что это конкретное событие должно обрабатываться синхронно.
Решение 1
Наивным решением было бы следующее:

Код: Выделить всё

void handleNewEvent() {
source = data;
syncJob.cancel();
syncJob.schedule();
syncJob.join();
copy = result; // latest result?
}
Однако это не удастся, если
  • любое другое событие отменяет выполнение задания из другого потока, а затем «Результат» будет устаревшим, поскольку метод join() завершится, даже если задание будет перепланировано
    или предыдущий вызов задания завершится, несмотря на то, что он был отменен, по той же причине
Решение 2
Чтобы устранить эти проблемы, я пытаюсь:

Код: Выделить всё

void handleEvent() {
synchronized(syncJob) {
source = data;
syncJob.cancel();
syncJob.schedule();
}
}

void handleNewEvent() {
synchronized(syncJob) {
source = data;
syncJob.cancel();
syncJob.schedule();
}
for (;;) {
syncJob.join();
synchronized(syncJob) {
if (job.getState() == Job.NONE) { // can this happen before before last completion?
break;
}
}
}
copy = result; // latest result?
}
Однако нет никаких гарантий относительно семантики Job.getState(), и я не уверен, что она надежно синхронизирована с Job.schedule().< /p>
Решение 3
Другой вариант — обнаружить завершение, установив флаг после процесса():

Код: Выделить всё

private volatile Object source, result;
private volatile boolean completed = false;
private static final class SyncJob extends Job {
@Override
public void run(IProgressMonitor monitor) {
result = process(source, monitor);
completed = true;
}
@Override
public boolean shouldSchedule() {
completed = false;
return true;
}
}

void handleNewEvent() {
synchronized(syncJob) {
source = data;
syncJob.cancel();
syncJob.schedule();
}
for (;;) {
syncJob.join();
if (completed) { // will this ever happen?
break;
}
}
copy = result;
}
Однако это будет зависать навсегда, если пользователь или внешняя система отменит задание.
Я мог бы объединить несколько подходов, добавить прослушиватели заданий и проверьте getResult() задания, но я не чувствую, что достиг надежного решения.
Каков реальный и практический способ получить «Результат»? из данных определенного события с поддержкой отмены и перезапуска?

Подробнее здесь: https://stackoverflow.com/questions/791 ... n-of-a-job
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»