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

Java中synchronized 关键字

synchronized 是 Java 中用于实现线程同步的关键字,它提供了一种简单有效的方式来控制多线程对共享资源的访问,确保线程安全。

基本概念

synchronized 关键字可以实现:

  1. 互斥性:同一时刻只有一个线程可以执行被同步的代码

  2. 可见性:线程对共享变量的修改对其他线程立即可见

使用方式

synchronized 有三种主要使用方式:

1. 同步实例方法

public synchronized void method() {// 同步代码
}
  • 锁对象是当前实例对象(this)

  • 同一实例的同步方法在同一时刻只能被一个线程访问

2. 同步静态方法

public static synchronized void staticMethod() {// 同步代码
}
  • 锁对象是当前类的 Class 对象(如 MyClass.class)

  • 所有实例的同步静态方法在同一时刻只能被一个线程访问

3. 同步代码块

public void method() {// 非同步代码synchronized(lockObject) {// 同步代码}// 非同步代码
}
  • 可以灵活指定锁对象

  • 缩小同步范围,提高并发性能

实现原理

synchronized 是基于 JVM 内置锁(Monitor)实现的:

  1. 进入同步代码:线程尝试获取对象的 Monitor

    • 成功则持有 Monitor,计数器 +1

    • 失败则进入阻塞队列等待

  2. 退出同步代码:释放 Monitor,计数器 -1

    • 计数器为 0 时完全释放锁

    • 唤醒等待队列中的线程

锁的升级过程(JDK 1.6+优化)

为了减少锁操作的开销,JVM 实现了锁升级机制:

  1. 无锁状态:对象刚创建时

  2. 偏向锁:适用于只有一个线程访问的场景

    • 记录线程 ID,减少同步开销

  3. 轻量级锁(自旋锁):适用于短时间等待的场景

    • 线程通过 CAS 自旋尝试获取锁

  4. 重量级锁:竞争激烈时升级

    • 线程进入阻塞状态,由操作系统管理

注意事项

  1. 锁对象选择

    • 不要使用 String 常量等可能被共享的对象作为锁

    • 建议使用专门创建的私有 final 对象作为锁

  2. 死锁风险

    • 避免嵌套获取多个锁

    • 如果需要获取多个锁,应保持一致的获取顺序

  3. 性能考虑

    • 尽量减小同步代码块的范围

    • 避免在同步代码块中执行耗时操作

与 Lock 接口的比较

特性synchronizedLock (如 ReentrantLock)
实现方式JVM 内置Java 代码实现
锁获取方式自动获取释放需要手动 lock/unlock
尝试非阻塞获取锁不支持tryLock() 支持
公平锁非公平可配置公平/非公平
条件变量单一可创建多个 Condition
性能JDK 优化后接近更灵活但稍复杂

synchronized 是 Java 中最基本的线程同步机制,虽然功能不如 Lock 接口丰富,但在大多数情况下已经足够,并且随着 JVM 的优化,其性能已经非常优秀。

http://www.xdnf.cn/news/6935.html

相关文章:

  • Spring MVC 如何处理文件上传? 需要哪些配置和依赖?如何在 Controller 中接收上传的文件 (MultipartFile)?
  • Selenium无法定位元素的几种解决方案详解
  • AgentCPM-GUI,清华联合面壁智能开源的端侧GUI智能体模型
  • 远程主机状态监控-GPU服务器状态监控-深度学习服务器状态监控
  • 使用ts-node搭建typescript运行环境
  • Java Stream流:高效数据处理的现代解决方案
  • 操作系统学习笔记第4章 (竟成)
  • JavaScript性能优化实战(11):前沿技术在性能优化中的应用
  • 基于Spring Boot和Vue的在线考试系统架构设计与实现(源码+论文+部署讲解等)
  • Canva 推出自有应用生成器以与 Bolt 和 Lovable 竞争
  • 2025年渗透测试面试题总结-安恒[实习]安全工程师(题目+回答)
  • 谈谈未来iOS越狱或巨魔是否会消失
  • 卸载和安装JDK
  • 【持续更新中】架构面试知识学习总结
  • 布隆过滤器深度解析
  • 【OpenGL学习】(二)OpenGL渲染简单图形
  • Spring6学习及复习笔记
  • flutter 配置 安卓、Ios启动图
  • CoverM:contig/bin的相对丰度计算
  • 数字万用表与指针万用表使用方法及注意事项
  • Redis键(Key)操作完全指南:从基础到高级应用
  • Java-Objects类高效应用的全面指南
  • Animaster:一次由 CodeBuddy 主导的 CSS 动画编辑器诞生记
  • 小型气象站应用之鱼塘养殖方案
  • GitHub文档加载器设计与实现
  • Win11下轻松搭建wiki.js,Docker.desktop部署指南(mysql+elasticsearch+kibana+wiki.js)
  • 国内AWS CloudFront与S3私有桶集成指南:安全访问静态内容
  • 用Python玩转人工智能——数字识别技术 之三
  • React 中,闭包陷阱
  • hadoop.proxyuser.代理用户.授信域 用来干什么的