Java包装类线程安全的根本原因是其不可变性:实例创建后内部状态不可修改,“修改”操作均返回新对象,故多线程读取无需同步;但引用变量的赋值操作非原子,需额外同步机制保障。

Java中的包装类(如 Integer、Boolean、Character 等)是线程安全的,根本原因在于它们是不可变对象(immutable)。
不可变性带来天然线程安全
每个包装类实例一旦创建,其内部状态(如 int value 在 Integer 中)就无法被修改。所有“改变值”的操作(如 i++、Integer.valueOf(5))实际都返回一个新对象,原对象保持不变。因此:
- 多个线程可以同时读取同一个包装类实例,无需同步——没有竞态条件
- 不存在写-写冲突或写-读不一致问题
- 不需要加锁、CAS 或 volatile 修饰也能安全共享
注意:变量引用本身不是线程安全的
虽然包装类对象不可变,但引用变量本身可能被多线程并发赋值。例如:
Integer counter = 0;// 线程A:counter = counter + 1;// 线程B:counter = counter + 1;// 结果可能为1(丢失一次更新),因为 counter = ... 是读-改-写三步操作
这里出问题的不是 Integer,而是对引用变量 counter 的非原子赋值。要保证这类逻辑安全,需用 AtomicInteger、synchronized 或 volatile(仅适用于简单读写,不能解决复合操作)等机制。
立即学习“Java免费学习笔记(深入)”;
缓存机制不影响线程安全性
像 Integer.valueOf(-128 ~ 127) 返回的是缓存对象,但这只是优化手段。缓存对象本身仍不可变,多个线程获取到同一个缓存实例也完全安全。超出范围时每次新建对象,同样因不可变而安全。
与集合包装器的区别要分清
别把 Collections.synchronizedList() 这类“同步包装器”和“基本类型包装类”混淆。前者是对可变集合加锁,后者是对不可变值的封装——两者设计目标、实现原理和安全边界完全不同。


















