登录
首页 >  文章 >  java教程

synchronized锁粒度分析与影响

时间:2025-12-29 14:18:43 379浏览 收藏

在文章实战开发的过程中,我们经常会遇到一些这样那样的问题,然后要卡好半天,等问题解决了才发现原来一些细节知识点还是没有掌握好。今天golang学习网就整理分享《synchronized方法锁粒度分析及影响》,聊聊,希望可以帮助到正在努力赚钱的你。

synchronized修饰方法时,实例方法锁住当前对象(this),静态方法锁住当前Class对象;锁粒度影响并发性能,实例锁支持多对象并行,类锁全局互斥;二者正交,可重入,异常自动释放锁。

在Java中使用synchronized修饰方法有什么影响_锁粒度分析

synchronized 修饰方法时,本质是给当前对象(非静态方法)或当前类(静态方法)加锁,影响核心在于锁的粒度、并发性能和线程安全边界。锁粒度越粗,并发度越低;越细,控制越精确但实现成本可能上升。

实例方法加synchronized:锁住当前对象(this)

每个对象实例拥有独立的锁。不同对象调用同一synchronized实例方法,互不阻塞;同一对象的多个synchronized方法调用会串行执行。

  • 等价于在方法体首尾加上 synchronized(this) { ... }
  • 若一个对象有 A() 和 B() 两个 synchronized 方法,线程1调用 A() 未返回前,线程2无法进入该对象的 B()
  • 注意:普通方法、static 方法、其他对象的 synchronized 方法不受影响

静态方法加synchronized:锁住当前Class对象

锁的是 MyClass.class,属于类级别锁。所有该类的实例共享同一把锁,粒度比实例锁更粗。

  • 等价于 synchronized(MyClass.class) { ... }
  • 即使创建了100个对象,只要有一个线程在执行某个 synchronized static 方法,其余所有线程都无法进入该类的任意 synchronized static 方法
  • 与实例方法锁完全正交:静态方法锁不影响实例方法执行,反之亦然

锁粒度对比与选型建议

选择取决于数据共享范围和并发需求:

  • 操作的是实例成员变量 → 优先用 synchronized 实例方法(或 this 锁块)
  • 操作的是类共享状态(如计数器、缓存、配置)→ 考虑 synchronized static 方法(或 Class 锁块)
  • 只锁部分逻辑,而非整个方法 → 改用同步代码块,明确指定锁对象,避免无谓阻塞
  • 高并发场景下,粗粒度锁易成瓶颈,可考虑 ReentrantLock、分段锁(如 ConcurrentHashMap)、无锁设计(CAS)等替代方案

常见误区提醒

容易忽略但影响实际行为的关键点:

  • synchronized 方法无法被继承重写“自动同步”:子类重写后默认不带 synchronized,需显式添加
  • 构造方法不能用 synchronized 修饰(编译报错),对象初始化本身不具备原子性保障,需自行同步关键字段赋值
  • 锁不可重入?错——synchronized 是可重入锁,同一个线程可多次获取同一把锁(如 synchronized 方法内部调用另一个本对象的 synchronized 方法)
  • 异常不会导致锁泄漏:无论是否抛出异常,锁都会在方法退出时自动释放

以上就是《synchronized锁粒度分析与影响》的详细内容,更多关于的资料请关注golang学习网公众号!

相关阅读
更多>
最新阅读
更多>
课程推荐
更多>