Heute werden wir lernen, wie man im Frühling asynchrone Programme durchführt. Wir alle wissen, dass die Threads, die der Webserver verarbeitet, request Anforderungen an den Thread -Pool erhalten, was nicht schwer zu erklären ist, da die Anzahl der Webanforderungen sehr groß ist, wie ein Verarbeitungs -Thread erstellt wird, wenn eine Anforderung eingeht. Da der Overhead des Erstellens von Threads und Thread -Kontext -Umschaltungen relativ groß ist, wird der Webserver schließlich zu einem Absturz stehen. Darüber hinaus werden die vom Webserver erstellten Verarbeitungs -Threads von Anfang bis Ende standardmäßig synchron ausgeführt. Wenn die Bearbeitung von Thread A für die Verarbeitung von Anforderungen B verantwortlich ist, kann die Verarbeitung von Thread A, wenn B nicht return , nicht entkommen, um andere Anforderungen zu verarbeiten, was die gleichzeitige Verarbeitungsfunktion des Webservers stark einschränkt.
Daher löst der Thread -Pool das Problem des Thread -Recyclings. Die Antwort ist die asynchrone Verarbeitung. Was ist eine asynchrone Verarbeitung? Durch die asynchrone Verarbeitung kann die obige B -Anfrage hauptsächlich im Leerlauf sein, bevor die obige Anfrageverarbeitung abgeschlossen ist, und Thread A kann befreit werden, um weitere Anfragen fortzusetzen. Anschließend können wir dies tun, Thread C in Thread A neu starten, um die Aufgabe auszuführen, eine direkte zum Webserver zurückzugeben und weiterhin neue Anforderungen zu akzeptieren.
Bevor ich die folgende Erklärung beginne, werde ich hier zunächst zwei Konzepte unterscheiden:
1. Verarbeitungsthreads
Der Verarbeitungs -Thread gehört zum Webserver, ist für die Verarbeitung von Benutzeranforderungen verantwortlich und wird vom Thread -Pool verwaltet
2. Asynchrones Fäden
Asynchrone Threads sind benutzerdefinierte Threads und können von Thread-Pools verwaltet werden.
Die Frühling unterstützt asynchrone Aufgaben. Asynchrone Aufgaben können mit WebAsyncTask -Klasse implementiert werden. Gleichzeitig können wir auch die entsprechende Rückrufverarbeitung für asynchrone Aufgaben festlegen, z. Asynchrone Aufgaben sind normalerweise sehr praktisch. Zum Beispiel möchten wir eine Operation überlassen, die für den asynchronen Thread für eine lange Zeit verarbeitet werden kann, oder wenn eine Bestellung bezahlt wird, ermöglichen wir der asynchronen Aufgabe, das Zahlungsergebnis der Bestellung abzufragen.
1. Normale asynchrone Aufgaben
Zur Demonstrationsbequemlichkeit wird die Ausführung asynchroner Aufgaben unter Verwendung von Thread.sleep(long) simuliert. Nehmen Sie nun an, dass der Benutzer die folgende Schnittstelle anfordert:
http://localhost:7000/demo/getUserWithNoThing.json
Die asynchrone Task -Schnittstelle ist wie folgt definiert:
/*** Testen Sie asynchrone Aufgaben ohne Ausnahme*/@requestMapping (value = "getUserWithnothing.json", method = requestMethod.get) public Webasynctask <string> getUserWithnothing () {// PROCUTION Thread System.ERR.Println ("Der Hauptname des Threads. // Dies simuliert eine asynchrone Aufgabe mit einem Zeitlimit von 10S Webasynctask <string> task1 = Neues Webasynctask <string> (10 * 1000L, () -> {System.err.println ("Der erste Threadname ist" + Thread.Current Thread (). "Aufgabe 1 führt erfolgreich aus! Es wird keine Ausnahme geworfen!"; // Die Methode wird aufgerufen, wenn die Aufgabenausführung abgeschlossen ist. System.err.println ("Task1 geht weiterhin mit anderen Dingen um!"); return task1;}Die Konsole druckt wie folgt:
Der Haupt-Thread-Name ist HTTP-NIO-7000-EXEC-1
Task1 geht weiter mit anderen Dingen zu!
Der erste Threadname ist MVCASYNC1
Aufgabe 1 wurde abgeschlossen!
Die Browserergebnisse sind wie folgt:
2. Übereinstimmung der Ausnahme asynchrone Aufgabe
Schnittstellenanruf: http://localhost:7000/demo/getUserWithError.json
/*** Testen Sie die asynchrone Aufgabe, bei der ein Fehler auftritt Asynchrone Aufgabe. Webasynctask <string> task3 = new Webasynctask <string> (10 * 1000L, () -> {System.err.println ("Der zweite Thread -Name ist" + thread.currentThread (). -> {System.err.println("==================================================================================== ==========================================================ieben ==========================================================ieben ==================================================================ieben "================================================================== ====================================================================== ====================================================================== ====================================================================== ====================================================================== ====================================================================== ====================================================================== ======================================================================Die Konsolenausgabe ist wie folgt:
Der Haupt-Thread-Name ist HTTP-NIO-7000-EXEC-1
Task3 befasst sich weiterhin mit anderen Dingen!
Der zweite Threadname ist mvcasync1
2018-06-15 09: 40: 13.538 Fehler 9168 --- [NIO-7000-EXEC-2] OACCC [. [. [.java.lang.arithmeMexception: / nach Null
unter com.example.demo.controller.getUserinfocontroller.lambda $ 5 (GetUserinfocontroller.java:93) ~ [Klassen/: Na]
unter org.springframework.web.context.request.async.webasyncManager.lambda $ startcallableprocessing $ 4 (WebAsyncManager.java:317) ~ [Spring-Web-5.0.6.Relase.jar: 5.0.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.
bei java.util.concurrent.executors $ runnableadapter.call (Executors.java:511) ~ [NA: 1.8.0_161]
bei java.util.concurrent.futuretask.run (futuretask.java:266) ~ [NA: 1.8.0_161]
bei java.lang.thread.run (thread.java:748) [NA: 1.8.0_161]2018-06-15 09: 40: 13.539 Fehler 9168 --- [NIO-7000-EXEC-2] OACCC [. [. [. Eine verschachtelte Ausnahme ist Java.lang.arithmeTexception: / bis Null] mit der Grundursache
java.lang.arithmeMexception: / nach Null
unter com.example.demo.controller.getUserinfocontroller.lambda $ 5 (GetUserinfocontroller.java:93) ~ [Klassen/: Na]
unter org.springframework.web.context.request.async.webasyncManager.lambda $ startcallableprocessing $ 4 (WebAsyncManager.java:317) ~ [Spring-Web-5.0.6.Relase.jar: 5.0.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.
bei java.util.concurrent.executors $ runnableadapter.call (Executors.java:511) ~ [NA: 1.8.0_161]
bei java.util.concurrent.futuretask.run (futuretask.java:266) ~ [NA: 1.8.0_161]
bei java.lang.thread.run (thread.java:748) [NA: 1.8.0_161]==================================================================================ieben
Mission 3 ist aufgetreten!
Aufgabe 3 wurde abgeschlossen!
Natürlich können Sie auch eine Ausnahmebehandlung des oben genannten machen, um die Meinung des Benutzers unfreundlich zu vermeiden. Für die Ausnahmebehandlung können Sie einen anderen Artikel in meinem Artikel über die Verwendung von Spring Boot/Spring Unified Fehlerbehandlungsschema lesen
Browserausgangsergebnisse:
3. Timeout Asynchrone Aufgabe
Schnittstellenanruf: http://localhost:7000/demo/getUserWithTimeOut.json
/*** Testen Sie die asynchrone Aufgabe, in der die Aufgabe zeitlich ausgeführt wurde // Dies wird simuliert, um eine asynchrone Aufgabe zu starten, Zeitüberschreitung von 10S Webasynctask <string> task2 = New Webasynctask <string> (10 * 1000L, () -> {System.err.println ("Der zweite Threadname ist" + Thread.Current thead (). // Task Timeout ruft diese Methode auf Task2.ontimeout (() -> { System.err.println("===================================================================================== ==================================================================ieben ==================================================================ieben ==================================================================ieben "================================================================== ====================================================================== ====================================================================== ====================================================================== ====================================================================== ====================================================================== ====================================================================== ======================================================================Konsolenausführungsergebnisse:
Der Haupt-Thread-Name ist HTTP-NIO-7000-EXEC-4
Task2 befasst sich weiterhin mit anderen Dingen!
Der zweite Threadname ist mvcasync2
===========================================================================================================ieben
Aufgabe 2 wurde abgeschlossen!
Browserausführungsergebnisse:
4. Fadenpool asynchrone Aufgaben
Die asynchronen Aufgaben in den oben genannten drei Fällen werden standardmäßig nicht vom Thread -Pool -Mechanismus verwaltet. Das heißt, wenn eine Anfrage eingeht, obwohl der Verarbeitungs -Thread veröffentlicht wird, erstellt das System weiterhin einen asynchronen Task -Thread für jede Anforderung, nämlich der asynchrone Task -Thread, beginnend mit MvcAsync , wie wir oben gesehen haben. Das heißt, das wird nicht funktionieren, der Overhead ist besonders hoch! Daher können wir den Thread -Pool für die Verwaltung verwenden und eine ThreadPoolTaskExecutor -Objektinstanz im WebAsyncTask -Klassenkonstruktor direkt übergeben.
Schauen wir uns zunächst an, was passiert, wenn Sie im ersten Fall gleichzeitige Anforderungen im obigen Fall durchführen (hier simulieren wir gleichzeitige Anrufe an http://localhost:7000/demo/getUserWithNoThing.json ):
Die Konsolenausgabe ist wie folgt:
Der erste Threadname ist mvcasync57
Der erste Threadname ist mvcasync58
Der erste Threadname ist mvcasync59
Der erste Threadname ist mvcasync60
Der erste Threadname ist mvcasync61
Der erste Threadname ist mvcasync62
Der erste Threadname ist mvcasync63
Der erste Threadname ist mvcasync64
Der erste Threadname ist mvcasync65
Der erste Threadname ist mvcasync66
Der erste Threadname ist mvcasync67
Der erste Threadname ist mvcasync68
Der erste Threadname ist mvcasync69
Der erste Threadname ist mvcasync70
Der erste Threadname ist mvcasync71
Der erste Threadname ist mvcasync72
Der erste Threadname ist mvcasync73
Der erste Threadname ist mvcasync74
Der erste Threadname ist mvcasync76
Der erste Threadname ist mvcasync75
Der erste Threadname ist mvcasync77
Der erste Threadname ist mvcasync78
Der erste Threadname ist mvcasync79
Der erste Threadname ist mvcasync80
Da der Thread -Pool nicht hinzugefügt wird, öffnen 100 Anfragen 100 asynchrone Aufgaben -Threads, was besonders teuer ist und nicht empfohlen wird.
Das Folgende ist die Implementierung des Threadpools:
Rufschnittstelle: http://localhost:7000/demo/getUserWithExecutor.json
/*** Testen von Thread Pool* @return*/ @requestMapPing (value = "getUserWithexecutor.json", method = requestMethod.get) public webasynctask <string> getUserWitHexeCutor () {System.err.println ("Der Haupt -Thread -Name" + Thread.Current thread (). // Dies wird simuliert, um eine asynchrone Aufgabe zu starten, und hier wird ein Thread -Pool übergeben. WebAsynctask <string> Task1 = Neue Webasynctask <string> (10 * 1000L, Executor, () -> {System.err.println ("Der erste Threadname ist" + Thread.CurrentThread (). GetName (); // diese Methode aufrufen, wenn die Aufgabenausführung abgeschlossen ist task1.onCompletion (() -> {System.err.println ("Aufgabe 4 ausgeführt abgeschlossen!");}); System.err.println ("Task4 geht weiterhin mit anderen Dingen um!"); return task1;}Der Thread -Pool ist wie folgt definiert:
@ConfigurationPublic Class myexecutor {@Bean public static threadPooltaskexecutor getExecutor () {Threadpooltaskexecutor taskexecutor = new Threadpooltaskexecutor (); taskexecutor.setcorepoolsize (30); taskexecutor.setMaxpoolSize (30); taskexecutor.setQueuecapacity (50); taskexecutor.setthreadnameprefix ("Huang"); // Asynchronous Task -Thread Name ist Huang Präfix return taskexecutor; }}Gleichzeitige Tests oben können verwendet werden, um die folgenden Ergebnisse zu erhalten:
Die Beispielcodeadresse dieses Artikels: https://github.com/smallercoder/webasynctask
Durch die Verwendung von Thread -Pools können Serverressourcen speichern und die Serververarbeitungsfunktionen optimieren. Denken Sie daran, sie häufig zu verwenden! Danke fürs Lesen! Wenn Sie der Meinung sind, dass es für Sie hilfreich sein wird, fangen Sie bitte an!
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, es wird für das Lernen aller hilfreich sein und ich hoffe, jeder wird Wulin.com mehr unterstützen.