Можно ли создать 500 потоков в Java?

«Можно ли создать 500 потоков в Java?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Да, технически возможно, но крайне не рекомендуется из-за высоких накладных расходов.

Проблемы с 500 потоками:

  • Потребление памяти: Каждый поток выделяет стек (по умолчанию ~1 МБ). 500 потоков ≈ 500 МБ только на стеки.
  • Переключение контекста: Частые переключения между большим количеством потоков создают нагрузку на планировщик ОС, деградируя производительность.
  • Конкуренция (Contention): Увеличивается борьба за общие ресурсы (процессор, блокировки).
  • Риск OutOfMemoryError: Может исчерпаться память под стеки или heap.
  • Ограничения ОС: Могут сработать системные лимиты (например, ulimit -u в Linux).

Пример создания (не рекомендуется):

for (int i = 0; i < 500; i++) {
    new Thread(() -> {
        // Логика потока
    }).start();
}

Правильный подход — пул потоков: Используйте ExecutorService с фиксированным размером пула, основанным на доступных ядрах процессора.

import java.util.concurrent.*;

// Оптимальный размер часто равен количеству ядер CPU
int coreCount = Runtime.getRuntime().availableProcessors();
ExecutorService executor = Executors.newFixedThreadPool(coreCount);

// Или используйте пул, адаптируемый под задачи
ExecutorService workStealingPool = Executors.newWorkStealingPool();