Является ли Tomcat многопоточным
Что проверяют
Знаете ли вы, как сервлет-контейнер обслуживает нагрузку и что из этого следует для кода. Сам ответ очевиден, ценность в продолжении: устройство пула, потокобезопасность сервлетов и понимание, где приложение упирается на самом деле.
Как отвечать
Да, многопоточный. Экземпляр сервлета один на приложение, а его метод обработки вызывается параллельно из множества потоков.
Опишите схему. Соединения принимает отдельный поток, готовность сокетов отслеживает поллер, а рабочий поток из пула занимается запросом только на время обработки. Поэтому тысячи открытых keep-alive соединений не означают тысячи потоков: за число соединений отвечает maxConnections, за число одновременно обрабатываемых запросов maxThreads, а лишние подключения ждут в очереди acceptCount и после её переполнения отбрасываются.
Следствие для кода: поля сервлета, статические изменяемые структуры и общие кеши это разделяемое состояние, а локальные переменные и параметры безопасны. Долгая операция удерживает поток пула, поэтому для ожидания внешнего ответа есть асинхронная обработка через AsyncContext, которая возвращает поток в пул.
Сильный финал это оговорка про настройку: поднимать maxThreads бессмысленно, если приложение упирается в пул соединений к базе или во внешний сервис. Лишние потоки просто встанут в очередь за коннектом, добавив переключений контекста и памяти под стеки.
Где спотыкаются
Говорят, что на каждый запрос создаётся новый поток. Потоки берутся из пула и переиспользуются, иначе сервер не выдерживал бы всплесков; заодно теряется различие между соединением и запросом.
Хранят состояние в поле сервлета или в статической переменной. При одном пользователе в тестах всё работает, на проде начинаются перемешанные ответы и плавающие баги, которые не воспроизводятся поштучно.
Крутят число потоков вверх как универсальное лекарство. Пропускная способность упирается в базу, внешний сервис или сборку мусора, и после определённой точки рост пула только ухудшает время ответа.