Im vorhergehenden Artikel dieser Artikelserie habe ich Ihnen gezeigt wie Sie mittels des lock Befehls Codeabschnitte multithreadsicher gestalten können. Mittels lock kann dabei sichergestellt werden das ein oder mehrere Codeabschnitte nicht gleichzeitig von mehreren Threads ausgeführt werden. Der Monitor Befehl hat die gleiche Funktionalität. Daher stellt sich die Frage ob es Unterschiede zwischen diesen beiden Befehlen gibt und welcher wann vorzuziehen ist.
Lock
Nachfolgend sehen Sie einen Codeausschnitt mit einem lock Befehl. Eine detaillierte Beschreibung des lock Befehls finden Sie im vorhergehenden Artikel dieser Serie.
1 static readonly object _locker = new object();
2
3 public void DoSomething()
4 {
5 lock (_locker)
6 {
7 //do something
8 }
9 }
Monitor
Mittels Montior.Enter und Monitor.Exit lässt sich ebenfalls ein Code Abschnitt durch Sperren eines Synchronisierungsobjektes threadsicher realisieren. Dabei muss beachtet werden, das Monitor.Exit auch im Fehlerfall aufzurufen ist um Deadlocks zu vermeiden.
Während ein Thread mittels Montor.Enter auf die Freigabe des Synchronisierungsobjektes wartet, kann es theoretisch vorkommen dass dieser Thread mittels ThreadInterruptedException unterbrochen wird. Durch diese Ausnahme schlägt das Sperren des Synchronisierungsobjektes fehl. In diesem Fall darf dann logischerweise auch kein Monitor.Exit aufgerufen werden. Aus diesem Grund enthält die Monitor.Enter Funktion einen output Parameter welcher angibt ob das Sperren des Synchronisierungsobjektes erfolgreich war.
Das nachfolgende Beispiel zeigt ein entsprechendes Template für die Verwendung der Monitor Funktionen, welches die obigen Punkte umsetzt.
1 static readonly object _locker = new object();
2
3 public void DoSomething()
4 {
5 bool lockTaken = false;
6 try
7 {
8 Monitor.Enter(_locker, ref lockTaken);
9 //do something
10 }
11 finally { if (lockTaken) Monitor.Exit(_locker); }
12 }
Lock vs. Monitor
Wie Sie gesehen haben muss bei der Verwendung von Monitor einiges beachtet werden. Um den Entwicklern dem Umgang mit der Monitor Funktionalität zu erleichtern wurde der lock Befehl eingeführt. Der lock Befehl ist nämlich nichts anderes als syntaktischer Zuckerguss und wird vom Compiler in Monitor Anweisungen umgewandelt.
Die beiden gezeigten Codeausschnitte sind somit identisch. Der erste Codeausschnitt wird vom Compiler in das Monitor Konstrukt umgewandelt welches ich Ihnen im zweiten Code Ausschnitt gezeigt habe.
Fazit
Lock und Monitor haben den gleichen Zweck und die gleiche Funktionalität. Die Verwendung des lock Befehls macht den Quellcode besser lesbar. Darüber hinaus ist lock sicherer, da alle entsprechenden Punkte zur Freigabe des Sperrobjektes automatisch umgesetzt werden. Somit ist der lock Befehl den Monitor Funktionen vorzuziehen.