Ответ
Создание нативного потока ОС через new Thread().start() — дорогая операция по следующим причинам:
Основные затраты:
- Память: Каждому потоку выделяется собственный стек. Размер по умолчанию может быть значительным (например, 1 МБ на 64-битной JVM, задается параметром
-Xss). - Системные вызовы: JVM должна запросить у операционной системы создание нового нативного потока (например, pthread в Linux), что требует времени и ресурсов ядра ОС.
- Производительность: Частое создание потоков приводит к:
- Контекстным переключениям — сохранение/восстановление состояния потоков процессором, что снижает полезную нагрузку.
- Конкуренции за ресурсы (CPU, кэш).
Пример проблемного кода:
for (int i = 0; i < 1000; i++) {
new Thread(() -> doWork()).start(); // Катастрофически неэффективно
}
Решение — пулы потоков:
Используйте ExecutorService, который переиспользует заранее созданные потоки, минимизируя накладные расходы.
ExecutorService executor = Executors.newFixedThreadPool(10);
for (int i = 0; i < 1000; i++) {
executor.submit(() -> doWork()); // Задачи выполняются на 10 переиспользуемых потоках
}
executor.shutdown();