[轉載] 整理下java中stringBuilder和stringBuffer兩個類的區別
StringBuilder和StringBuffer這兩個類在動態拼接字串時常用,肯定比String的效率和開銷小,這是因為String的物件不會回收哦。
其實我一直用StringBuilder這個類,因為可以簡寫為sb的變數在程式裡很爽,可是後來師兄說web程式特別是高併發的程式中不要用stringbuilder,因為簡單說,stringBuilder不是執行緒安全的,而StirngBuffer就是執行緒安全的。從網上看到Stringbuffer中方法大都採用了synchronized的關鍵字修飾。
來來來,我們先複習下syncronized的用法,有篇部落格寫的挺好的,給個連結 http://leo-faith.iteye.com/blog/177779
1、synchronized關鍵字的作用域有二種: 1)是某個物件例項內,synchronized aMethod(){}可以防止多個執行緒同時訪問這個物件的synchronized方法(如果一個物件有多個synchronized方法,只要一個執行緒訪問了其中的一個synchronized方法,其它執行緒不能同時訪問這個物件中任何一個synchronized方法)。這時,不同的物件例項的synchronized方法是不相干擾的。也就是說,其它執行緒照樣可以同時訪問相同類的另一個物件例項中的synchronized方法; 2)是某個類的範圍,synchronized static aStaticMethod{}防止多個執行緒同時訪問這個類中的synchronized static 方法。它可以對類的所有物件例項起作用。
2、除了方法前用synchronized關鍵字,synchronized關鍵字還可以用於方法中的某個區塊中,表示只對這個區塊的資源實行互斥訪問。用法是: synchronized(this){/*區塊*/},它的作用域是當前物件;
3、synchronized關鍵字是不能繼承的,也就是說,基類的方法synchronized f(){} 在繼承類中並不自動是synchronized f(){},而是變成了f(){}。繼承類需要你顯式的指定它的某個方法為synchronized方法;
好了,言歸正傳,我們繼續StringBuffer和StringBuilder的區別。
就是說,StringBuffer中所有的方法都要加鎖,所以好多操作看上去都是線性操作的。所以要慢些。
一般情況下,速度從快到慢:StringBuilder>StringBuffer>String.當需要在迴圈中多次使用字串拼接時,建議使用StringBuilder或StringBuffer.當數量級在百萬級(這裡可能不準確)時,StringBuilder的速度會體現出來.
以下是實驗資料
01 final static int ttime = 30000;// 測試迴圈次數
02
03 public void test(String s) {
04 long begin = System.currentTimeMillis();
05 for (int i = 0; i < ttime; i++) {
06 s += "add";
07 }
08 long over = System.currentTimeMillis();
09 System.out.println(" 操作 " + s.getClass().getName() + " 型別使用的時間為: " + (over - begin) + " 毫秒 ");
10 }
11
12 public void test(StringBuffer s) {
13 long begin = System.currentTimeMillis();
14 for (int i = 0; i < ttime; i++) {
15 s.append("add");
16 }
17 long over = System.currentTimeMillis();
18 System.out.println(" 操作 " + s.getClass().getName() + " 型別使用的時間為: " + (over - begin) + " 毫秒 ");
19 }
20
21 public void test(StringBuilder s) {
22 long begin = System.currentTimeMillis();
23 for (int i = 0; i < ttime; i++) {
24 s.append("add");
25 }
26 long over = System.currentTimeMillis();
27 System.out.println(" 操作 " + s.getClass().getName() + " 型別使用的時間為: " + (over - begin) + " 毫秒 ");
28 }
29
30 // 對 String 直接進行字串拼接的測試
31 public void test2() {
32 String s2 = "abadf";
33 long begin = System.currentTimeMillis();
34 for (int i = 0; i < ttime; i++) {
35 String s = s2 + s2 + s2;
36 }
37 long over = System.currentTimeMillis();
38 System.out.println(" 操作字串物件引用相加型別使用的時間為: " + (over - begin) + " 毫秒 ");
39 }
40
41 public void test3() {
42 long begin = System.currentTimeMillis();
43 for (int i = 0; i < ttime; i++) {
44 String s = "abadf" + "abadf" + "abadf";
45 }
46 long over = System.currentTimeMillis();
47 System.out.println(" 操作字串相加使用的時間為: " + (over - begin) + " 毫秒 ");
48 }
49
50 public static void main(String[] args) {
51 String s1 = "abc";
52 StringBuffer sb1 = new StringBuffer("abc");
53 StringBuilder sb2 = new StringBuilder("abc");
54 Test t = new Test();
55 t.test(s1);
56 t.test(sb1);
57 t.test(sb2);
58 t.test2();
59 t.test3();
60 }
試驗結果如下:
操作 java.lang.String 型別使用的時間為: 2432 毫秒
操作 java.lang.StringBuffer 型別使用的時間為: 3 毫秒
操作 java.lang.StringBuilder 型別使用的時間為: 3 毫秒
操作字串物件引用相加型別使用的時間為: 6 毫秒
操作字串相加使用的時間為: 1 毫秒
把迴圈次數調的很大,試了用下jconsle來監視記憶體GC,第一次使用,不太明白,有個部落格寫的很好的,有空研究一下
http://jiajun.iteye.com/blog/810150
再補充一個Jstat的工具 http://xiaolele.iteye.com/blog/592022
/**
*20120516昨天忘看原始碼了
**/
StringBuffer中append方法有很多過載,有synchronized關鍵字沒錯,主要呼叫的還是AbstractStringBuilder的super的方法。
1 public synchronized StringBuffer append(String s)
2 {
3 super.append(s);
4 return this;
5 }
父類的方法為
01 public AbstractStringBuilder append(String s) {
02
03 if (s == null)
04 s = "null";
05 int i = s.length();
06 if (i == 0)
07 return this;
08 int j = count + i;
09 if (j > value.length)
10 expandCapacity(j);
11 s.getChars(0, i, value, count);
12 count = j;
13 return this;
14 }
StringBuilder類中的append就沒有同步的關鍵字了。父類的方法基本上差不多。
總結一下,StringBuffer執行緒安全,內部有synchronized方法,StringBuilder是1.5之後出來的,高併發就不要用了。另外synchronized的使用要熟悉,以後研究下java記憶體的工具,比如jconsle。
轉載:http://my.oschina.net/zimingforever/blog/57514
相關文章
- StringBuffer 和 StringBuilder 的 3 個區別UI
- [java基礎]StringBuilder和StringBuffer的3個區別JavaUI
- StringBuffer和StringBuilder的區別UI
- StringBuilder和StringBuffer的區別UI
- Java StringBuffer 和 StringBuilder 類JavaUI
- stringbuilder和stringbuffer區別UI
- Java中的String,StringBuilder,StringBuffer三者的區別JavaUI
- StringBuffer 和 StringBuilder 類UI
- String,StringBuilder,StringBuffer的區別UI
- String、StringBuffer、StringBuilder的區別UI
- String、StringBuilder、StringBuffer的區別UI
- String、StringBuffer、StringBuilder區別?UI
- String,StringBuffer,StringBuilder區別UI
- String、StringBuffer和StringBuilder類的UI
- String,StringBuffer與StringBuilder的區別UI
- 【Java】String、StringBuilder和StringBufferJavaUI
- Java 之String、StringBuffer 和 StringBuilder 三者區別介紹JavaUI
- Android- String、StringBuffer、StringBuilder區別AndroidUI
- 『Java 語法基礎』String、StringBuffer 與 StringBuilder 的區別JavaUI
- JAVA面試題 StringBuffer和StringBuilder的區別,從原始碼角度分析?Java面試題UI原始碼
- StringBuffer和StringBuilderUI
- 從原始碼看String,StringBuffer,StringBuilder的區別原始碼UI
- 面試必知:String、StringBuilder、StringBuffer的區別面試UI
- Java 21的StringBuilder和StringBuffer新增了一個repeat方法JavaUI
- String StringBuffer StringBuilder的區別(前端面試必備)UI前端面試
- String、StringBuilder和StringBufferUI
- Java中String,StringBuffer,StringBuilder基礎知識JavaUI
- 認識Java中String與StringBuffer以及StringBuilderJavaUI
- StringBuffer類的delete()方法和deleteCharAt()方法的區別delete
- String和StringBuilder的區別UI
- StringBuilder和String 的區別?UI
- C# string、stringBuffer和stringBuilderC#UI
- System,Runtime,Math,StringBuffer和StringBuilderUI
- java複習之 String,StringBuffer,StringBuilderJavaUI
- Java中StringBuffer類的常用方法Java
- String、StringBuffer、StringBuilder的理解UI
- java中maven下載和安裝整理JavaMaven
- String、StringBuffer、StringBuilder剖析UI