1. Γιατί να κλειδώσετε και τι είναι κλειδωμένο;
Όταν χρησιμοποιούμε νήματα, ο πιο αποτελεσματικός τρόπος είναι φυσικά ο ασύγχρονος, δηλαδή κάθε νήμα τρέχει ταυτόχρονα, χωρίς να βασίζεται το ένα στο άλλο και να περιμένει. Ωστόσο, όταν διαφορετικά νήματα πρέπει να έχουν πρόσβαση σε έναν συγκεκριμένο πόρο, απαιτείται ένας μηχανισμός συγχρονισμού, δηλαδή, όταν διαβάζουμε και γράφουμε τον ίδιο πόρο, πρέπει να κάνουμε τον πόρο να λειτουργεί μόνο από ένα νήμα ταυτόχρονα για να διασφαλίσουμε ότι κάθε λειτουργία είναι αποτελεσματική και άμεση, δηλαδή για να διασφαλίσουμε την ατομικότητα της λειτουργίας του. lock είναι η πιο συχνά χρησιμοποιούμενη μέθοδος συγχρονισμού στη C#, με τη μορφή lock(objectA){codeB}.
lock(objectA){codeB} φαίνεται απλό, αλλά στην πραγματικότητα έχει τρεις σημασίες, οι οποίες είναι απαραίτητες για τη σωστή χρήση του: 1. Είναι κλειδωμένο το αντικείμενοΑ; Αν όχι, θα το κλειδώσω, διαφορετικά περιμένετε μέχρι να απελευθερωθεί το αντικείμενο Α. 2. Μετά το κλείδωμα, άλλα νήματα δεν μπορούν να καλέσουν τον κωδικό Β ή να χρησιμοποιήσουν το αντικείμενο Α κατά την εκτέλεση του κωδικού Β. 3. Μετά την εκτέλεση του codeB, απελευθερώστε το objectA και το codeB είναι προσβάσιμο από άλλα νήματα.
2. Τι συνέβη με το κλείδωμα;
Ας δούμε ένα παράδειγμα:
Στο νήμα t1, το LockMe καλεί το lock(this), δηλαδή το c1 στην κύρια συνάρτηση και όταν καλεί το lock(c1) στο κύριο νήμα, πρέπει να περιμένει να εκτελεστεί το μπλοκ κλειδώματος στο t1 πριν αποκτήσει πρόσβαση στο c1, δηλαδή, όλες οι λειτουργίες που σχετίζονται με το c1 δεν μπορούν να ολοκληρωθούν, οπότε βλέπουμε ότι ακόμη και το c1. Το DoNotLockMe() δεν εκτελείται.
|