volatile仅仅用来保证该变量对所有线程的可见性,但不保证原子性
volatile与synchronized的差异
volatile | synchronized |
---|---|
告诉jvm当前变量在寄存器中的值是不确定的,需要从主存中读取 | 锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞 |
变量级别 | 变量、方法级别 |
变量修改可见性 | 变量修改可见性和原子性 |
不会造成线程阻塞 | 可能会造成阻塞 |
标记变量不会被编译器优化 | 编辑变量会被编辑器优化 |
仅在有限情况下volatile 可以替代锁,要使volatile变量提供理想的线程安全,必须同时满足下面两个条件:
- 对变量的写操作不依赖与当前值
- 改变量没有包含在具有其他变量的不变式中
volatile适用情况
- boolean 状态标志
- 一次性安全发布,volatile 类型的引用可以确保对象的发布形式的可见性,但是如果对象的状态在发布后将发生更改,那么就需要额外的同步。
- 独立观察,发布的值是有效不可变的
- volatile bean 模式。
-- volatile bean 模式的基本原理是:很多框架为易变数据的持有者(例如 HttpSession)提供了容器,但是放入这些容器中的对象必须是线程安全的。
5.开销较低的读-写锁策略
并发编程中的三个概念
1.原子性 --java内存模型只保证基本读取和复制时原子性操作,除此外需要通过synchronized和lock来实现
2.可见性 --使用volatile修饰共享变量,保证被修饰的变量会被立即更新到主存,其他线程需要读取时,会从内存中读取新值。或通过synchronized和lock也可保证
3.有序性 --可以通过volatile或synchronized或lock来保证