暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

多线程中元老级的锁:Synchronized锁详解

奔波儿灞取经 2021-03-27
278

synchronized是Java多线程中元老级的锁也是面试的高频考点,让我们来详细了解synchronized吧。

在Java中,synchronized锁可能是我们最早接触的锁了。

在 JDK1.5之前synchronized是一个重量级锁,相对于juc包中的Lock,synchronized显得比较笨重。

庆幸的是在 Java 6 之后 Java 官⽅对从 JVM 层⾯对synchronized进行⼤优化,所以现在的 synchronized 锁效率也优化得很不错。

synchronized使用场景我们在使用,synchronized的时候都知道它是可以使用在方法上的也可以使用在代码块上的。

首先有一点要说明一下,各位可能或多或少都听过这样的说法:

“synchronized 的性能不行,比显式锁差很多,开发中还是要慎用。”

大可不必有这样的顾虑要说在 JDK 1.6 之前,synchronized 的性能确实有点差。

但是 JDK 1.6 之后,JDK 开发团队已经持续对 synchronized 做了性能优化,其性能已经与其他显式锁基本没有差距了。

所以在考虑是不是使用 synchronized的时候,只需要根据场景是否合适来决定,性能问题不用作为衡量标准。

那么使用在这两个地方有什么区别呢?

Synchronized主要有三种用法:synchronized 关键字加到 static 静态方法和 synchronized(class) 代码块上都是是给 Class 类上锁。


synchronized 关键字加到实例方法上是给对象实例上锁。

在 Java 中,关键字 synchronized可以保证在同一个时刻。

只有一个线程可以执行某个方法或者某个代码块(主要是对方法或者代码块中存在共享数据的操作)。

同时我们还应该注意到synchronized另外一个重要的作用,synchronized可保证一个线程的变化(主要是共享数据的变化)被其他线程所看到(保证可见性,完全可以替代Volatile功能)。

synchronized底层语义原理:Java 虚拟机中的同步(Synchronization)基于进入和退出管程(Monitor)对象实现。

无论是显式同步(有明确的 monitorenter 和 monitorexit 指令,即同步代码块)还是隐式同步都是如此。

在 Java 语言中,同步用的最多的地方可能是被 synchronized 修饰的同步方法。

同步方法并不是由 monitorenter 和 monitorexit 指令来实现同步的。

而是由方法调用指令读取运行时常量池中方法的 ACC_SYNCHRONIZED 标志来隐式实现的,关于这点,稍后详细分析。

线程安全问题并发编程中,当多个线程同时访问同一个资源的时候,就会引发线程安全问题。

由于每个线程执行的过程是不可控的,所以很有可能导致最终的结果和实际期望的结果违背或者直接导致程序出错。

在这里总结一下在使用synchronized关键字的时候,本质上是否获得锁是通过修改锁对象头中的markword的内容来标记是否获得锁。

并由虚拟机来根据具体的应用场景来锁进行升级。

简单地将上述几个零散的markword变化合在一起,展示在下面:

— end —

奔波儿灞取经

扫码关注,我在等你

点分享

点点赞

点在看

文章转载自奔波儿灞取经,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论