StringBuffer類和StringBuilder類功能基本類似。算是兩個雙胞胎。
下面主要說兩點java
第一點 線程安全
StringBuffer 線程安全
StringBuilder 線程不安全編程
關於線程安全的知識,正在學習,剛接觸,沒有太深刻的瞭解,在這知識稍微的提一下。安全
線程安全——若是你的代碼所在的進程中有多個線程在同時運行,而這些線程可能會同時運行這段代碼。若是每次
運行結果和單線程運行的結果是同樣的,並且其餘的變量的值也和預期的是同樣的,就是線程安全的。多線程
StringBuffer類和StringBuilder類二者沒有很大的區別,可是在線程安全方面,StringBuffer容許多線程進行字
符操做。這是由於在源代碼中StringBuffer的不少方法都被關鍵字synchronized(這個關鍵字是爲線程同步機制設定
的。) 修飾了,而StringBuilder沒有。app
簡單的說一說synchronized的含義:
每個類對象都對應一把鎖,當某個Java技術線程A調用類對象O中的synchronized方法M時,必須得到對象O的鎖纔可以執行
M方法,不然線程A阻塞。一旦線程A開始執行M方法,將獨佔對象O的鎖。使得其它須要調用O對象的M方法的線程阻
塞。只有線程A執行完畢,釋放鎖後。那些阻塞線程纔有機會從新調用M方法。這就是解決線程同步問題的鎖機制。學習
所以,多線程編程中StringBuffer比StringBuilder要安全的多。測試
有一點須要注意的是,有的人會問,String類是否是也不安全? 事實上不存在這個問題,String是不可變的。線
程對於堆中指定的一個String對象只能讀取,沒法修改。還有什麼不安全的?ui
第二點 效率問題
通常狀況下,速度從快到慢:StringBuilder>StringBuffer>String,這種比較是相對的,不是絕對的。
舉個簡單的例子:
[java] view plaincopy在CODE上查看代碼片派生到個人代碼片
public class TestCharacter{
final static int time=100; //循環次數
public TestCharacter(){
}
public void test(String s){
long begin = System.currentTimeMillis();
for(int i=0;i<time;i++){
s+="add";
}
long over=System.currentTimeMillis();
System.out.println("操做"+s.getClass().getName() +"類型使用的時間爲:" +(over-begin)+"毫秒");
}
public void test(StringBuffer s){
long begin = System.currentTimeMillis();
for(int i=0; i<time; i++){
s.append("add");
}
long over = System.currentTimeMillis();
System.out.println("操做"+s.getClass().getCanonicalName()+"類型使用的時間爲:"+(over-begin)+"毫秒");
}
public void test(StringBuilder s){
long begin = System.currentTimeMillis();
for(int i=0; i<time; i++){
s.append("add");
}
long over = System.currentTimeMillis();
System.out.println("操做"+s.getClass().getName()+"類型使用的時間爲:"+(over-begin)+"毫秒");
}
/*對 String 直接進行字符串拼接的測試*/
public void test2(){
String s2 = "abcd";
long begin = System.currentTimeMillis();
for(int i=0; i<time; i++){
String s = s2 + s2 +s2;
}
long over = System.currentTimeMillis();
System.out.println("操做字符串對象引用相加類型使用的時間爲:"+(over-begin)+"毫秒");
}
public void test3(){
long begin = System.currentTimeMillis();
for(int i=0; i<time; i++){
String s ="abcd" + "abcd" + "abcd";
}
long over = System.currentTimeMillis();
System.out.println("操做字符串相加使用的時間爲:"+(over-begin)+"毫秒");
}
public static void main(String[] args){
String s1 = "abcd";
StringBuffer st1 = new StringBuffer("abcd");
StringBuilder st2 = new StringBuilder("abcd");
TestCharacter tc = new TestCharacter();
tc.test(s1);
tc.test(st1);
tc.test(st2);
tc.test2();
tc.test3();
}
} 線程