sychronize的实现原理是怎么样的?

简介: 基础


public class SyncTest {
    public void syncBlock(){
        synchronized (this){
            System.out.println("hello block");
        }
    }
    public synchronized void syncMethod(){
        System.out.println("hello method");
    }
}点击复制代码复制出错复制成功

当SyncTest.java被编译成class文件的时候,synchronized关键字和synchronized方法的字节码略有不同,我们可以用javap -v 命令查看class文件对应的JVM字节码信息,部分信息如下:

{
  public void syncBlock();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=3, args_size=1
         0: aload_0
         1: dup
         2: astore_1
         3: monitorenter                       // monitorenter指令进入同步块
         4: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
         7: ldc           #3                  // String hello block
         9: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        12: aload_1
        13: monitorexit                          // monitorexit指令退出同步块
        14: goto          22
        17: astore_2
        18: aload_1
        19: monitorexit                          // monitorexit指令退出同步块
        20: aload_2
        21: athrow
        22: return
      Exception table:
         from    to  target type
             4    14    17   any
            17    20    17   any
  public synchronized void syncMethod();
    descriptor: ()V
    flags: ACC_PUBLIC, ACC_SYNCHRONIZED      //添加了ACC_SYNCHRONIZED标记
    Code:
      stack=2, locals=1, args_size=1
         0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #5                  // String hello method
         5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: return
}点击复制代码复制出错复制成功

对于synchronized关键字而言,javac在编译时,会生成对应的monitorentermonitorexit指令分别对应synchronized同步块的进入和退出,有两个monitorexit指令的原因是为了保证抛异常的情况下也能释放锁,所以javac为同步代码块添加了一个隐式的try-finally,在finally中会调用monitorexit命令释放锁。

而对于synchronized方法而言,javac为其生成了一个ACC_SYNCHRONIZED关键字,在JVM进行方法调用时,发现调用的方法被ACC_SYNCHRONIZED修饰,则会先尝试获得锁。

synchronized锁执行流程图

这是网上看到的一个流程图:

就是Java对象的内存布局其实由对象头+实例数据+对齐填充三部分组成,而对象头主要包含Mark Word+指向对象所属的类的指针组成。Mark Word主要用于存储对象自身的运行时数据,哈希码,GC分代年龄,锁标志等。

下面就是Mark Word的数据映射表

相关文章
|
7月前
|
存储 缓存 安全
ConcurrentHashMap:使用方法和底层原理详解
ConcurrentHashMap:使用方法和底层原理详解
205 1
|
2月前
|
存储 JavaScript 前端开发
事件队列的实现原理
【10月更文挑战第15天】事件队列的实现原理
44 6
|
1月前
|
存储 缓存 安全
ConcurrentHashMap的实现原理,非常详细,一文吃透!
本文详细解析了ConcurrentHashMap的实现原理,深入探讨了分段锁、CAS操作和红黑树等关键技术,帮助全面理解ConcurrentHashMap的并发机制。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
ConcurrentHashMap的实现原理,非常详细,一文吃透!
|
1月前
|
存储 人工智能 算法
pfinder实现原理揭秘
`pfinder`算法通过启发式搜索和图搜索方法,提供了一种高效的路径查找和路径优化解决方案。在导航系统、机器人路径规划和游戏AI等领域,`pfinder`算法具有广泛的应用前景。本文详细解析了 `pfinder`算法的实现原理及其在实际中的应用,希望对您理解和实现路径查找算法有所帮助。
28 1
|
4月前
|
Java 调度
【多线程面试题十四】、说一说synchronized的底层实现原理
这篇文章解释了Java中的`synchronized`关键字的底层实现原理,包括它在代码块和方法同步中的实现方式,以及通过`monitorenter`和`monitorexit`指令以及`ACC_SYNCHRONIZED`访问标志来控制线程同步和锁的获取与释放。
|
7月前
|
网络协议 小程序 测试技术
ChaoBlade 的实现原理
【4月更文挑战第6天】ChaoBlade 的实现原理
263 3
ChaoBlade 的实现原理
|
7月前
|
存储 前端开发 Java
深入剖析ThreadLocal使用场景、实现原理、设计思想
深入剖析ThreadLocal使用场景、实现原理、设计思想
深入剖析ThreadLocal使用场景、实现原理、设计思想
|
前端开发 JavaScript API
Zustand 底层原理🚀🚀🚀
Zustand 底层原理🚀🚀🚀
|
数据采集 算法 安全
GSI服务的实现原理是什么?
答:通过光算科技自研的GPC爬虫池系统。 GSI服务,全称Google Search Infrastructure服务,是Google用来处理和返回用户搜索查询结果的基础设施。 这个基础设施包括了庞大的硬件和软件系统,通过复杂的算法和技术,它可以在瞬间处理数亿的搜索查询,返回相关且有价值的结果。 下面,我们将深入探讨GSI服务的实现原理。
206 0
GSI服务的实现原理是什么?