Search code examples
javamultithreadingstringbuildersynchronizedstringbuffer

StringBuffer or synchronized method?


I have following code:

public class MyLogger {
   private StringBuilder logger = new StringBuilder();

   public void log(String message, String user) {
      logger.append(message);
      logger.append(user);
   }
}

The programmer must guarantee that a single MyLogger object works properly for a multi-threaded system. How must this code be changed to be thread-safe?

A. synchronize the log method

B. replace StringBuilder with StringBuffer

Please advise the best approach.


Solution

  • StringBuffer is not enough to guarantee that the two information are always sent grouped :

      logger.append(message);
      logger.append(user);
    

    It guarantees only that append() will not be invoked in a concurrent way and that so you don't risk to break the state of the StringBuffer object.
    You could indeed have two threads that interleave during the log() invocation and get these invocations :

    Thread 1 : logger.append(message);

    Thread 2 : logger.append(message);

    Thread 1 : logger.append(user);

    Thread 2 : logger.append(user);

    This is so better :

      public synchronized void log(String message, String user) {
          logger.append(message);
          logger.append(user);
       }
    

    You can also do the synchronization on the private logger object.
    Which has the advantage to not allow the client of the class to lock it outside the class.