import java.util.concurrent.RecursiveTask;
public class SumTask extends RecursiveTask<Long> {
private final long[] array;
private final int start;
private final int end;
private final int threshold = 10_000; // Порог для разделения задачи
public SumTask(long[] array, int start, int end) {
this.array = array;
this.start = start;
this.end = end;
}
@Override
protected Long compute() {
int length = end - start;
if (length <= threshold) {
// 1. Базовый случай: задача достаточно мала, считаем напрямую
return sum();
} else {
// 2. Рекурсивный случай: задача большая, делим её
int mid = start + length / 2;
// Создаём задачу для левой половины
SumTask leftTask = new SumTask(array, start, mid);
// Создаём задачу для правой половины
SumTask rightTask = new SumTask(array, mid, end);
// Асинхронно выполняем левую задачу
leftTask.fork(); // ← "Вилкуем" задачу в пул
// Выполняем правую задачу в текущем потоке
Long rightResult = rightTask.compute(); // ← Эффективность: не создаём лишний поток
// Ждём завершения левой задачи и получаем результат
Long leftResult = leftTask.join(); // ← "Соединяем" результат
return leftResult + rightResult;
}
}
private long sum() {
long sum = 0;
for (int i = start; i < end; i++) {
sum += array[i];
}
return sum;
}
} import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;
import java.util.Random;
public class ForkJoinPoolDemo {
public static void main(String[] args) throws InterruptedException {
// Создаём большой массив для демонстрации
long[] numbers = new long[100_000_000];
Random random = new Random();
for (int i = 0; i < numbers.length; i++) {
numbers[i] = random.nextInt(100); // Заполняем случайными числами
}
// Создаём ForkJoinPool (обычно используют общий пул)
ForkJoinPool pool = new ForkJoinPool();
// Создаём корневую задачу
SumTask mainTask = new SumTask(numbers, 0, numbers.length);
long startTime = System.currentTimeMillis();
// Запускаем задачу и ждём результата
Long result = pool.invoke(mainTask); // ← invoke запускает и ждёт завершения
long endTime = System.currentTimeMillis();
System.out.println("Сумма: " + result);
System.out.println("Время выполнения: " + (endTime - startTime) + " мс");
pool.shutdown();
pool.awaitTermination(1, TimeUnit.MINUTES);
}
}
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.concurrent.RecursiveTask;
public class FileSearchTask extends RecursiveTask<Integer> {
private final File directory;
private final String searchText;
public FileSearchTask(File directory, String searchText) {
this.directory = directory;
this.searchText = searchText;
}
@Override
protected Integer compute() {
int count = 0;
File[] files = directory.listFiles();
if (files == null) {
return 0;
}
for (File file : files) {
if (file.isDirectory()) {
// Рекурсивно создаём задачу для поддиректории
FileSearchTask subTask = new FileSearchTask(file, searchText);
subTask.fork(); // ← Отправляем в пул
count += subTask.join(); // ← Добавляем результат
} else if (file.getName().endsWith(".txt")) {
// Базовый случай: ищем в текстовом файле
count += searchInFile(file);
}
}
return count;
}
private int searchInFile(File file) {
try {
String content = Files.readString(file.toPath());
if (content.contains(searchText)) {
System.out.println("Найдено в файле: " + file.getAbsolutePath());
return 1;
}
} catch (IOException e) {
System.err.println("Ошибка чтения файла: " + file.getAbsolutePath());
}
return 0;
}
} import java.io.File;
import java.util.concurrent.ForkJoinPool;
public class ParallelFileSearcher {
public static void main(String[] args) {
// Укажите путь к директории для поиска
File rootDir = new File("./"); // Текущая директория
String textToFind = "TODO";
// Используем общий пул ForkJoinPool
ForkJoinPool pool = ForkJoinPool.commonPool();
FileSearchTask task = new FileSearchTask(rootDir, textToFind);
System.out.println("Начинаем поиск текста '" + textToFind + "' в директории " + rootDir.getAbsolutePath());
long startTime = System.currentTimeMillis();
int totalMatches = pool.invoke(task);
long endTime = System.currentTimeMillis();
System.out.println("\\nПоиск завершён.");
System.out.println("Всего найдено совпадений: " + totalMatches);
System.out.println("Заняло времени: " + (endTime - startTime) + " мс");
}
}