【高薪程序员必看】万字长文拆解Java并发编程!(4-1):悲观锁底层原理与性能优化实战

简介: 目录4. JVM字节码文件4.1. 字节码文件-组成4.1.1. 组成-基础信息4.1.1.1. 基础信息-魔数4.1.1.2. 基础信息-主副版本号4.1.2. 组成-常量池4.1.3. 组成-方法4.1.3.1. 方法-工作流程4.1.4. 组成-字段4.1.5. 组成-属性4.2. 字节码文件-查看工具4.2.1. javap4.2.2. jclasslib4.2.3. 阿里Arthas

 

image.gif 编辑

Hello大家好!👋 我是摘星✨,今天我们来深度拆解Java并发编程中最经典的「悲观锁」🔒设计。

在多线程环境下,当你的转账操作被重复提交💸、库存被超卖📉、计数器结果离奇错误❌时,背后往往是因为缺乏合理的锁控制。而悲观锁作为Java并发中最「简单粗暴」的解决方案,从JDK1.0时代的重量级锁⛓️,到如今JVM层级的锁升级优化⚡,其底层实现堪称一部高性能并发的发展史📜

本文将带你穿透**synchronized关键字**的表面语法,直击三大核心问题💡:

  1. **🤔 为什么悲观锁能保证线程安全?**(从Java对象头到Monitor的硬件级协作)
  2. **⚡ JDK1.6后synchronized如何实现性能飞跃?**(偏向锁/轻量级锁的取舍智慧)
  3. **🚫 高并发场景下如何规避锁的性能陷阱?**(从字节码层面理解锁膨胀的条件)

📌 举个真实案例:某电商平台在秒杀活动中使用synchronized导致TPS从8000📈暴跌到300📉,最终通过缩小锁粒度+锁分离优化提升15倍性能🚀——我们将在文中用代码还原这个优化过程。

下面我们直接切入正题,从操作系统与JVM的协作契约🤝开始讲起!

目录

4. 有锁并发-悲观锁

4.1. 悲观锁思想

4.2. Synchronized

4.3. Java对象头

4.4. Monitor


4. 有锁并发-悲观锁

4.1. 悲观锁思想

悲观锁:假设其他线程会修改共享资源,在进入同步代码块时就加上锁,防止其他线程的干扰。但是如果竞争激烈,就会发生线程上下文切换,性能相对低。

4.2. Synchronized

synchronized关键字,基于Monitor实现,用于实现多线程之间的同步,是悲观锁

synchronized的执行流程:

  1. 第一个线程获取对象锁执行同步代码块
  2. 其他想要获取对象锁进入同步代码块的线程进入阻塞状态
  3. 第一个线程退出同步代码块释放锁后,会唤醒阻塞中的线程
  4. 被唤醒的线程进行非公平的锁争抢,抢到锁的线程执行同步代码块,其他线程继续阻塞

synchronized的特性:

  1. 原子性(Atomicity):synchronized保证同时只能有一个线程执行同步代码块,对共享数据的操作是原子的。
  2. 可见性(Visibility):一个线程执行synchronized同步代码块时,会先获取主内存中的数据到工作内存中,修改共享资源,退出同步代码块时,会将工作内存中的数据刷新到主内存中,保证数据的可见性。
  3. 有序性(Ordering):synchronized会禁止JVM对字节码指令重排优化,保证线程执行的有序性。

synchronized的作用范围:

  1. 成员方法:synchronized修饰成员方法时,锁住的是当前对象实例。
  2. 静态方法:synchronized修饰静态方法时,锁定的是当前类的Class对象。
  3. 代码块:synchronized修饰代码块时,锁定的是指定的对象。

多线程只有获取同一个对象的锁才能起到同步互斥的效果

JDK1.6之前synchronized是重量级锁,jdk1.6之后对synchronized做了一系列优化,加入了偏向锁和轻量级锁,优化了线程上下文切换的性能

4.3. Java对象头

synchronized是悲观锁,在操作共享资源之前需要先加锁,加的锁就存在于Java对象头中.

Hotspot虚拟机中的对象头主要包含两部分数据:Mark Word(标记字段)和Klass Pointer(类型指针)

  • Mark Word:存储对象的hashcode,分代年龄,锁标志位信息.这些信息跟对象自定定义无关,所以Mark Word被设计为非固定的数据结构以便在极小的空间中存储多的数据,它会根据对象的状态复用空间,也就是说在运行期间,Mark Word中的存储数据会跟着锁标志位变化而变化

    image.gif 编辑
  • Klass Pointer:指向类元数据的指针,用于确定当前对象是哪个类的实例

4.4. Monitor

Monitor是一种同步机制,依赖于操作系统底层的Mutex Lock(同步锁)来实现同步,在Java中,每一个Java对象都会关联一个Monitor对象,synchronized关键字就是通过Monitor来实现线程同步的,是重量级锁

Monitor的组成部分:

  • owner(所有者):用于存放当前拥有了Monitor对象的线程,也就是拥有对象锁的线程,只有owner线程才能执行同步代码块.
  • waitlist(等待队列):用于存放因调用了wait方法而处于等待中的线程,同时释放该对象锁
  • EntryList(入口队列):用于存放尝试获取对象锁未成功而处于阻塞状态中的线程,当owner释放对象锁时,会唤醒EntryList中的线程来竞争对象锁,成功者成为会owner,失败者则继续等待

Monitor的执行流程:

  1. 第一个进入synchronized代码块的线程,首先尝试获取对象锁,如果锁是空闲状态,则获取到锁,成为owner。如果锁已被其他线程占用,则进入阻塞
  2. 其他访问synchronized代码块的线程尝试获取对象锁未成功,处于阻塞状态,进入EntryList队列,等待对象锁的释放
  3. synchronized代码块执行完毕后,会释放该对象锁,同时唤醒EntryList中阻塞的线程来竞争对象锁,竞争成功的线程成为新的owner,失败的线程则继续等待
相关文章
|
9月前
|
Java 关系型数据库 数据库
Java 项目实战教程从基础到进阶实战案例分析详解
本文介绍了多个Java项目实战案例,涵盖企业级管理系统、电商平台、在线书店及新手小项目,结合Spring Boot、Spring Cloud、MyBatis等主流技术,通过实际应用场景帮助开发者掌握Java项目开发的核心技能,适合从基础到进阶的学习与实践。
1366 4
|
9月前
|
缓存 前端开发 Java
基于最新 Java 技术栈的在线任务管理系统开发实战详解
本项目基于最新Java技术栈开发在线任务管理系统,涵盖任务创建、分配、跟踪、统计等功能。采用Spring Boot 3.2.x、React 18、PostgreSQL 16等主流技术,详解项目架构设计、核心功能实现及部署流程,助力掌握现代Java全栈开发技能。
499 6
|
7月前
|
安全 Java 开发者
告别NullPointerException:Java Optional实战指南
告别NullPointerException:Java Optional实战指南
352 119
|
9月前
|
Java API Maven
2025 Java 零基础到实战最新技术实操全攻略与学习指南
本教程涵盖Java从零基础到实战的全流程,基于2025年最新技术栈,包括JDK 21、IntelliJ IDEA 2025.1、Spring Boot 3.x、Maven 4及Docker容器化部署,帮助开发者快速掌握现代Java开发技能。
1741 1
|
8月前
|
存储 前端开发 Java
【JAVA】Java 项目实战之 Java Web 在线商城项目开发实战指南
本文介绍基于Java Web的在线商城技术方案与实现,涵盖三层架构设计、MySQL数据库建模及核心功能开发。通过Spring MVC + MyBatis + Thymeleaf实现商品展示、购物车等模块,提供完整代码示例,助力掌握Java Web项目实战技能。(238字)
1031 0
|
8月前
|
Java 开发者
Java并发编程:CountDownLatch实战解析
Java并发编程:CountDownLatch实战解析
589 100
|
9月前
|
数据采集 JSON Java
Java爬虫获取1688店铺所有商品接口数据实战指南
本文介绍如何使用Java爬虫技术高效获取1688店铺商品信息,涵盖环境搭建、API调用、签名生成及数据抓取全流程,并附完整代码示例,助力市场分析与选品决策。
|
9月前
|
消息中间件 Java 数据库
Java 基于 DDD 分层架构实战从基础到精通最新实操全流程指南
本文详解基于Java的领域驱动设计(DDD)分层架构实战,结合Spring Boot 3.x、Spring Data JPA 3.x等最新技术栈,通过电商订单系统案例展示如何构建清晰、可维护的微服务架构。内容涵盖项目结构设计、各层实现细节及关键技术点,助力开发者掌握DDD在复杂业务系统中的应用。
1779 0
|
8月前
|
人工智能 Java API
Java AI智能体实战:使用LangChain4j构建能使用工具的AI助手
随着AI技术的发展,AI智能体(Agent)能够通过使用工具来执行复杂任务,从而大幅扩展其能力边界。本文介绍如何在Java中使用LangChain4j框架构建一个能够使用外部工具的AI智能体。我们将通过一个具体示例——一个能获取天气信息和执行数学计算的AI助手,详细讲解如何定义工具、创建智能体并处理执行流程。本文包含完整的代码示例和架构说明,帮助Java开发者快速上手AI智能体的开发。
3278 8
|
8月前
|
人工智能 Java API
Java与大模型集成实战:构建智能Java应用的新范式
随着大型语言模型(LLM)的API化,将其强大的自然语言处理能力集成到现有Java应用中已成为提升应用智能水平的关键路径。本文旨在为Java开发者提供一份实用的集成指南。我们将深入探讨如何使用Spring Boot 3框架,通过HTTP客户端与OpenAI GPT(或兼容API)进行高效、安全的交互。内容涵盖项目依赖配置、异步非阻塞的API调用、请求与响应的结构化处理、异常管理以及一些面向生产环境的最佳实践,并附带完整的代码示例,助您快速将AI能力融入Java生态。
1407 12