Saturday, 25 February 2012

What's the difference between a StringBuffer and StringBuilder?

StringBuffer is in older versions of the Java API and it is thread-safe.String buffers are safe for use by multiple threads. The public methods are synchronized so that each method invocation on a StringBuffer instance acts as an atomic operation.For example two threads can't append one data to a StringBuffer instance at the same time.i.e. one thread can invoke append(String) only after the other thread has returned from the append(String) method.

StringBuilder was introduced in java 1.5.StringBuffer and StringBuilder have the same methods with one difference and that’s of synchronization. StringBuffer is synchronized whereas StringBuilder is not synchronized( which implies it isn’t thread safe).

So, if you aren’t going to use threading then use the StringBuilder class as it’ll be more efficient than StringBuffer due to the absence of synchronization.


Let us see one example

Here the calling thread waits for 1sec in the middle of an append() method invocation.Let us check the behavior in the cases of both StringBuffer and StringBuilder.

StringBuilder

public class Example {

        public static void main(String[] args) throws InterruptedException {
        StringBuilder resource = new StringBuilder();
        MyThread t1 = new MyThread(resource);
        t1.setName("t1");
        MyThread t2 = new MyThread(resource);
        t2.setName("t2");
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(resource);
    }

}

class MyThread extends Thread {
    StringBuilder resource;

    MyThread(StringBuilder resource) {
        this.resource = resource;
    }

    public void run() {
        resource.append(Thread.currentThread().getName() + mySleep() + "->"
                + Thread.currentThread().getName());

    }

    String mySleep() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            return "";
        }
    }
}

In StringBuilder method execution is not an atomic operation.Hence in this example, you can't always expect an exact output.The expected result is

t1->t1t2->t2 or t2->t2 t1->t1.But because of concurrency issue sometimes you may get t1->t1 or t2->t2 as output.

StringBuffer

In StringBuffer method execution is an atomic operation.Hence in the above example if you replace StringBuilder with StringBuffer, since the StringBuffer is thread-safe you always get  t1->t1t2->t2 or t2->t2 t1->t1 as output.

No comments:

Post a Comment