重入锁,公平锁,非公平锁

一、重入锁

       表示该锁还能够支持一个线程对资源重复加锁

      我们熟悉的ReentrantLock和syschronized都是支持重进入的锁,synchorinized是支持隐式加锁的。 

例子:

class SysTest{
     
     void test1(String str){
        synchronized(SysTest.class){
            System.out.println(str+"1");
            test2(str);   //这里在加锁后又加了锁,不会出现死锁
            System.out.println("end" + str);
       }
    }
    
    void test2(String str){
        synchronized(SysTest.class){ 
            System.out.println(str+"2");
        }
    }
}

上面如果不支持重入锁的话,那么在调用test2方法时,由于当前锁(SysTest.class)已经被获取走了,就会在调用这个方法这里阻塞等待,最终就会造成死锁。

ReentrantLock实现重进入

        重进入是指任意线程在获取到锁之后能够再次获取该锁而不会被锁阻塞,该特性需要解决如下问题:

          1. 线程再次获取锁。锁需要去识别获取锁的线程,并是否为当前占据锁的线程,如果是,则再次获取成功

          2.锁的最终释放,线程重复n次获取了锁,随后在第n次释放锁后,其他线程能够获取到该锁,锁的最终释放要求锁对于获取进行计数自增,计数表示当前锁的重复次数,而锁被释放时,计数就递减,当计数为0时表示锁已经成功释放。

二、公平锁和非公平锁

           公平锁与否是针对获取锁而言的,如果一个锁公平的,那么锁获取的顺序就是应该符合请求的绝对时间顺序,也就是FIFO,先进入尝试获取锁那么后续获取锁就越早,这就是公平锁,反之对于时间没有绝对的概念就是非公平锁

  1. ReentrantLock的构造函数有如下两个,通过传入true和false来判定是否采用公平锁(true表示用公平锁),默认是采用非公平锁,原因是非公平锁效率更高。

ReentrantLock()

ReentrantLock(boolean fair)   // 创建一个具有给定公平策略的 ReentrantLock。

  源码:

 public ReentrantLock(){
        sync = new NonfairSync();
    }

    public ReentrantLock(boolean fair){      
        sync = fair ? new FairSync() : new NonfairSync();  
          //FairSync和NonfairSync是两个继承Sync 的子类(Sync是继承AQS同步器的子类)
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_40792878/article/details/81271427