User Tools

Site Tools


java:synchronized_methods_blocks

Differences

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

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
java:synchronized_methods_blocks [2017/03/17 07:27] – [Συγχρονισμένες μέθοδοι] gthanosjava:synchronized_methods_blocks [2018/03/08 12:03] (current) – external edit 127.0.0.1
Line 3: Line 3:
 Η Java παρέχει δύο βασικούς τρόπους συγχρονισμού προκειμένου να αποφεύγονται τα προβλήματα συγχρονισμού που παρουσιάστηκαν προηγούμενα **α)** τις συγχρονισμένες μεθόδους και **β)** τα συγχρονισμένα blocks.  Η Java παρέχει δύο βασικούς τρόπους συγχρονισμού προκειμένου να αποφεύγονται τα προβλήματα συγχρονισμού που παρουσιάστηκαν προηγούμενα **α)** τις συγχρονισμένες μεθόδους και **β)** τα συγχρονισμένα blocks. 
  
-Η διαδικασίες συγχρονισμού που περιγράφονται παρακάτω βασίζονται σε έναν εσωτερικό μηχανισμό που διαθέτουν όλα τα αντικείμενα στην Java, το λεγόμενο intrinsic lock ή monitor lock ή monitor. Όταν ένα νήμα θέλει να εκτελέσει τη συγχρονισμένη μέθοδο ενός αντικειμένου θα πρέπει να λάβει το //monitor lock// για το αντικείμενο αυτό. Αντίστοιχα, όταν το ίδιο νήμα θα βγει από την συγχρονισμένη μέθοδο του αντικειμένου θα ελευθερώσει το //monitor lock// για το αντικείμενο. Όταν ένα νήμα έχει το //monitor lock// για ένα αντικείμενο, κανένα άλλο νήμα δεν μπορεί να λάβει ταυτόχρονα αυτό το lock. Μόνο το υφιστάμενο αντικείμενο μπορεί να αφήσει το lock εξερχόμενο από την συγχρονισμένη μέθοδο ή το συγχρονισμένο block.+Η διαδικασίες συγχρονισμού που περιγράφονται παρακάτω βασίζονται σε έναν εσωτερικό μηχανισμό που διαθέτουν όλα τα αντικείμενα στην Java, το λεγόμενο //intrinsic lock// ή //monitor lock// ή //monitor// 
 + 
 +Όταν ένα νήμα θέλει να εκτελέσει τη συγχρονισμένη μέθοδο ενός αντικειμένου θα πρέπει να λάβει το //monitor lock// για το αντικείμενο αυτό. Αντίστοιχα, όταν το ίδιο νήμα θα βγει από την συγχρονισμένη μέθοδο του αντικειμένου θα ελευθερώσει το //monitor lock// για το αντικείμενο. Όταν ένα νήμα έχει το //monitor lock// για ένα αντικείμενο, κανένα άλλο νήμα δεν μπορεί να λάβει ταυτόχρονα αυτό το //lock//. Μόνο το υφιστάμενο αντικείμενο μπορεί να αφήσει το //lock// εξερχόμενο από την συγχρονισμένη μέθοδο ή το συγχρονισμένο block.
  
 ===== Συγχρονισμένες μέθοδοι ===== ===== Συγχρονισμένες μέθοδοι =====
  
-Προκειμένου να δημιουργήσετε μία συγχρονισμένη μέθοδο σε μία κλάση αρκεί να προσθέσετε το keywords synchronized κατά την δήλωση της μεθόδου, όπως παρακάτω+Προκειμένου να δημιουργήσετε μία συγχρονισμένη μέθοδο σε μία κλάση αρκεί να προσθέσετε το keyword //synchronized// κατά την δήλωση της μεθόδου, όπως παρακάτω
  
 <code java SynchronizedCounter.java> <code java SynchronizedCounter.java>
 public class SynchronizedCounter { public class SynchronizedCounter {
-    private int c = 0;+  private int c = 0;
  
-    public synchronized void increment() { +  public synchronized void increment() { 
-        c++; +    c++; 
-    }+  }
  
-    public synchronized void decrement() { +  public synchronized void decrement() { 
-        c--; +    c--; 
-    }+  }
  
-    public synchronized int value() { +  public synchronized int value() { 
-        return c; +    return c; 
-    }+  }
 } }
 </code> </code>
  
 Αν έχουμε ένα αντικείμενο //counter// της παραπάνω κλάσης τότε ισχύουν τα παρακάτω Αν έχουμε ένα αντικείμενο //counter// της παραπάνω κλάσης τότε ισχύουν τα παρακάτω
-  * Δεν είναι δυνατόν κλήσεις συγχρονισμένων μεθόδων για το ίδιο αντικείμενο να κληθούν ταυτόχρονα από διαφορετικά νήματα. Αν υποθέσουμε ότι ένα νήμα εκτελεί μία από τις συγχρονισμένες μεθόδους ενός αντικειμένου. Όσα άλλα νήματα επιχειρούν να έχουν πρόσβαση σε συγχρονισμένες μεθόδους του ιδίου αντικειμένου, αναμένουν έως ότου το τρέχον νήμα να ολοκληρώσει την εκτέλεση της συγχρονισμένης μεθόδου την οποία εκτελεί. Αυτό διασφαλίζει ότι η αλληλουχία των κλήσεων του παραδείγματος των νημάτων A,B [[java:synchronization|που παρουσιάστηκε σε προηγούμενη σελίδα]] θα είναι η ενδεδειγμένη.+  * Δεν είναι δυνατόν η ίδια συγχρονισμένη μέθοδος ή διαφορετικές συγχρονισμένες μέθοδοι ενός αντικειμένου να κληθούν ταυτόχρονα από διαφορετικά νήματα. Ας υποθέσουμε ότι ένα νήμα εκτελεί μία από τις συγχρονισμένες μεθόδους ενός αντικειμένου. Όσα άλλα νήματα επιχειρούν να έχουν πρόσβαση σε συγχρονισμένες μεθόδους του ιδίου αντικειμένου, αναμένουν έως ότου το τρέχον νήμα να ολοκληρώσει την εκτέλεση της συγχρονισμένης μεθόδου την οποία εκτελεί και να ελευθερώσει το //monitor lock// για το αντικείμενο αυτό. Αυτό διασφαλίζει ότι η αλληλουχία των κλήσεων του παραδείγματος των νημάτων A,B [[java:synchronization|που παρουσιάστηκε σε προηγούμενη σελίδα]] θα είναι η ενδεδειγμένη.
  
 ===== Συγχρονισμένα Βlocks ===== ===== Συγχρονισμένα Βlocks =====
  
-Σε αναλογία με τις συγχρονισμένες μεθόδους ορίζονται και τα συγχρονισμένα blocks με την διαφορά ότι τα συχρονισμένα blocks οφείλουν να ορίσουν το αντικείμενο του οποίου λαμβάνουν το //monitor lock//, όπως παρακάτω+Σε αναλογία με τις συγχρονισμένες μεθόδους ορίζονται και τα συγχρονισμένα blocks με την διαφορά ότι τα συγχρονισμένα blocks οφείλουν να ορίσουν το αντικείμενο του οποίου λαμβάνουν το //monitor lock//, όπως παρακάτω
  
 <code java> <code java>
-public void addName(String name) { +public class SynchronizedCounter { 
-    synchronized(this) { +  private int c = 0;  
-        lastName = name; +  public void increment() { synchronized (this) {c++;} }  
-        nameCount++; +  public void decrement() { synchronized (this) {c--;}  
-    +  public int value() { synchronized (this) {return c;} }
-    nameList.add(name);+
 } }
 </code> </code>
Line 55: Line 56:
     public void inc1() {     public void inc1() {
         synchronized(lock1) {         synchronized(lock1) {
-            c1++;+            while(true) { 
 +               for(long i=0; i<999999999L; i++
 +                 ; 
 +               System.out.println("Counter1: "+ ++c1); 
 +            }
         }         }
     }     }
Line 61: Line 66:
     public void inc2() {     public void inc2() {
         synchronized(lock2) {         synchronized(lock2) {
-            c2++;+            while(true) { 
 +               for(long i=0; i<999999999L; i++
 +                 ; 
 +               System.out.println("Counter2: "+ ++c2); 
 +            }
         }         }
     }     }
Line 67: Line 76:
 </code> </code>
  
-<WRAP round center tip> +<WRAP important 80% round center
-Αν και ένα νήμα δεν μπορεί να λάβει το //monitor lock// ενός αντικειμένου, όταν αυτό έχει καταληφθεί από άλλο αντικείμενο, το ίδιο thread μπορεί να λάβει το //monitor lock// του ιδίου αντικειμένου όσες φορές χρειαστεί αν υπάρχουν εμφωλευμένες (nested) κλήσεις συγχρονισμένων μεθόδων ή συγχρονισμένων blocks. Σε αυτές τις περιπτώσεις το monitor lock απελευθερώνεται μόνο όταν το νήμα βγει και από την τελευταία μέθοδο ή block στην οποία μπήκε πριν από κάθε άλλη κλήση συγχρονισμένης μεθόδου ή μπλοκ.+Στο παραπάνω παράδειγμα, οι μέθοδοι **inc1** και **inc2** περιέχουν δύο συγχρονισμένα blocks που κλειδώνουν από διαφορετικά αντικείμενα (**lock1** και **lock2**). Αυτό πρακτικά σημαίνει ότι οι μέθοδοι **inc1** και **inc2** μπορούν να κληθούν ταυτόχρονα από δύο διαφορετικά νήματα. Ενδεικτικό είναι το παρακάτω πρόγραμμα: 
 +</WRAP> 
 + 
 +<code java SyncBlockThread.java> 
 +public class SyncBlockThread extends Thread { 
 +  SyncBlock block; 
 +  boolean counter1; 
 +  public SyncBlockThread(SyncBlock block, boolean counter1) { 
 +    this.block = block; 
 +    this.counter1 = counter1; 
 +  } 
 +   
 +  public void run() { 
 +    if(counter1) 
 +      block.inc1(); 
 +    else 
 +      block.inc2(); 
 +  } 
 +   
 +  public static void main(String []args) { 
 +    SyncBlock block = new SyncBlock(); 
 +    new SyncBlockThread(block, true).start(); 
 +    new SyncBlockThread(block, false).start(); 
 +  } 
 +
 +</code> 
 + 
 +<WRAP tip 80% round center
 +Αν και ένα νήμα δεν μπορεί να λάβει το //monitor lock// ενός αντικειμένου, όταν αυτό έχει καταληφθεί από άλλο αντικείμενο, το ίδιο νήμα μπορεί να λάβει το //monitor lock// του ιδίου αντικειμένου όσες φορές χρειαστεί αν υπάρχουν εμφωλευμένες (nested) κλήσεις συγχρονισμένων μεθόδων ή συγχρονισμένων blocks. Σε αυτές τις περιπτώσεις το //monitor lock// απελευθερώνεται μόνο όταν το νήμα βγει και από την αρχική συγχρονισμένη μέθοδο ή το αρχικό συγχρονισμένο block που μπήκε πριν από οποιαδήποτε άλλη κλήση συγχρονισμένης μεθόδου ή μπλοκ.
 </WRAP> </WRAP>
  
-Δείτε το παραπάνω παράδειγμα εμφωλευμένων κλήσεων συγχρονισμένων μεθόδων +Δείτε το παρακάτω παράδειγμα εμφωλευμένων κλήσεων συγχρονισμένων μεθόδων 
  
 <code java NestedSyncMethods.java> <code java NestedSyncMethods.java>
Line 85: Line 122:
 </code> </code>
  
-<WRAP round center tip> +<WRAP round center tip 80%
-Αναφέρθηκε παραπάνω ότι μόνο ένα thread λαμβάνει το monitor lock ενός αντικειμένου και να εκτελέσει το συγχρονισμένο block ή την συγχρονισμένη μέθοδο που συνδέεται με το αντικείμενο αυτό. Τα υπόλοιπα threads που πιθανόν θέλουν και εκείνα να προσπελάσουν τη συγκεκριμένη μέθοδο ή block βρίσκονται σε κατάσταση busy-wait, δηλαδή αναμένουν ενεργά μέχρι να ελευθερωθεί το monitor lock για την μέθοδο ή το block στο οποίο αναμένουν.+Αναφέρθηκε παραπάνω ότι μόνο ένα νήμα λαμβάνει το //monitor lock// ενός αντικειμένου προκειμένου να εκτελέσει το συγχρονισμένο block ή την συγχρονισμένη μέθοδο που συνδέεται με το αντικείμενο αυτό. Τα υπόλοιπα νήματα που πιθανόν θέλουν και εκείνα να προσπελάσουν τη συγκεκριμένη μέθοδο ή block βρίσκονται σε κατάσταση //busy-wait//, δηλαδή αναμένουν ενεργά μέχρι να ελευθερωθεί το //monitor lock// από τη μέθοδο ή το block στο οποίο αναμένουν.
 </WRAP> </WRAP>
  
  
 +|Προηγούμενο: [[:java:thread_memory_model| Το μοντέλο μνήμης της Java ]] | [[:toc | Περιεχόμενα ]] | Επόμενο: [[java:thread_signalling | Συγχρονισμός νημάτων ]]|
  
  
java/synchronized_methods_blocks.1489735625.txt.gz · Last modified: 2017/03/17 07:27 (external edit)