標籤:string stringbuffer stringbuilder
上一篇文章新手學JAVA(二)----String類與StringBuffer類的區別中瞭解到,String的值是不可變的,這就導致
每次對String的操作都會產生新的String對象,不僅效率低下,而且大量浪費有限的記憶體空間,StringBuffer是可變
類,和安全執行緒的字串操作類,任何對它指向的字串的操作都不會產生新的對象。
StringBuffer類和StringBuilder類功能基本相似。算是兩個雙胞胎。
下面主要說兩點
第一點 安全執行緒
StringBuffer 安全執行緒
StringBuilder 線程不安全
關於安全執行緒的知識,正在學習,剛接觸,沒有太深入的瞭解,在這知識稍微的提一下。
安全執行緒——如果你的代碼所在的進程中有多個線程在同時運行,而這些線程可能會同時運行這段代碼。如果每次
運行結果和單線程啟動並執行結果是一樣的,而且其他的變數的值也和預期的是一樣的,就是安全執行緒的。
StringBuffer類和StringBuilder類兩者沒有很大的區別,但是線上程安全方面,StringBuffer允許多線程進行字
符操作。這是因為在原始碼中StringBuffer的很多方法都被關鍵字synchronized(這個關鍵字是為線程同步機制設定
的。) 修飾了,而StringBuilder沒有。
簡單的說一說synchronized的含義:
每一個類對象都對應一把鎖,當某個線程A調用類對象O中的synchronized方法M時,必須獲得對象O的鎖才能夠執行
M方法,否則線程A阻塞。一旦線程A開始執行M方法,將獨佔對象O的鎖。使得其它需要調用O對象的M方法的線程阻
塞。只有線程A執行完畢,釋放鎖後。那些阻塞線程才有機會重新調用M方法。這就是解決線程同步問題的鎖機制。
因此,多線程編程中StringBuffer比StringBuilder要安全的多。
有一點需要注意的是,有的人會問,String類是不是也不安全? 事實上不存在這個問題,String是不可變的。線
程對於堆中指定的一個String對象只能讀取,無法修改。還有什麼不安全的?
第二點 效率問題
一般情況下,速度從快到慢:StringBuilder>StringBuffer>String,這種比較是相對的,不是絕對的。
舉個簡單的例子:
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(); } }
下面是迴圈50000次,10000次,1000次,100次的運行結果:
總結
(1).如果要操作少量的資料用 = String
(2).單線程操作字串緩衝區 下操作大量資料 = StringBuilder
(3).多線程操作字串緩衝區 下操作大量資料 = StringBuffer
新手學JAVA(三)----StringBuilder類