在 Java 中,常说 String 是线程安全的,这并不是因为 String 内部用了锁或同步,而是因为它的不可变性(immutability)。
下面从原理上解释:
String 是不可变的(核心原因)在 JDK 中,String 的关键特征:
public final class String
implements Serializable, Comparable<String>, CharSequence {
private final char value[]; // JDK 8 及以前
// JDK 9+ 使用 byte[] value
}
关键点:
String 类被 final 修饰:不能被继承value 是 private finalString 不提供任何修改内部数据的方法(如 setValue、append 等)一旦创建:
String s = "abc";
s 指向的字符串内容就永远不会改变。
例如:
String s1 = "abc";
String s2 = s1.concat("def");
实际发生的是:
s1 不变String 对象 "abcdef"s2 指向新对象✅ 原有对象状态从未被修改
✅ 多个线程同时“读取”同一个 String 不会互相影响
线程安全的定义(简化):
多个线程同时访问一个对象,不需要额外同步,也不会出现数据不一致。
因为:
String所以:
不可变对象天生就是线程安全的
StringBuilder sb = new StringBuilder();
sb.append("a");
sb.append("b");
StringBuilder 内部数组可变append 会出问题(非线程安全)而:
StringBuffer
StringBuildersynchronized除了线程安全,String 不可变还带来:
Java 的
String是线程安全的,因为它不可变;任何“修改”都会创建新对象,而不是改变原对象。
如果你愿意,我也可以从 JVM 内存模型 / 字节码 / 源码层面再深入讲一遍。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。