Versuchen Sie, synchronisierte Methoden aus mehreren Threads in Java aufzurufen

Einführung

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.

Überprüfungsmethode

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.

Verifizierungsquelle

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");
        }
    }
}

Prüfergebnis

Der Inhalt der Datei

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

Nummer

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

abschließend

Ich werde mit dieser Methode ein Schlagprotokoll ausgeben!

Nachtrag 1

Ü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.

Nachtrag 2

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

Versuchen Sie, synchronisierte Methoden aus mehreren Threads in Java aufzurufen
Versuchen Sie, JavaScript in Java aufzurufen
Versuchen Sie, den CORBA-Dienst unter Java 11+ aufzurufen
Versuchen Sie, Nim von Java über JNI aufzurufen
Versuchen Sie, den CORBA-Dienst von Spring (Java) aus aufzurufen.
Verschiedene Threads in Java
Verhalten beim Aufrufen von Java-Argumentmethoden mit variabler Länge aus Scala / Kotlin / Java
Rufen wir IBM Watson Assistant 2018-07-10 aus dem Java SDK auf.
Versuchen Sie es mit RocksDB mit Java
Lassen Sie uns Spresense mit Java entwickeln (1)
Probieren Sie den Funktionstyp in Java aus! ①
Versuchen Sie, Android Hilt in Java zu implementieren
Versuchen Sie, Selenuim 3.141.59 mit Eclipse (Java) auszuführen.
Versuchen Sie einen If-Ausdruck in Java
Verketten Sie Zeichenfolgen, die von Mehrobjektmethoden in Java Stream zurückgegeben werden
Versuchen Sie, AWS X-Ray in Java auszuführen
Versuchen Sie, Yuma in Java zu implementieren
Fangen Sie mehrere Ausnahmen zusammen in Java
Beim Aufrufen von println usw. aus einer externen Java-Klassendatei in Processing
Lernen Sie Deep Learning von Grund auf in Java.
Bei der Suche nach mehreren in einem Java-Array
Versuchen Sie, Project Euler in Java zu lösen
Versuchen Sie, n-ary Addition in Java zu implementieren
Rufen Sie Java-Methoden aus JavaScript auf, das in Java ausgeführt wird
OCR in Java (Zeichenerkennung aus Bildern)
Versuchen Sie es mit der Stream-API in Java
Rufen Sie Java von C ++ auf Android NDK auf
Schlüssel vom Wert in Java Map umkehren
Führen Sie die Blockierungsverarbeitung mit dem Reaktor in mehreren Threads aus
Versuchen Sie es mit der JSON-Format-API in Java
Versuchen Sie, Kubernetes Job von Java aus auszuführen
Probieren Sie verschiedene Java Stream API-Methoden aus (jetzt)
Lassen Sie uns eine Taschenrechner-App mit Java erstellen
Abrufen des Verlaufs vom Zabbix-Server in Java
Versuchen Sie, Watson NLU, die Japanisch zu unterstützen scheint, vom Java SDK aus aufzurufen
Java-Methoden
Java-Methoden
GetInstance () aus einer @ Singleton-Klasse in Groovy aus Java
Versuchen Sie, etwa 30 Zeilen in Java zu kratzen (CSV-Ausgabe)
Java-Methodenaufruf von RPG (Methodenaufruf in eigener Klasse)
Versuchen Sie, ein Bulletin Board in Java zu erstellen
Zweite Abkochung: Versuchen Sie einen If-Ausdruck in Java
Versuchen Sie es mit Sourcetrail (Win-Version) mit Java-Code
Versuchen Sie, die Cloud Vision-API von GCP in Java zu verwenden
So erhalten Sie eine Klasse von Element in Java
Textextraktion in Java aus PDF mit pdfbox-2.0.8
Versuchen Sie es mit Sourcetrail (MacOS-Version) mit Java-Code
Erfassen und speichern Sie die Selen-Installation in Java
Holen Sie sich Unixtime (Sekunden) von ZonedDateTime in Scala / Java
Versuchen Sie, mit JZOS von Java aus auf das Dataset zuzugreifen
Überprüfen Sie das statische und öffentliche Verhalten in Java-Methoden
[Java] Ruft mehrere Werte von einem Rückgabewert ab
[Deep Learning von Grund auf neu] in Java 3. Neuronales Netzwerk
Versuchen Sie es mit der Syntaxanalyse der COTOHA-API in Java
Generieren Sie OffsetDateTime aus Clock und LocalDateTime in Java
[Java] KFunction von Method / Constructor in Java abrufen [Kotlin]