 <p>I will clarify the thread-safety point. The other points are well described in older questions.</p> <p>It's quite rare case when <code>StringBuffer</code> suits your needs. While it's thread-safe it doesn't mean you will get what expected when using it from different threads. For example, suppose you have the following code:</p> <pre><code>StringBuffer buf = new StringBuffer(); public void appendMessage(String message) { buf.append("INFO: ").append(message).append(System.lineSeparator()); } </code></pre> <p>If you are using it in multithread environment it will not fail, but you may end up having content like this:</p> <pre><code>INFO: INFO: thread1 message thread2 message </code></pre> <p>That's because individual <code>append</code> calls are synchronized, but the whole sequence is not.</p> <p>In order to ensure that your messages are separately added, you must have an external synchronization like this:</p> <pre><code>Object lock = new Object(); StringBuilder buf = new StringBuilder(); public void appendMessage(String message) { synchronized(lock) { buf.append("INFO: ").append(message).append(System.lineSeparator()); } } </code></pre> <p>Here the whole sequence of calls is synchronized, so you will have the whole message appended at once. And as you are using the external synchronization, <code>StringBuilder</code> will work fine as well.</p> <p>So in general <code>StringBuffer</code> should not be used in the most of situations.</p>