Java-программа TextAnaлиз — безопасно писать в несколько потоков на JavaJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Java-программа TextAnaлиз — безопасно писать в несколько потоков на Java

Сообщение Anonymous »

Код: Выделить всё

package org.example;

/**
* Hello world!
*
*/
import java.io.*;
import java.util.*;
import java.util.stream.Collectors;

public class App {

public static void main(String[] args) throws InterruptedException, IOException {
String filename = "log.txt";
FileManager fileManager = new FileManager(filename);

// Thread für Fehler filtern
Thread errorThread = new Thread(() -> {
try {
List lines = fileManager.readFile();
List errors = lines.stream()
.filter(l -> l.startsWith("ERROR"))
.collect(Collectors.toList());
fileManager.writeFile("error.txt", errors);
} catch (IOException e) {
e.printStackTrace();
}
});

// Thread für Statistik
Thread statsThread = new Thread(() -> {
try {
List lines = fileManager.readFile();
Map stats = lines.stream()
.collect(Collectors.groupingBy(
line -> {
if(line.startsWith("INFO")) return "INFO";
else if(line.startsWith("WARNING")) return "WARNING";
else if(line.startsWith("ERROR")) return "ERROR";
else return "OTHER";
},
Collectors.counting()
));
fileManager.writeStats("stats.txt", stats);
} catch (IOException e) {
e.printStackTrace();
}
});

errorThread.start();
statsThread.start();

errorThread.join();
statsThread.join();

System.out.println("=== ERROR File ===");
fileManager.readFile().stream()
.filter(l -> l.startsWith("ERROR"))
.forEach(System.out::println);

System.out.println("=== Statistics ===");
try {
List statLines = fileManager.readFile("stats.txt");
statLines.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}

System.out.println("Processing finished.");
}
}

package org.example;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class FileManager {
private String filename;

public FileManager(String filename) {
this.filename = filename;
}

public synchronized void writeFile(String outFile, List lines) throws IOException {
try (BufferedWriter bw = new BufferedWriter(new FileWriter(outFile))) {
for(String line : lines) {
bw.write(line);
bw.newLine();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}

public synchronized void writeStats(String outFile, Map stats) throws IOException {
try (BufferedWriter bw = new BufferedWriter(new FileWriter(outFile))) {
for(Map.Entry entry : stats.entrySet()) {
bw.write(entry.getKey() + ": " + entry.getValue());
bw.newLine();
}
}
}

public List readFile() throws IOException {
return readFile(this.filename);
}

public List readFile(String file) throws IOException {
List  lines = new ArrayList();
try(BufferedReader br = new BufferedReader(new FileReader(file))) {
String line;
while((line = br.readLine()) != null) {
lines.add(line);
}
}
return lines;
}
}
Я работаю над программой Java, которая читает файл журнала () и обрабатывает его в двух отдельных потоках:
  • Один поток фильтрует строки, начинающиеся с ERROR, и записывает их в error.txt.
  • Другой поток вычисляет статистику для строк INFO, WARNING, ERROR и OTHER и записывает их в stats.txt.
Оба потока используют один и тот же экземпляр FileManager:

Код: Выделить всё

FileManager fileManager = new FileManager("log.txt");
В настоящее время методы writeFile и writeStats в FileManager синхронизированы. Несмотря на это, я иногда вижу неполные файлы или отсутствующие записи, когда оба потока работают одновременно.
Вопросы:
  • Достаточно ли использования синхронизированного в методах записи для безопасной записи файлов из нескольких потоков?
  • Можно ли читать (

    Код: Выделить всё

    readFile
    ) одновременно при записи вызывает проблемы?
  • Как лучше всего безопасно записывать различные выходные данные из нескольких потоков с использованием одного и того же файлового менеджера?
Будем признательны за любые рекомендации по потокобезопасным операциям с файлами в Java.>

Подробнее здесь: https://stackoverflow.com/questions/798 ... ds-in-java
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»