登录
首页 >  文章 >  java教程

synchronized锁粒度分析与优化技巧

时间:2025-12-24 23:34:37 225浏览 收藏

亲爱的编程学习爱好者,如果你点开了这篇文章,说明你对《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学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!

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