Do I need to implement synchronized on writing dat

2019-06-23 16:33发布

I am working on Webmethods Integration Server. Inside there is a java service which is in form of a static java method for writing data to a log file (server.log) by using BufferedWriter and FileWriter. The static method code is like this:

public static void writeLogFile(String message) throws ServiceException{
    try {
        BufferedWriter bw = new BufferedWriter(new FileWriter("./logs/server.log", true));
        bw.write(message);
        bw.newLine();
        bw.close();
    } catch (Exception e) {
        throw new ServiceException(e.getMessage());
    }
}

Note:
-The code has been simplified for example purpose.
-I can't change the writeLogFile method declaration and attribute. That means, it will always be: public static void writeLogFile. This kind of modification is prohibited: public synchronized void writeLogFile.

There is a chance that the writeLogFile method can be invoked by different instances, so I need to make sure that there are no two or more instances access same resource (server.log) in same time. That means, if there are two instances try to access the server.log, one of the instances must have to wait another instance to finish writing data to the server.log.

The questions are: Should I change the code above? If so, what kind of modification I need to do? Should I implement "synchronized" inside the java static method?

@EJP:
So, which one below is the best code to implement synchronized?

1)

        FileWriter fw = new FileWriter("./logs/server.log", true);
        synchronized (fw) {
            BufferedWriter bw = new BufferedWriter(fw);
            bw.write(message);
            bw.newLine();
            bw.close();
        }

2)

        BufferedWriter bw = new BufferedWriter(new FileWriter("./logs/server.log", true));
        synchronized(bw) {
            bw.write(message);
            bw.newLine();
            bw.close();
        }

3)

        synchronized(util.class) {  //yes, the class name is started with lowercase
            BufferedWriter bw = new BufferedWriter(new FileWriter("./logs/server.log", true));
            bw.write(message);
            bw.newLine();
            bw.close();
        }

4) Other opinion?

Thanks.

3条回答
家丑人穷心不美
2楼-- · 2019-06-23 16:48

I have another suggestion. I guess synchronization can be treated as an aspect and the same can be achieved using some AOP framework. This conforms to you requirement of not changing the code. But I am not 100% sure about it and posted a question for the same. Please monitor its responses .

查看更多
我欲成王,谁敢阻挡
3楼-- · 2019-06-23 16:53

No. the base class of BufferedWriter and FileWriter is java.io.Writer,

it has it own lock on each write operation

Object java.io.Writer.lock

The object used to synchronize operations on this stream. 

try make the BufferedWriter bw static and ref to it by a static method ,thus all write is write to file via same Writer object

btw, i guess you are inventing yet-another-log-lib... may be you could use log4j or any kind of log lib instead

查看更多
混吃等死
4楼-- · 2019-06-23 16:58

Just make the method synchronized. It doesn't affect its method signature for binary compatibility purposes.

查看更多
登录 后发表回答