Запланированный исполнитель: опросить результат по фиксированной ставке и выйти, если тайм-аут или результат верны

Проблема: У меня есть требование вызывать метод dao с фиксированной скоростью, скажем, каждые 10 секунд, а затем мне нужно проверить, верен ли результат, если да, выйдите, иначе продолжайте вызывать этот метод каждые 10 секунд, пока я не получу действительный результат или определенное время ожидания. (скажем, 2 минуты) закончилась.

подходы: Я хочу разделить логику задачи и планировщика и написать задачу таким образом, чтобы она могла использоваться разными классами, имеющими схожие требования.

Один способ, которым я могу думать, - это определить новую задачу опроса

public abstract class PollerTask<T> implements Runnable {

    abstract public boolean isValid(T result);

    abstract public T task();

    private T result;

    private volatile boolean complete;

    public boolean isComplete() {
        return complete;
    }

    public T getResult() {
        return result;
    }

    @Override
    final public void run() {
        result = task();
        if (complete = isValid(result)) {
            //may be stop scheduler ??
        }

    }
}

Пользователю нужно просто обеспечить выполнение задачи и isValid;

Затем мы можем определить отдельный класс, который использует пул freq и timeout, создает запланированного исполнителя и отправляет эту задачу.

public class PollerTaskExecutor {

    private int pollingFreq;
    private int timeout;
    private ScheduledExecutorService executor;
    private ScheduledExecutorService terminator;
    private ExecutorService condition;
    private volatile boolean done;
    private ScheduledFuture future;

    public PollerTaskExecutor(int pollingFreq, int timeout) {
        this.pollingFreq = pollingFreq;
        this.timeout = timeout;
        executor = Executors.newSingleThreadScheduledExecutor();
        terminator = Executors.newSingleThreadScheduledExecutor();
        condition = Executors.newSingleThreadExecutor();
    }

    public void submitTaskForPolling(final PollerTask pollerTask) {
        future = executor.scheduleAtFixedRate(pollerTask, 0, pollingFreq, TimeUnit.SECONDS);
        terminator.schedule(new Runnable() {
            @Override
            public void run() {
                complete();
            }
        }, timeout, TimeUnit.SECONDS);
        condition.execute(new Runnable() {
            @Override
            public void run() {
                if (pollerTask.isComplete()) {
                    complete();
                }
            }
        });

    }

    public boolean isDone() {
        return done;
    }

    public void complete() {
        future.cancel(false);
        executor.shutdown();
        terminator.shutdown();
        condition.shutdown();
        done = true;

    }

Теперь пользователь может подождать, пока pollerExecutor.isDone вернет true и получить результат. Мне пришлось использовать трех исполнителей для следующих целей:

исполнитель для запуска задачи с фиксированным интерваломисполнитель, чтобы остановить все, когда время истеклоисполнитель, чтобы остановить все, если действительный результат получен до истечения времени ожидания.

Может кто-нибудь предложить лучший подход, это кажется сложным для такой тривиальной задачи?

Ответы на вопрос(2)

Ваш ответ на вопрос