美文网首页
JAVA并发之synchronized

JAVA并发之synchronized

作者: 小软_GCX | 来源:发表于2020-07-02 19:31 被阅读0次

    synchronized

    synchronized

    首先synchronized是jdk提供的内置锁,既然是锁那就具有互斥性和可见性,可保证在多线程竞争资源时不会出现并发问题

    synchronized用法

    根据修饰对象分类

    • 同步方法

      1. 同步静态方法

        public synchronized void method(){
        //逻辑代码
        }
        
      2. 同步非静态方法

        public synchronized static void method(){
        //逻辑代码
        }
        
    • 同步代码块

      synchronized(object) {}
      
      

    根据获取的锁分类

    ​ 在 Java 中,每个对象都会有一个 monitor 对象,这个对象其实就是 Java 对象的锁 ,因为类对象本来也是一个对象,所以每个类也有一个类锁。

    ​ 当某一线程占有这个monitor对象的时候,先看monitor计数器是不是0,如果是0,说明还没有线程占用,这时候该线程占有这个锁,并且计数器+1;如果计数器不是0,看当前占有锁的线程是不是本线程,如果是本线程就+1,这就是可重入的概念;如果当前计数器不是0也不是当前线程占有,则进去阻塞状态。

    • 对象锁

    • 类锁

    synchronized原理分析

    代码块加锁的实现是通过monitorEnter 和monitorExit来实现的,通过javap 反编译class文件你会发现synchronized所包含的代码前面和后面分别加了monitorEnter 和monitorExit,其中有两个monitorExit,第一个是正常解锁时执行的,第二个是异常时用来释放锁的。

    image.png

    对方法加锁的实现是通过标志位ACC_SYNCHRONIZED来实现的

    image.png

    JAVA虚拟机对synchronized的优化

    在jdk1.6以前synchronized是一个重量级锁,1.6及以后将它优化为无锁,偏向锁,轻量级锁,重量级锁

    偏向锁: 在对象第一次被某一线程占有的时候 ,将线程号写入,下一个线程再次访问时,发现线程号是当前占用线程号,直接成功,否则升级为轻量级锁

    轻量级锁:是一个自旋锁,通过cas自旋来获取锁,超过一定次数升级为重量级锁

    重量级锁:通过互斥量来实现,性能比较低

    synchronized是一个非公平锁

    moniter 对象中有两个集合 _EntryList, _WaitSet 当线程阻塞的时阻塞线程会进入_EntryList,等待count为0重新调用,当线程调用了wait方法是线程会阻塞进入_WaitSet中 等待notify唤醒 ,无论是哪种情况 当一个新的线程进来同时count 为0 是 都不能保证新的线程在_EntryList或者_WaitSet 中先执行其中线程

    相关文章

      网友评论

          本文标题:JAVA并发之synchronized

          本文链接:https://www.haomeiwen.com/subject/eofdqktx.html