ReentrantLock实现原理-何为可重入

Posted aspirant

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ReentrantLock实现原理-何为可重入相关的知识,希望对你有一定的参考价值。

原文:https://www.shiyanlou.com/questions/2460

1 . 什么是可重入锁

锁的概念就不用多解释了,当某个线程A已经持有了一个锁,当线程B尝试进入被这个锁保护的代码段的时候.就会被阻塞.而锁的操作粒度是”线程”,而不是调用(至于为什么要这样,下面解释).同一个线程再次进入同步代码的时候.可以使用自己已经获取到的锁,这就是可重入锁java里面内置锁(synchronize)和Lock(ReentrantLock)都是可重入的

在继承的情况下,如果不是可重入的,那就形成死锁了

我自己写了个例子:

 

 

package entrantlock_test;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class parent {
    
     protected Lock lock=new ReentrantLock();
     
     public void test(){
         lock.lock();
         try{
             System.out.println("Parent");
         }finally{
             lock.unlock();
         }
     }
     
     
}

class Sub extends parent{

    @Override
    public void test() {
        // TODO Auto-generated method stub
        lock.lock();
        try{
        super.test();
        System.out.println("Sub");
        
        }finally{
            lock.unlock();
        }
    }
    
    
}

public class LockTest{
    
    public static void main(String[] args){
        
        Sub s=new Sub();
        s.test();
        
    }
}

 

2 . 为什么要可重入

 

如果线程A继续再次获得这个锁呢?比如一个方法是synchronized,递归调用自己,那么第一次已经获得了锁,第二次调用的时候还能进入吗? 直观上当然需要能进入.这就要求必须是可重入的.可重入锁又叫做递归锁,再举个例子.

public class Widget {
        public synchronized void doSomething() {
            ...
        }
}

public class LoggingWidget extends Widget {
        public synchronized void doSomething() {
            System.out.println(toString() + ": calling doSomething");
            super.doSomething();//若内置锁是不可重入的,则发生死锁
        }
}

 

这个例子是java并发编程实战中的例 子.synchronized 是父类Widget的内置锁,当执行子 类的方法的时候,先获取了一次Widget的锁,然后在执行super的时候,就要获取一次,如果不可重入,那么就跪了.

3 . 如何实现可重入锁

为每个锁关联一个获取计数器和一个所有者线程,当计数值为0的时候,这个所就没有被任何线程只有.当线程请求一个未被持有的锁时,JVM将记下锁的持有者,并且将获取计数值置为1,如果同一个线程再次获取这个锁,技术值将递增,退出一次同步代码块,计算值递减,当计数值为0时,这个锁就被释放.ReentrantLock里面有实现

4 . 有不可重入锁吗

这个还真有.Linux下的pthread_mutex_t锁是默认是非递归的。可以通过设置PTHREAD_MUTEX_RECURSIVE属性,将pthread_mutex_t锁设置为递归锁。如果要自己实现不可重入锁,同可重入锁,这个计数器只能为1.或者0,再次进入的时候,发现已经是1了,就进行阻塞.jdk里面没有默认的实现类.

以上是关于ReentrantLock实现原理-何为可重入的主要内容,如果未能解决你的问题,请参考以下文章

Java并发-- ReentrantLock 可重入锁实现原理2 - 释放锁

ReentrantLock实现原理及源码分析

Java并发-- ReentrantLock 可重入锁实现原理1 - 获取锁

Java并发包4--可重入锁ReentrantLock的实现原理

java可重入锁(ReentrantLock)的实现原理

ReentrantLock可重入锁在我们的代码中。