Heim  >  Artikel  >  Java  >  Detaillierte Erläuterung der Unterschiede zwischen synchron, asynchron, blockierend und nicht blockierend

Detaillierte Erläuterung der Unterschiede zwischen synchron, asynchron, blockierend und nicht blockierend

Y2J
Y2JOriginal
2017-05-06 13:03:451552Durchsuche

In diesem Artikel werden hauptsächlich relevante Informationen zur detaillierten Erläuterung der Unterschiede zwischen Synchronisierung, Asynchronität, Blockierung und Nichtblockierung in Java vorgestellt. Freunde in Not können sich auf

Synchronisierung, Asynchronität, Blockierung und Nicht blockierend in Java Detaillierte Erklärung des Unterschieds

Einfach ausgedrückt:

Blockieren bedeutet, dass Sie nicht zurückkehren dürfen, bis Sie das abgeschlossen haben Arbeit, und Sie warten immer, bis die Angelegenheit bearbeitet ist, bevor Sie sie zurücksenden Wenn etwas klemmt, melden Sie es sofort dem Leiter.

Nehmen wir als Beispiel die beiden am häufigsten verwendeten Funktionen send und recv...

Wenn Sie beispielsweise die Sendefunktion aufrufen, um ein bestimmtes Byte zu senden, ist die Arbeit erledigt Durch Senden innerhalb des Systems werden die Daten lediglich in den Ausgabepuffer des TCP/IP-Protokollstapels übertragen (kopiert). Die erfolgreiche Ausführung bedeutet nicht, dass die Daten erfolgreich gesendet wurden Sie müssen über genügend Puffer verfügen, um die von Ihnen kopierten Daten zu speichern. Was die Daten betrifft, kommt hier der Unterschied zwischen Blockierung und Nichtblockierung ins Spiel: Die Socket-Sendefunktion im Blockierungsmodus kehrt erst zurück, wenn der Systempuffer über genügend Platz verfügt Kopieren Sie die Daten, die Sie senden möchten. Bei nicht blockierenden Sockets gibt send sofort WSAEWOULDDBLOCK zurück, um dem Anrufer mitzuteilen: „Der Sendevorgang ist blockiert!!! Sie können einen Weg finden, damit umzugehen …“

Für die recv-Funktion gilt das gleiche Prinzip. Der interne Arbeitsmechanismus der Funktion wartet tatsächlich darauf, dass der Empfangspuffer des TCP/IP-Protokollstapels ihn benachrichtigt: Hallo, Ihre Daten kommen. Für Sockets im Blockierungsmodus. Wenn der Empfangspuffer des TCP/IP-Protokollstapels nicht benachrichtigt wird, wird Folgendes nie zurückgegeben: Systemressourcen verbrauchen... Bei nicht blockierenden Modus-Sockets kehrt die Funktion sofort zurück und teilt Ihnen dann Folgendes mit: WSAEWOULDDBLOCK- --"Im Moment sind keine Daten vorhanden, schauen Sie später noch einmal nach"

Erweiterung:

Bei der Netzwerk-Programmierung

sehen wir häufig vier Aufrufmethoden : synchron, asynchron, blockierend und nicht blockierend. Diese Methoden sind nicht leicht zu verstehen. Nachfolgend finden Sie mein Verständnis dieser Begriffe.

1. Synchronisation

Die sogenannte Synchronisation bedeutet, dass beim Ausgeben eines Funktionsaufrufs der Aufruf erst zurückgegeben wird, wenn das Ergebnis vorliegt . Gemäß dieser Definition werden die meisten Funktionen tatsächlich synchron aufgerufen (z. B. sin, isdigit

usw.). Wenn wir jedoch von synchron und asynchron sprechen, beziehen wir uns im Allgemeinen insbesondere auf Aufgaben, die die Zusammenarbeit anderer Komponenten erfordern oder deren Ausführung eine gewisse Zeit in Anspruch nimmt. Das häufigste Beispiel ist SendMessage. Diese Funktion sendet eine Nachricht an ein Fenster und kehrt erst zurück, wenn die andere Partei die Nachricht verarbeitet hat. Nachdem die andere Partei die Verarbeitung abgeschlossen hat, gibt die Funktion den von der Nachrichtenverarbeitungsfunktion zurückgegebenen LRESULT-Wert an den Aufrufer zurück.

2. Asynchron

Das Konzept von Asynchron ist das Gegenteil von Synchron. Wenn ein asynchroner Prozeduraufruf ausgegeben wird, erhält der Aufrufer das Ergebnis nicht sofort. Die Komponente, die den Anruf tatsächlich abwickelt, benachrichtigt den Anrufer über Status

, Benachrichtigungen und Rückrufe, wenn der Anruf abgeschlossen ist. Nehmen Sie als Beispiel die Klasse CAsycSocket (beachten Sie, dass CSocket von CAsyncSocket abgeleitet ist, seine Funktion jedoch von asynchron in synchron umgewandelt wurde). Wenn ein Client durch Aufrufen der Connect-Funktion eine Verbindungsanforderung ausgibt, kann der Aufrufer-Thread sofort nach unten ausgeführt werden. Wenn die Verbindung tatsächlich hergestellt wird, sendet die unterste Ebene des Sockets eine Nachricht, um das

-Objekt zu benachrichtigen. Hier wird erwähnt, dass die Ausführungskomponente und der Anrufer Ergebnisse über drei Kanäle zurückgeben: Status, Benachrichtigung und Rückruf. Welche davon verwendet werden kann, hängt von der Implementierung der Exekutive ab und unterliegt nicht der Kontrolle des Anrufers, es sei denn, die Exekutive stellt mehrere Auswahlmöglichkeiten zur Verfügung. Wenn die Ausführungskomponente den Status zur Benachrichtigung verwendet, muss der Aufrufer ihn jedes Mal überprüfen, was sehr ineffizient ist (einige Leute, die neu in der Multithread-Programmierung sind, verwenden immer gerne eine Schleife, um eine bestimmte Variable Wert, das ist tatsächlich ein sehr schwerwiegender Fehler). Wenn die Benachrichtigung verwendet wird, ist die Effizienz sehr hoch, da die Ausführungskomponente nahezu keine zusätzlichen Operationen erfordert. Die Rückruffunktion unterscheidet sich eigentlich nicht wesentlich von der Benachrichtigung.
3. Blockieren

Blockierender Aufruf bedeutet, dass der aktuelle Thread angehalten wird, bevor das Aufrufergebnis zurückgegeben wird. Die Funktion kehrt erst zurück, nachdem sie das Ergebnis erhalten hat. Manche Leute setzen blockierende Anrufe möglicherweise mit synchronen Anrufen gleich, aber tatsächlich sind sie unterschiedlich. Bei synchronen Aufrufen ist in vielen Fällen der aktuelle Thread noch aktiv, aber logischerweise kehrt die aktuelle Funktion nicht zurück. Beispielsweise rufen wir die Empfangsfunktion in CSocket auf. Wenn sich keine Daten im Puffer befinden, wartet diese Funktion, bis Daten vorhanden sind, bevor sie zurückkehrt. Zu diesem Zeitpunkt verarbeitet der aktuelle Thread weiterhin verschiedene Nachrichten. Wenn sich das Hauptfenster und die aufrufende Funktion im selben Thread befinden, sollte die Hauptschnittstelle trotzdem aktualisiert werden, es sei denn, Sie rufen sie in einer speziellen Schnittstellenoperationsfunktion auf. Recv, eine weitere Funktion, die der Socket zum Empfangen von Daten verwendet, ist ein Beispiel für einen blockierenden Aufruf. Wenn der Socket im Blockierungsmodus arbeitet und diese Funktion ohne Daten aufgerufen wird, wird der aktuelle Thread angehalten, bis Daten vorhanden sind.

4. Nicht-blockierend

Die Konzepte von Nicht-Blockierung und Blockierung entsprechen einander, was bedeutet, dass die Funktion nicht blockiert Bis das Ergebnis nicht sofort abgerufen werden kann, wird der aktuelle Thread sofort zurückgegeben.

Der Blockierungsmodus des Objekts und der Blockierungsfunktionsaufruf

Es besteht eine starke Korrelation zwischen der Frage, ob sich das Objekt im Blockierungsmodus befindet und ob die Funktion den Aufruf blockiert, aber es gibt keinen- Eins-zu-Eins-Korrespondenz. Es kann nicht blockierende Aufrufmethoden für blockierende Objekte geben. Wir können den Status über eine bestimmte API abfragen und die Blockierungsfunktion zum richtigen Zeitpunkt aufrufen, um eine Blockierung zu vermeiden. Bei nicht blockierenden Objekten können durch den Aufruf spezieller Funktionen auch blockierende Aufrufe erfolgen. Die Funktion select ist ein solches Beispiel.

【Verwandte Empfehlungen】

1. Kostenloses Java-Video-Tutorial

2. Geek Academy Java-Video-Tutorial

3. Java-Tutorial-Handbuch

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Unterschiede zwischen synchron, asynchron, blockierend und nicht blockierend. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn