java:thread_signalling

This is an old revision of the document!


A PCRE internal error occured. This might be caused by a faulty plugin

====== Συγχρονισμός Νημάτων ====== Ο συγχρονισμός νημάτων έχει σαν στόχο να επιτρέπει σε διαφορετικά νήματα να διαβάζουν ή να γράφουν με ασφάλεια σε διαμοιραζόμενες μεταβλητές χωρίς να προκύπτουν ασάφειες ως προς τις τιμές των μεταβλητών αυτών λόγω ταυτόχρονης μεταβολής τους. Ας υποθέσουμε ότι έχουμε δύο νήματα Α, Β και το νήμα Α θέλει να ειδοποιήσει το νήμα Β μόλις ολοκληρώσει την επεξεργασία των δεδομένων του, ώστε εκείνο να ξεκινήσει την επεξεργασία των δεδομένων. ===== Συγχρονισμός μέσω διαμοιραζόμενων αντικειμένων ===== Ο πιο απλός τρόπος για να επικοινωνήσουν δύο νήματα μεταξύ τους είναι μέσω διαμοιραζόμενων αντικειμένων. Για το παραπάνω παράδειγμα, ας υποθέσουμε ότι το νήμα Α θέτει την boolean τιμή //hasDataToProcess// σε true μέσα από μία συγχρονισμένη μέθοδο και το νήμα Β διαβάζει την τιμή //hasDataToProcess// και πάλι μέσω μίας συγχρονισμένης μεθόδου <code java MySignal.java> public class MySignal{ protected boolean hasDataToProcess = false; public synchronized boolean hasDataToProcess(){ return this.hasDataToProcess; } public synchronized void setHasDataToProcess(boolean hasData){ this.hasDataToProcess = hasData; } } </code> ===== Συγχρονισμός μέσω διαρκούς επανάληψης ===== Το νήμα Β περιμένει έως ότου τα δεδομένα να είναι διαθέσιμα περιμένοντας διαρκώς σε ένα while() βρόγχο (loop), όπως παρακάτω <code java> protected MySignal sharedSignal = ... ... while(!sharedSignal.hasDataToProcess()){ //do nothing... busy waiting } </code> Στο παράδειγμα αυτό το νήμα περιμένει, αλλά παράλληλα παραμένει και ενεργό (busy). ===== Συγχρονισμός με χρήση wait(), notify(), notifyAll() ===== Το παραπάνω σχήμα αν και είναι αποτελεσματικό ως προς τον συγχρονισμό δαπανά πολλά resources καθώς το νήμα Β παραμένει ενεργό περιμένοντας. Θα ήταν πιο αποδοτικό αν αντί να παραμένει ενεργό το νήμα Β //"κοιμόταν"// περιμένοντας το νήμα Α να ολοκληρώσει. Η Java διαθέτει ένα μηχανισμό προκειμένου να επιτρέψει σε νήματα να κοιμηθούν περιμένοντας τα νήματα που εκτελούνται να ολοκληρώσουν το έργο τους. Συγκεκριμένα διαθέτει τρεις μεθόδους που επιτρέπουν το συγκεκριμένο συγχρονισμό [[https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#wait--|wait()]], [[https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#notify--|notify()]], [[https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#notifyAll--|notifyAll()]]. Όταν ένα νήμα καλεί την μέθοδο //wait()// πάνω σε ένα αντικείμενο, τότε το νήμα κοιμάται έως ότου ένα άλλο νήμα καλέσει τη μέθοδο //notify()// πάνω στο ίδιο αντικείμενο. Προκειμένου να κληθούν οι wait() και notify() το συγκεκριμένο νήμα θα πρέπει να λάβει το monitor lock για το συγκεκριμένο αντικείμενο, δηλαδή τόσο η wait() όσο και η notify() θα πρέπει να κληθούν μέσα σε μία συγχρονισμένη μέθοδο ή συγχρονισμένο μπλοκ. Δείτε το παρακάτω παράδειγμα συγχρονισμού με χρήση των wait()/notify(). <code java MonitorObject.java> public class MonitorObject{ } </code> <code java MyWaitNotify.java> public class MyWaitNotify{ MonitorObject myMonitorObject = new MonitorObject(); public void doWait(){ synchronized(myMonitorObject){ try{ myMonitorObject.wait(); } catch(InterruptedException e){...} } } public void doNotify(){ synchronized(myMonitorObject){ myMonitorObject.notify(); } } } </code>

java/thread_signalling.1427659350.txt.gz · Last modified: 2016/02/26 11:15 (external edit)