This shows you the differences between two versions of the page.
|
java:synchronized_methods_blocks [2016/05/15 19:02] gthanos [Συγχρονισμένα Βlocks] |
java:synchronized_methods_blocks [2018/03/08 12:03] |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ====== Συγχρονισμένες μέθοδοι και συγχρονισμένα blocks ====== | ||
| - | |||
| - | Η Java παρέχει δύο βασικούς τρόπους συγχρονισμού προκειμένου να αποφεύγονται τα προβλήματα συγχρονισμού που παρουσιάστηκαν προηγούμενα **α)** τις συγχρονισμένες μεθόδους και **β)** τα συγχρονισμένα blocks. | ||
| - | |||
| - | Η διαδικασίες συγχρονισμού που περιγράφονται παρακάτω βασίζονται σε έναν εσωτερικό μηχανισμό που διαθέτουν όλα τα αντικείμενα στην Java, το λεγόμενο intrinsic lock ή monitor lock ή monitor. Όταν ένα νήμα θέλει να εκτελέσει τη συγχρονισμένη μέθοδο ενός αντικειμένου θα πρέπει να λάβει το //monitor lock// για το αντικείμενο αυτό. Αντίστοιχα, | ||
| - | |||
| - | ===== Συγχρονισμένες μέθοδοι ===== | ||
| - | |||
| - | Προκειμένου να δημιουργήσετε μία συγχρονισμένη μέθοδο σε μία κλάση αρκεί να προσθέσετε το keywords synchronized κατά την δήλωση της μεθόδου, | ||
| - | |||
| - | <code java SynchronizedCounter.java> | ||
| - | public class SynchronizedCounter { | ||
| - | private int c = 0; | ||
| - | |||
| - | public synchronized void increment() { | ||
| - | c++; | ||
| - | } | ||
| - | |||
| - | public synchronized void decrement() { | ||
| - | c--; | ||
| - | } | ||
| - | |||
| - | public synchronized int value() { | ||
| - | return c; | ||
| - | } | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | Αν έχουμε ένα αντικείμενο //counter// της παραπάνω κλάσης τότε ισχύουν τα παρακάτω | ||
| - | * Δεν είναι δυνατόν κλήσεις συγχρονισμένων μεθόδων για το ίδιο αντικείμενο να κληθούν ταυτόχρονα από διαφορετικά νήματα. Αν υποθέσουμε ότι ένα νήμα εκτελεί μία από τις συγχρονισμένες μεθόδους ενός αντικειμένου. Όσα άλλα νήματα επιχειρούν να έχουν πρόσβαση σε συγχρονισμένες μεθόδους του ιδίου αντικειμένου, | ||
| - | * Όταν ένα νήμα ' | ||
| - | |||
| - | ===== Συγχρονισμένα Βlocks ===== | ||
| - | |||
| - | Σε αναλογία με τις συγχρονισμένες μεθόδους ορίζονται και τα συγχρονισμένα blocks με την διαφορά ότι τα συχρονισμένα blocks οφείλουν να ορίσουν το αντικείμενο του οποίου λαμβάνουν το //monitor lock//, όπως παρακάτω | ||
| - | |||
| - | <code java> | ||
| - | public void addName(String name) { | ||
| - | synchronized(this) { | ||
| - | lastName = name; | ||
| - | nameCount++; | ||
| - | } | ||
| - | nameList.add(name); | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | Στο παρακάτω παράδειγμα έχουμε δύο συγχρονισμένα blocκ μέσα σε δύο μη συγχρονισμένες μεθόδους. Η διαφορά είναι ότι η κλάση ορίζει δύο επιπλέον αντικείμενα μόνο και μόνο για να χρησιμοποιήσει τα //monitor locks// των αντικειμένων αυτών | ||
| - | |||
| - | <code java SyncBlock.java> | ||
| - | public class SyncBlock { | ||
| - | private long c1 = 0; | ||
| - | private long c2 = 0; | ||
| - | private Object lock1 = new Object(); | ||
| - | private Object lock2 = new Object(); | ||
| - | |||
| - | public void inc1() { | ||
| - | synchronized(lock1) { | ||
| - | c1++; | ||
| - | } | ||
| - | } | ||
| - | |||
| - | public void inc2() { | ||
| - | synchronized(lock2) { | ||
| - | c2++; | ||
| - | } | ||
| - | } | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | <WRAP round center tip> | ||
| - | Αν και ένα νήμα δεν μπορεί να λάβει το //monitor lock// ενός αντικειμένου, | ||
| - | </ | ||
| - | |||
| - | Δείτε το παραπάνω παράδειγμα εμφωλευμένων κλήσεων συγχρονισμένων μεθόδων | ||
| - | |||
| - | <code java NestedSyncMethods.java> | ||
| - | public class NestedSyncMethods { | ||
| - | void synchronized outer() { | ||
| - | inner(); | ||
| - | } | ||
| - | | ||
| - | void synchronized inner() { | ||
| - | ... | ||
| - | } | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | <WRAP round center tip> | ||
| - | |||
| - | </ | ||
| - | |||
| - | |||
| - | |||