synchronized锁状态和底层实现

锁的状态

无锁状态偏向锁状态轻量级锁状态重量级锁状态。锁的状态是通过对象监视器在对象头中的字段来表明的,四种状态会随着竞争的情况逐渐升级。偏向锁、轻量级锁、重量级锁是针对synchronized的状态。

这四种状态都不是 Java 语言中的锁,而是 JVM 为了提高锁的获取与释放效率而做的优化(使用synchronized时)

无锁:没有任何线程使用锁对象。

偏向锁:当前只有一个线程访问,在对象头 Mark World 中记录线程id,下次此线程访问时,可以直接获取锁。

轻量级锁:当锁的状态为偏向锁时,还有线程来访问,升级为轻量级锁,然后让线程以自旋的方式获取锁,线程不会阻塞。

重量级锁:当锁的状态为轻量级锁时,线程自旋获取锁的次数到达一定数量时,锁的状态升级为重量级锁,会让自旋次数多的线程进入阻塞状态,等待操作系统调度。因为访问量大时,线程都自旋获取锁,CPU消耗大。

以上的状态设计都是Java为了优化 synchronized锁。

对象结构

在 Hotspot 虚拟机中,对象在内存中的布局分为三块区域:对象头,实例数据和对齐填充;Java对象头是实现 synchronized 锁对象的基础。一般而言,synchronized 使用的锁对象是存储在Java对象头中,对象头是轻量级锁和重量级锁的关键。

对象头中有一块区域称为 Mark World,用于存储对象自身运行时的数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID等待

复制代码
<!--添加依赖-->
<dependency>
    <groupId>org.openjdk.jol</groupId>
    <artifactId>jol-core</artifactId>
    <version>0.10</version>
</dependency>
java 复制代码
import org.openjdk.jol.info.ClassLayout;

public class PrintMarkWord {
    public static void main(String[] args) {
        PrintMarkWord printMarkWord = new PrintMarkWord();
        // 打印相关的对象头信息
        System.out.println(ClassLayout.parseInstance(printMarkWord).toPrintable());

        System.out.println("============================================================分割线============================================================");

        synchronized (printMarkWord) {
            // 尝试加锁改变对象头信息
            System.out.println(ClassLayout.parseInstance(printMarkWord).toPrintable());
        }
    }
}
相关推荐
第二只羽毛3 分钟前
重载和继承的实践
java·开发语言
王嘉俊9258 分钟前
设计模式--适配器模式:优雅解决接口不兼容问题
java·设计模式·适配器模式
王嘉俊92510 分钟前
设计模式--组合模式:统一处理树形结构的优雅设计
java·设计模式·组合模式
道199317 分钟前
50 台小型无人车与50套穿戴终端 5 公里范围内通信组网方案深度研究
java·后端·struts
迎風吹頭髮22 分钟前
UNIX下C语言编程与实践35-UNIX 守护进程编写:后台执行、脱离终端、清除掩码与信号处理
java·c语言·unix
光军oi39 分钟前
全栈开发杂谈————JAVA微服务全套技术栈详解
java·开发语言·微服务
帮帮志39 分钟前
目录【系列文章目录】-(关于帮帮志,关于作者)
java·开发语言·python·链表·交互
聪明的笨猪猪40 分钟前
Java Spring “MVC ”面试清单(含超通俗生活案例与深度理解)
java·经验分享·笔记·面试
qiuiuiu4131 小时前
正点原子RK3568学习日记-GIT
linux·c语言·开发语言·单片机
草莓熊Lotso1 小时前
《C++ STL list 完全指南:从基础操作到特性对比,解锁链表容器高效用法》
开发语言·c++·list