Как сделать чтобы один поток подсчитывал количество строк в одном файле, второй во втором и т.д.?
public class ThreadMain {
static ArrayList
public static void main(String[] args) {
String mask;
Scanner DIR_NAME = new Scanner(System.in);
Scanner MASK_NAME = new Scanner(System.in);
System.out.println("Введите директорию :");
getFilesList(DIR_NAME.nextLine());
System.out.println("Введите маску для поиска");
mask = MASK_NAME.nextLine();
System.out.println("Результат поиска :");
ExecutorService executor = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++) {
Runnable worker = new ThreadPools(FilesFind, mask);
executor.execute(worker);
}
executor.shutdown();
while (!executor.isTerminated()) {
}
System.out.println("Потоки закончили работу");
}
public static void getFilesList(String nameDirectory) {
File f = new File(nameDirectory);
for (File str : f.listFiles()) {
if (str.isFile()) {
FilesFind.add(str);
} else if (str.isDirectory()) {
getFilesList(str.getAbsolutePath());
}
}
}
}
Класс ThreadPools
class ThreadPools implements Runnable {
private ArrayList
ThreadPools(ArrayList
@Override
public void run() {
CountStrings();
}
public void CountStrings() {
for (File fill : FilesFindThread) {
try {
BufferedReader reader = new BufferedReader(new FileReader(fill));
int count = 0;
while ((search = reader.readLine()) != null) {
if (search.contains(maskThread) && !search.isEmpty()) {
count++;
}
}
reader.close();
System.out.println(Thread.currentThread().getName() + ":" + "Name files :" + fill.getName() + " ---- > " + count);
} catch (java.io.IOException e) {
System.out.println(e);
}
}
}
}
Ответ
Статический метод Executors.newFixedThreadPool предназначен для создания пула с фиксированным числом потоков (это число вы указываете в качестве параметра конструктора). Если количество задач будет больше числа доступных потоков, то они добавляются в очередь и извлекаются из нее по мере освобождения одного из потоков.
С помощью метода execute() мы запускаем выполнение определенной задачи (выполнение может начаться сразу или позже, см. выше).
Поскольку нам необходимо многопоточно обработать определенное число файлов, то просто добавляем их обработку в качестве очередной задачи, за все остальное уже отвечает ExecutorService
Для завершения выполнения пула потоков используем два метода:
shutdown() - сообщаем, что наш сервис больше не принимает никаких новых задач.
awaitTermination() - блокирующий метод пока все задачи не будут выполнены, либо текущий поток не будет прерван, либо не будет достигнут указанный таймаут.
Далее привожу пример многопоточного чтения файлов и подсчет количества строк в них. Пояснил код комментариями. Пример легко сможете адаптировать под свою задачу, добавив более сложную логику по поиску файлов на основе фильтров.
Основной метод для получения исходного каталога и запуска обработки файлов:
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
// Считываем исходный каталог для поиска файлов.
System.out.print("Введите исходную директорию для поиска файлов:");
final String directoryPath = reader.readLine();
reader.close();
File directory = new File(directoryPath);
// Убедимся, что директория найдена и это реально директория, а не файл.
if (directory.exists() && directory.isDirectory()) {
processDirectory(directory);
} else {
System.out.println("Не удалось найти директорию по указанному пути.");
}
} catch (IOException e) {
e.printStackTrace();
}
Метод processDirectory(File directory) для поиска файлов и их обработки:
private static void processDirectory(File directory) {
// Получаем список доступных файлов в указанной директории.
File[] files = directory.listFiles();
if (files == null) {
System.out.println("Нет доступных файлов для обработки.");
return;
} else {
System.out.println("Количество файлов для обработки: " + files.length);
}
// Непосредственно многопоточная обработка файлов.
ExecutorService service = Executors.newFixedThreadPool(10);
for (final File f : files) {
if (!f.isFile()) {
continue;
}
service.execute(new Runnable() {
@Override
public void run() {
try (BufferedReader reader = new BufferedReader(new FileReader(f))) {
int lines = 0;
while (reader.readLine() != null) {
++lines;
}
System.out.println("Поток: " + Thread.currentThread().getName() + ". Файл: " + f.getName() + ". Количество строк: " + lines);
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
// Новые задачи более не принимаем, выполняем только оставшиеся.
service.shutdown();
// Ждем завершения выполнения потоков не более 10 минут.
try {
service.awaitTermination(10, TimeUnit.MINUTES);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Пример выполнения данного кода:
Введите исходную директорию для поиска файлов: C:\projects\FindCentroid\src\pro\parshinpn
Количество файлов для обработки: 6
Поток: pool-1-thread-1. Файл: Cluster.java. Количество строк: 25
Поток: pool-1-thread-4. Файл: Point.java. Количество строк: 90
Поток: pool-1-thread-3. Файл: Graph.java. Количество строк: 120
Поток: pool-1-thread-2. Файл: Edge.java. Количество строк: 92
Поток: pool-1-thread-6. Файл: Vertex.java. Количество строк: 69
Поток: pool-1-thread-5. Файл: UnionFindStructure.java. Количество строк: 102
Комментариев нет:
Отправить комментарий