16

Suppose our application have only one thread. and we are using StringBuffer then what is the problem?

I mean if StringBuffer can handle multiple threads through synchronization, what is the problem to work with single thread?

Why use StringBuilder instead?

Saurabh Gokhale
  • 53,625
  • 36
  • 139
  • 164
MANISH PATHAK
  • 2,602
  • 4
  • 27
  • 31

8 Answers8

27

StringBuffers are thread-safe, meaning that they have synchronized methods to control access so that only one thread can access a StringBuffer object's synchronized code at a time. Thus, StringBuffer objects are generally safe to use in a multi-threaded environment where multiple threads may be trying to access the same StringBuffer object at the same time.

StringBuilder's access is not synchronized so that it is not thread-safe. By not being synchronized, the performance of StringBuilder can be better than StringBuffer. Thus, if you are working in a single-threaded environment, using StringBuilder instead of StringBuffer may result in increased performance. This is also true of other situations such as a StringBuilder local variable (ie, a variable within a method) where only one thread will be accessing a StringBuilder object.

So, prefer StringBuilder because,

  • Small performance gain.
  • StringBuilder is a 1:1 drop-in replacement for the StringBuffer class.
  • StringBuilder is not thread synchronized and therefore performs better on most implementations of Java

Check this out :

Saurabh Gokhale
  • 53,625
  • 36
  • 139
  • 164
  • It's better to say StringBuffer is "thread safe" but it's very easy to concoct scenarios where two threads in contention for the same buffer cause race conditions. Even if you have a need to share a string buffer between threads, it is very likely that you need to enforce higher level control on it than the synchronized methods it shows. Therefore I cannot think of many reasons to use StringBuffer unless a 3rd party lib demands you use it, or for legacy / niche purposes. – locka Mar 28 '14 at 10:48
  • `StringBuilder` is not exactly a 1:1 drop-in replacement for `StringBuffer`. For example, the `appendReplacement` method of `Matcher` requires a `StringBuffer` as its first argument. – Josh Broadhurst Jan 09 '18 at 21:19
7

StringBuilder is supposed to be a (tiny) bit faster because it isn't synchronised (thread safe).

You can notice the difference in really heavy applications.

The StringBuilder class should generally be used in preference to this one, as it supports all of the same operations but it is faster, as it performs no synchronization.

http://download.oracle.com/javase/6/docs/api/java/lang/StringBuffer.html

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
Bart Vangeneugden
  • 3,436
  • 4
  • 33
  • 52
  • @MANISH PATHAK - please read the answer - question: `Why use StringBuilder instead?` - answer: `StringBuilder is supposed to be a (tiny) bit faster` (the first sentence of this post) – user85421 May 30 '11 at 09:49
  • 3
    To clarify: even when one thread is using an object, synchronized methods force the thread to get and release the monitor for each access. This can slow down the program. – Jonathan May 30 '11 at 10:53
6

Using StringBuffer in multiple threads is next to useless and in reality almost never happens.

Consider the following

Thread1: sb.append(key1).append("=").append(value1);
Thread2: sb.append(key2).append("=").append(value2);

each append is synchronized, but a thread can stoop at any point so you can have any of the following combinations and more

key1=value1key2=value2
key1key2==value2value1
key2key1=value1=value2
key2=key1=value2value1

This can be avoided by synchronizing the whole line at a time, but this defeats the point of using StringBuffer instead of StringBuilder.

Even if you have a correctly synchronized view, it more complicated than just creating a thread local copy of the whole line e.g. StringBuilder and log lines at a time to a class like a Writer.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
3

StringBuffer is not wrong in a single-threaded application. It will work just as well as StringBuilder.

The only difference is the tiny overhead added by having all synchronized methods, which brings no advantage in a single-threaded application.

My opinion is that the main reason StringBuilder was introduced is that the compiler uses StringBuffer (and now StringBuilder) when it compiles code that contains String concatenation: in those cases synchronization is never necessary and replacing all of those places with an un-synchronized StringBuilder can provide a small performance improvement.

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
2

StringBuilder has a better performance because it's methods are not synchronized.

So if you do not need to build a String concurrently (which is a rather untypical scenarion anyway), then there's no need to "pay" for the unnecessary synchronization overhead.

Andreas Dolk
  • 113,398
  • 19
  • 180
  • 268
0

This will help u guys, Be Straight Builder is faster than Buffer,

public class ConcatPerf {
        private static final int ITERATIONS = 100000;
        private static final int BUFFSIZE = 16;

        private void concatStrAdd() {
            System.out.print("concatStrAdd   -> ");
            long startTime = System.currentTimeMillis();
            String concat = new String("");
            for (int i = 0; i < ITERATIONS; i++) {
                concat += i % 10;
            }
            //System.out.println("Content: " + concat);
            long endTime = System.currentTimeMillis();
            System.out.print("length: " + concat.length());
            System.out.println(" time: " + (endTime - startTime));
        }

        private void concatStrBuff() {
            System.out.print("concatStrBuff  -> ");
            long startTime = System.currentTimeMillis();
            StringBuffer concat = new StringBuffer(BUFFSIZE);
            for (int i = 0; i < ITERATIONS; i++) {
                concat.append(i % 10);
            }
            long endTime = System.currentTimeMillis();
            //System.out.println("Content: " + concat);
            System.out.print("length: " + concat.length());
            System.out.println(" time: " + (endTime - startTime));
        }

        private void concatStrBuild() {
            System.out.print("concatStrBuild -> ");
            long startTime = System.currentTimeMillis();
            StringBuilder concat = new StringBuilder(BUFFSIZE);
            for (int i = 0; i < ITERATIONS; i++) {
                concat.append(i % 10);
            }
            long endTime = System.currentTimeMillis();
           // System.out.println("Content: " + concat);
            System.out.print("length: " + concat.length());
            System.out.println(" time: " + (endTime - startTime));
        }

        public static void main(String[] args) {
            ConcatPerf st = new ConcatPerf();
            System.out.println("Iterations: " + ITERATIONS);
            System.out.println("Buffer    : " + BUFFSIZE);

            st.concatStrBuff();
            st.concatStrBuild();
            st.concatStrAdd();
        }
    }

Output  

    run:
    Iterations: 100000
    Buffer    : 16
    concatStrBuff  -> length: 100000 time: 11
    concatStrBuild -> length: 100000 time: 4
    concatStrAdd   -> 
MyStack
  • 103
  • 2
  • 12
0

Manish, although there is just one thread operating on your StringBuffer instance, there is some overhead in acquiring and releasing the monitor lock on the StringBuffer instance whenever any of its methods are invoked. Hence StringBuilder is a preferable choice in single thread environment.

0

There is a huge cost to synchronize objects. Don't see a program as a standalone entity; its not a problem when you are reading the concepts and applying them on small programs like you have mentioned in your question details, the problems arise when we want to scale the system. In that case your single threaded program might be dependent on several other methods/programs/entities, so synchronized objects can cause a serious programming complexity in terms of performance. So if you are sure that there is no need to synchronize an object then you should use StringBuilder as it is a good programming practice. At the end we want to learn programming to make scalable high performance systems, so that is what we should do!

Nikhil Arora
  • 329
  • 3
  • 9