1.final语义与使用
final的语义
-
编译器做的处理
- 编译器可以跨同步屏障移动对final修饰的字段值进行读取和调用任意或未知的方法
- 对于final与non-final修饰的字段,允许编译器保存一份final的数据缓存放在寄存器中,对比必须要加载non-final数据的情况下,它不需要从主内存中加载就可以获取
-
并发线程下是安全的
- 对于final修饰的字段在所有线程中是属于不可变(基本类型值不可变,引用类型是引用地址不可变),也就是对于程序员而言,在线程中重新对final修饰的字段赋值将会编译不通过
- 只有在对象完全初始化之后,线程才能看到对该对象的引用,这样就可以保证看到该对象的final字段的正确初始化值
基于Happen-Before原则,程序任何对象的初始化happen-before于程序中任何其他的动作操作行为 因此能够保证不会被重排序,也就是说final修饰的字段在线程读取已经先在构造器中执行写操作 因而所有线程看到final修饰的变量均为最终最新的版本
-
final的使用模型
- 在对象的构造函数中为对象设置final字段;在对象的构造函数完成之前,不允许在其他线程可以看到的地方对正在构造的对象的引用执行写操作
- 这样可以保证在线程看