Try calling synchronized methods from multiple threads in Java

Introduction

Last time, I wrote an article Log output to file with Java. Therefore, I wrote that it seems that exclusive control can be performed on the log file by changing the log output method to the syncronized method, so I would like to verify it this time.

Method of verification

Execute 10 threads that call the log output method 10000 times in parallel, and check if the log specified by each thread is completely output to the log file.

Validation source

As for threads, there are various samples, so no explanation is necessary. The log output method has been moved to the writeLog method of the LogWriter class so that it can be called from various 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];

        //Thread preparation
        for (int i = 0; i < threadSamples.length; i++) {
            threadSamples[i] = new ThreadSample("Trhead["  + i + "]");
        }

        //Start thread
        for (int i = 0; i < threadSamples.length; i++) {
            threadSamples[i].start();
        }

    }
}

//Log output class
class LogWriter {
    public static SimpleDateFormat sdf = new SimpleDateFormat("YYYY/MM/dd HH:mm:ss");


    //Log output method
    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);

        //Log output
        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 {

    //Thread name
    private String name = null;

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

    //Thread that writes 10000 lines to the log
    public void run() {
        for (int i = 0; i < 10000; i++) {
            System.out.println(name + "," + i);
            LogWriter.writeLog(name + "," + i + ":hogehoge");
        }
    }
}

inspection result

The contents of the file

The contents of the file shouldn't be corrupted like this. You can also see that the logs of various threads are output to a file in parallel.

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

number

The number of cases was 10,000 for each thread, for a total of 100,000, and it was confirmed that all the threads were output.

$ 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

in conclusion

I'll output a pounding log using this method!

Addendum 1

By the way, even without syncronized, the log was output without exception in a small job environment. The processing was also overwhelmingly fast. However, it can be a coincidence, so it is better to add syncronized at the expense of processing time.

Addendum 2

In a small program, date processing and file name determination are performed in the synchronized method, but if you move this to the caller and shorten the synchronization processing time, it may be a little faster (not yet). Experiment).

Recommended Posts

Try calling synchronized methods from multiple threads in Java
Try calling JavaScript in Java
Try calling the CORBA service in Java 11+
Try calling Nim from Java via JNI
Try calling the CORBA service from Spring (Java)
Various threads in java
Behavior when calling Java variadic methods from Scala / Kotlin / Java
Try calling IBM Watson Assistant 2018-07-10 from the Java SDK.
Try using RocksDB in Java
Try developing Spresense in Java (1)
Try functional type in Java! ①
Try implementing Android Hilt in Java
Try implementing GraphQL server in Java
Try running Selenuim 3.141.59 in eclipse (java)
Try an If expression in Java
Concatenate strings returned by methods of multiple objects in Java Stream
Try running AWS X-Ray in Java
Try to implement Yubaba in Java
Catch multiple exceptions together in java
When calling println etc. from an external Java class file in Processing
Study Deep Learning from scratch in Java.
When seeking multiple in a Java array
Try to solve Project Euler in Java
Try to implement n-ary addition in Java
Call Java method from JavaScript executed in Java
OCR in Java (character recognition from images)
Try using the Stream API in Java
Calling java from C ++ on Android NDK
Reverse Key from Value in Java Map
Execute blocking processing in reactor in multiple threads
Using JavaScript from Java in Rhino 2021 version
Try using JSON format API in Java
Try running a Kubernetes Job from Java
Try various Java Stream API methods (now)
Try making a calculator app in Java
Call Java methods from Nim using jnim
Get history from Zabbix server in Java
Try calling Watson NLU that seems to support Japanese from the Java SDK
Java methods
Java methods
GetInstance () from a @Singleton class in Groovy from Java
Try scraping about 30 lines in Java (CSV output)
Java method call from RPG (method call in own class)
Try to create a bulletin board in Java
Second decoction: Try an If expression in Java
Try using Sourcetrail (win version) in Java code
Try using GCP's Cloud Vision API in Java
How to get Class from Element in Java
Text extraction in Java from PDF with pdfbox-2.0.8
Try using Sourcetrail (macOS version) in Java code
Capture and save from selenium installation in Java
Get unixtime (seconds) from ZonedDateTime in Scala / Java
Try accessing the dataset from Java using JZOS
Check static and public behavior in Java methods
Basics of threads and Callable in Java [Beginner]
[Java] Get multiple values from one return value
[Deep Learning from scratch] in Java 3. Neural network
Try using the COTOHA API parsing in Java
Generate OffsetDateTime from Clock and LocalDateTime in Java
[Java] Get KFunction from Method / Constructor in Java [Kotlin]