In Java besitzt jedes Objekt genau ein Lock5.4. Wenn ein Objekt referenziert wird (Zugriff auf das Objekt selbst, ein Attribut oder eine Methode des Objekts), wird der Lock üblicherweise ignoriert. Nur wenn die Methode auf die zugegriffen wird durch synchronized ausgezeichnet ist, wird der Lock betrachtet. Ist in diesem Fall der Lock von einem anderen Thread bereits gesetzt worden, so wird der aktuelle Thread blockiert und in eine Menge von wartenden Threads eingetragen. Wenn der Lock nicht gesetzt ist, so setzt der aktuelle Thread den Lock und arbeitet die synchronized Methode ab. Beim Verlassen der Methode wird der Lock wieder aufgehoben. Wenn nun die Menge der wartenden Threads nicht leer ist, so wird ein zufälliger Thread bestimmt, der dann den Lock setzt und in den rechenbereiten Zustand überführt wird.
Betrachten wir im Folgenden das Erzeuger-Verbraucher-Problem implementiert in Java.
Zunächst die Klasse BoundedBuffer, die den Speicher
(Buffer) mit ihren Methoden enter_item und remove_item
(Abbildung
).
Am Ende der beiden Methoden wird jeweils die Methode notify aufgerufen. Auch diese Methode hat die Klasse BoundedBuffer von der Klasse Object geerbt. Die Methode notify hat folgende Eigenschaften:
Die Klasse Producer (Abbildung
) ist für die
Produktion der Speichereinträge verantwortlich.
Die Klasse Consumer (Abbildung
) ist das Gegenstück
zu Consumer und funktioniert analog.
Bleibt noch eine Klasse, die die Erzeuger-Verbraucher-Implementierung
steuert: BufferServer (Abbildung
).