#java #многопоточность
Как сделать чтобы один поток подсчитывал количество строк в одном файле, второй во
втором и т.д.?
public class ThreadMain {
static ArrayList FilesFind = new 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 FilesFindThread;
private String maskThread;
private String search;
ThreadPools(ArrayList FilesFind, String mask) {
this.FilesFindThread = FilesFind;
this.maskThread = mask;
}
@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);
}
}
}
}
Ответы
Ответ 1
Статический метод 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
Комментариев нет:
Отправить комментарий