Подобных вопросов очень много, но у меня ни одно решение не помогло.
У меня есть Callable, который должен работать определенное время. Во время выполнения метода Call он должен периодически выполнять некоторые проверки в условии while, чтобы проверить, должен ли он продолжать работу. Я также хочу иметь возможность останавливать вызываемый извне (вызов API).
Приведенный ниже код является упрощенной версией, но имеет ту же проблему:
Когда вызываемый объект возвращается, поток остается в состоянии WAITING. Как мне убить эту ветку?
public class MyCallable implements Callable<Foo> {
private AtomicBoolean stop = new AtomicBoolean(false);
@Override
public Foo call() {
System.out.printf("New thread with ID=%d\n",
Thread.currentThread().getId());
Foo foo = new Foo();
while (!stop.get()) {
try {
Thread.sleep(1000); // Sleep for some time before doing checks again
} catch (InterruptedException e) {
}
}
System.out.printf("State before returning foo: %s\n",
Thread.currentThread().getState());
return foo;
}
public void stop() {
this.stop.set(true);
}
}
public class Main {
public static void main(String[] args) throws InterruptedException {
MyCallable myCallable = new MyCallable();
ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
Future<Foo> future = executorService.submit(myCallable);
printThreads();
System.out.println("Calling stop\n");
myCallable.stop();
while (!future.isDone()) {
Thread.sleep(200);
}
System.out.println("After future is done: ");
printThreads();
}
// Helper method
private static void printThreads() {
List<Thread> threads = Thread.getAllStackTraces().keySet()
.stream()
.filter(t -> t.getName().contains("pool"))
.collect(Collectors.toList());
threads.forEach(t -> System.out.printf("ID=%s STATE=%s\t\n", t.getId(), t.getState()));
System.out.println();
}
}
Это результат работы программы
1 ответ
Вам не нужно вручную закрывать потоки, управляемые ExecutorService
. Вам нужно корректно закрыть службу, и она завершит свои потоки.
executorService.shutdown();
Обычно поток-воркер не завершается после выполнения одной задачи. Он переводится в состояние WAITING
до появления новой задачи. Эти вещи управляются ExecutorService
. Его закрытие приведет к завершению потоков, за которые он отвечает.
Похожие вопросы
Новые вопросы
java
Java - это язык программирования высокого уровня. Используйте этот тег, если у вас возникли проблемы с использованием или пониманием самого языка. Этот тег редко используется отдельно и чаще всего используется вместе с [spring], [spring-boot], [jakarta-ee], [android], [javafx], [hadoop], [gradle] и [maven].