public class MainClass {
private static final int size = 5;
private ExecutorService prodExec = Executors.newFixedThreadPool(size);
private ExecutorService consExec = Executors.newFixedThreadPool(size);
//main method here
public void start(String[] args) {
for (int index = 0; index < size; index++) {
Runnable producer = new Producer(consExec, listOfIds);
prodExec.execute(producer);
}
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
prodExec.shutdown();
try {
prodExec.awaitTermination(10, TimeUnit.SECONDS);
} catch (InterruptedException ignore) {
}
consExec.shutdown();
try {
consExec.awaitTermination(10, TimeUnit.SECONDS);
} catch (InterruptedException ignore) {
}
}
});
}
}
public class Producer implements Runnable {
private ExecutorService consExec;
private List<Long> list;
public Producer(ExecutorService exec, List<Long> list) {
this.consExec = exec;
this.list = list;
}
public void run() {
for (Long id: list) {
data = get data from db for the id
consExec.execute(new Consumer(data));
}
}
}
public class Consumer implements Runnable {
public void run() {
// call web service
}
}
Я хотел бы обработать сценарий, когда пользователь запрашивает отключение, нажав Ctrl+C. Я думаю, что это можно сделать в хуке выключения. Однако, как и в приведенном выше коде, каждый производитель получает список идентификаторов (может быть, 250?) для обработки, т. е. вызывает базу данных для получения данных для идентификатора и отправки данных в поток-потребитель, который затем обращается к сети. услуга.
Как выйти из цикла for в каждом потоке Producer, если было запрошено отключение, чтобы каждый поток не обрабатывал идентификаторы, которые еще не были обработаны? Мне удалось заставить ShutDownHook работать, но я не уверен, как каждый поток должен включать логику в методе run для выхода из метода run() в случае запроса на завершение работы. Может быть, установив логическую переменную (AtomicBoolean) извне, чтобы каждый поток проверял цикл for перед обработкой каждого идентификатора?
Насколько я понимаю, если я вызываю shutdown(), он выполняет все отправленные задачи, а затем завершает работу. В этом случае невозможно остановить обработку, так как задачи уже поставлены в очередь на сервис-исполнитель.
Если я вызову shutdownNow() вместо shutdown(), это может привести к неожиданным результатам?