Java锁重入

isen
isen
发布于 2023-09-26 / 22 阅读 / 0 评论 / 0 点赞

Java锁重入

Locks in Java

synchronized 重入

synchronized块(同步快)是可重入的。如果线程获取同步块的监视器的锁,那么该线程也可以进入其他同步于该锁的synchronized 块。换句话,如果线程获取监视器的锁,那么线程可以进入所有同步于该锁的同步块。

可重入锁是可以被一个线程在已经获取该锁的情况下,再次获取该锁。

public class Reentrant{

  public synchronized outer(){
    inner();
  }

  public synchronized inner(){
    //do something
  }
}
public class Reentrant2{

  Lock lock = new Lock();

  public outer(){
    lock.lock();
    inner();
    lock.unlock();
  }

  public synchronized inner(){
    lock.lock();
    //do something
    lock.unlock();
  }
}

//该锁是不可重入锁,使用它可能会发生重入锁死问题
public class Lock{

  boolean isLocked = false;

  public synchronized void lock() throws InterruptedException{
    while(isLocked){
      wait();
    }
    isLocked = true;
  }

  ...
}

对Lock进行修改,使其能够重入

public class Lock{

  boolean isLocked = false;
  Thread  lockedBy = null;
  int     lockedCount = 0;

  public synchronized void lock() throws InterruptedException{
    Thread callingThread = Thread.currentThread();
    while(isLocked && lockedBy != callingThread){
      wait();
    }
    isLocked = true;
    lockedCount++;
    lockedBy = callingThread;
  }


  public synchronized void unlock(){
    if(Thread.curentThread() == this.lockedBy){
      lockedCount--;

      if(lockedCount == 0){
        isLocked = false;
        notify();
      }
    }
  }

  ...
}

避免发生重入锁死问题,要么使用重入锁,要么在编写代码时避免再次获取已经持有的锁。