Android全集

【Java】锁升级与CAS

2021-02-02  本文已影响0人  littlefogcat

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操作执行期间,其他线程抢占了这个锁,那么本线程就竞争失败了,于是开始自旋重新竞争锁。

上一篇 下一篇

猜你喜欢

热点阅读