← 每日面试题 学习看板

synchronized锁的是什么?

面试题/00java/02Java 并发编程/06线程同步与锁机制/synchronized锁的是什么?.md

面试记录 2026-09-29

题目:synchronized 锁的是什么?

难度:low(题库标注)

标签:java/lock, difficulty/low

评分:⭐⭐⭐⭐☆(4/5)

我的回答

synchronized 的锁是加在对象头上的,锁的其实是那个对象,判定这个对象是否加了锁,是否有线程持有,对应的线程是不是当前线程,是在这对象头上做的判定。

Synchronized 的加锁的位置是可以在方法上,可以方法块的对象上。加在方法上,其实它是对当前这个类的对象加锁,加的是整体的一个锁。然后方法区内,它是因为你方法区里边,代码块里边,你会设置一个对象去加锁,它把那个锁就加在这个你设置的静态类的对象上。在对象头上去判定你这个锁。

点评

优点:

不足:

补充(必背):

synchronized 锁三种对象的对照表:

用法锁的对象典型场景
synchronized 非静态方法this单实例级别的互斥
synchronized 静态方法Class<T>.class 对象类级别的互斥(所有实例共享一把锁)
synchronized(obj) {}显式指定的 obj细粒度锁(常用一个 private final Object 作为锁)

底层实现要点:

面试陷阱:

完整讲解

第一部分:知识重点剖析

核心考点定位:区分 synchronized 三种用法各自锁定的对象,以及底层 monitor 机制,考察对 Java 内置锁粒度的理解。

知识点拆解:

  1. 底层原理:每个 Java 对象都有一个隐含的 monitor(内置锁),对象头(Mark Word)里存放锁状态和指向 monitor 的指针;字节码层面通过 monitorenter / monitorexit 指令加解锁
  2. 设计权衡:三种用法对应三种锁粒度——this(实例级)、Class(类级单例)、显式对象(自定义细粒度);粒度过粗影响并发度,过细影响正确性
  3. 工程实践:细粒度锁推荐声明 private final Object lock = new Object() 作为专用锁对象,避免锁共享导致意外的互斥

第二部分:考察方向与延伸递进

考察方向:

延伸递进面试题:

  1. 为什么 static synchronized 锁的是 Class 对象而不是"类"?
  1. 锁 String 常量有什么坑?
  1. 如何避免锁 this 带来的隐患?

第三部分:面试者参考回答(300-600 字口语化)

面试官您好,synchronized 本质是给一个对象加内置锁(monitor),锁信息存在对象头里,通过 monitorenter 和 monitorexit 字节码指令实现。它有三种典型用法,锁的对象各不相同:

第一种,synchronized 修饰非静态方法,锁的是 this——当前实例对象,只有同一实例的多个线程才会互斥。

第二种,synchronized 修饰静态方法,锁的是类的 Class 对象,比如 MyClass.class。每个类在 JVM 里加载后都有一个唯一的 Class 实例,所以 static synchronized 相当于类级别的锁,所有实例共享一把锁。

第三种,synchronized(obj) {} 代码块,锁的是显式传入的 obj。工程实践中推荐用一个私有的 final Object lock = new Object() 作为专用锁,粒度可控、不会被外部拿到。

有几个坑需要注意:第一,锁 this 时如果外部代码能拿到这个对象,会形成意外的共享锁;第二,synchronized("常量") 锁的是常量池 String,全 JVM 共享一把锁,大坑;第三,static synchronized 因为锁的是 Class 对象,两个不同的实例对象也会互相阻塞——这是很多人忽略的。