What is the difference between StringBuffer and StringBuilder?
Both `StringBuffer` and `StringBuilder` are mutable character sequences used when you need to build or modify strings without creating multiple intermediate `String` objects. They share the same API — `append()`, `insert()`, `delete()`, `reverse()`, `toString()` — and both inherit from `AbstractStringBuilder`. The critical difference is thread safety.
`StringBuffer` was introduced in Java 1.0 and every public method is `synchronized`. This means only one thread can execute any mutating method at a time, making it safe for concurrent use. The synchronization overhead, however, makes it slower in single-threaded contexts.
`StringBuilder` was introduced in Java 5 specifically to address that overhead. Its methods are not synchronized. In a single-threaded environment — which covers the vast majority of string-building work — it is the correct choice and is measurably faster.
In practice, `StringBuilder` is almost always the right default. `StringBuffer` is appropriate only when you genuinely need a shared mutable string across threads, which is rare in modern code because most such patterns are better served by other concurrency primitives or by passing immutable strings across thread boundaries.
The Java compiler itself uses `StringBuilder` internally when it optimizes the `+` operator for string concatenation (up to Java 8; Java 9+ uses `invokedynamic` with `StringConcatFactory` for even more efficient compilation).
Capacity management is identical in both: they start with a default internal buffer of 16 characters and grow by doubling when capacity is exceeded. Pre-sizing with `new StringBuilder(expectedSize)` avoids reallocations in performance-sensitive code.
For interviews, the clean summary is: same API, `StringBuffer` is synchronized (thread-safe, slower), `StringBuilder` is not (not thread-safe, faster). Use `StringBuilder` by default.
| Aspect | StringBuffer | StringBuilder |
|---|---|---|
| Thread safety | Yes — all methods synchronized | No — not synchronized |
| Performance | Slower due to lock overhead | Faster in single-threaded use |
| Introduced in | Java 1.0 | Java 5 |
| Use case | Shared mutable string across threads | Single-threaded string building |
| API surface | Identical to StringBuilder | Identical to StringBuffer |
| Preferred default | No | Yes |
Correctly identifies that StringBuffer is synchronized and StringBuilder is not, and states the performance implication.
Also explains when to use each, mentions they share AbstractStringBuilder, and notes the compiler's preference for StringBuilder internally.
Reading the answer is step one. Explaining it unprompted — under interview pressure — is what actually matters. Get AI-graded feedback on your answer with follow-up probes on your weak points.
Get Graded — Free Assessment