Sobes.tech
Middle+

Πώς λειτουργεί ο μηχανισμός συγχρονισμού 'synchronized' στη Java πίσω από τα παρασκήνια;

sobes.tech AI

Απάντηση από AI

Ο μηχανισμός synchronized στη Java βασίζεται στην έννοια των monitor (αντικείμενα monitor). Σε κάθε αντικείμενο στη Java συσχετίζεται ένας monitor.

Όταν ένα νήμα εισέρχεται σε ένα συγχρονισμένο μπλοκ ή μέθοδο, προσπαθεί να αποκτήσει τον monitor του αντίστοιχου αντικειμένου. Αν ο monitor είναι ελεύθερος, το νήμα τον αποκτά και συνεχίζει την εκτέλεση. Αν ο monitor είναι κατειλημμένος από άλλο νήμα, το τρέχον νήμα μπλοκάρεται και περνά σε κατάσταση αναμονής μέχρι να ελευθερωθεί ο monitor.

Μέσα στον monitor υλοποιούνται:

  1. Αμοιβαία αποκλειστικότητα (Mutual Exclusion): Μόνο ένα νήμα μπορεί να κατέχει τον monitor ενός αντικειμένου σε μια δεδομένη στιγμή. Αυτό διασφαλίζει ότι μόνο ένα νήμα μπορεί να εκτελέσει κώδικα συγχρονισμένο για αυτό το αντικείμενο.
  2. Αναμονή και ειδοποίηση (Waiting and Notification): Ο monitor περιλαμβάνει μια σειρά από συναφείς μεθόδους wait(), notify() και notifyAll(). Αυτές οι μέθοδοι επιτρέπουν στα νήματα που κατέχουν τον monitor να τον ελευθερώσουν προσωρινά και να περάσουν σε κατάσταση αναμονής, και στη συνέχεια να ειδοποιηθούν από άλλα νήματα για την πιθανότητα συνέχισης.

Η υλοποίηση σε χαμηλό επίπεδο περιλαμβάνει:

  • Εντολή monitorenter: Εκτελείται κατά την είσοδο σε ένα συγχρονισμένο μπλοκ ή μέθοδο. Προσπαθεί να αποκτήσει τον monitor του αντικειμένου.
  • Εντολή monitorexit: Εκτελείται κατά την έξοδο από ένα συγχρονισμένο μπλοκ ή μέθοδο (είτε με κανονικό τερματισμό είτε με εξαίρεση). Απελευθερώνει τον monitor του αντικειμένου.

Αυτές οι εντολές αποτελούν μέρος του bytecode της Java και διαχειρίζονται από τη Java Virtual Machine (JVM). Η JVM χρησιμοποιεί εγγενείς μηχανισμούς του λειτουργικού συστήματος (όπως mutexes, semaphores) για τη διαχείριση των monitor και το κλείδωμα/ξεκλείδωμα των νημάτων.

Η απόκτηση του monitor μπορεί να υλοποιηθεί σε επίπεδο αντικειμένου (για μεθόδους και μπλοκ στιγμιότυπου) ή σε επίπεδο κλάσης (για στατικές μεθόδους και μπλοκ), χρησιμοποιώντας το αντικείμενο Class ως κλείδωμα.

Παράδειγμα χρήσης:

public class Counter {
    private int count = 0;

    public synchronized void increment() { // Συγχρονισμένη μέθοδος
        count++;
    }

    public void decrement() {
        synchronized (this) { // Συγχρονισμένο μπλοκ
            count--;
        }
    }

    public static synchronized void staticMethod() { // Στατική συγχρονισμένη μέθοδος
        // ...
    }
}

Πίνακας μεθόδων της κλάσης Object που σχετίζονται με τους monitor:

Μέθοδος Περιγραφή
wait() Το νήμα που κατέχει τον monitor το απελευθερώνει προσωρινά και περνά σε κατάσταση αναμονής.
notify() Ειδοποιεί ένα από τα νήματα σε αναμονή ότι μπορεί να προσπαθήσει να αποκτήσει τον monitor και να συνεχίσει.
notifyAll() Ειδοποιεί όλα τα νήματα σε αναμονή.