关于Synchronized实例与代码块的线程锁机制疑问
问题解答
第一个问题:你的理解完全正确
当类中的非静态synchronized方法被调用时,本质是获取了当前对象实例的内置锁(对象锁)。对于同一个A类实例:
- 线程t1调用
methodA时,会持有该实例的对象锁; - 此时线程t2调用同一个实例的
methodB,由于methodB也是非静态synchronized方法,同样需要获取这个对象锁,但锁已被t1持有,所以t2会进入阻塞状态,直到t1释放锁(比如methodA执行完成退出)。
第二个问题:synchronized代码块的情况分两种
情况1:使用同一锁对象
如果两个synchronized代码块都以当前对象实例作为锁(示例代码如下),结论和之前一致,t2会被阻塞:
class A{ public void methodA(){ synchronized(this){ // Do Something } } public void methodB(){ synchronized(this){ // Do Something } } }
这种场景下,两个代码块争抢的是同一把对象锁,和synchronized方法的逻辑完全等价。
情况2:使用不同锁对象
如果两个synchronized代码块使用不同的锁对象(示例代码如下),t2不会被阻塞:
class A{ private final Object lock1 = new Object(); private final Object lock2 = new Object(); public void methodA(){ synchronized(lock1){ // Do Something } } public void methodB(){ synchronized(lock2){ // Do Something } } }
因为两个代码块持有的是不同的锁,相互之间不存在竞争关系,t1和t2可以同时执行各自的代码块。
内容的提问来源于stack exchange,提问作者AAA
相关产品推荐
相关产品推荐

