volatile
volatile在转成汇编的时候,会加一条lock指令前缀,该指令的作用:
1.对变量值的改动会引起处理器的缓存刷新到主内存
2.导致其他处理器的缓存会无效
适用于一下的场景:
1.运算结果并不依赖变量的当前值,或者能够确保只有单一的线程修改变量的值
2.变量不需要与其他状态变量共同参与不变约束
i++,进行汇编之后是四句指令,先读取i,然后把i+1赋值给i,这依赖当前变量的值,所以并不是线程安全的。如果是单一线程,则肯定是安全的。
a线程拿的时候是最新的,拿完之后,还要进行add和赋值操作,主内存已经被更改过了。只能保证拿的时候是最新的,当前线程再操作其他指令的时候不能保证了。
对于2也是同样的例子,if(bo1)是原子性的,但是对于if(bo2&&bo1)并不是原子性的
偏向锁、轻量级锁、重量级锁
偏向锁:第一个线程过来看对象头里面是否有当前线程id,如果没有,则用cas设置当前线程id存储在mark word,再执行该同步块,则不需要经常任何同步操作。
当另外一个线程尝试获取锁,偏向模式宣告结束。如果锁处于锁定状态,则升级成为轻量级锁(01),否则撤销偏向到未锁定状态(00)。
(适用的场景是单个线程操作,如果多个线程竞争存在锁消除和升级的消耗)
轻量级锁:线程访问同步块,cas修改mark word 指向到当前线程。下次执行直接判断mark word 指向的是不是当前线程,是则可以直接执行同步体。
释放锁的过程也是通过cas 去替换回来,成功表示同步过程完成。失败表示其他线程在竞争已经进入阻塞状态了,释放锁的同时还要唤醒等待中的线程。
其他线程来访问,也是进行cas 修改mark word ,修改失败则自旋获取锁,还是失败,修改锁为重量级锁进入阻塞状态
重量级锁即传统的锁机制
volatile在转成汇编的时候,会加一条lock指令前缀,该指令的作用:
1.对变量值的改动会引起处理器的缓存刷新到主内存
2.导致其他处理器的缓存会无效
适用于一下的场景:
1.运算结果并不依赖变量的当前值,或者能够确保只有单一的线程修改变量的值
2.变量不需要与其他状态变量共同参与不变约束
i++,进行汇编之后是四句指令,先读取i,然后把i+1赋值给i,这依赖当前变量的值,所以并不是线程安全的。如果是单一线程,则肯定是安全的。
a线程拿的时候是最新的,拿完之后,还要进行add和赋值操作,主内存已经被更改过了。只能保证拿的时候是最新的,当前线程再操作其他指令的时候不能保证了。
对于2也是同样的例子,if(bo1)是原子性的,但是对于if(bo2&&bo1)并不是原子性的
偏向锁、轻量级锁、重量级锁
偏向锁:第一个线程过来看对象头里面是否有当前线程id,如果没有,则用cas设置当前线程id存储在mark word,再执行该同步块,则不需要经常任何同步操作。
当另外一个线程尝试获取锁,偏向模式宣告结束。如果锁处于锁定状态,则升级成为轻量级锁(01),否则撤销偏向到未锁定状态(00)。
(适用的场景是单个线程操作,如果多个线程竞争存在锁消除和升级的消耗)
轻量级锁:线程访问同步块,cas修改mark word 指向到当前线程。下次执行直接判断mark word 指向的是不是当前线程,是则可以直接执行同步体。
释放锁的过程也是通过cas 去替换回来,成功表示同步过程完成。失败表示其他线程在竞争已经进入阻塞状态了,释放锁的同时还要唤醒等待中的线程。
其他线程来访问,也是进行cas 修改mark word ,修改失败则自旋获取锁,还是失败,修改锁为重量级锁进入阻塞状态
重量级锁即传统的锁机制