1. 无锁态
对象刚创建,没有任何锁
2. 偏向锁
当处于无锁态时,如果同步代码被线程访问,线程自动获得锁,状态变为偏向锁。
这个时候,锁的markword保存了指向该线程的指针。
此时,如果发生线程竞争锁,则锁升级为轻量锁。
3. 轻量锁(自旋锁)
当多个线程竞争一个偏向锁,则锁升级为轻量锁。
轻量级锁对象的markword保存了指向某个线程栈LockRecord的指针。
当线程竞争锁时,使用CAS(compare and swap)操作尝试将锁markword中的指针指向自己(的LockRecord),如果成功,那么就获得锁。如果失败,那么重新竞争(自旋)。
如果一直自旋下去,会非常消耗cpu资源,因为所有竞争的线程都在运行。
所以当自旋到一定条件之后(竞争剧烈到一定程度),锁会升级为重量级锁。
4. 重量级锁
系统提供的锁机制。
开销大,进行了从用户态到内核态的转换。
重量级锁的优势在于,没有获得锁的线程将被挂起,不消耗资源。
5. CAS(Compare and Swap)
CAS是一个有三个参数的原子操作,这里写作CAS(a, b, val)。
CAS(a, b, val)的含义是,如果a的值等于b,那么将a的值设置为val。
在上面轻量锁的例子中,当一个线程竞争锁时,会首先在自己内部保存锁markword的副本;然后使用CAS操作尝试更新锁的指向。
在这里,a就是锁指向的线程(即锁对象markword中保存的指向线程LockRecord的指针),b就是竞争线程中锁的副本,val就是竞争线程自身。
这个操作的含义是,如果CAS执行成功,说明在竞争线程保存锁副本到CAS操作执行期间,其他线程没有竞争到锁,那么本线程竞争成功;如果执行失败,即a不等于b,说明在竞争线程保存锁副本到CAS操作执行期间,其他线程抢占了这个锁,那么本线程就竞争失败了,于是开始自旋重新竞争锁。
网友评论