Letztes Mal habe ich einen Artikel geschrieben Ausgabe in Datei mit Java protokollieren. Aus diesem Grund habe ich geschrieben, dass die Protokolldatei anscheinend exklusiv gesteuert werden kann, indem die Protokollausgabemethode in die synkronisierte Methode geändert wird. Daher möchte ich sie diesmal überprüfen.
Führen Sie 10 Threads aus, die die Protokollausgabemethode 10000 Mal parallel aufrufen, und prüfen Sie, ob das von jedem Thread angegebene Protokoll vollständig in die Protokolldatei ausgegeben wird.
Für Threads gibt es verschiedene Beispiele, daher ist keine Erklärung erforderlich. Die Protokollausgabemethode wurde in die writeLog-Methode der LogWriter-Klasse verschoben, damit sie von verschiedenen Threads aufgerufen werden kann.
LogWriterTest.java
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Calendar;
import java.io.*;
public class LogWriterTest{
public static void main(String[] argv){
ThreadSample[] threadSamples = new ThreadSample[10];
//Fadenvorbereitung
for (int i = 0; i < threadSamples.length; i++) {
threadSamples[i] = new ThreadSample("Trhead[" + i + "]");
}
//Thread starten
for (int i = 0; i < threadSamples.length; i++) {
threadSamples[i].start();
}
}
}
//Protokollausgabeklasse
class LogWriter {
public static SimpleDateFormat sdf = new SimpleDateFormat("YYYY/MM/dd HH:mm:ss");
//Protokollausgabemethode
public static synchronized void writeLog(String text) {
Calendar calendar = Calendar.getInstance();
String OUTPUT_DIR = "out";
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH) + 1;
Date date = calendar.getTime();
String yearStr = String.format("%04d", year);
String monthStr = String.format("%02d", month);
//Protokollausgabe
String file_name = OUTPUT_DIR + File.separator + yearStr + "_" + monthStr + ".log";
File file = new File(file_name);
FileWriter fw = null;
String line = sdf.format(date) + "," + text;
try {
fw = new FileWriter(file, true);
fw.write(line + "\n");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fw != null) {
try {
fw.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}
}
class ThreadSample extends Thread {
//Threadname
private String name = null;
public ThreadSample(String name) {
this.name = name;
}
//Thread, der 10000 Zeilen in das Protokoll schreibt
public void run() {
for (int i = 0; i < 10000; i++) {
System.out.println(name + "," + i);
LogWriter.writeLog(name + "," + i + ":hogehoge");
}
}
}
Der Inhalt der Datei sollte nicht so beschädigt werden. Sie können auch sehen, dass die Protokolle verschiedener Threads parallel in die Datei ausgegeben werden.
2020/05/23 09:48:59,Trhead[2],0:hogehoge
2020/05/23 09:48:59,Trhead[5],0:hogehoge
2020/05/23 09:48:59,Trhead[6],0:hogehoge
2020/05/23 09:48:59,Trhead[9],0:hogehoge
2020/05/23 09:48:59,Trhead[0],0:hogehoge
2020/05/23 09:48:59,Trhead[7],0:hogehoge
2020/05/23 09:48:59,Trhead[8],0:hogehoge
2020/05/23 09:48:59,Trhead[3],0:hogehoge
2020/05/23 09:48:59,Trhead[1],0:hogehoge
2020/05/23 09:48:59,Trhead[4],0:hogehoge
2020/05/23 09:48:59,Trhead[1],1:hogehoge
2020/05/23 09:48:59,Trhead[3],1:hogehoge
2020/05/23 09:48:59,Trhead[8],1:hogehoge
2020/05/23 09:48:59,Trhead[7],1:hogehoge
2020/05/23 09:48:59,Trhead[0],1:hogehoge
2020/05/23 09:48:59,Trhead[9],1:hogehoge
2020/05/23 09:48:59,Trhead[6],1:hogehoge
2020/05/23 09:48:59,Trhead[5],1:hogehoge
2020/05/23 09:48:59,Trhead[2],1:hogehoge
2020/05/23 09:48:59,Trhead[5],2:hogehoge
2020/05/23 09:48:59,Trhead[6],2:hogehoge
Die Anzahl der Fälle betrug 10.000 für jeden Thread, insgesamt 100.000, und es wurde bestätigt, dass alle Fälle ausgegeben wurden.
$ grep 'Trhead\[0\]' 2020_05.log |wc -l
10000
$ grep 'Trhead\[1\]' 2020_05.log |wc -l
10000
$ grep 'Trhead\[2\]' 2020_05.log |wc -l
10000
$ grep 'Trhead\[3\]' 2020_05.log |wc -l
10000
$ grep 'Trhead\[4\]' 2020_05.log |wc -l
10000
$ grep 'Trhead\[5\]' 2020_05.log |wc -l
10000
$ grep 'Trhead\[6\]' 2020_05.log |wc -l
10000
$ grep 'Trhead\[7\]' 2020_05.log |wc -l
10000
$ grep 'Trhead\[8\]' 2020_05.log |wc -l
10000
$ grep 'Trhead\[9\]' 2020_05.log |wc -l
10000
$ wc -l 2020_05.log
100000 2020_05.log
Ich werde mit dieser Methode ein Schlagprotokoll ausgeben!
Übrigens wurde das Protokoll auch ohne Synchronisierung ausnahmslos in einer kleinen Jobumgebung ausgegeben. Die Verarbeitung war ebenfalls überwältigend schnell. Es kann jedoch ein Zufall sein, daher ist es besser, synkronisiert hinzuzufügen, selbst wenn Sie die Verarbeitungszeit opfern.
In einem kleinen Programm wird das Datum verarbeitet und der Dateiname in der synchronisierten Methode ermittelt. Wenn Sie dies jedoch auf den Aufrufer verschieben und die Verarbeitungszeit für die Synchronisierung verkürzen, ist dies möglicherweise etwas schneller (noch nicht). Experiment).
Recommended Posts