Mehrere Threads aufrufen statische Hilfsmethode
Ich habe eine web-Anwendung auf Tomcat.
Es gibt verschiedene Berechnungen, die getan werden müssen, die auf mehrere Orte in der web-Anwendung. Kann ich die Berechnungen statische helper-Funktionen? Wenn der server über genügend Prozessorkerne können mehrere Anrufe an, die statische Funktion (eine Folge von mehrfachen Anfragen an verschiedene servlets) laufen parallel? Oder ist eine Aufforderung zu warten, bis der andere Anfrage beendet den Anruf?
public class Helper {
public static void doSomething(int arg1, int arg2) {
//do something with the args
return val;
}
}
wenn die Aufrufe parallel laufen:
Ich habe noch eine helper-Klasse mit statischen Funktionen, sondern beinhaltet die Klasse eine private statische member, die in der statischen Funktionen. Wie kann ich sicherstellen, dass das Funktionen sind thread-sicher?
public class Helper {
private static SomeObject obj;
public static void changeMember() {
Helper.obj.changeValue();
}
public static String readMember() {
Helper.obj.readValue();
}
}
changeValue()
und readValue()
Lesen/ändern Sie die gleichen member-variable des Helper.obj
. Muss ich, um die ganze statische Funktionen synchronisiert werden, oder nur der block, wo Helper.obj
verwendet wird? Wenn ich sollte ein block, was für ein Objekt soll ich verwenden, um es zu sperren?
- ich danke Ihnen allen, dass Sie definitiv meine Frage beantwortet und außerdem gab mir Denkanstöße. ich kann leider nicht akzeptieren mehrere Antworten :-/
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ja, und ja.
Dass es funktionieren wird.
Wird auch funktionieren.
Verwenden
static Object
:Ideal, wenn Sie schreiben würden die Helfer Klasse unveränderlich (stateless oder anderweitig), so dass Sie nur don ' T haben sorgen um die thread-Sicherheit.
HttpServletRequest#getSession()
?synchronize
auf, Nein?Sollten Sie erfassen die Berechnungen in einer Klasse, und erstellen Sie eine Instanz der Klasse für jeden thread. Was du jetzt hast, ist nicht threadsicher sind, wie Sie wissen, und machen es threadsicher Sie synchronisieren müssen, auf die statische Ressource/die Methoden, die Zugriff auf das statische Ressource, die zu Blockierungen führen.
Beachten Sie, dass es Muster gibt, um Ihnen zu helfen mit diesem. Können Sie das Strategie-Muster (in seiner kanonischen form, die Strategie muss gewählt werden, zur Laufzeit, die möglicherweise oder möglicherweise nicht für hier) oder eine Variante. Erstellen Sie einfach eine Klasse für jede Berechnung mit einer execute-Methode (und einer Schnittstelle, die die Methode), und übergeben Sie ein Kontext-Objekt ausführen. Der Rahmen hält alle die den Zustand der Berechnung. Eine Strategie Instanz pro thread, mit seinem Kontext, und Sie sollten keine Probleme haben.
static
oder nicht-statisch) dann bist du gut.Wenn Sie nicht haben, zu teilen, können Sie machen es zu lokalen thread, dann ist es nicht thread-sicher.
Werde ich zusammenfassen, was gesagt wurde in den Kommentaren zu den Matt Ball ist Antwort, da es ziemlich lange am Ende und die Nachricht verloren: und die Nachricht war
in einer gemeinsamen Umgebung, die wie ein web - /application-server sollten Sie sehr hart versuchen, eine Lösung zu finden, ohne zu synchronisieren. Die Verwendung von statischen Helfer synchronisiert auf statisches Objekt funktioniert möglicherweise gut genug für die stand-alone-Anwendung mit einem Benutzer vor dem Bildschirm, in einem multiuser/multiapplication-Szenario, dies zu tun würde den meisten wahrscheinlich am Ende in eine sehr schlechte Leistung - es würde effektiv bedeuten, Serialisierung Zugriff auf Ihre Anwendung, die alle Benutzer warten müsste auf die gleiche Sperre. Sie vielleicht nicht bemerken das problem für eine lange Zeit: wenn die Berechnung schnell genug sind und die Last ist gleichmäßig verteilt.
Aber dann plötzlich alle Ihre Benutzer könnten versuchen, gehen durch die Berechnung um 9 Uhr und Sie die app aufhören zu arbeiten! Ich meine nicht wirklich aufhören, aber Sie würden alle block auf das Schloss und machen eine riesige Schlange.
Nun unabhängig von der Notwendigkeit einer gemeinsamen Staat, da Sie ursprünglich benannt Berechnungen als Thema Synchronisation: Ihre Ergebnisse müssen freigegeben werden? Oder sind die Berechnungen, die spezifisch für einen Benutzer/session? In diesem Fall ist mit einer ThreadLocal-pro Peter Lawrey genug sein würde. Ansonsten würde ich sagen, dass für die Gesamt-performance besser wäre es, zu duplizieren die Berechnungen für alle benötigen Sie, um die Synchronisierung nicht (hängt von den Kosten).
Session-management sollte auch besser Links um den container: es wurde optimiert, um mit Ihnen umzugehen effizient, wenn notwendig, auch clustering etc. Ich bezweifle, dass man eine bessere Lösung, ohne investieren viel Arbeit und macht viele Fehler auf dem Weg dorthin. Aber wie Matt Ball hat erklärt, es sollte besser gefragt getrennt.
Wenn Sie besorgt über die Synchronisierung und thread-Sicherheit, verwenden Sie nicht statisch Helfer. Erstellen Sie eine normale Klasse mit Ihrem Helfer-Methoden und erstellen Sie eine Instanz auf servlet-Anfrage. Keep it simple 🙂
Im ersten Fall brauchen Sie nicht zu befürchten, threading Probleme, weil die Variablen sind lokal für jeden thread. Sie korrekt zu identifizieren, das problem im zweiten Fall aber, da mehrere threads Lesen und schreiben, die das gleiche Objekt. Synchronisieren auf die Methoden der Arbeit, als würde synchronisierte Blöcke.
Für den ersten Teil:
Ja, diese Anrufe sind unabhängig und parallel ausgeführt, wenn Sie aufgerufen, die von verschiedenen threads.
Für den letzten Teil:
Verwenden synchronisieren von Blöcken, die auf der gleichzeitigen Objekt, ein dummy-Objekt oder Objekt-Klasse. Sich bewusst sein, der kaskadierten Blöcke synchronisieren. Sie führen in dead locks beim Erwerb in einer anderen Reihenfolge.