首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

StringBuffer vs StringBuilder:線程安全與效能的取捨

     編輯:Java 相關知識

核心差異一覽

特性StringBufferStringBuilder
引入版本JDK 1.0JDK 5.0
線程安全所有公共方法 synchronized非線程安全
效能同步開銷,較慢無同步,單執行緒下顯著更快
API 相容性完全相同完全相同
繼承關係AbstractStringBuilderAbstractStringBuilder

為什麼要有 StringBuilder?

StringBuffer 早期為了線程安全,所有方法加 synchronized。但實際使用場景中,字串建構器多為 方法區域變數,不跨執行緒共享,同步完全多餘。JDK 5 引入 StringBuilder 移除同步,提供 2-3 倍效能提升。

典型使用模式

// 方法內部區域變數 → 單執行緒 → 用 StringBuilder
public String toString() {
    return new StringBuilder()
        .append("User{id=").append(id)
        .append(", name='").append(name).append('\'')
        .append(", email='").append(email).append('\'')
        .append('}').toString();
}

// 共享緩衝區(罕見) → 需線程安全 → 用 StringBuffer
// 或更佳:ThreadLocal / 並發容器

效能實測 (JMH 風格)

@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class StringBuilderBenchmark {
    @Benchmark
    public void stringBuffer() {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < 100; i++) sb.append("test");
    }

    @Benchmark
    public void stringBuilder() {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 100; i++) sb.append("test");
    }
}
// 典型結果:StringBuilder 約快 2-3 倍

String 不可變性補充

String 為 final class,內部 final char[] value(JDK 9+ 為 byte[] + coder)。每次拼接 s += "x" 都會建立新物件、複製陣列,循環中會產生大量暫存物件 → GC 壓力。StringBuilder 內部維護可擴充陣列,只在 toString() 時建立最終 String。

最佳實踐建議

  1. 預設使用 StringBuilder:單執行緒字串建構、拼接、JSON/CSV 產出等。
  2. 僅在共享可變字串緩衝區跨執行緒時用 StringBuffer:極少見,通常改用 ThreadLocal 或不可變設計。
  3. 預估容量:new StringBuilder(estimatedSize) 減少擴容複製。
  4. 避免在循環中使用 String +:編譯器會自動優化單條語句,但循環不會。

總結

StringBuilder 是 StringBuffer 的非同步替代品,針對單執行緒場景優化。理解「區域變數不共享」這一事實,是選擇正確工具的關鍵。現代代碼中,StringBuilder 應為首選。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved