当前位置:   article > 正文

全网最详细的synchronized讲解(锁升级、查看对象头标记、底层实现)_javap能看到对象头吗

javap能看到对象头吗

大家好,我是wave,这次来和大家详细的聊一聊Synchronized这个关键字,希望大家看完可以对synchronized关键字有一个非常全面的了解。

Synchronized基本操作

synchronized主要有三种使用方式:

修饰实例方法: 给一个类上的方法添加synchronized关键字,这个锁会作用于这个类当前的实例对象上,进入同步代码前要获得 当前对象实例的锁

public synchronized void method(){
   
        // do something
    }
  • 1
  • 2
  • 3
  • 4

修饰静态方法: 由于静态方法属于类,就相当于给一个类加了锁,会作用于类的所有对象实例 ,进入同步代码前要获得 当前 class 的锁

public synchronized static void method(){
   
        // do something
    }
  • 1
  • 2
  • 3
  • 4

修饰代码块 :指定加锁对象,对给定对象/类加锁。synchronized(this|object) 表示进入同步代码库前要获得给定对象的锁。synchronized(类.class) 表示进入同步代码前要获得 当前 class 的锁

public class Solution {
   
    public void method(){
   
        synchronized (this){
   
            //给当前对象加锁
        }
        synchronized (Solution.class){
   
            //给Solution这个类加锁
        }
        Object lock = new Object();
        synchronized (lock){
   
            //给Object这个对象加锁
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

synchronized在JDK早期是一个非常重量级的锁,依靠JVM的指令对代码块进行加锁,所以synchronized是JVM层面的锁,而Lock是用Java代码实现的,所以可以看作是API层面的锁。但是后续JDK对synchronized进行了非常多的优化和升级,目前synchronized与Lock的效率已经相差不多了。

synchronized修饰代码块

synchronized修饰代码块是用两个指令monitorenter、monitorexit完成的,口说无凭,我带大家看一看字节码吧~

public class Solution {
   
   public void method(){
   
       synchronized (this){
   
           System.out.println("synchronized修饰代码块");
       }
   }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 首先写一段这样的代码,然后可以通过javap来查看它的字节码。如果使用IDEA的话可以经过一点小小的配置就可以在控制台直接输出字节码了,先给大家看看IDEA应该如何配置
  • File->setting->Tools->External->左上角的+号,里面中间的三个配置分别为:
  • $JDKPath$\bin\javap.exe
  • -verbose -p -c $FileClass$
  • $OutputPath$
  • 然后编译一下程序,按运行旁边的绿色小锤子就可以了,再右键打开External tool找到刚才配置的工具,就可以在控制台打印出字节码了。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i0NuCB6I-1608209600129)( http://gtwave.gitee.io/image/images/wechart/synchronized字节码.png)]

打开工具

字节码结果

现在我说synchronized加在同步代码块上是用JVM指令来实现的就没啥问题了吧~当JVM执行到monitorenter的时候线程试图获取锁也就是获取 对象监视器 monitor 的持有权。

synchronized修饰方法

public class Solution {
   
    public synchronized void method(){
   
        System.out.println("synchronized 修饰方法");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

修饰方法

可以看到修饰一个方法就会有一个ACC_SYNCHRONIZED标识,代表这个方法是同步方法。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/309829
推荐阅读
相关标签
  

闽ICP备14008679号