Традиционная мудрость говорит нам о том, что приложения большого объема предприятия Java должны использовать пул потоков, предпочитая создавать новые рабочие потоки. Использование java.util.concurrent
делает это простым.
Однако существуют ситуации, когда пул потоков не подходит. Конкретным примером, с которым я сейчас борюсь, является использование InheritableThreadLocal
, который позволяет передавать ThreadLocal
переменные вниз на любые порожденные потоки. Этот механизм ломается при использовании пулов потоков, поскольку рабочие потоки обычно не генерируются из потока запросов, но уже существуют.
Теперь есть пути вокруг этого (локаторы потоков могут быть явно переданы), но это не всегда правильно или практично. Самое простое решение - порождать новые рабочие потоки по запросу и InheritableThreadLocal
выполнять свою работу.
Это возвращает нас к вопросу - если у меня есть сайт с большим объемом, где потоки пользовательского запроса порождают полдюжины рабочих потоков каждый (т.е. не используют пул потоков), это приведет к тому, что JVM будет проблемой? Мы потенциально говорим о создании нескольких сотен новых потоков каждую секунду, каждая из которых длится менее секунды. Могут ли современные JVM оптимизировать это? Я помню дни, когда объединение объектов было желательно в Java, потому что создание объекта было дорогостоящим. С тех пор это стало ненужным. Мне интересно, относится ли это к пулу потоков.
Я бы оценил это, если бы знал, что измерить, но я боюсь, что проблемы могут быть более тонкими, чем можно измерить с помощью профилировщика.
Примечание: мудрость использования локаторов потоков здесь не проблема, поэтому, пожалуйста, не предлагайте, чтобы я их не использовал.