多线程共享变量的情况下,为保证数据的一致性,往往需要对变量的访问进行同步操作,比如加锁了。
显式锁和CAS操作,会带来额外的开销和问题,如上下文切换/等待时间、ABA问题。
Immutable Object模式的意图是通过使用对外可见的状态不可变对象,使得共享对象天生具有线程安全的特性,而无需同步控制。从既保证了数据一致性,又避免了同步访问控制产生的开销和额外控制。
所谓状态不可变对象,即对象一经创建,其对外可见的状态就保持不变。String、Integer
所谓状态不可变对象并非指被建模的对象在现实世界里状态不可变,而是一种决策:现实世界里状态总是变化的,但我们可以用状态不可变的对象来进行实体建模。
类图:
类图说明:
时序图:
一个严格意义上的不可变对象要满足以下条件。
- 类本身是由final修饰,防止子类改变其行为。
- 所有的字段final修饰,final修饰的字段在其他线程可视的情况下,必定是初始化完成的。
- 对象在创建时,this关键字没有产生泄漏,防止其他类如该类的匿名内部类在对象的创建过程中修改其状态。
- 任何字段,若其引用了其他的状态不可变类的对象,则这些字段必须private修饰,并且这些值不可以对外暴露。若有相关方法要返回这些字段值,应该进行防御性复制。