Wenn ein Prozess in den blockierten Zustand überführt wurde und niemals wieder in den rechenbereiten Zustand kommt, so spricht man von einem Deadlock. Ein Prozess wird in einen blockierten Zustand überführt, wenn er eine Ressource (Speicher, I/O, kritische Ressource, ...) anfordert und diese im Moment nicht zur Verfügung steht. D.h. ein Deadlock ist erreicht, wenn die Ressource nie mehr zur Verfügung steht.
Betrachten wir zunächst ein Beispiel. In Abbbildung
auf
Seite
sind die Threads threadA und threadB gegeben. Beide erhalten
als geteilten Speicher die Objekte m1 (first) und m2
(second) der Klasse
Mutex. Während threadA in der Methode run zunächst
m1 (first) als kritische Ressource lockt und so für den
Zugriff anderer Threads gesperrt, lockt der Thread threadA zunächst
m2 (second). Jeweils im
zweiten Teil der run-Methoden wollen die beiden Threads auf die
jeweils andere kritische Ressource zugreifen ohne die von ihnen gelockte kritische
Ressource wieder freizugeben. Wenn der Scheduler es ermöglicht hat, dass die Schleife
des Threads threadA einmal unterbrochen wurde und threadB
m2 (second) locken konnte, so kommt es nach Beendigung der Schleife zu einem
Deadlock: threadA will auf m2 (second) zugreifen,
das von threadB gelockt ist und andersherum will threadB
auf m1 (first) zugreifen, das von threadA gelockt
ist. Es blockieren sich also beide Threads gegenseitig. Es ergibt sich ein Deadlock.