Можно ли убить 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);
}