Нужно ли реализовывать синхронизацию при записи данных в один и тот же файл с помощью BufferedWriter и FileWriter? - PullRequest
5 голосов
/ 29 сентября 2011

Я работаю на сервере интеграции Webmethods. Внутри есть java-сервис, который имеет форму статического java-метода для записи данных в файл журнала (server.log) с использованием BufferedWriter и FileWriter. Код статического метода выглядит следующим образом:

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

Примечание:
Код был упрощен для примера.
-Я не могу изменить объявление и атрибут метода writeLogFile. Это означает, что это всегда будет: public static void writeLogFile. Этот вид модификации запрещен: публичная синхронизация void writeLogFile.

Существует вероятность, что метод writeLogFile может быть вызван разными экземплярами, поэтому мне нужно убедиться, что нет двух или более экземпляров, обращающихся к одному и тому же ресурсу (server.log) одновременно. Это означает, что если два экземпляра пытаются получить доступ к server.log, один из экземпляров должен ждать другого экземпляра, чтобы завершить запись данных в server.log.

Вопросы: Должен ли я изменить код выше? Если да, то какую модификацию мне нужно сделать? Должен ли я реализовать "синхронизированный" внутри статического метода Java?

@ EJP:
Итак, какой из приведенных ниже является лучшим кодом для реализации синхронизированных?

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) Другое мнение?

Спасибо.

Ответы [ 3 ]

2 голосов
/ 29 сентября 2011

Просто сделайте метод синхронизированным. Это не влияет на сигнатуру метода для двоичной совместимости.

0 голосов
/ 29 сентября 2011

У меня есть еще одно предложение. Я предполагаю, что синхронизация может рассматриваться как аспект, и то же самое может быть достигнуто, используя некоторую платформу AOP. Это соответствует вашему требованию не менять код. Но я не уверен на 100% в этом и опубликовал вопрос для того же. Пожалуйста, следите за его ответами.

0 голосов
/ 29 сентября 2011

Нет.базовый класс BufferedWriter и FileWriter - java.io.Writer,

имеет собственную блокировку для каждой операции записи

Object java.io.Writer.lock

The object used to synchronize operations on this stream. 

, попробуйте сделать BufferedWriter bw статическим и сослаться на него с помощьюстатический метод, поэтому вся запись - это запись в файл через тот же Writer object

btw, я полагаю, вы изобретаете еще один-другой-log-lib ... может быть, вы могли бы использовать log4j иливместо любого вида журнала lib

...