diff --git a/docs/java/basis/java-basic-questions-02.md b/docs/java/basis/java-basic-questions-02.md index 2aa14b0946a..cb95be7eb1e 100644 --- a/docs/java/basis/java-basic-questions-02.md +++ b/docs/java/basis/java-basic-questions-02.md @@ -603,7 +603,8 @@ public native int hashCode(); **可变性** -`String` 是不可变的(后面会详细分析原因)。 +`String` 是不可变的(后面会详细分析原因),每次修改都会生成新的对象,并将引用指向新的实例,而 `StringBuffer` 和 `StringBuilder` 都是可变的,它们在修改字符串时不会创建新对象,而是直接在原有字符数组上进行操作。 + `StringBuilder` 与 `StringBuffer` 都继承自 `AbstractStringBuilder` 类,在 `AbstractStringBuilder` 中也是使用字符数组保存字符串,不过没有使用 `final` 和 `private` 关键字修饰,最关键的是这个 `AbstractStringBuilder` 类还提供了很多修改字符串的方法比如 `append` 方法。 @@ -631,7 +632,11 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { **性能** -每次对 `String` 类型进行改变的时候,都会生成一个新的 `String` 对象,然后将指针指向新的 `String` 对象。`StringBuffer` 每次都会对 `StringBuffer` 对象本身进行操作,而不是生成新的对象并改变对象引用。相同情况下使用 `StringBuilder` 相比使用 `StringBuffer` 仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险。 +两者的性能差异主要来源于线程安全机制: +- `StringBuffer` 的方法通常是同步的(线程安全),因此会带来一定的性能开销; +- `StringBuilder` 没有同步开销(非线程安全),在单线程场景下通常具有更好的性能表现。 +相同情况下使用 `StringBuilder` 相比使用 `StringBuffer` 仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险。 +另外,具体的性能差异并不是固定的,在现代 JVM 中由于锁优化(如锁消除),两者在某些场景下性能差距可能较小。 **对于三者使用的总结:**