Обычно у каждой задачи есть несколько решений. Надо обойти набор элементов? Меню JDK предлагает цикл
do, do while, for в двух вариантах, Stream API. Выбирай, что удобно или привычно.С многопоточкой такое не пройдёт. Здесь выбор инструмента влияет и на красоту кода, и на системные метрики. Расход памяти, задержки, скорость обработки и так далее.
Давайте разберём ситуацию в вопросе перед постом. Как выглядела картина ДО рефакторинга:
🔹 Сервис А в потоке X шлёт HTTP запрос в сервис Б.
🔹 Сервис Б принимает запрос, что-то считает и возвращает результат.
🔹 Пока Б развлекается, поток Х в сервисе А терпеливо ждёт.
Сколько (допустим) выполняется запрос
/stat:➕ Логика в сервисе А - 100мс
➕ Ожидание ответа сервиса Б - 500мс
➕ Обработка ответа - 100мс
Итого: 700мс
В java 11 добавилась опция асинхронных HTTP запросов. Что стало с системой ПОСЛЕ рефакторинга:
🔹 Сервис А шлёт асинхронный HTTP запрос в сервис Б.
🔹 Сервис Б работает над запросом.
🔹 Поток в сервисе А в это время делает другие задачи.
🔹 Cервис Б заканчивает работу.
🔹 На сервисе А вызывается коллбэк, который обрабатывает ответ сервиса Б.
Что получаем:
➕ Логика в сервисе А - 100мс
➕ Ожидание ответа от сервиса Б - 500мс
➕ Обработка ответа - 100мс
Итого: 700мс
Запрос
/stat не стал быстрее.Что изменилось?
Раньше поток сервиса А ждал ответ от Б и простаивал. Во время асинхронного запроса поток возвращается в планировщик и решает другие задачи.
Время выполнения запроса
/stat не меняется, но общее количество работы, которое выполняет сервис А, увеличивается. Пропускная способность растёт: сервис обрабатывает больше запросов в секунду, чем раньше. При небольшой нагрузке у сервиса может снизиться расход CPU. Но за такое редко выдают премии🙂
Так что правильный ответ на вопрос перед постом: увеличилась пропускная способность сервиса А.
Выводы
Иногда эффект многопоточных улучшений виден только под нагрузкой:
🔸 При работе с одним запросом разница может быть незаметна
🔸 Важно следить не только за кодом, но и за метриками