| Both sides previous revision
Previous revision
Next revision
|
Previous revision
Next revision
Both sides next revision
|
java:synchronized_methods_blocks [2017/03/19 18:47] gthanos [Συγχρονισμένα Βlocks] |
java:synchronized_methods_blocks [2018/03/08 11:15] gthanos [Συγχρονισμένα Βlocks] |
| |
| Αν έχουμε ένα αντικείμενο //counter// της παραπάνω κλάσης τότε ισχύουν τα παρακάτω | Αν έχουμε ένα αντικείμενο //counter// της παραπάνω κλάσης τότε ισχύουν τα παρακάτω |
| * Δεν είναι δυνατόν κλήσεις συγχρονισμένων μεθόδων για το ίδιο αντικείμενο να κληθούν ταυτόχρονα από διαφορετικά νήματα. Αν υποθέσουμε ότι ένα νήμα εκτελεί μία από τις συγχρονισμένες μεθόδους ενός αντικειμένου. Όσα άλλα νήματα επιχειρούν να έχουν πρόσβαση σε συγχρονισμένες μεθόδους του ιδίου αντικειμένου, αναμένουν έως ότου το τρέχον νήμα να ολοκληρώσει την εκτέλεση της συγχρονισμένης μεθόδου την οποία εκτελεί. Αυτό διασφαλίζει ότι η αλληλουχία των κλήσεων του παραδείγματος των νημάτων A,B [[java:synchronization|που παρουσιάστηκε σε προηγούμενη σελίδα]] θα είναι η ενδεδειγμένη. | * Δεν είναι δυνατόν η ίδια συγχρονισμένη μέθοδος ή διαφορετικές συγχρονισμένες μέθοδοι ενός αντικειμένου να κληθούν ταυτόχρονα από διαφορετικά νήματα. Ας υποθέσουμε ότι ένα νήμα εκτελεί μία από τις συγχρονισμένες μεθόδους ενός αντικειμένου. Όσα άλλα νήματα επιχειρούν να έχουν πρόσβαση σε συγχρονισμένες μεθόδους του ιδίου αντικειμένου, αναμένουν έως ότου το τρέχον νήμα να ολοκληρώσει την εκτέλεση της συγχρονισμένης μεθόδου την οποία εκτελεί και να ελευθερώσει το //monitor lock// για το αντικείμενο αυτό. Αυτό διασφαλίζει ότι η αλληλουχία των κλήσεων του παραδείγματος των νημάτων A,B [[java:synchronization|που παρουσιάστηκε σε προηγούμενη σελίδα]] θα είναι η ενδεδειγμένη. |
| |
| ===== Συγχρονισμένα Βlocks ===== | ===== Συγχρονισμένα Βlocks ===== |
| 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); |
| | } |
| } | } |
| } | } |
| 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); |
| | } |
| } | } |
| } | } |
| Αν και ένα νήμα δεν μπορεί να λάβει το //monitor lock// ενός αντικειμένου, όταν αυτό έχει καταληφθεί από άλλο αντικείμενο, το ίδιο νήμα μπορεί να λάβει το //monitor lock// του ιδίου αντικειμένου όσες φορές χρειαστεί αν υπάρχουν εμφωλευμένες (nested) κλήσεις συγχρονισμένων μεθόδων ή συγχρονισμένων blocks. Σε αυτές τις περιπτώσεις το //monitor lock// απελευθερώνεται μόνο όταν το νήμα βγει και από την αρχική συγχρονισμένη μέθοδο ή το αρχικό συγχρονισμένο block που μπήκε πριν από οποιαδήποτε άλλη κλήση συγχρονισμένης μεθόδου ή μπλοκ. | Αν και ένα νήμα δεν μπορεί να λάβει το //monitor lock// ενός αντικειμένου, όταν αυτό έχει καταληφθεί από άλλο αντικείμενο, το ίδιο νήμα μπορεί να λάβει το //monitor lock// του ιδίου αντικειμένου όσες φορές χρειαστεί αν υπάρχουν εμφωλευμένες (nested) κλήσεις συγχρονισμένων μεθόδων ή συγχρονισμένων blocks. Σε αυτές τις περιπτώσεις το //monitor lock// απελευθερώνεται μόνο όταν το νήμα βγει και από την αρχική συγχρονισμένη μέθοδο ή το αρχικό συγχρονισμένο block που μπήκε πριν από οποιαδήποτε άλλη κλήση συγχρονισμένης μεθόδου ή μπλοκ. |
| </WRAP> | </WRAP> |
| | |
| | <WRAP important 80% round center> |
| | Στο παραπάνω παράδειγμα, οι μέθοδοι 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> |
| |
| Δείτε το παρακάτω παράδειγμα εμφωλευμένων κλήσεων συγχρονισμένων μεθόδων | Δείτε το παρακάτω παράδειγμα εμφωλευμένων κλήσεων συγχρονισμένων μεθόδων |