Fundamentals 6 min read

Why Is StringBuilder Faster Than StringBuffer? Understanding Java’s Mutable vs Immutable Strings

This article explains the fundamental differences between Java's String, StringBuilder, and StringBuffer—covering immutability, thread‑safety, internal caching mechanisms, and performance characteristics—while providing concrete code examples that illustrate how each class behaves in single‑threaded and multi‑threaded scenarios.

Mike Chen's Internet Architecture
Mike Chen's Internet Architecture
Mike Chen's Internet Architecture
Why Is StringBuilder Faster Than StringBuffer? Understanding Java’s Mutable vs Immutable Strings

Mutable vs Immutable Difference

In Java, String objects are immutable and stored in the string constant pool, while StringBuilder and StringBuffer are mutable classes that allow their contents to be changed.

Because a String cannot be altered after creation, the JVM can safely share the same instance across threads, making it effectively thread‑safe. Mutable classes are used when frequent modifications are required.

Thread‑Safety Difference

String

and StringBuffer are thread‑safe; StringBuilder is not. StringBuffer synchronizes all its public methods, which adds a synchronized lock to each call. This ensures correctness in multi‑threaded environments but reduces throughput.

@Override
public synchronized StringBuffer append(String str) {
    toStringCache = null;
    super.append(str);
    return this;
}

In contrast, StringBuilder does not synchronize its methods, so it runs faster in single‑threaded contexts.

@Override
public StringBuilder append(String str) {
    super.append(str);
    return this;
}

Cache Difference

StringBuffer

caches the result of toString() in a field called toStringCache. When toString() is called, it reuses this cached value if present, avoiding the creation of a new String object.

@Override
public synchronized String toString() {
    if (toStringCache == null) {
        toStringCache = new String(value, 0, count);
    }
    return new String(toStringCache, true);
}
StringBuilder

does not keep such a cache; each call to toString() creates a fresh String by copying the internal character array.

@Override
public String toString() {
    // Create a copy, don't share the array
    return new String(value, 0, count);
}

Performance Difference

Typical execution speed ranking is: StringBuilder (fastest)

StringBuffer
String

(slowest)

The reason is that String creates a new immutable object for every modification, causing extra object allocation and garbage collection. StringBuilder modifies the underlying character array directly without synchronization, while StringBuffer adds synchronization overhead on each operation.

Example demonstrating the cost of immutability:

String str = "abc";
System.out.println(str);
str = str + "de"; // JVM creates a new String object
System.out.println(str);

During the concatenation, the JVM allocates a new String for the result and discards the original, illustrating why repeated concatenations with String are inefficient compared to using StringBuilder or StringBuffer.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaThread Safetystringstringbuilderstringbuffer
Mike Chen's Internet Architecture
Written by

Mike Chen's Internet Architecture

Over ten years of BAT architecture experience, shared generously!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.