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

java中的synchronized关键字​

  synchronized是 Java 中用于实现​​线程同步​​的关键字,它提供了一种​​互斥访问共享资源​​的机制,确保多个线程在访问临界区(Critical Section)时不会发生数据竞争(Data Race),从而保证线程安全。


1. synchronized的作用​

synchronized的主要作用是:

  1. ​互斥访问(Mutual Exclusion)​​:确保同一时间只有一个线程可以进入同步代码块或方法,防止多个线程同时修改共享数据。

  2. ​可见性(Visibility)​​:确保线程对共享变量的修改对其他线程立即可见(类似于 volatile的可见性保证)。

  3. ​有序性(Ordering)​​:防止指令重排序,确保同步代码块内的操作按预期顺序执行。

2. synchronized的底层原理​

  synchronized的底层实现依赖于 ​​JVM 的 Monitor(监视器)机制​​ 和 ​​Monitor Enter/Monitor Exit 指令​​。

​2.1. Monitor(监视器)机制​

  • 每个 Java 对象都有一个 ​​Monitor(监视器锁)​​,也称为 ​​内置锁(Intrinsic Lock)​​ 或 ​​对象锁​

  • 当线程进入 synchronized代码块时,会尝试 ​​获取该对象的 Monitor 锁​​(MonitorEnter

  • 如果锁已被其他线程持有,则当前线程会 ​​阻塞​​,直到锁被释放

  • 当线程退出 synchronized代码块时,会 ​​释放 Monitor 锁​​(MonitorExit

2.2. JVM 指令​

synchronized方法或代码块在字节码层面会被编译为:

  • monitorenter​(进入同步块,获取锁)

  • monitorexit​(退出同步块,释放锁)

如果发生异常,JVM 会确保 monitorexit被执行,防止死锁。​


3. synchronized的使用方式​ 

​3.1. 同步实例方法(同步当前对象) 

public class Counter {private int count = 0;// 同步实例方法,锁的是当前对象(this)public synchronized void increment() {count++;}
}
  • ​锁对象​​:当前实例对象(this)。

  • ​作用范围​​:整个方法体。

  • ​适用场景​​:当多个线程访问同一个对象的同步方法时,同一时间只有一个线程可以执行该方法。

3.2. 同步静态方法(同步类对象)​ 

public class Counter {private static int count = 0;// 同步静态方法,锁的是当前类的 Class 对象(Counter.class)public static synchronized void increment() {count++;}
}
  • ​锁对象​​:当前类的 Class对象(如 Counter.class)。

  • ​作用范围​​:整个静态方法体。

  • ​适用场景​​:当多个线程访问同一个类的静态同步方法时,同一时间只有一个线程可以执行该方法。

3.3. 同步代码块(灵活控制锁对象)​

public class Counter {private int count = 0;private final Object lock = new Object(); // 自定义锁对象public void increment() {synchronized (lock) { // 同步代码块,锁的是 lock 对象count++;}}
}
  • ​锁对象​​:可以是任意对象(如 thisClass对象、自定义对象)。

  • ​作用范围​​:仅限于 synchronized块内的代码。

  • ​适用场景​​:当只需要同步部分代码时,使用同步代码块可以提高性能(减少锁的粒度)。

4. volatile 与synchronized的核心功能对比

特性

synchronized

volatile

​原子性​

✅ 保证代码块或方法的原子性(复合操作)

❌ 仅保证单次读/写操作的原子性(如 i++不安全)

​可见性​

✅ 保证线程修改后对其他线程立即可见

✅ 保证线程修改后对其他线程立即可见

​有序性​

✅ 防止指令重排序(同步块内的操作顺序固定)

✅ 防止指令重排序(volatile读写前后插入内存屏障)

​阻塞机制​

✅ 线程竞争锁时会阻塞,直到获取锁

❌ 不会导致线程阻塞

​适用场景​

复杂同步(如多步操作、临界区保护)

单一变量可见性(如状态标志)

  • volatile性能更高​​:因为它不涉及锁竞争和线程阻塞,仅通过内存屏障保证可见性。

  • synchronized在低竞争时优化后性能接近 volatile​,但在高竞争时会显著变慢。

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

相关文章:

  • 福彩双色球第2025088期篮球号码分析
  • PyTorch 张量核心操作——比较、排序与数据校验
  • 利用DeepSeek将Rust程序的缓冲输出改写为C语言实现提高输出效率
  • 深入 Go 底层原理(十五):cgo 的工作机制与性能开销
  • 探索:Uniapp 安卓热更新
  • 【Android】RecyclerView实现新闻列表布局(1)适配器使用相关问题
  • 原生JS使用svg-pan-zoom库平移和缩放svg
  • 八股取士--docker
  • 【C++】第二十一节—一文详解 | 红黑树实现(规则+效率+结构+插入+查找+验证)
  • Day18--二叉树--530. 二叉搜索树的最小绝对差,501. 二叉搜索树中的众数,236. 二叉树的最近公共祖先
  • 【MQ】kafka同步和异步的区别
  • 函数指针——回调函数
  • MybatisPlus-逻辑删除
  • Redis核心机制与实践深度解析:从持久化到分布式锁
  • 江协科技STM32 13-1 PWR电源控制
  • AG32mcu通过寄存器方式操作cpld
  • 3 使用 Jenkins 构建镜像:将你的应用打包成镜像
  • sqli-labs:Less-18关卡详细解析
  • 【隧道篇 / IPsec】(7.6) ❀ 02. 如何删除向导创建的IPsec安全隧道 (点对点) ❀ FortiGate 防火墙
  • K8S部署ELK(三):部署Elasticsearch搜索引擎
  • Java基础——实现图书管理系统交互功能
  • java实现运行SQL脚本完成数据迁移
  • String boot 接入 azure云TTS
  • 【深度学习②】| DNN篇
  • Python 字典为什么查询高效
  • Python编程基础与实践:Python基础数据类型入门
  • 如何在Ubuntu上部署excalidraw
  • 逻辑回归 银行贷款资格判断案列优化 交叉验证,调整阈值,下采样与过采样方法
  • 管家婆线下CS产品创建账套(普普、普及、辉煌II)
  • 小迪23-28~31-js简单回顾