Java同步关键字Synchronized深入理解

题记

讲讲写这篇博客的原因,因为自认为对synchronized这个关键字很了解了,前几天和一个刚好在找工作的朋友聊到了这个。结果他把面试遇到的一个问题给我出了出来,当我蒙圈的那一刻才懂得自己之前的了解只是皮毛。

正文

对于synchronized这个关键字,只要是学过java的我们对它都不陌生,而且感觉还非常熟悉。那我们就先来说一说面试和实际使用当中会遇到的两个场景。

  • 场景1:
public class SynchronizedTest {
    public synchronized static int getGender(){
        return 1;
    }
    public synchronized int getAge(){
        return 25;
    }

}

当同时调用这两个方法的时候会不会阻塞?根据锁的门栓的不同,静态方法锁的是类的字节码文件,而实例方法锁的是调用方法的实例对象。所以同时调用两个方法并不会阻塞!

  • 场景2:
   public class SynchronizedTest {
    public synchronized int getGender() {
        return 1;
    }

    public synchronized int getAge() {
        return 25;
    }

    public String getName() {
        return "测试";
    }

}

这种情况当同时调用三个方法的时候会不会阻塞,由场景1的经验知道,前两个锁的对象是一样的,所以前两个方法之间会阻塞,第三个方法则不受影响。

  • 场景3:终极场景
public class SynchronizedTest {
    public synchronized int getGender() {
        return 1;
    }

    public int getAge() {
        int i = 0;
        synchronized (this) {
            i++;
            return i;
        }
    }

}

当同时调用这两个方法的时候会不会阻塞?重点内容随着查阅资料和对synchronized 的实现的深入了解,知道synchronized 修饰实例方法和修饰代码块的synchronized(this)的内部实现是不一样的,所以它们锁的门栓并不是一样的。修饰在实例方法上时它是基于常量池里面的ACC_SYNCHRONIZED这个标识来实现的同步锁机制,而修饰代码块的这种synchronized(this)方式是基于对象存储的时候的头对象中的Mark Word里面的信息来实现的。
于2018-08-11特意来道歉,上面的描述不够准确,经过自测,虽然synchronized修饰代码块和修饰方法通过用javap -c 命令反编译的汇编来看是不一样的,但是他们还是获得的一样的锁,一样会互斥阻塞。反编译参考下面文章
https://www.cnblogs.com/huangyin/p/6586469.html

感想

后续还要持续研究,继续深入了解java相关的深入实现~
另外附上对此理解更深刻,研究比较透彻的几篇文章

深入理解Java并发之synchronized实现原理
synchronized在JVM底层的实现原理及Java多线程锁理解
Java并发编程:Synchronized及其实现原理

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值