Locking order

Generic1

Top Contributor
Hallo,

ich lese gerade das Buch "Java Concurrency" und in diesem steht drinnen, dass auf die locking order geachtet werden muss. Das ist mir jetzt nicht ganz klar -> wenn ich zwei Threads habe, die auf die gleiche Ressource zugreifen, dann sollen diese 2 Threads in der gleichen Reihenfolge auf die Ressource zugreifen:

Java:
public class Ressource {

     public void methodInRessource1() {
         }

     public void methodInRessource2() {
         }

}


Das würde also im oberen Code heißen, dass von den Threads immer zuerst "methodInRessource1" aufgerufen werden soll und dann erst methodInRessource2.
Kann man das so sagen und wie kann man das sicherstellen?
lg
 

Sued_Faust

Bekanntes Mitglied
Naja also sagen wir du hast eine Variable x,y und z und du rechnest mit der einem Thread eine Addition und mit dem anderen eine Multiplikation.

x = 2;
y = 3;

Threa 1:
Java:
x+y = z;

Thread 2:
Java:
x*y=z;

Auserhalb der Threads:
Java:
System.out.print(z);

So nun ist es bei Asynchronen Threads so das du zwei verschiene Ausgaben haben kannst.

5 und 6
oder,
6 und 5

um dies zu vermeiden, musst du die Threads Synchronisieren (lock()).
 

ice-breaker

Top Contributor
was jedoch absolut an dem vorbei war, was er gefragt hat, hast du überhaupt seine Frage gelesen? ......


In dem Buch Java Concurrency in Practice steht irgendwo folgendes Beispiel (habe vergessen wo):
Stell dir vor du hast 2 Konten (A und B). A möchte Geld an B überweisen, und B an A, beides passiert gleichzeitig.
Für die erste Transaktion würde also ein Thread einen Lock auf A setzen, für die 2 Transaktion würde zeitgleich ein Lock auf B gesetzt werden, jetzt haben wir aber das Problem, dass die erste Transaktionen einen Lock auf B möchte und die zweite einen auf A - ein Deadlock tritt auf.

Bei der Lock-Order geht es darum Locks so zu bekommen, dass sie immer in der gleichen Reihenfolge auftreten, da A und B eine Kontonummer haben, kann man z.B. eine natürliche Ordnung herstellen, beide Threads müssten erst A und dann B locken, da A eine kleinere Kontonummer hat als B, dadurch sind Deadlocks ausgeschlossen.

Mit verschiedenen Methoden einer Klasse hat das eher wenig zu tun.
 

Generic1

Top Contributor
was jedoch absolut an dem vorbei war, was er gefragt hat, hast du überhaupt seine Frage gelesen? ......


In dem Buch Java Concurrency in Practice steht irgendwo folgendes Beispiel (habe vergessen wo):
Stell dir vor du hast 2 Konten (A und B). A möchte Geld an B überweisen, und B an A, beides passiert gleichzeitig.
Für die erste Transaktion würde also ein Thread einen Lock auf A setzen, für die 2 Transaktion würde zeitgleich ein Lock auf B gesetzt werden, jetzt haben wir aber das Problem, dass die erste Transaktionen einen Lock auf B möchte und die zweite einen auf A - ein Deadlock tritt auf.

Bei der Lock-Order geht es darum Locks so zu bekommen, dass sie immer in der gleichen Reihenfolge auftreten, da A und B eine Kontonummer haben, kann man z.B. eine natürliche Ordnung herstellen, beide Threads müssten erst A und dann B locken, da A eine kleinere Kontonummer hat als B, dadurch sind Deadlocks ausgeschlossen.

Mit verschiedenen Methoden einer Klasse hat das eher wenig zu tun.

Ja, genau das meinte ich, wie kann ich das aber jetzt machen, dass zuerst immer der lock für A und dann für B gelockt wird? Gibt es da bestimmte Methoden oder muss ich da im Code irgendwie schaun dass das gegeben ist?
lg
 

ice-breaker

Top Contributor
Das musst du implementieren:
Wenn ein Lock irgendwo benötigt wird, musst du dies so implementieren, dass dies eben immer in der richtigen Order passiert.
 

ice-breaker

Top Contributor
Hab ich doch bereits beschrieben, du vergleichst die Kontonummern welche kleiner ist ???:L

Ansonsten findest du ein Beispiel auch in dem von dir genannten Buch (ich frage mich deswegen sowieso, warum du die Frage stellst):
Kapitel: 10.1.1 Lock-ordering deadlocks
Seite: 206 - 210
 

Sued_Faust

Bekanntes Mitglied
Naja ich denk ma er stellt die Frage, weil es das Beispiel aus dem Buch nicht ganz nachvollziehen konnte. Da hilft es ihm auch nicht viel wenn du ihm das selbe Beispiel übersetzt.
 

ice-breaker

Top Contributor
Das Beispiel ist eben richtig gut und noch mehr erklärt, als ich es habe, deswegen ist es mir unverständlich, was man daran nicht verstehen kann.
 

mvitz

Top Contributor
Wenn du für dein obiges Beispiel sicherstellen möchtest, dass immer zuerst methode1 und dann erst methode2 aufgerufen wird, dann kannst du nur einen Wrapper bauen, der genau das tut. Sicherstellen, dass jeder Client der Klasse das macht, kannst du programatisch nicht, höchstens per API Kommentar oder indem du in Methode 2 prüfst ob Methode 1 schon aufgerufen wurde und wenn nicht eine Exception wirfst.
 

Ähnliche Java Themen

Neue Themen


Oben