结论先行:不可变对象(Immutable Object)是天然线程安全的,前提是它真的“不可变”。
但“不可变”不是口头说说,而是有严格条件的。
不可变对象一旦创建,状态就不能被修改,因此:
线程安全问题只发生在“写”上
不可变对象没有写,所以一定是线程安全的
类不能被继承
final class所有字段都是 final
对象构造过程是安全的
this 逃逸字段引用的是不可变对象
public final class Point {
private final int x;
private final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() { return x; }
public int getY() { return y; }
}
✅ 线程安全
✅ 无需 synchronized
✅ 可自由共享
public final class User {
private final List<String> roles;
public User(List<String> roles) {
this.roles = roles; // ❌ 外部仍可修改
}
}
问题:
roles 是 finalList 本身是可变的✅ 修复方式:
this.roles = Collections.unmodifiableList(new ArrayList<>(roles));
或直接使用不可变集合(如 Guava / Java 9+)
这是一个常见误区。
“只要字段是 final,就是不可变”
对象整体状态不可变
例如:
final 引用this ❌✅ 天生线程安全
✅ 无需锁,性能高
✅ 易于推理、调试
✅ 适合作为 Map key / 缓存对象
✅ 函数式编程友好
this 逃逸public class Unsafe {
public Unsafe() {
new Thread(() -> System.out.println(this)).start();
}
}
❌ 对象尚未构造完成就被使用
final Date date;
Date 是可变的 ❌
那是“破坏不可变性”,不属于正常语义范围。
不可变对象在正确实现的前提下,是天然线程安全的;
但“看起来不可变”不等于“真的不可变”。
如果你愿意,我可以:
你更想深入哪一块?
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。