本文来源于翁舒航的博客,点击即可跳转原文观看!!!(被转载或者拷贝走的内容可能缺失图片、视频等原文的内容)
若网站将链接屏蔽,可直接拷贝原文链接到地址栏跳转观看,原文链接:https://www.cnblogs.com/wengshuhang/p/10200269.html
这两天在看《java并发编程的艺术》,记录下看到的知识当做笔记吧!
java中的synchronized锁是存储在对象头中的,内容是mark word,长度根据计算机的位数来定32 or 64bit,
锁一共有4种状态,级别从低到高依次是:无锁,偏向锁,轻量级锁,重量级锁。锁只能逐一升级,不能降级。目的是为了提高获得锁和释放锁的效率。
1、偏向锁:当不存在多线程竞争时候,锁资源总是由同一个线程多次获得,所以为了节省线程获得锁的代价而引入偏向锁, 当检测对象中的mark word中线程id为当前线程时候,就默认获得了锁,若是没有,则检测是否偏向锁1,是则使用CAS将对象头偏向锁指向当前进程,不是的话则使用cas竞争锁。
当有多线程竞争时候,才能释放锁的机制,当全局安全点时候,暂停偏向锁的进程,线程不处于活跃状态则将对象头设置成无锁状态。
偏向锁是默认开启的,可以用 -XX:BiasdLockingStartupDelay=0 关闭偏向锁,程序会默认进入轻量级锁。
2、轻量级锁:
加锁:线程先获取对象头中的mark word复制到锁记录 Displaced mark word中,然后尝试使用CAS将对象头中mark word替换为当前锁记录的指针,成功则获得锁,失败则表示其他线程竞争锁,线程则使用自旋来获取锁
解锁:线程解锁时,使用cas操作将Displaced mark word替换回对象头,成功则没有锁竞争,失败则锁会膨胀成重量级锁。
3、重量级锁:因为自旋会消耗cpu,为了避免无用的自旋,当升级成为重量级锁就不会再回复到轻量级,只有当持有锁的线程释放锁后,便会唤醒等待的线程,让等待的线程再去争夺锁。
锁的优缺点对比: