Essayez d'appeler des méthodes synchronisées à partir de plusieurs threads en Java

introduction

La dernière fois, j'ai écrit un article Log output to file with Java. Par conséquent, j'ai écrit qu'il semble qu'un contrôle exclusif puisse être effectué sur le fichier journal en changeant la méthode de sortie du journal en méthode synchronisée, donc je voudrais le vérifier cette fois.

Méthode de vérification

Exécutez 10 threads qui appellent la méthode de sortie du journal 10000 fois en parallèle et vérifiez si le journal spécifié par chaque thread est sorti dans le fichier journal sans exception.

Source de vérification

En ce qui concerne les threads, il existe différents exemples, aucune explication n'est donc nécessaire. La méthode de sortie du journal a été déplacée vers la méthode writeLog de la classe LogWriter afin qu'elle puisse être appelée à partir de différents threads.

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];

        //Préparation du fil
        for (int i = 0; i < threadSamples.length; i++) {
            threadSamples[i] = new ThreadSample("Trhead["  + i + "]");
        }

        //Démarrer le fil
        for (int i = 0; i < threadSamples.length; i++) {
            threadSamples[i].start();
        }

    }
}

//Classe de sortie du journal
class LogWriter {
    public static SimpleDateFormat sdf = new SimpleDateFormat("YYYY/MM/dd HH:mm:ss");


    //Méthode de sortie du journal
    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);

        //Sortie de journal
        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 {

    //Nom du fil
    private String name = null;

    public ThreadSample(String name) {
        this.name = name;
    }

    //Thread qui écrit 10000 lignes dans le journal
    public void run() {
        for (int i = 0; i < 10000; i++) {
            System.out.println(name + "," + i);
            LogWriter.writeLog(name + "," + i + ":hogehoge");
        }
    }
}

résultat de l'inspection

Le contenu du fichier

Le contenu du fichier ne doit pas être corrompu de cette manière. Vous pouvez également voir que les journaux de différents threads sont générés dans le fichier en parallèle.

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

nombre

Le nombre de cas était de 10 000 pour chaque thread, pour un total de 100 000, et il a été confirmé que tous les cas étaient sortis.

$ 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

en conclusion

Utilisez cette méthode pour générer un journal de martèlement!

Addendum 1

À propos, même sans synchronisation, le journal a été produit sans exception dans un petit environnement de travail. Le traitement a également été extrêmement rapide. Cependant, cela peut être une coïncidence, il est donc préférable d'ajouter synchronisé au détriment du temps de traitement.

Addendum 2

Dans un petit programme, la date est traitée et le nom du fichier est déterminé dans la méthode synchronisée, mais si vous le déplacez vers l'appelant et raccourcissez le temps de traitement de la synchronisation, cela peut être un peu plus rapide (pas encore). Expérience).

Recommended Posts

Essayez d'appeler des méthodes synchronisées à partir de plusieurs threads en Java
Essayez d'appeler JavaScript en Java
Essayez d'appeler le service CORBA sur Java 11+
Essayez d'appeler Nim depuis Java via JNI
Essayez d'appeler le service CORBA depuis Spring (Java)
Divers threads en java
Comportement lors de l'appel des méthodes d'argument de longueur variable Java à partir de Scala / Kotlin / Java
Appelons IBM Watson Assistant 2018-07-10 à partir du SDK Java.
Essayez d'utiliser RocksDB avec Java
Essayez de développer Spresense avec Java (1)
Essayez le type fonctionnel en Java! ①
Essayez d'implémenter Android Hilt en Java
Essayez d'exécuter Selenuim 3.141.59 avec eclipse (java)
Essayez une expression If en Java
Concaténer les chaînes renvoyées par des méthodes multi-objets dans Java Stream
Essayez d'exécuter AWS X-Ray en Java
Essayez d'implémenter Yuma en Java
Attrapez plusieurs exceptions ensemble dans Java
Lors de l'appel de println etc. à partir d'un fichier de classe Java externe en traitement
Étudiez le Deep Learning à partir de zéro en Java.
Lors de la recherche de plusieurs dans un tableau Java
Essayez de résoudre Project Euler en Java
Essayez d'implémenter l'ajout n-aire en Java
Appel de méthodes Java à partir de JavaScript exécutées en Java
OCR en Java (reconnaissance de caractères à partir d'images)
Essayez d'utiliser l'API Stream en Java
Appeler java depuis C ++ sur Android NDK
Inverser la clé de la valeur dans la carte Java
Exécuter le traitement de blocage avec le réacteur dans plusieurs threads
Essayez d'utiliser l'API au format JSON en Java
Essayez d'exécuter Kubernetes Job à partir de Java
Essayez différentes méthodes d'API Java Stream (maintenant)
Créons une application de calcul avec Java
Obtenir l'historique du serveur Zabbix en Java
Essayez d'appeler Watson NLU qui semble prendre en charge le japonais à partir du SDK Java
Méthodes Java
Méthodes Java
GetInstance () à partir d'une classe @Singleton dans Groovy à partir de Java
Essayez de gratter environ 30 lignes en Java (sortie CSV)
Appel de méthode Java depuis RPG (appel de méthode dans sa propre classe)
Essayez de créer un babillard en Java
Deuxième décoction: essayez une expression If en Java
Essayez d'utiliser Sourcetrail (version win) avec du code Java
Essayez d'utiliser l'API Cloud Vision de GCP en Java
Comment obtenir une classe depuis Element en Java
Extraction de texte en Java à partir de PDF avec pdfbox-2.0.8
Essayez d'utiliser Sourcetrail (version macOS) avec du code Java
Capture et sauvegarde de l'installation de sélénium en Java
Obtenez unixtime (secondes) de ZonedDateTime dans Scala / Java
Essayez d'accéder à l'ensemble de données depuis Java en utilisant JZOS
Vérifier le comportement statique et public dans les méthodes Java
[Java] Obtenir plusieurs valeurs à partir d'une valeur de retour
[Deep Learning from scratch] dans Java 3. Réseau neuronal
Essayez d'utiliser l'analyse syntaxique de l'API COTOHA en Java
Générer OffsetDateTime à partir de Clock et LocalDateTime en Java
[Java] Obtenir KFunction à partir de la méthode / du constructeur en Java [Kotlin]