start()方法加synchronized是为了保证Thread对象状态安全,防止重复启动导致资源泄漏、状态混乱或IllegalThreadStateException;其锁对象是this,仅保障单个Thread实例的启动原子性。

start() 方法本身是线程安全的,它内部用 synchronized 保证了线程启动过程的原子性。这不是为了保护你写的业务逻辑,而是防止多个线程反复调用同一个 Thread 对象的 start(),避免状态混乱或重复创建底层系统线程。
为什么 start() 必须加 synchronized?
一个 Thread 对象只能启动一次。如果没加同步,两个线程同时调用同一个 thread.start(),可能出现以下问题:
- 底层操作系统线程被重复创建,资源泄漏
- Thread 内部状态(如 NEW → RUNNABLE)被并发修改,导致 IllegalStateException(“IllegalThreadStateException: already started”)
- JVM 级别的线程注册机制出现竞态,影响线程生命周期管理
start() 的同步对象是谁?
start() 方法被声明为 synchronized,锁的是当前 Thread 实例本身(即 this)。也就是说,对同一个 Thread 对象的多次 start() 调用会串行执行——但第二次及以后都会直接抛异常,不会真正启动新线程。这个锁不涉及你的业务代码,也不影响其他 Thread 对象的 start() 调用。
它和你代码里的 synchronized 不是一回事
很多人混淆:start() 的 synchronized 是 JVM 层保障线程对象状态安全的基础设施;而你在 run() 里写的 synchronized 是为了解决共享数据的并发访问问题(比如账户余额、缓存计数器等)。两者作用域不同:
立即学习“Java免费学习笔记(深入)”;
- start() 的锁 → 保护 Thread 对象自身状态(NEW / STARTING / RUNNABLE)
- 你写的 synchronized → 保护业务数据对象(如 Account、List、Map)
不安全的常见误用
以下写法看似“启动”,实则无效且易误导:
- thread.run():只是普通方法调用,在主线程中执行,不开启新线程
- 重复调用 thread.start():第二次起抛 IllegalThreadStateException
- 在已启动的 thread 上再次 start():哪怕中间 stop() 或 interrupt() 过,也不能重启


















