java:nested_lockeout

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

java:nested_lockeout [2015/03/30 07:17]
gthanos
java:nested_lockeout [2016/02/26 11:15]
Line 1: Line 1:
-====== Αδιέξοδο λόγο χρήσης εμφωλευμένων συγχρονισμένων μεθόδων ή μπλοκ ====== 
- 
-Το αδιέξοδο χρήσης εμφωλευμένων συγχρονισμένων μεθόδων ή μπλοκ είναι αντίστοιχο με το deadlock αν και ο λόγος για τον οποίο συμβαίνει είναι διαφορετικός. Δείτε το παρακάτω παράδειγμα "​κλειδαριάς"​. 
- 
-<code java Lock.java>​ 
-public class Lock{ 
-  protected MonitorObject monitorObject = new MonitorObject();​ 
-  protected boolean isLocked = false; 
- 
-  public void lock() throws InterruptedException{ 
-    synchronized(this){ 
-      while(isLocked){ 
-        synchronized(this.monitorObject){ 
-            this.monitorObject.wait();​ 
-        } 
-      } 
-      isLocked = true; 
-    } 
-  } 
- 
-  public void unlock(){ 
-    synchronized(this){ 
-      this.isLocked = false; 
-      synchronized(this.monitorObject){ 
-        this.monitorObject.notify();​ 
-      } 
-    } 
-  } 
-} 
-</​code>​ 
- 
-Notice how the lock() method first synchronizes on "​this",​ then synchronizes on the monitorObject member. If isLocked is false there is no problem. The thread does not call monitorObject.wait(). If isLocked is true however, the thread calling lock() is parked waiting in the monitorObject.wait() call. 
- 
-Παρατηρήστε ότι η μέθοδος lock() πρώτα λαμβάνει το monitor lock του αντικειμένου "​this"​ και στη συνέχεια λαμβάνει το monitor lock του αντικειμένου //​monitorObject//​. Εάν η κλειδαριά δεν είναι κλειδωμένη δηλ (isLocked!=true) τότε το νήμα δεν μπαίνει μέσα στο while() και δεν λαμβάνει και το 2ο lock. Αν όμως η κλειδαριά είναι κλειδωμένη τότε το νήμα λαμβάνει και το 2ο lock και κοιμάται μέσα στην μέθοδο //wait()// περιμένοντας κάποιο άλλο νήμα να το ξυπνήσει. 
- 
-Το πρόβλημα με το παραπάνω σχήμα είναι ότι το νήμα που κοιμάται ελευθερώνει το monitor lock που συνδέεται με το monitorObject,​ αλλά δεν ελευθερώνει το monitor lock που συνδέεται με το this object. Έτσι όταν ένα άλλο νήμα θα προσπαθήσει να ξεκλειδώσει την κλειδαριά μέσω της unlock() θα μπλοκάρει μέσα στον κώδικα 
-<code java> 
-    synchronized(this){ 
-      this.isLocked = false; 
-      synchronized(this.monitorObject){ 
-        this.monitorObject.notify();​ 
-      } 
-    } 
-</​code>​ 
- 
-Παρακάτω δίνεται ένα πιο ρεαλιστικό παράδειγμα με βάση την κλάση FairLock. 
- 
-<code java FairLock.java>​ 
-public class FairLock { 
-  private boolean ​          ​isLocked ​      = false; 
-  private Thread ​           lockingThread ​ = null; 
-  private List<​QueueObject>​ waitingThreads = 
-            new ArrayList<​QueueObject>​();​ 
- 
-  public void lock() throws InterruptedException{ 
-    QueueObject queueObject = new QueueObject();​ 
- 
-    synchronized(this){ 
-      waitingThreads.add(queueObject);​ 
- 
-      while(isLocked || waitingThreads.get(0) != queueObject){ 
- 
-        synchronized(queueObject){ 
-          try{ 
-            queueObject.wait();​ 
-          }catch(InterruptedException e){ 
-            waitingThreads.remove(queueObject);​ 
-            throw e; 
-          } 
-        } 
-      } 
-      waitingThreads.remove(queueObject);​ 
-      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; 
-    if(waitingThreads.size() > 0){ 
-      QueueObject queueObject = waitingThread.get(0);​ 
-      synchronized(queueObject){ 
-        queueObject.notify();​ 
-      } 
-    } 
-  } 
-} 
-</​code>​ 
  
java/nested_lockeout.txt · Last modified: 2016/02/26 11:15 (external edit)