StringBuffer in Java

Naveen AnamaneniUpdated · 4 min read

StringBuffer is a changeable string, just like StringBuilder, with the same append, insert, delete, replace and reverse methods. It's actually the older of the two: it has existed since Java 1.0, while StringBuilder arrived in Java 5. The one difference is that every StringBuffer method is synchronized, which makes it safe to use from several threads at once, at a small cost in speed.

Same Methods, Same Results

Buffer.java▶ Try it
public class Buffer {
    public static void main(String[] args) {
        StringBuffer sb = new StringBuffer("Order");
        sb.append(" #").append(301).append(" for ").append("Advitha");
        System.out.println(sb);
        System.out.println(sb.length() + " characters");
 
        sb.insert(0, "[NEW] ");
        System.out.println(sb);
        sb.reverse();
        System.out.println(sb);
    }
}
Output
Order #301 for Advitha
22 characters
[NEW] Order #301 for Advitha
ahtivdA rof 103# redrO ]WEN[

Swap the word StringBuffer for StringBuilder and the program prints exactly the same. Both classes extend the same internal parent, AbstractStringBuilder, and share its code.

What "Synchronized" Means Here

When a method is synchronized, only one thread can run it on a given object at a time; other threads wait their turn. So if two threads append to the same StringBuffer simultaneously, the appends happen one after another and nothing is lost. Here's two threads each appending 100,000 characters to both kinds of builder:

Race.java▶ Try it
public class Race {
    public static void main(String[] args) throws Exception {
        StringBuilder unsafe = new StringBuilder();
        StringBuffer safe = new StringBuffer();
        Runnable task = () -> {
            for (int i = 0; i < 100_000; i++) {
                unsafe.append('x');
                safe.append('x');
            }
        };
        Thread a = new Thread(task);
        Thread b = new Thread(task);
        a.start();
        b.start();
        a.join();
        b.join();
        System.out.println("StringBuffer length:  " + safe.length());
        System.out.println("StringBuilder length: " + unsafe.length());
    }
}
Output
StringBuffer length:  200000
StringBuilder length: 197017

The StringBuffer always ends with exactly 200,000 characters. The StringBuilder loses characters, a different number each run, because both threads sometimes write into the same slot at the same moment. (It can even crash with an ArrayIndexOutOfBoundsException.) Threads get their own lessons later in the course; for now, the point is what "thread-safe" protects you from.

Where You'll Still See It

PlaceWhy
Code written before Java 5StringBuilder didn't exist yet
Some older JDK APIs, such as Matcher.appendReplacement(StringBuffer, ...)They were designed before Java 5 (newer overloads accept StringBuilder)
Interview questions"What's the difference between String, StringBuffer and StringBuilder?"

Common Mistakes

Choosing StringBuffer "to be safe" in single-threaded code. It just adds locking you don't need.

Thinking StringBuffer makes a whole sequence of calls atomic. Each call is synchronized on its own; "check, then append" across two calls can still interleave with another thread.

Interview Corner

What is StringBuffer?

StringBuffer is a mutable, thread-safe sequence of characters available since Java 1.0. Its methods are synchronized, so multiple threads can modify the same instance without corrupting it. It has the same API as StringBuilder, which was added in Java 5 as a faster, unsynchronized alternative for single-threaded use.

Practice

  1. Easy: Rewrite the bill example from "StringBuilder in Java" with StringBuffer and confirm the output is identical.
  2. Harder: Run Race.java five times and record the StringBuilder length each time. Why does it change, and why does the StringBuffer length never change?

Quick check: StringBuffer

4 questions
1What makes StringBuffer different from StringBuilder?
2Which came first?
3Is StringBuffer mutable?
4In single-threaded code, which should you usually choose?

Key Takeaways

Was this tutorial helpful?

Lesson 199 of 482