在Java中,synchronized 关键字是实现线程同步的核心工具,用于保证同一时刻只有一个线程可以执行被修饰的代码块或方法。以下从基本原理、锁升级过程、应用场景及优化建议四个维度详细解析:

一、基本原理

1. 同步的对象

synchronized 锁的是对象而非代码:

  • 修饰实例方法:锁的是当前实例对象(this);
  • 修饰静态方法:锁的是类的Class对象(如MyClass.class);
  • 修饰代码块:锁的是括号中的对象(如synchronized(obj))。
2. 底层实现
  • JVM层面:通过对象头中的Mark Word和**Monitor(监视器)**实现。
    对象头的Mark Word包含锁状态位(如偏向锁、轻量级锁、重量级锁)和指向Monitor的指针。
  • 字节码层面
    • 同步方法:通过ACC_SYNCHRONIZED标志位标识;
    • 同步代码块:通过monitorentermonitorexit指令实现。
3. 互斥锁语义
  • 线程进入同步块前需获取Monitor的所有权(锁),退出时释放锁;
  • 未获取到锁的线程会被阻塞,进入Monitor的等待队列。

二、锁升级的具体过程

JDK 6之后,synchronized 锁机制进行了优化,引入锁升级(偏向锁 → 轻量级锁 → 重量级锁)以减少性能开销。

1. 偏向锁(Biased Locking)
  • 适用场景:单线程环境,无锁竞争。
  • 原理
    1. 首次线程访问同步块时,Mark Word存储该线程ID(偏向状态);
    2. 后续该线程再次进入同步块时,无需CAS操作,直接获取锁;
    3. 若其他线程尝试竞争锁,偏向锁撤销,升级为轻量级锁。
  • 优点:无CAS操作,仅首次获取锁时有少量开销。
  • 缺点:存在锁撤销(偏向锁撤销需STW),若存在多线程竞争,反而增加开销。
2. 轻量级锁(Lightweight Locking)
  • 适用场景:多线程交替执行同步块(无实际竞争)。
  • 原理
    1. 线程进入同步块时,JVM在当前线程栈帧中创建锁记录(Lock Record)
    2. 通过CAS将对象头的Mark Word复制到锁记录,并将Mark Word指向锁记录地址;
    3. 若CAS成功,获取轻量级锁;若失败,说明存在竞争,锁膨胀为重量级锁。
  • 优点:竞争不激烈时,避免线程阻塞,减少用户态/内核态切换。
  • 缺点:竞争激烈时,频繁CAS导致性能下降。
3. 重量级锁(Heavyweight Lock)
  • 适用场景:多线程同时竞争锁。
  • 原理
    1. 锁膨胀后,Mark Word指向操作系统的Monitor对象
    2. 未获取到锁的线程被阻塞(进入内核态),放入Monitor的等待队列;
    3. 锁释放时,唤醒等待队列中的线程(需从内核态转回用户态)。
  • 缺点:线程阻塞/唤醒涉及用户态与内核态切换,性能开销大。
4. 锁升级流程图
无锁状态 → 偏向锁(单线程) → 轻量级锁(多线程交替) → 重量级锁(多线程竞争)
5. 锁升级的触发条件
  • 偏向锁撤销:当其他线程尝试访问偏向锁对象时,JVM在安全点(Safepoint)撤销偏向锁;
  • 轻量级锁膨胀:线程尝试CAS获取轻量级锁失败时,锁膨胀为重量级锁;
  • 批量重偏向/撤销:当一个类的对象频繁发生偏向锁撤销时,JVM会对该类的对象批量重偏向或撤销。

三、应用场景

1. 保护共享资源
  • 示例:多线程操作同一个计数器:
    public class Counter {private int count = 0;// 同步方法,锁的是thispublic synchronized void increment() {count++;}
    }
    
2. 实现原子操作
  • 示例:双重检查锁定(DCL)实现单例模式:
    public class Singleton {private static volatile Singleton instance; // 必须用volatile禁止指令重排public static Singleton getInstance() {if (instance == null) { // 第一次检查synchronized (Singleton.class) { // 锁的是Class对象if (instance == null) { // 第二次检查instance = new Singleton();}}}return instance;}
    }
    
3. 保证复合操作的原子性
  • 示例:检查再执行(Check-Then-Act)操作:
    public class Inventory {private Map<String, Integer> stock = new HashMap<>();// 复合操作:先检查库存,再扣减public synchronized boolean decreaseStock(String product, int amount) {if (stock.getOrDefault(product, 0) >= amount) {stock.put(product, stock.get(product) - amount);return true;}return false;}
    }
    
4. 线程间协作(wait/notify机制)
  • 示例:生产者-消费者模型:
    public class ProducerConsumer {private final Queue<Integer> queue = new LinkedList<>();private final int CAPACITY = 10;// 生产者方法public synchronized void produce(int item) throws InterruptedException {while (queue.size() == CAPACITY) {wait(); // 等待队列有空间}queue.add(item);notifyAll(); // 通知消费者有新元素}// 消费者方法public synchronized int consume() throws InterruptedException {while (queue.isEmpty()) {wait(); // 等待队列有元素}int item = queue.poll();notifyAll(); // 通知生产者有空间return item;}
    }
    

四、优化建议

1. 缩小同步块范围
  • 反例
    public synchronized void process() {// 非关键代码long startTime = System.currentTimeMillis();// 关键代码(需要同步)synchronized (this) {// 操作共享资源}// 非关键代码System.out.println("耗时:" + (System.currentTimeMillis() - startTime));
    }
    
  • 正例:仅同步关键代码:
    public void process() {long startTime = System.currentTimeMillis();// 仅同步关键代码synchronized (this) {// 操作共享资源}System.out.println("耗时:" + (System.currentTimeMillis() - startTime));
    }
    
2. 优先使用同步代码块而非同步方法
  • 同步方法默认锁的是this,可能导致锁范围过大;
  • 同步代码块可精确控制锁对象。
3. 使用细粒度锁替代粗粒度锁
  • 反例
    public class Bank {private Map<String, Account> accounts = new HashMap<>();// 粗粒度锁:整个方法同步public synchronized void transfer(String from, String to, double amount) {// 转账逻辑}
    }
    
  • 正例
    public class Bank {private Map<String, Account> accounts = new HashMap<>();// 细粒度锁:仅锁相关账户public void transfer(String from, String to, double amount) {Account fromAccount = accounts.get(from);Account toAccount = accounts.get(to);// 按顺序加锁,避免死锁Account first = fromAccount.hashCode() < toAccount.hashCode() ? fromAccount : toAccount;Account second = first == fromAccount ? toAccount : fromAccount;synchronized (first) {synchronized (second) {// 转账逻辑}}}
    }
    
4. 考虑替代方案
  • 原子类(如AtomicInteger)替代简单计数器的synchronized
  • 读写锁ReentrantReadWriteLock)替代读多写少场景的synchronized
  • 并发容器(如ConcurrentHashMap)替代synchronized Map

五、总结

synchronized 关键字的核心特点:

  • 优点
    • 使用简单,无需手动释放锁;
    • 锁升级机制在不同场景下有较好的性能表现;
    • 支持线程间协作(wait/notify)。
  • 缺点
    • 无法中断正在等待锁的线程;
    • 不支持超时获取锁;
    • 锁粒度较粗(要么全锁,要么全放)。

适用场景

  • 简单的同步需求(如保护共享资源、实现原子操作);
  • 需配合wait/notify实现线程间协作。

在高并发场景下,若性能敏感,可考虑使用ReentrantLockStampedLock等更灵活的锁机制。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/913685.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/913685.shtml
英文地址,请注明出处:http://en.pswp.cn/news/913685.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MTK项目wifi.cfg文件如何配置的Tput和功耗参数

下面的MTK参数主要与无线网络(Wi-Fi)配置相关,特别是与WMM(Wi-Fi Multimedia)和功率控制相关的设置 WMM相关参数: WmmParamCwMax/WmmParamCwMin:定义竞争窗口的最大/最小值,这里设置为10/4,用于控制信道访问的退避机制13 WmmParamAifsN:仲裁帧间间隔数,设置为3影响不同…

分水岭算法:图像分割的浸水原理

分水岭算法&#xff1a;基于拓扑地貌的边界提取核心原理 分水岭算法将图像视为拓扑地貌&#xff0c;灰度值代表海拔高度。通过模拟浸水过程&#xff1a;局部极小值&#xff1a;对应集水盆&#xff08;区域内部&#xff09;。分水岭线&#xff1a;集水盆之间的山脊&#xff08;区…

汽车功能安全系统阶段开发【技术安全方案TSC以及安全分析】5

文章目录1 技术安全方案 (Technical Safety Concept - TSC)2 系统安全架构设计 (System Safety Architecture Design)3 如何进行安全分析 (Safety Analysis)4 技术安全需求 (TSR) 如何分配到系统架构1 技术安全方案 (Technical Safety Concept - TSC) 技术安全方案 (Technical…

学习软件测试的第十二天(接口测试)

一.如果一个接口请求不通&#xff0c;那么你会考虑那些方面的问题&#xff1f;如果一个接口请求不通&#xff0c;我会像“排查水管漏水”一样一步步定位问题发生在哪一段&#xff0c;主要从这几个方向去思考&#xff1a;当一个接口请求不通时&#xff0c;我会从以下几个方面进行…

Linux下的C/C++开发之操作Zookeeper

ZooKeeper C 客户端简介与安装ZooKeeper C API 简介ZooKeeper 官方提供了多语言客户端&#xff0c;C 语言客户端是最底层的实现之一&#xff0c;功能全面且稳定&#xff0c;适合嵌入式开发、系统级组件、C 项目集成等场景。zookeeper.h 是 ZooKeeper 提供的 C 语言客户端头文件…

【openp2p】学习3:【专利分析】一种基于混合网络的自适应切换方法、装 置、设备及介质

本专利与开源项目无关,但可能是实际商用的一种专利。专利地址从此专利,可见p2p的重要性。透传服务可能是实时转发服务,提供中继能力 透传服务可以是指一种通过公网服务器将数据从第一客户端传递到另一个设备 或客户端的服务。这种服务通常用于克服网络中的障碍,如防火墙、…

OpenCV中DPM(Deformable Part Model)目标检测类cv::dpm::DPMDetector

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 OpenCV 中用于基于可变形部件模型&#xff08;DPM&#xff09; 的目标检测器&#xff0c;主要用于行人、人脸等目标的检测。它是一种传统的基于特…

macOS 26快捷指令更新,融入AI打造智能操作体验

快捷指令作为Mac系统中提升用户操作效率的得力助手&#xff0c;在macOS 26中迎来了一次具有突破性的重大更新。此次更新融入了先进的AI技术&#xff0c;推出“智能操作”&#xff08;Intelligent Actions&#xff09;功能&#xff0c;让快捷指令从简单的自动化工具升级为真正的…

InstructBLIP:迈向具备指令微调能力的通用视觉语言模型

温馨提示&#xff1a; 本篇文章已同步至"AI专题精讲" InstructBLIP&#xff1a;迈向具备指令微调能力的通用视觉语言模型 摘要 大规模的预训练与instruction tuning在构建通用语言模型方面已取得显著成效。然而&#xff0c;构建通用的视觉-语言模型仍然具有挑战性&…

基于dropbear实现嵌入式系统ssh服务端与客户端完整交互

以下基于 Dropbear 实现 SSH 服务端与客户端交互的完整步骤&#xff0c;涵盖服务端部署、客户端连接、认证配置及消息传输&#xff0c;结合了多篇权威资料的核心实践&#xff1a;环境准备与安装 服务端安装 • Linux 系统&#xff08;以 Ubuntu/CentOS 为例&#xff09; Ubuntu…

深圳安锐科技发布国内首款4G 索力仪!让斜拉桥索力自动化监测更精准高效

近日&#xff0c;深圳安锐科技正式发布国内首款无线自供电、一体化的斜拉索实时监测设备 “4G索力监测仪”&#xff0c;成功攻克了传统桥梁索体监测领域长期存在的实时性差、布设困难和成本高昂的行业难题&#xff0c;为斜拉桥、系杆拱桥提供全无线、自动化、云端实时同步的索力…

Pipeline 引用外部数据源最佳实践

场景解析在企业网络安全日志处理场景中&#xff0c;防火墙、入侵检测系统&#xff08;IDS&#xff09;等设备会持续产生大量日志&#xff0c;记录网络流量、访问请求、异常事件等基础信息&#xff0c;但这些原始日志仅能呈现表面现象&#xff0c;难以全面剖析安全威胁&#xff…

UI + MCP Client + MCP Server(并且链接多个Server)

项目结构前端项目--------->MCP Client----------->MCP Serverserver就不过多赘述了&#xff0c;他只是相当于添加了多个的tools 链接前后端 http.createServer创建一个服务器// ---------------------------------------------------------------- // server.js import …

香港站群服务器与普通香港服务器对比

在选择香港服务器时&#xff0c;用户常常会遇到"站群服务器"和"普通服务器"两种选项&#xff0c;虽然它们都基于香港数据中心的基础设施&#xff0c;但在 IP 地址配置、功能定位和管理复杂度、成本上存在显著差异&#xff0c;理解这些差异有助于用户根据实…

4.B树和B+树的区别?为什么MySQL选择B+树作为索引?

区别&#xff1a;1.数据存储位置B树每个节点都存储了索引和数据B树只有叶子节点存储数据&#xff0c;非叶子节点仅存储索引2.叶子节点的链接B树的所有叶子节点通过指针连接成一个双向链表&#xff0c;可以高效地进行范围查询或者顺序遍历B树则没有这样的连接关系&#xff0c;查…

转换狂魔,Modbus TCP转Profinet网关打通视觉传感线连接之路

在汽车零部件冲压生产线的世界中&#xff0c;液压机的压力稳定性是确保产品质量的秘密武器。然而&#xff0c;旧时代的人工巡检和传统监测方式却好似拖累现代化进程的沉重枷锁&#xff1a;效率低、成本高&#xff0c;还总是赶不上实时反馈的快车。这时&#xff0c;工厂决心大刀…

C++进阶—二叉树进阶

第一章&#xff1a;内容安排说明 map和set特性需要先铺垫二叉搜索树&#xff0c;而二叉搜索树也是一种树形结构二叉搜索树的特性了解&#xff0c;有助于更好的理解map和set的特性二叉树中部分面试题稍微有点难度&#xff0c;在前面讲解大家不容易接受&#xff0c;且时间长容易…

驱动下一代E/E架构的神经脉络进化—10BASE-T1S

汽车电子电气架构的演进正经历一场深刻的变革&#xff0c;“中央计算单元区域控制器”的架构模式已成为当前主流车型平台发展的明确方向。这种从传统的“功能域”&#xff08;Domain&#xff09;架构向“区域”&#xff08;Zonal&#xff09;架构的转型升级&#xff0c;旨在实现…

某学校系统中挖矿病毒应急排查

本篇文章主要记录某学校长期未运营维护的程序&#xff0c;被黑客发现了漏洞&#xff0c;但好在学校有全流量设备&#xff0c;抓取到了过程中的流量包 需要你进行上机以及结合流量分析&#xff0c;排查攻击者利用的漏洞以及上传利用成功的木马 文章目录靶机介绍1.使用工具分析共…

vue 、react前端页面支持缩放,echarts、地图点击左边不准的原因和解决办法

原因 由于以上都是通过canvas画布生成的&#xff0c;一旦初始化&#xff0c;就会按照比例进行缩放&#xff0c;但与此同时&#xff0c;比例尺并没有变化&#xff0c;导致坐标偏移 解决办法 设置一个zoomVal产量&#xff0c;在页面加载时计算缩放比例&#xff0c;然后在canvas容…