Verklemmung

Status
Nicht offen für weitere Antworten.
M

Malcolm

Gast
Hallo,

hab da ne Frage zu folgendem Programm. Wird die Methode ueberweisen von mehreren Threads auf dasselbe Objekt angewendet, so kann es zu Verklemmungen kommen. Kann mir einer von euch ein Beispiel für eine Verklemmung in diesem Programm angeben?

Wie kann ich die Methode überweisen so ändern das keine Verklemmungen mehr möglich sind (die ineinander geschachtelten synchronized Blöcke sollen erhalten bleiben)?

Code:
class Konto
{
	private float stand;	

	...

	public void aendern(float betrag)
	{
		stand += betrag;
	}
}


class Bank
{
	...

	public void ueberweisen(int vonKontoNr, int nachKontoNr, float betrag)
	{
		synchronized(konten[vonKontoNr])
		{
			synchronized(konten[nachKontoNr])
			{
				konten[vonKontoNr].ändern(-betrag);
				konten[nachKontoNr].ändern(betrag);
			}
		}
	}	

	...
}
 
M

Malcolm

Gast
Hallo,

bin mir nicht ganz sicher ober das folgende ganz richtig ist.

Folgende Situation kann auftreten

Thread1 hat die Aufgabe 100 Euro vom Konto 1234 zum Konto 1235 zu überweisen. Thread2 hat die Aufgabe 100 Euro vom Konto 1235 zum Konto 1234 zu überweisen. Thread1 sperrt zunächst das Objekt 1234. Es kann nun vorkommen das zwischen den beiden synchronized Blöcken von Thread1 auf Thread2 umgeschaltet wird. Thread2 sperrt nun das Objekt mit der Nummer 1235. Thread2 kann nun den inneren synchronized Block nicht mehr aufrufen da das Objekt 1234 ja noch von Thread1 gesperrt wird. Es wird auf Thread1 umgeschaltet. Thread1 macht an der Stelle weiter wo er vorher aufgehört hat. Er versucht in den inneren synchronized Block zu gelangen. Dies geht nicht da das Objekt 1235 noch von Thread2 gesperrt ist. Beide Threads warten nun das der jeweils andere Thread den entsprechenden synchronized Block freischaltet. Es kommt zur Verklemmung(Deadlock).

Thread1 wartet auf Thread2
Thread2 wartet auf Thread1

Falls das richtig sein sollte wie kann ich denn Fehler beheben und trotzdem die verschachtelten synchronized Blöcke beibehalten.

mfg Malcolm
 

foobar

Top Contributor
Es kann nicht zu einer Deadlock-Situation kommen, da die Synchronized-Blöcke ineinander geschachtelt sind. Dadurch wird beim betreten des äußeren Blocks gewährleistet, daß der innere Synchronized-Block auch vom aktuellen Thread, ohne Unterbrochen zu werden,abgearbeitet werden kann.
Ein Deadlock würde dann enstehen, wenn 2 Threads die Locks auf verschiedene Objekte halten, beide Threads aber auf den Lock des anderen Threads warten.

HTH
 
M

Malcolm

Gast
Hallo,

Zu einer Verklemmung kann es kommen. Da bin ich mir 100% sicher. Es ist ein Unterschied ob ich eine Methode synchronized setze (und damit die Methode für alle anderen Objekte dieser Klasse sperre) oder ob ich einen bestimmten Bereich in einen synchronized Block setze und als Argument ein Objekt einer anderen Klasse übergebe (so wie im Beispiel). Gesperrt werden nur die jeweiligen Konten und nicht die Bank. Ich kann also in den inneren synchronized Block kommen. Somit ist auch eine Verklemmung möglich.

Ich hoffe einer kann mir sagen wie ich die Verklemmung vermeiden kann und trotzdem den verschachtelten synchronized Block beibehalten.

mfg Malcolm
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Oben