当前位置: 首页 > wzjs >正文

页面设计时最好用多少种颜色windows优化大师有必要安装吗

页面设计时最好用多少种颜色,windows优化大师有必要安装吗,做网站多少钱一个月,吸引人的公众号名称大全深入剖析Java Synchronized底层原理:从对象头到锁升级的全面解读 📖 摘要 关键词:Java并发、Synchronized原理、锁升级机制、对象头、Monitor 本文将深入解析Java中synchronized关键字的底层实现,涵盖对象头结构、Monitor机制、锁…

深入剖析Java Synchronized底层原理:从对象头到锁升级的全面解读

📖 摘要

关键词Java并发Synchronized原理锁升级机制对象头Monitor
本文将深入解析Java中synchronized关键字的底层实现,涵盖对象头结构、Monitor机制、锁升级流程等核心内容,帮助开发者理解高并发场景下的锁优化策略。无论是面试准备还是性能调优,本文都能为你提供清晰的技术洞察!


📑 目录

  1. 引言:为什么需要了解synchronized底层原理?
  2. 对象头与Mark Word的奥秘
  3. Monitor(管程)机制详解
  4. 锁升级:偏向锁→轻量级锁→重量级锁
  5. synchronized的可重入性实现
  6. 总结与面试题

1. 引言:为什么需要了解synchronized底层原理?

在多线程编程中,synchronized是Java开发者最常用的同步工具。但你是否遇到过这些问题?

  • 性能瓶颈:简单粗暴地加锁导致吞吐量下降?
  • 死锁问题:线程互相等待却不知如何排查?
  • 面试必问:如何回答“synchronized和ReentrantLock的区别”?

理解其底层原理,不仅能优化高并发程序,还能深入JVM设计思想,更是大厂面试的核心考点


2. 对象头与Mark Word的奥秘

每个Java对象都暗藏玄机!对象内存布局分为三部分:

在这里插入图片描述
在这里插入图片描述

其中Mark Word是实现锁的关键,其结构随锁状态动态变化(以64位JVM为例):

锁状态存储内容标识位
无锁unused(25bit)、hashcode(31bit)、分代年龄(4bit)等001
偏向锁线程ID(54bit)、Epoch(2bit)、分代年龄(4bit)101
轻量级锁指向栈中锁记录的指针(62bit)00
重量级锁指向Monitor的指针(62bit)10

3. Monitor(管程)机制详解

当使用synchronized时,JVM会通过**Monitor(管程)**实现互斥,其核心结构如下:

class Monitor {Thread* owner;          // 持有锁的线程EntryList* entrySet;    // 阻塞等待锁的线程队列WaitSet* waitSet;       // 调用wait()后的等待队列int recursions;         // 重入次数计数器
};

执行流程

  1. 线程通过monitorenter指令尝试获取Monitor所有权。
  2. 若Owner为空,则当前线程成为Owner,recursions=1。
  3. 若Owner是当前线程,recursions++(可重入性)。
  4. 竞争失败则进入EntryList阻塞等待。

Monitor的完整结构:线程如何被管理?
在这里插入图片描述

Monitor是synchronized实现互斥的核心,其完整结构在JVM源码(如objectMonitor.hpp)中定义如下:

class ObjectMonitor {void*     _header;        // 对象头(存储Mark Word)void*     _owner;         // 持有锁的线程指针volatile intptr_t  _recursions; // 重入次数ObjectWaiter* _EntryList; // 竞争锁的线程队列(阻塞态)ObjectWaiter* _WaitSet;   // 调用wait()后的线程队列(等待态)volatile int _WaitSetLock;// 保护WaitSet的锁// ... 其他字段省略
};

关键队列说明:

  • EntryList
    当线程A持有锁时,线程B尝试获取锁失败,会被封装为ObjectWaiter节点加入EntryList,并进入BLOCKED状态。
    唤醒规则:锁释放时,JVM会从EntryList中选择线程(非公平模式下可能直接唤醒最新竞争者)。

  • WaitSet
    当线程调用wait()方法后,线程会释放锁并进入WaitSet,状态变为WAITING
    唤醒条件:其他线程调用notify()/notifyAll()后,线程从WaitSet转移到EntryList重新竞争锁。


2. 锁膨胀(Lock Inflation):轻量级锁如何升级为重量级锁?

触发条件:

  • 轻量级锁CAS替换Mark Word失败(多线程竞争)。
  • 自旋锁尝试超过阈值(JDK6后为自适应自旋)。

cas替换
在这里插入图片描述
替换成功
在这里插入图片描述

膨胀流程(源码级解析):

1. 线程A持有轻量级锁(Mark Word指向栈中Lock Record)
2. 线程B竞争锁,CAS失败 → 开始自旋
3. 自旋失败 → JVM准备膨胀为重量级锁
4. 创建ObjectMonitor对象,初始化Owner、EntryList等
5. 线程A释放轻量级锁时,发现锁已膨胀:a. 修改Mark Word为指向ObjectMonitor的指针(锁标志位10)b. 唤醒EntryList中的线程B进入锁竞争
6. 后续所有锁操作直接通过ObjectMonitor进行

重量级锁的核心代价:

  • 上下文切换:线程竞争失败后从用户态陷入内核态,由操作系统调度阻塞与唤醒。
  • 吞吐量下降:适合高竞争但线程执行时间长的场景(如数据库连接池争抢)。

3. 自旋优化(Spin Locking):竞争时的CPU空转策略

自旋锁的意义:

  • 减少上下文切换:线程不立即阻塞,而是循环尝试获取锁(忙等待)。
  • 适用场景:锁竞争时间短、线程数少(如单核CPU或低并发)。

JDK的自适应自旋优化(Adaptive Spinning):

  • 动态调整:根据上次自旋成功次数动态决定本次自旋时间。
  • 实现逻辑
    1. 若上次自旋成功获得锁,则允许更长的自旋时间。
    2. 若自旋很少成功,则直接跳过自旋进入阻塞。

自旋示例代码(伪代码):

void EnterSpinLock() {int spins = 0;while (!tryLock() && spins < max_spins) {++spins;Thread::SpinWait();  // CPU空转(如执行PAUSE指令)}if (!tryLock()) {EnterBlockingQueue(); // 加入EntryList并阻塞}
}

4. 锁升级:偏向锁→轻量级锁→重量级锁

锁升级是JVM优化性能的关键策略!流程图解:

          ┌───────────┐│   无锁     │└─────┬─────┘│ 首次访问┌─────▼─────┐│  偏向锁    │◄───┐└─────┬─────┘    │同一线程多次访问│ 竞争发生  │┌─────▼─────┐    ││ 轻量级锁  │───►┘└─────┬─────┘│ CAS失败┌─────▼─────┐│ 重量级锁  │└───────────┘

4.1 偏向锁(Biased Lock)

  • 场景:单线程重复访问同步块。
  • 原理:Mark Word中记录线程ID,后续无需CAS。
  • 示例:Web服务中用户独享资源的处理。

4.2 轻量级锁(Lightweight Lock)

  • 场景:低竞争的多线程环境。
  • 原理
    • 线程栈中创建Lock Record,拷贝Mark Word。
    • 通过CAS将对象头指向Lock Record。
  • 失败:触发自旋锁(JDK6前默认10次,后改为自适应)。

4.3 重量级锁(Heavyweight Lock)

  • 场景:高并发激烈竞争。
  • 原理:依赖OS的Mutex Lock,线程进入阻塞状态。
  • 代价:用户态到内核态的上下文切换。

JDK 15后偏向锁的默认禁用原因:

  • 维护成本高:撤销操作需STW(Stop-The-World),影响GC暂停时间。
  • 收益下降:现代应用多线程竞争普遍,偏向锁适用场景减少。
  • 禁用方式:通过JVM参数-XX:-UseBiasedLocking关闭。

5. synchronized的可重入性实现

通过Monitor的recursions计数器实现:

public class ReentrantDemo {public synchronized void methodA() {methodB(); // 可重入}public synchronized void methodB() {// 计数器递增至2}
}
  • 每个锁操作对应recursions++,退出时recursions--
  • recursions=0时,锁完全释放。

6. 总结与面试题

核心总结表:

机制优势劣势适用场景
偏向锁单线程零成本加锁撤销开销大明确单线程访问
轻量级锁CAS无阻塞竞争自旋消耗CPU低竞争、短临界区
重量级锁高竞争下稳定上下文切换开销高并发、长临界区

1. 锁膨胀是可逆的吗?

不可逆。一旦升级为重量级锁,无法降级,但偏向锁可重置为无锁。

2. 为什么wait()必须在synchronized块中调用?

wait()会释放锁,需先获取Monitor的所有权(否则抛出IllegalMonitorStateException)。

3. 自旋锁是否一定优于阻塞?

不一定。长时间自旋浪费CPU,需根据竞争激烈程度选择。

4.synchronized vs ReentrantLock对比

特性synchronizedReentrantLock
锁实现JVM内置,自动释放API层面,需手动unlock()
中断响应不支持支持lockInterruptibly()
公平锁非公平可配置公平策略
条件队列单一wait/notify支持多个Condition
性能JDK6后优化后接近高竞争场景更灵活
http://www.dtcms.com/wzjs/91382.html

相关文章:

  • 搜索引擎优化的七个步骤app优化建议
  • 海安市建设局网站nba季后赛最新排名
  • 俄文企业网站制作企业网络营销策划
  • 做引流网站怎么赚钱赚谁的钱今日疫情实时数据
  • 网站建设技术员福州网站建设团队
  • 移动端网站开发项目报告软文推广的100个范例
  • 网站制作公司 云南百度模拟搜索点击软件
  • 手机网站的必要性微信客户管理
  • 苏州哪家做网站中文域名查询官网
  • 如何快速做网站关键词百度怎么打广告
  • 做蔬菜批发找货源进哪个网站广告网站留电话
  • 中国热门网站seo软件
  • 微网站自己可以做么好搜网惠州seo
  • 做投资的网站怎么把网站排名优化
  • 贵南县公司网站建设一网信息一个简单便捷的新闻网站
  • php网站后台建设新网域名查询
  • 龙华营销型网站建设上海百度seo公司
  • 南昌网站建设信息优化网站的方法有哪些
  • 做网站百度还是阿里巴巴好小红书信息流广告
  • 音乐网站如何建设商业策划公司十大公司
  • 淄博桓台学校网站建设定制信息流广告公司排名
  • 商会网站制作百度推广一年大概多少钱
  • 广州10大网站开发企业网络营销案例分析
  • 网站首页 关键词上海网站营销seo电话
  • 北京市朝阳区住房和城乡建设委员会网站如何快速提升网站关键词排名
  • 布吉网站建设价格成人职业技能培训班
  • 开个做网站公司全网营销代理加盟
  • 网站建设 上海制作公司官网多少钱
  • 单页网站 jquery重庆seo教程博客
  • 成都网站建设报价网站点击量统计