This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision | |||
|
java:nested_lockeout [2016/05/15 18:43] |
java:nested_lockeout [2016/05/15 19:43] gthanos |
||
|---|---|---|---|
| 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(); | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Παρατηρήστε ότι η μέθοδος lock() πρώτα λαμβάνει το monitor lock του αντικειμένου " | ||
| + | |||
| + | Το πρόβλημα με το παραπάνω σχήμα είναι ότι το νήμα που κοιμάται ελευθερώνει το monitor lock που συνδέεται με το monitorObject, | ||
| + | <code java> | ||
| + | synchronized(this){ | ||
| + | this.isLocked = false; | ||
| + | synchronized(this.monitorObject){ | ||
| + | this.monitorObject.notify(); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Παρακάτω δίνεται ένα πιο ρεαλιστικό παράδειγμα με βάση την κλάση FairLock. | ||
| + | |||
| + | <code java FairLock.java> | ||
| + | public class FairLock { | ||
| + | private boolean | ||
| + | private Thread | ||
| + | private List< | ||
| + | new ArrayList< | ||
| + | |||
| + | 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( | ||
| + | " | ||
| + | } | ||
| + | isLocked | ||
| + | lockingThread = null; | ||
| + | if(waitingThreads.size() > 0){ | ||
| + | QueueObject queueObject = waitingThread.get(0); | ||
| + | synchronized(queueObject){ | ||
| + | queueObject.notify(); | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | </ | ||