java:reentrant_locks

Reentrant Locks

Σε προηγούμενη ενότητα είδαμε την κλάση Lock που υλοποιεί την απλή κλειδαριά, όπως παρακάτω

Lock.java
public class Lock{
  private boolean isLocked      = false;
  private Thread  lockingThread = null;
 
  public synchronized void lock() throws InterruptedException{
    while(isLocked){
      wait();
    }
    isLocked      = true;
    lockingThread = Thread.currentThread();
  }
 
  public synchronized void unlock(){
    if(this.lockingThread != Thread.currentThread()){
      throw new IllegalMonitorStateException(
        "Calling thread has not locked this lock");
    }
    isLocked      = false;
    lockingThread = null;
    notify();
  }
}

Η παραπάνω κλάση δεν μας επιτρέπει να επιχειρήσουμε να κλειδώσουμε περισσότερες της μία φορές, χωρίς προηγούμενα να ξεκλειδώσουμε. Στη πραγματικότητα, εάν επιχειρήσουμε να κλειδώσουμε ξανά την κλειδαριά το νήμα που θα επιχειρήσει να κλειδώσει 2η φορά θα περιμένει για πάντα, καθώς η μεταβλητή isLocked έχει την τιμή true. Εάν θέλουμε να μπορούμε να κλειδώσουμε μία υφιστάμενη κλειδαριά περισσότερες από μία φορές και αντίστοιχα να τη ξεκλειδώσουμε χρειαζόμαστε ένα re-entrant lock, όπως παρακάτω:

ReentrantLock.java
public class ReentrantLock {
 
  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();
      }
    }
  }
 
}
java/reentrant_locks.txt · Last modified: 2016/02/26 11:15 (external edit)