2. Synchronisation
d. Monitore
Das Konzept des Monitors wurde von C.A. Hoare und
P.B. Hansen 1974 eingeführt, es ist ebenfalls ein Konstrukt für die
Synchronisierung von nebenläufigen Prozessen.
Monitore sind hochsprachlich zu implementierende Algorithmen, die eine Erweiterung
der Semaphore darstellen. Hier werden die gemeinsame Variable, sowie die Prozeduren,
die auf diese zugreifen dürfen, in dem Monitor gekapselt, von anderen Prozeduren
darf also nicht auf diese Variable zugegriffen werden. Nur ein Prozess zurzeit
darf auf den Monitor zugreifen, somit ist das Konzept des gegenseitigen Ausschlusses
hier realisiert. Die Kapselung der zugehörigen Prozeduren erinnert stark
an das Konzept der objekt-orientierten Programmierung, auch bei den Monitoren
werden die Strukturierung und Lesbarkeit der Programme als ein Vorteil erachtet.
Bei einem Monitor wird der gegenseitige Ausschluss auf Compilerebene realisiert,
eine explizite Programmierung ist nicht notwendig. Allerdings muss ein Monitor
Bedingungsvariablen, sowie die Prozeduren suspend und continue
einbinden. Diese Prozeduren dienen zum Hinzufügen der Prozesse, die den
Monitor betreten wollen in eine Warteschlange, und zum Fortführen des Prozesses,
sobald die Bedingungsvariable erfüllt ist.
Monitore in Java
Java unterstützt das Konzept des Monitors auf zwei Arten. So bietet es die Möglichkeit, ganze Methoden mit dem Schlüsselwort „synchronized“ zu kennzeichnen. Dadurch wird der Zugriff auf diese Methode nur einem Thread gestattet. Eine elegantere Möglichkeit ist das Sperren einzelner Objekte (Syntax: synchronized (Object o) ), bei der möglicherweise die Dauer, für die ein Prozess in seinem kritischen Abschnitt ist minimiert wird im Gegensatz zum ersten Ansatz.
Die oben angesprochenen Operationen suspend() und continue() werden in Java durch die Methoden wait() und notify(), bzw. notifyAll() repräsentiert. Um Methoden nebenläufig ausführen zu lassen, muss entweder die Klasse „Thread“ erweitert oder die Schnittstelle „Runnable“ implementiert werden. Jeweils wird eine Methode run() zur Verfügung gestellt, in der die parallel zu verarbeitenden Programmzeilen eingefügt werden. Eine Semaphor-Implementation würde also wie folgt in Java aussehen:
public class Semaphore { private int cnt = 1; public Semaphore( int cnt ) { if ( cnt > 1 ) // nur Zähler größer 1 akzeptieren this.cnt = cnt; } public synchronized void enter() // P { while ( cnt <= 0 ) try { wait(); } catch( InterruptedException e ) {} cnt--; } public synchronized void leave() // V { cnt++; notify(); } } |