Difference between StringBuilder and StringBuffer

2018-12-31 02:24发布

What is the main difference between StringBuffer and StringBuilder? Is there any performance issues when deciding on any one of these?

30条回答
泛滥B
2楼-- · 2018-12-31 02:53

StringBuffer

  • Synchronized hence threadsafe
  • thread safe hence slow
  • -

StringBuilder

  • Introduced in Java 5.0
  • Asynchronous hence fast & efficient
  • User explicitly need to synchronize it, if he wants
  • You can replace it will StringBuilder without any other change
查看更多
ら面具成の殇う
3楼-- · 2018-12-31 02:53

String is an immutable.

StringBuffer is a mutable and synchronized.

StringBuilder is also mutable but its not synchronized.

查看更多
永恒的永恒
4楼-- · 2018-12-31 02:54

String-Builder :

int one = 1;
String color = "red";
StringBuilder sb = new StringBuilder();
sb.append("One=").append(one).append(", Color=").append(color).append('\n');
System.out.print(sb);
// Prints "One=1, Colour=red" followed by an ASCII newline.

String-Buffer

StringBuffer sBuffer = new StringBuffer("test");
sBuffer.append(" String Buffer");
System.out.println(sBuffer);  

It is recommended to use StringBuilder whenever possible because it is faster than StringBuffer. However, if the thread safety is necessary, the best option is StringBuffer objects.

查看更多
千与千寻千般痛.
5楼-- · 2018-12-31 02:56

The javadoc explains the difference:

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.

查看更多
高级女魔头
6楼-- · 2018-12-31 02:56

StringBuilder is much faster than StringBuffer because It's non synchronized.

Here you got more idea about the cost of synchronize

Let take programmatically look how much StringBuilder faster than StringBuffer

public class Test{  
 public static void main(String[] args){  
    long startTime = System.currentTimeMillis();  
    StringBuffer sb = new StringBuffer("Yasir");  
    for (int i=0; i<10000; i++){  
        sb.append("Shabbir");  
    }  
    System.out.println("Time taken by StringBuffer: " + (System.currentTimeMillis() - startTime) + "ms");  
    startTime = System.currentTimeMillis();  
    StringBuilder sb2 = new StringBuilder("Yasir");  
    for (int i=0; i<10000; i++){  
        sb2.append("Shabbir");  
    }  
    System.out.println("Time taken by StringBuilder: " + (System.currentTimeMillis() - startTime) + "ms");  
}  
}  

OutPut

Time taken by StringBuffer: 16ms

Time taken by StringBuilder: 0ms

查看更多
琉璃瓶的回忆
7楼-- · 2018-12-31 02:58

In single threads, StringBuffer is not significantly slower than StringBuilder, thanks to JVM optimisations. And in multithreading, you can't use safely a StringBuilder.

Here is my test :

public static void main(String[] args) {

    String withString ="";
    long t0 = System.currentTimeMillis();
    for (int i = 0 ; i < 100000; i++){
        withString+="some string";
    }
    System.out.println("strings:" + (System.currentTimeMillis() - t0));

    t0 = System.currentTimeMillis();
    StringBuffer buf = new StringBuffer();
    for (int i = 0 ; i < 100000; i++){
        buf.append("some string");
    }
    System.out.println("Buffers : "+(System.currentTimeMillis() - t0));

    t0 = System.currentTimeMillis();
    StringBuilder building = new StringBuilder();
    for (int i = 0 ; i < 100000; i++){
        building.append("some string");
    }
    System.out.println("Builder : "+(System.currentTimeMillis() - t0));
}

Results :
strings: 319740
Buffers : 23
Builder : 7 !

So Builders are faster than Buffers, and WAY faster than strings concatenation. Now let's use an Executor for multiple threads :

public class StringsPerf {

    public static void main(String[] args) {

        ThreadPoolExecutor executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
        //With Buffer
        StringBuffer buffer = new StringBuffer();
        for (int i = 0 ; i < 10; i++){
            executorService.execute(new AppendableRunnable(buffer));
        }
        shutdownAndAwaitTermination(executorService);
        System.out.println(" Thread Buffer : "+ AppendableRunnable.time);

        //With Builder
        AppendableRunnable.time = 0;
        executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
        StringBuilder builder = new StringBuilder();
        for (int i = 0 ; i < 10; i++){
            executorService.execute(new AppendableRunnable(builder));
        }
        shutdownAndAwaitTermination(executorService);
        System.out.println(" Thread Builder: "+ AppendableRunnable.time);

    }

   static void shutdownAndAwaitTermination(ExecutorService pool) {
        pool.shutdown(); // code reduced from Official Javadoc for Executors
        try {
            if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
                pool.shutdownNow();
                if (!pool.awaitTermination(60, TimeUnit.SECONDS))
                    System.err.println("Pool did not terminate");
            }
        } catch (Exception e) {}
    }
}

class AppendableRunnable<T extends Appendable> implements Runnable {

    static long time = 0;
    T appendable;
    public AppendableRunnable(T appendable){
        this.appendable = appendable;
    }

    @Override
    public void run(){
        long t0 = System.currentTimeMillis();
        for (int j = 0 ; j < 10000 ; j++){
            try {
                appendable.append("some string");
            } catch (IOException e) {}
        }
        time+=(System.currentTimeMillis() - t0);
    }
}

Now StringBuffers take 157 ms for 100000 appends. It's not the same test, but compared to the previous 37 ms, you can safely assume that StringBuffers appends are slower with multithreading use. The reason is that the JIT/hotspot/compiler/something makes optimizations when it detects that there is no need for checking locks.

But with StringBuilder, you have java.lang.ArrayIndexOutOfBoundsException, because a concurrent thread tries to add something where it should not.

Conclusion is that you don't have to chase StringBuffers. And where you have threads, think about what they are doing, before trying to gain a few nanoseconds.

查看更多
登录 后发表回答