Ответ
Прямого ограничения на количество одновременно обрабатываемых файлов нет. Параллелизм определяется уровнем параллелизма (parallelism level) пула и стратегией разделения задачи.
Ключевые факторы:
- Уровень параллелизма: По умолчанию равен
Runtime.getRuntime().availableProcessors(). Это количество рабочих потоков.ForkJoinPool pool = new ForkJoinPool(4); // 4 рабочих потока - Рекурсивное разделение (Fork): Задача может рекурсивно делиться на множество подзадач (например, по одному на файл). Все они попадают в общую очередь пула.
- Work-Stealing алгоритм: Простаивающие потоки могут "красть" задачи из очереди других потоков, что повышает утилизацию.
Пример обработки директории:
class FileProcessingTask extends RecursiveAction {
private File file;
FileProcessingTask(File file) { this.file = file; }
@Override
protected void compute() {
if (file.isDirectory()) {
// Fork подзадачи для каждого файла в директории
List<FileProcessingTask> subtasks = new ArrayList<>();
for (File f : file.listFiles()) {
subtasks.add(new FileProcessingTask(f));
}
ForkJoinTask.invokeAll(subtasks); // Параллельное выполнение
} else {
processFile(file); // Обработка одного файла
}
}
private void processFile(File f) { /* ... */ }
}
// Использование
ForkJoinPool.commonPool().invoke(new FileProcessingTask(rootDir));
Важное предупреждение: ForkJoinPool оптимизирован для вычислительно интенсивных (CPU-bound) задач с коротким временем жизни. Для I/O-операций (чтение/запись файлов) его использование неэффективно, так как потоки будут блокироваться. Для I/O лучше подойдет:
Executors.newFixedThreadPoolс размером, подобранным под возможности диска/сети.CompletableFutureс собственным пулом для асинхронных операций.