this引用逃逸指构造函数未完成时,this被发布给其他线程或外部代码,导致访问到部分初始化对象;常见场景包括构造器中启动线程、注册监听器、创建内部类或存入静态容器,可能读到默认值或引发数据不一致。

在Java多线程开发中,this引用逃逸是最隐蔽也最危险的陷阱之一——它不抛异常、不报错,却会让对象在未初始化完成时就被其他线程访问,导致读到部分构造的状态,引发不可预测的行为。
构造器里别暴露this
这是最常见的逃逸场景:在构造函数中把this传给外部方法、注册监听器、启动线程或存入静态容器。此时对象可能连final字段都还没赋值完毕,JVM允许指令重排序,甚至final字段也可能被看到默认值(如0、null)。
- 避免在构造器中调用非私有方法(尤其是可能被子类重写的方法),因为子类方法可能访问未初始化字段
- 不要在构造器中新建内部类并将其引用传递出去(如匿名监听器),内部类隐式持有
this - 禁止将
this存入静态集合、全局事件总线、缓存或线程池任务中
启动线程要延迟到构造完成之后
在构造函数里直接new Thread().start(),等于把半成品对象交给另一个线程运行。尤其当该线程访问实例变量或调用实例方法时,很可能读到初始值或null。
- 提供显式的
start()或init()方法,由调用方在对象完全构造后再触发 - 若必须异步初始化,改用
ExecutorService提交延迟任务,确保构造链已结束 - 考虑用静态工厂方法封装构造与启动逻辑,例如
createAndStart()
正确发布对象的三个关键点
安全发布的核心是:保证其他线程看到的对象状态,一定是构造完成后的最终态。
- 用
final修饰所有不可变字段——JMM保证final域在构造器结束前对其他线程可见 - 通过同步机制发布:如将对象引用赋值给
synchronized块内共享变量,或放入ConcurrentHashMap等线程安全容器 - 使用
volatile字段发布引用(适用于单次写、多读场景),但注意它只保障引用本身可见,不保证对象内部状态已初始化完毕
警惕继承链中的this泄露
子类构造器执行前,父类构造器已先运行。如果父类构造器中用了this(比如回调、注册、日志打印),而此时子类字段仍是默认值,就可能破坏业务逻辑。
- 父类构造器中避免调用可被重写的方法(即非
private、非final方法) - 设计上优先使用组合而非继承,减少构造时的耦合风险
- 必要时用静态工厂+私有构造器,控制对象创建全过程
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











