zoukankan      html  css  js  c++  java
  • Synchronized底层实现逻辑原理解析

    什么是同步的

    如果一个资源被多个线程共享,我们需要同步线程,以避免资源抢占造成的资源数据混乱。在Java中,synchronized是实现线程同步的关键字。

    使用synchronized关键字获取Java对象的锁并保护锁定的代码块。JVM保证只有一个线程可以获得Java对象的锁并同时执行相应的代码块,从而实现线程安全。

    使用同步

    synchronized关键字可用于装饰三个位置:

    • 在装饰实例方法中,锁定对象是此对象的当前对象。
    • 修饰代码块,即synchronized(object){},lock对象是()中的对象,通常是this或explicit对象。
    • 在修改静态方法时,锁对象是方法区域中的类对象和全局锁。
    • 修改一个类,即直接影响一个类。

    根据同步修改的不同位置,实现原理不同。

    从反编译的结果中,我们可以看到sync()方法中还有一个标识符。JVM基于此acc_uuusynchronized标识符来实现方法同步,即:

    当执行该方法时,JVM调用该指令来检查是否在方法uuSynchronized identifier上设置了ACC,如果设置了ACCuSynchronized identifier,则将获得锁对象的监控对象。线程执行方法体后,将释放锁对象的监视器对象。在此期间,其他线程无法获取锁对象的监视器对象。

    显然,在线程0完成执行之前,线程1不会开始执行。再次检查字节码信息:

    我们可以看到sync()字节码指令中有两条monitorenter和monitorexit指令:

    Monitorenter:此指令指示要获取锁定对象的监视器对象。此时,监视器对象中的计数将增加+1。如果监视器已被其他线程获取,则该线程将被阻止,直到count=0,然后再次尝试获取监视器对象。

    Monitorexit:此指令指示线程释放锁对象的监视器对象。此时,监视器对象的计数将从-1变为0。其他被阻止的线程可以再次尝试获取锁定对象的监视器对象。

     您可以看到,与instance方法一样,sync()方法上还有一个标识符。可以得出结论,同步在实例方法上的实现原理与在静态方法上的实现原理相同,两者都是acc_uuu同步标识符来实现。只是它们锁定了不同的对象。

  • 相关阅读:
    全排列和全组合实现
    (原)关于MEPG-2中的TS流数据格式学习
    linux的PAM认证和shadow文件中密码的加密方式
    vim 撤销 回退操作
    memcached解压报错gzip: stdin: not in gzip format tar: Child returned status 1 tar: Error is not recoverable: exiting now的解决方法
    Linux系统安全之pam后门安装使用详解
    漏洞预警:Linux内核9年高龄的“脏牛”0day漏洞
    linux软链接的创建、删除和更新
    关于“.bash_profile”和“.bashrc”区别的总结
    linux下批量杀死进程
  • 原文地址:https://www.cnblogs.com/aishangJava/p/15322856.html
Copyright © 2011-2022 走看看