Was passiert in Java, wenn zwei Klassen gleichzeitig eine Methode in einer dritten Klasse aufrufen?
-
27-10-2019 - |
Frage
In meinem Projekt habe ich eine Spielklasse, die von einer Client-Klasse aufgerufen wird.Im Moment schreibt die Spielklasse einen Pfad zu einer Datei und die Client-Klasse liest aus dieser Datei und löscht den Inhalt.Ich habe hier zu viele Konflikte mit dem Zugriff, daher möchte ich eine andere Klasse als Methode zum Speichern der Pfaddaten verwenden.Ich möchte jedoch wissen, ob es immer noch ein Problem gibt oder wie das Ergebnis aussehen wird, wenn die Spielklasse versucht, die Methode in der Speicherklasse zum Schreiben aufzurufen, während die Client-Klasse gleichzeitig die Methode im Speicher aufruftKlasse zum Lesen und Löschen.
Lösung
Klingt so, als müssten Sie über Threading und Synchronisation nachdenken.Ich würde empfehlen, "Java Concurrency in Practice" zu lesen.
Andere Tipps
Bei Vorhandensein mehrerer Threads müssen Ihre Klassen threadsicher sein.Eine Möglichkeit, dies zu erreichen, besteht darin, die Methoden, auf die gleichzeitig zugegriffen wird, synchronized
zu machen.
Hier ist ein Beispiel für den Einstieg:
public class Test {
public static void main(String[] args) throws Exception {
new Thread() { public void run() { Test.method(); }}.start();
new Thread() { public void run() { Test.method(); }}.start();
}
public synchronized static void method() {
System.out.println("hello ");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
System.out.println("world");
}
}
Ohne den synchronized
-Modifikator hätte dieses Programm gedruckt
hello
hello
world
world
Mit dem Schlüsselwort synchronized
kann jeweils nur ein Thread method
aufrufen, sodass das Programm druckt
hello
world
hello
world
Ich gehe davon aus, dass Ihre beiden Klassen in separaten Threads ausgeführt werden, sodass sie möglicherweise gleichzeitig auf die dritte Klasse zugreifen.Der Zugriff auf die Ressource, die sie lesen und schreiben, muss synchronisiert (mutexiert) werden.Java hat das Schlüsselwort "synchronisiert", das auf verschiedene Arten verwendet werden kann, um gleichzeitige Änderungen zu verhindern. Siehe hier und hier für Details
Die theoretisch korrekte Antwort lautet: "Alles kann passieren".
Die beiden Aufrufe können nacheinander ausgeführt oder miteinander verschachtelt werden. Die Ergebnisse sind unvorhersehbar und möglicherweise katastrophal.
Deshalb bietet Ihnen Java verschiedene Möglichkeiten, damit umzugehen.
-
Der einfachste (klingende) Weg besteht darin, Ihre Methoden threadsicher zu schreiben. In der Praxis bedeutet dies normalerweise, dass Sie nur lokale Variablen verwenden sollten und die Objekte, die Ihnen als Parameter übergeben werden, nicht ändern dürfen. (Keine Nebenwirkungen.) Viele Methoden fallen automatisch in diese Kategorie. In diesem Fall müssen Sie sich keine Gedanken über die Parallelität machen.
-
Wenn Ihre Methode nicht threadsicher gemacht werden kann, müssen Sie gleichzeitige Aufrufe irgendwie verarbeiten.
synchronized
-Blöcke sind die am häufigsten verwendeten Konstrukte, aber in einigen Fällen reicht einvolatile
-Feld oder die Verwendung vonAtomic*
-Klassen aus. Dieses Thema ist jedoch viel zu schwer, um in einer einzigen Antwort behandelt zu werden. Ich empfehle daher, das Parallelitäts-Tutorial .