StringBuilder vs StringBuffer
StringBuilder使用方式跟StringBuffer一模一樣。
以下列出不同的地方。
執行緒安全
StringBuffer有synchronized
StringBuffer在append()方法前面有synchronized。
1
2
3
4
5
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
StringBuilder沒synchronized
StringBuilder在append()方法前面是沒有synchronized。
1
2
3
4
public StringBuilder append(String str) {
super.append(str);
return this;
}
效率
String
以下的程式碼,執行到第2行,會產生以下步驟:
- 變數s與+會呼叫StringBuffer的append()方法。
- 呼叫toString()方法。
- new String()建立物件。
- 在Heap中建立記憶體空間。
- s變數指向Heap的記憶體位址。
String是final char[]陣列,經過步驟5,原本的final char[] value = "a"
,這個物件就會變成孤兒,等待記憶體回收。
如果以下的程式碼進行2000次就會產生2000個孤兒,所以String的效率最慢。
1
2
String s = "a";
s += "b";
StringBuffer與StringBuilder
StringBuffer與StringBuild不是final。
append、replace、delete,也只是對字元陣列進行修改,不會一直再建立新的物件,所以執行效率比String快。
1
char[] value = "a"
由於StringBuffer的append()是synchronized,一次只能被一個thread執行緒執行,其它執行緒們threads只能被卡住Blocked,等待synchronized方法中的執行緒做完,他們之中只有一個才能進入append()方法。
所以效率比Builder差,因為Builder不是執行緒安全。
執行效率程式碼
1秒 = 1000毫秒
0.5秒 = 500毫秒
0.1秒 = 100毫秒
0.001秒 = 1毫秒
請自行換算,以下執行結果是以毫秒為單位。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class Test2 {
public static void main(String[] args) {
long startT = System.currentTimeMillis();
String str = "a";
for (int i = 0; i < 20000; i++) {
str += "b";
}
long endT = System.currentTimeMillis();
System.out.println("String = " + (endT - startT));
startT = System.currentTimeMillis();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 2000; i++) {
sb.append(i);
}
endT = System.currentTimeMillis();
System.out.println("StringBuffer = " + (endT - startT));
startT = System.currentTimeMillis();
StringBuilder sbder = new StringBuilder();
for (int i = 0; i < 2000; i++) {
sbder.append(i);
}
endT = System.currentTimeMillis();
System.out.println("StringBuilder = " + (endT - startT));
}
}
String = 92
StringBuffer = 2
StringBuilder = 1
由執行結果可以發現String要執行92毫秒,速度最慢。