Ob im Leben oder in einem Programm, sie kann grob in zwei Typen unterteilt werden: synchron und asynchron.
Synchronisation: Wenn Sie beispielsweise Haidilao essen gehen, müssen Sie zuerst den Topfboden bestellen, dann das Geschirr, dann bringt der Kellner den Topfboden, dann das Geschirr und Endlich können Sie das Geschirr essen. Dieser Vorgang muss in der richtigen Reihenfolge durchgeführt werden.
Asynchrone Aufgabe: Lass uns Haidilao essen. Es kann sein, dass viele Leute vor dir Schlange stehen und warten müssen, bis du das Restaurant betreten kannst . Aber was ist, wenn Sie auf halbem Weg zur Toilette gehen möchten und sich bei Ihrer Rückkehr erneut anstellen müssen? Es gibt also ein Anrufsystem. Man stellt sich zuerst an, um eine Nummer zu bekommen, und dann kann man sich massieren lassen, einen Film ansehen, ins Spa gehen, eine Tasse Milchtee kaufen ... Jetzt sind Sie endlich an der Reihe. Sie werden benachrichtigt, dass Sie in der Schlange stehen, und können dann eintreten. Dieser Prozess ist asynchron.
Zuerst dachte ich darüber nach, einen Thread-Pool zu öffnen und Aufgaben in den Thread-Pool zu werfen, um sie abzuschließen.
Später fiel mir ein, dass SpringBoot ein bequemeres asynchrones Framework Async hat
Der Code ist auch sehr einfach. Sie müssen nur @Async zu der Methode hinzufügen, die eine asynchrone Ausführung erfordert. SpringBoot-Startup-Klasse @EnableAsync zu
@Async public void task() { // do something }
Obwohl der Code klein ist, werden die Fallstricke mit abnehmender Codemenge nicht kleiner.
Der Einfachheit halber habe ich eine lokale Demo erstellt und sie direkt codiert
@RestController public class AsyncController { @Autowired private AsyncService asyncService; @GetMapping("/v1/say") public String sayV1() { asyncService.sayV1(); return "success1"; } @GetMapping("/v2/say") public String sayV2() { asyncService.sayV2(); return "success2"; } }
@Service public class AsyncService { public void sayV1() { try { Thread.sleep(3000L); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("hello world"); } @Async public void sayV2() { try { Thread.sleep(3000L); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("hello world"); } }
Es ist eine sehr einfache Demo, die zwei Schnittstellen bereitstellt, /v1/say und /v2 /say, eine synchrone Ausführung, eine asynchrone Ausführung, 3 Sekunden ruhen lassen, um zeitaufwändige Aufgaben zu simulieren
Normalerweise ohne Probleme starten, bei synchroner Ausführung 3 Sekunden warten, bevor der Hauptthread zurückkehrt , wenn es asynchron ausgeführt wird. Kehren Sie sofort zurück und warten Sie 3 Sekunden, bevor Sie helloworld
ausgeben. Als ich jedoch einen Haltepunkt hinzugefügt habe, ist ein Problem aufgetreten.
Ich habe zuerst einen Haltepunkt in der Zeile hinzugefügt, in der „Hallo Welt“ gedruckt wird. Der Effekt ist der gleiche wie beim Original, außer dass er vor dem Drucken blockiert wird, aber keinen Einfluss auf die Rückkehr des Hauptthreads hat .
edit
Aber als ich einen Haltepunkt hinzugefügt habe, an dem die Methode ins Spiel kommt, stellte ich fest, dass der Hauptthread tatsächlich blockiert war !
Bearbeiten
Verschiedene Fehlerbehebungen, @Async wird nicht wirksam, Asynchrone Aufgaben warten auf die Rückkehr des Hauptthreads, es wurde jedoch keine wirksame Lösung gefunden.
Später erinnerte mich ein Kollege daran, ob es ein Thread sein könnte, der durch die Debug-Funktion blockiert wurde?
Mit der Einstellung, es auszuprobieren, habe ich die Debug-Konfiguration gefunden
bearbeiten
# 🎜🎜 #Breakpoint kann wählen, ob die JVM blockiert werden soll oder ob der aktuelle Thread blockiert werden soll. Wählen Sie „Für Thread anhalten“ und der Hauptthread wird nicht mehr blockiertDas obige ist der detaillierte Inhalt vonImplementierung und Analyse asynchroner Java-Aufgaben. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!