Можно ли убить Runnable task внути run()

Передо мной стоит следующая задача - нужно оставить опрашивать сервер после того как проверяемое поле станет равно "ready" (образно). Каждый раз, когда я создаю определенный объект и передаю его на сервер, я каждый 2 секунды проверяю не изменилось ли состояние каждого такого объекта (REST) с помощью scheduledExecutorService.scheduleAtFixedRate(runnableTask, 0, 2, TimeUnit.SECONDS). Если одно из полей конкретного объекта станет равно "ready", то я должен убить поток который опрашивал этот объект, но остальные объекты должны продолжать опрашиваться. Я попробовал сделать проверку на "ready" прямо внутри run() и за ней Thread.currentThread().interrupt(); но это не сработало, поток не остановился (код ниже). Как можно реализовать остановку конкретно потока?

ScheduledExecutorService executorService = Executors.newScheduledThreadPool(50);

public void checkById(String id) {
    Runnable runnableTask = () -> {
        Pojo pojo = getById(id);
        if (pojo.getStatus.equals("ready")) {
            System.out.println("Interrupted");
            Thread.currentThread().interrupt();
        }
    };
    executorService.scheduleAtFixedRate(runnableTask, 0, 2, TimeUnit.SECONDS);
}

Ответы (1 шт):

Автор решения: Дмитрий Никифоров

Преимущество при использовании Executors: с тредами работают за вас. Так что вам не нужно убивать тред (к тому же interrupt() несколько для другого нужен), а нужно отменить запланированное повторение таска.

Изнутри, наверное, проще всего выбросить исключение при выполнении нужного условия. Согласно документации, это предотвращает последующие выполнения этого задания.

Runnable task2 = () -> {
  ...
  if (...) throw new CancellationException();
};

Для полноты картины, снаружи это можно сделать используя объект, возвращаемый методом scheduleAtFixedRate:

ScheduledFuture<?> t =
    executorService.scheduleAtFixedRate(runnableTask, 0, 2, TimeUnit.SECONDS);
if (...) {
  t.cancel(false);
}
→ Ссылка