I have a very basic question. I have read that if we have a multi-threaded application then it is better to go with StringBuffer. But if we have a single thread application then it’s better to go with StringBuilder. But isn't the whole point of having a multi-threaded application is that simultaneously all the threads can work on the same piece of code? Shouldn't the requirement be that if we don't want the String to be manipulated by all the threads at a time, then we should go for StringBuffer, otherwise it's fine to go for StringBuilder? What I am trying to understand is for a multi-threaded application why is it required to go for a synchronized implementation (if the requirement doesn't state that).

3

There are 3 best solutions below

1
Louis Wasserman On BEST ANSWER

Shouldn't the requirement be that if we don't want the String to be manipulated by all the threads at a time, then we should go for StringBuffer, otherwise it's fine to go for StringBuilder? What I am trying to understand is for a multi-threaded application why is it required to go for a synchronous implementation (if the requirement doesn't state that).

Yes.

Very few applications actually concurrently modify a character sequence, with the result that there's almost no reason to use StringBuffer.

2
paulsm4 On
  • StringBuffer has been around "forever". It is thread safe.
  • StringBuilder is "newer" (first introduced in Java 1.5).
  • String is immutable. StringBuffer and StringBuilder are both mutable. Using either StringBuffer or StringBuilder is VASTLY more efficient than modifying raw strings.

Per the documentation:

https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/StringBuilder.html

[StringBuilder] is mutable sequence of characters. This class provides an API compatible with StringBuffer, but with no guarantee of synchronization. This class is designed for use as a drop-in replacement for StringBuffer in places where the string buffer was being used by a single thread (as is generally the case). Where possible, it is recommended that this class be used in preference to StringBuffer as it will be faster under most implementations.

Personally, I always use StringBuffer in preference to manipulating raw String. Mostly out of force of habit.

Yes, StringBuilder might be "faster". Or, in all likelihood, it will make little or no difference in overall "performance".

The key points to remember:

  • Don't manipulate strings directly if you can use StringBuilder or StringBuffer instead.
  • StringBuilder is non-synchronized (i.e. not thread safe). If two threads happen to use StringBuilder simultaneously, the results will be indeterminate.

You might also be interested in this:

https://www.javatpoint.com/mutable-and-immutable-in-java

What are Mutable Objects?

The mutable objects are objects whose value can be changed after initialization. We can change the object's values, such as field and states, after the object is created. For example, Java.util.Date, StringBuilder, StringBuffer, etc.

When we made a change in existing mutable objects, no new object will be created; instead, it will alter the value of the existing object. These object's classes provide methods to make changes in it.

1
Gray On

I have read that if we have a multi-threaded application then it is better to go with StringBuffer. But if we have a single thread application then it’s better to go with StringBuilder.

This is a very simplistic answer to a usually complicated question. The answer really should be that if multiple threads are updating the same string appender, you should use StringBuffer. If you have two threads and each of them are using their own local string appender, then there is no need to pay for StringBuffer synchronization and StringBuilder can be used. You should know that anytime you use the string + operator, a StringBuilder is being created under the covers. But when it comes down to it, I've never seen the case of multiple threads sharing a string appender.

But isn't the whole point of having a multi-threaded application is that simultaneously all the threads can work on the same piece of code?

No. There are many reasons to write multi-threaded applications. A web-server uses multiple threads so that web requests can be handled asynchronously and in parallel without necessarily sharing any code or data.

Shouldn't the requirement be that if we don't want the String to be manipulated by all the threads at a time, then we should go for StringBuffer, otherwise it's fine to go for StringBuilder?

Not quite. Don't think that StringBuffer stops multiple threads from manipulating the buffer. Think that it protects the buffer from inappropriate access by multiple threads that would result in race-conditions and other unintended consequences.

What I am trying to understand is for a multi-threaded application why is it required to go for a synchronized implementation

There is no such requirement except when multiple threads are updating an object. If the threads are working on their own objects and never sharing them between threads, the no synchronization is required. If multiple threads are updating an object (such as a shared StringBuffer then the synchronized keywords ensure that the changes are appropriately published between the threads and that the critical areas are protected by mutexes which insure only one thread can enter them at a time.

It is also important to realize that if Thread #1 creates (for example) a HashMap and then Thread #2 wants to use that HashMap, even if it is not updating it, then some sort of synchronization needs to happen to appropriately sync the memory between Thread #1 and #2.

synchronization enforces proper mutex locks so that critical code only has one thread working on it at a time and ensures appropriate memory publishing so that threads work on the latest version of an object as opposed to possibly stale versions in their local memory caches.