The difference between StringBuffer and StringBuilder in string splicing

Keywords: JDK Java

jdk version 1.8

StringBuffer and StringBuilder inherit from the same parent class AbstractStringBuilder. The source code of append is respectively
StringBuffer

    @Override
    public synchronized StringBuffer append(String str) {
        toStringCache = null;
        super.append(str);
        return this;
    }

StringBuilder

    @Override
    public StringBuilder append(String str) {
        super.append(str);
        return this;
    }

toStringCache is the cache variable used in toString method, which has nothing to do with string splicing. Therefore, the only difference between the two classes in string splicing is synchronization.

What are the differences in synchronization

Run the following code (the specific number of cycles needs to be determined according to the computer configuration, otherwise the expected results may not be output)

import java.util.concurrent.CountDownLatch;

public class Test02 {
	
	static StringBuilder str = new StringBuilder();
	
	static String append1 = "1111111111";
	static String append2 = "aaaaaaaaaa";
	
	public static void main(String[] args) throws InterruptedException {
		CountDownLatch cl = new CountDownLatch(2);
		new Thread(() -> {
			for(int i = 0; i < 1000; i++) {
				str.append(append1 + "\r\n");
			}
			cl.countDown();
			System.out.println(str);
		}).start();
		new Thread(() -> {
			for(int i = 0; i < 1000; i++) {
				str.append(append2 + "\r\n");
			}
			cl.countDown();
			System.out.println(str);
		}).start();
		
		cl.await();
		
	}
	
}

You'll see output like this on the console

This is the error generated by asynchronous code under multithreading, which will not occur in thread safe StringBuffer.

When it comes to the source code, the two classes are called at the bottom
System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
The reason is that there is an out of sync problem during replication.

StringBuffer, StringBuilder and String efficiency differences in String splicing

Since you have read the source code, by the way

First of all, the plus sign of String is the slowest, which is undisputed. The specific reason needs to be decompiled for analysis, and we will do it again when we have time. Here we mainly compare the concat of String with the append of AbstractStringBuilder

Run the following code

public class Test01 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String s1 = "";
		s1.concat("1");
		StringBuffer s2 = new StringBuffer("");
		s2.append("1");
		StringBuilder s3 = new StringBuilder("");
		s3.append("1");
		
		long time = System.currentTimeMillis();
		for(int i = 0; i < 200000; i++) {
			s1 = s1.concat("1");
		}
		System.out.println(System.currentTimeMillis() - time);
		time = System.currentTimeMillis();
		s1 = "";
		
		for(int i = 0; i < 200000; i++) {
			s2.append("1");
		}
		
		System.out.println(System.currentTimeMillis() - time);
		time = System.currentTimeMillis();
		
		for(int i = 0; i < 200000; i++) {
			s3.append("1");
		}
		
		System.out.println(System.currentTimeMillis() - time);
		time = System.currentTimeMillis();
	}

}

output

6602
6
2

It can be seen that StringBuilder is slightly faster than StringBuffer due to no synchronization, but concat is much slower than the latter two, which can be easily analyzed from the source code

concat

    public String concat(String str) {
        int otherLen = str.length();
        if (otherLen == 0) {
            return this;
        }
        int len = value.length;
        char buf[] = Arrays.copyOf(value, len + otherLen);
        str.getChars(buf, len);
        return new String(buf, true);
    }

append

    public AbstractStringBuilder append(String str) {
        if (str == null)
            return appendNull();
        int len = str.length();
        ensureCapacityInternal(count + len);
        str.getChars(0, len, value, count);
        count += len;
        return this;
    }

As you can see, concat copies the string array every time it is spliced, and the append method has a similar caching mechanism. The ensurcapacityinternal method will multiply and copy when the array length is insufficient. When the length is enough, the append method simply copies the newly added string directly to the end of the array. In general, the number of array copies of concat method is far greater than append, so the natural speed is slow.

132 original articles published, 35 praised, 120000 visitors+
Private letter follow

Posted by pourmeanother on Tue, 03 Mar 2020 22:35:45 -0800