Спасибо каждому из вас за то, что вы ответили, а также за то, что указали на очевидные ошибки в коде, который я вставил.Я дам контекст проблемы, которую я решаю.
Я буду получать запросы (каждый запрос будет иметь набор идентификаторов задач);У меня есть пул потоков, который будет использоваться для отправки этого запроса (пакет задач для каждого запроса).Я буду принимать от клиентов слушателей, которые будут вызваны после завершения задачи.В текущем контексте я мог бы использовать ExecutorCompletionService
для ожидания выполнения всех задач, соответствующих запросу, однако я не хочу делать какие-либо блокирующие вызовы.
Вместо этого я хочу создать подкласс FutureTask
(переопределить done()
метод), и это будет реализовано в newTaskFor()
моей службы исполнителя подклассов.Все будущие задачи, соответствующие одному запросу, будут иметь общий TaskCompletionListener
, а в методе переопределения done()
вызовет один из success()
, error()
или отменится.TaskCompletionListener
будет инициализирован с начальным набором идентификатора задачи (количество задач) и для каждого вызова будет уменьшать счет на единицу, после чего будет сообщено о завершении.
Вот измененная версиякод, я надеюсь, что на этот раз я не совершил много ошибок (и да, еще раз спасибо за все ответы в прошлый раз).
public class TaskCompletionListener implements ITaskCompletionListener {
private final AtomicInteger taskCount;
private final IProcessCompletionListener completionListener;
public TaskCompletionListener(final HashSet<String> pTaskIds, IProcessCompletionListener pCompletionListener) {
taskCount = new AtomicInteger(pTaskIds.size());
completionListener = pCompletionListener;
}
// invoked concurrently
@Override
public void onCancel(String pTaskId) {
checkCompletion();
}
// invoked concurrently
@Override
public void onError(String pTaskId) {
checkCompletion();
}
// invoked concurrently
@Override
public void onSuccess(String pTaskId) {
checkCompletion();
}
private void checkCompletion() {
// method level confinement
int currentCount = taskCount.decrementAndGet();
if (currentCount == 0) {
completionListener.onProcessComplete();
}
}
interface IProcessCompletionListener {
void onProcessComplete();
}
}