美文网首页Android全集
【Java】锁升级与CAS

【Java】锁升级与CAS

作者: littlefogcat | 来源:发表于2021-02-02 21:36 被阅读0次

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

    相关文章

      网友评论

        本文标题:【Java】锁升级与CAS

        本文链接:https://www.haomeiwen.com/subject/sdbytltx.html