Hallo allerseits!
Wir starten den siebten Stream des
Java Developer- Kurses. In mehr als einem Jahr des Bestehens dieses Kurses wurde er verfeinert, verfeinert und ein neuer hinzugefügt, der über diese Zeit hinausging. Der gleiche Strom unterscheidet sich vom Rest dadurch, dass wir ein neues System von Schritten eingeführt haben, das den Kurs in drei Teile aufteilt und seine Gesamtdauer leicht erhöht. Jetzt muss man nicht mehr fünf Monate hintereinander erschöpft sein, um ein Zertifikat zu erhalten, sondern in Ruhe zwei Monate wählen und sich einer Schulung unterziehen. Aber dies sind die Texte. Kehren wir zu unserer Tradition über die verschiedenen Dienstprogramme vor dem Start des Kurses zurück.
Lass uns gehen.
1. Übersicht
Der Java-Servlet-Container (oder Webserver) ist multithreaded: Es können mehrere Anforderungen an dasselbe Servlet gleichzeitig ausgeführt werden. Daher müssen Sie beim Schreiben eines Servlets den Wettbewerb berücksichtigen.
Wie bereits erwähnt, wird nur eine Servlet-Instanz erstellt, und für jede neue Anforderung erstellt der Servlet-Container einen neuen Thread, um die Methoden doGet () oder doPost () des Servlets auszuführen.
Standardmäßig sind Servlets nicht threadsicher, der Programmierer muss sich selbst darum kümmern. In diesem Kapitel werden wir den Servlet-Wettbewerb diskutieren. Dies ist ein sehr wichtiges Konzept, also konzentrieren Sie sich.
2. Übersicht der Threads

Ein Thread ist ein einfacher Prozess, der über einen eigenen Aufrufstapel verfügt und auf die offenen Daten anderer Threads im selben Prozess zugreift (gemeinsam genutzter Heap). Jeder Thread hat seinen eigenen Cache.
Wenn wir sagen, dass ein Programm Multithreading ist, meinen wir, dass dieselbe Instanz eines Objekts mehrere Threads generiert und ein einzelnes Codeelement verarbeitet. Dies bedeutet, dass mehrere aufeinanderfolgende Steuerflüsse denselben Speicherblock durchlaufen. Daher führen mehrere Threads eine Instanz eines Programms aus und teilen daher Instanzvariablen und können versuchen, diese gemeinsam genutzten Variablen zu lesen und zu schreiben.
Schauen wir uns ein einfaches Java-Beispiel an.
public class Counter { int counter=10; public void doSomething() { System.out.println(“Inital Counter = ” + counter); counter ++; System.out.println(“Post Increment Counter = ” + counter); } }
Jetzt erstellen wir zwei Threads Thread1 und Thread2, um
doSomething()
auszuführen. Infolgedessen ist es möglich, dass:
- Thread1 liest einen Zählerwert von 10
- Zeigt den Anfangszähler = 10 an und wird erhöht
- Bevor Thread1 den Zähler erhöht, erhöht Thread2 auch den Zähler und ändert den Zähler auf 11
- Infolgedessen hat Thread1 einen Zählerwert von 10, der bereits veraltet ist
Dieses Szenario ist in einer Umgebung mit mehreren Threads wie Servlets möglich, da Instanzvariablen von allen Threads gemeinsam genutzt werden, die in derselben Instanz ausgeführt werden.
3. Thread-sichere Servlets schreiben
Ich hoffe, dass Sie in diesem Abschnitt die Probleme verstehen, die ich hervorheben möchte. Wenn Sie irgendwelche Zweifel haben, lesen Sie Punkt 2 noch einmal.
Es gibt einige Punkte, die wir beim Schreiben von Servlets berücksichtigen müssen.
Service()
, doGet()
, doPost()
oder allgemeiner die Methoden doXXX()
sollten doXXX()
nicht aktualisieren oder ändern, da Instanzvariablen von allen Threads derselben Instanz gemeinsam genutzt werden.- Wenn die Instanzvariable geändert werden muss, führen Sie dies in einem synchronisierten Block durch.
- Beide oben genannten Regeln gelten auch für statische Variablen, da sie ebenfalls häufig vorkommen.
- Lokale Variablen sind immer threadsicher.
- Die Anforderungs- und Antwortobjekte sind für die Verwendung threadsicher, da für jede Anforderung in Ihrem Servlet und daher für jeden in Ihrem Servlet ausgeführten Thread eine neue Instanz erstellt wird.
Das Folgende sind zwei Ansätze zur Gewährleistung der Gewindesicherheit:
a) Synchronisieren Sie den Block, in dem Sie die Instanz oder statische Variablen ändern (siehe den folgenden Codeausschnitt).
Wir empfehlen, dass Sie den Block synchronisieren, in dem Ihr Code die Instanzvariablen ändert, anstatt die vollständige Methode zu synchronisieren, um die Leistung zu verbessern.
Beachten Sie, dass wir die Servlet-Instanz sperren müssen, um den spezifischen Thread der Servlet-Instanz sicher zu machen.
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class ThreadSafeServlet extends HttpServlet { @override public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException int counter; { synchronized (this) {
b) Single-Thread-Modell - Implementieren Sie die SingleThreadModel-Schnittstelle, um den Thread Single-Threaded zu machen. Dies bedeutet, dass jeweils nur ein Thread die Methode service () oder doXXX () ausführt. Ein Single-Threaded-Servlet ist unter Last langsamer, da neue Anforderungen auf die Verarbeitung einer freien Instanz warten müssen
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class ThreadSafeServlet extends HttpServlet implements SingleThreadModel { int counter;
Die Verwendung von SingleThreadModel ist veraltet, da empfohlen wird, synchronisierte Blöcke zu verwenden.
4. Fazit
Wir müssen beim Schreiben von Servlets sehr vorsichtig sein, da "Servlets standardmäßig nicht threadsicher sind"
- Wenn Ihr Servlet keine statische Variable oder Mitgliedsvariable hat, brauchen Sie sich keine Sorgen zu machen, und Ihr Servlet ist threadsicher
- Wenn Ihr Servlet nur die Instanzvariable liest, ist Ihr Servlet threadsicher.
- Wenn Sie eine Instanz oder statische Variablen ändern müssen, aktualisieren Sie sie in einem synchronisierten Block, wobei die Instanz gesperrt bleibt
Wenn Sie die oben genannten Regeln befolgen und das nächste Mal jemand Sie fragt: "Ist der Servlet-Thread sicher?" - Antworten Sie sicher: "Standardmäßig sind sie nicht, aber" Meine Servlets "sind threadsicher."
DAS ENDE
Wie immer warten wir hier auf Ihre Fragen, Vorschläge usw. oder Sie können Sergey Petrelevich bei der
Open-Lektion zum Thema Multithreading fragen.