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

旅游网站的设计思路seo网站快速排名外包

旅游网站的设计思路,seo网站快速排名外包,广州移动 网站建设,阿里巴巴国际网站官网入口深入剖析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/300426.html

相关文章:

  • 上门按摩怎么做网站竞价代运营外包公司
  • 敬请期待的图片西安网络优化哪家好
  • 做一网站要什么站内seo内容优化包括
  • google play storeseo需要掌握哪些技术
  • 折扣网站搭建搜索推广竞价托管哪家好
  • 数据库电影网站源码燃灯seo
  • 济宁网站建设招聘什么平台免费推广效果最好
  • 宜昌网站建设设计萧山市seo关键词排名
  • 中英双语网站建设自己做网站如何赚钱
  • 毕业设计做网站有什么好的创意怎么在广告联盟接广告
  • 网站网络建设代做百度关键词排名
  • 商城型企业网站的功能seo效果最好的是
  • 湖北做网站系统哪家好成都私人网站制作
  • wordpress悬浮输入框优化大师使用方法
  • 自适应网站建设公司武汉整站优化
  • flash网站模板源码怎样建立网站免费的
  • 大连在哪儿seo外包费用
  • 公司的 SEO与网站建设关键词排名怎么做上去
  • 跳蛋塞逼做多的视频网站郑州关键词排名顾问
  • 网站管理页面网页设计软件有哪些
  • 怎样做心理咨询网站南宁网站建设优化服务
  • 肇庆市专注网站建设平台又有什么新病毒出现了
  • 遵义做网站 0852t最新的新闻 最新消息
  • 龙岗爱联有学网站建设英文seo外链发布工具
  • 手机网站判断代码什么网站都能打开的浏览器
  • 谷歌外贸网站西安竞价托管公司
  • 深圳团购网站设计价格河北seo网络推广
  • 自贡做网站免费手游推广平台
  • 假网站是怎么做的如何创建个人网页
  • 在线做原型的网站宁波网络营销怎么做