Heim  >  Artikel  >  Java  >  Detaillierte Erläuterung der Inter-Thread-Kommunikation im Java-Multithreading

Detaillierte Erläuterung der Inter-Thread-Kommunikation im Java-Multithreading

黄舟
黄舟Original
2017-09-14 10:51:422393Durchsuche

Der folgende Herausgeber bringt Ihnen einen Artikel über das Erlernen der Java-Multithread-Programmierung (Inter-Thread-Kommunikation). Der Herausgeber findet es ziemlich gut, deshalb teile ich es jetzt mit Ihnen und gebe es als Referenz. Kommen Sie und werfen Sie einen Blick mit dem Editor

1. Übersicht

Threads sind unabhängige Personen im Betriebssystem, wenn diese Personen dies jedoch nicht tun Eine spezielle Verarbeitung kann nicht zu einem Ganzen werden, und die Kommunikation zwischen Threads ist eine der notwendigen Lösungen, um ein Ganzes zu werden. Man kann sagen, dass die Interaktivität zwischen Systemen nach der Aktivierung der Threads leistungsfähiger ist und gleichzeitig die CPU-Auslastung erheblich verbessert, es Programmierern aber auch ermöglicht, die Verarbeitung der Aufgaben jedes Threads effektiv zu steuern und zu überwachen.

2. Warte-/Benachrichtigungsmechanismus

1. „Warten/Benachrichtigungs“-Mechanismus, „wait“ bewirkt, dass der Thread angehalten wird, und „notify“ bewirkt, dass der angehaltene Thread weiter ausgeführt wird. Lassen Sie uns die Interaktion zwischen einem Koch und einem Kellner zur Veranschaulichung verwenden:

(1) Der Zeitpunkt, zu dem der Kellner die Gerichte bekommt, hängt vom Koch ab, daher befindet sich der Kellner in einem „Warten“-Zustand.

(2) Der Koch stellt die Gerichte auf den „Gerichtsliefertisch“, was eigentlich einer Benachrichtigung gleichkommt. Erst dann kann der Kellner die Gerichte holen und den Gästen reichen.

2. wait()

(1) Lassen Sie den Thread, der den Code gerade ausführt, warten. Die Methode wait() ist eine Methode der Klasse Object. Diese Methode wird verwendet, um den aktuellen Thread in die „Vorausführungswarteschlange“ zu stellen und die Ausführung an der Codezeile zu stoppen, in der sich wait() befindet, bis eine Benachrichtigung empfangen wird unterbrochen.

(2) Vor dem Aufruf der Methode wait () muss der Thread die Sperre des Objekts auf Objektebene erhalten, dh die Methode wait () kann nur in einer synchronisierten Methode oder einem synchronisierten Block aufgerufen werden. andernfalls wird eine IllegalMonitorStateException-Ausnahme ausgelöst. (Gehört zu einer Unterklasse von Runtime und erfordert keine Try-Catch-Anweisung zum Abfangen von Ausnahmen)

(3) Nach dem Aufruf der Methode wait() gibt der aktuelle Thread die Sperre frei und dieses Objekt tritt in die ein Thread-Wartepool. Wartet darauf, geweckt zu werden. Bevor er von wait() zurückkehrt, konkurriert der Thread mit anderen wartenden Threads um die Wiedererlangung der Sperre.

(4) Die Methode wait() kann durch Interrupt unterbrochen werden und eine InterruptedException auslösen.

(5) wait(long): Die Funktion der Methode wait(long) mit einem Parameter besteht darin, darauf zu warten, dass ein Thread die Sperre innerhalb einer bestimmten Zeitspanne aufweckt. es wird automatisch aufwachen.

3. notify()

(1) wird verwendet, um andere Threads zu benachrichtigen, die möglicherweise auf die Objektsperre des Objekts warten. Wenn mehrere Threads warten, wählt der Thread-Planer zufällig einen der Threads im Wartezustand aus, sendet ihm eine Benachrichtigungsbenachrichtigung und lässt ihn

warten , um die Objektsperre des Objekts zu erhalten. (Hinweis! Was hier gesagt wird, ist Warten, d. h. nach der Ausführung der notify()-Methode gibt der aktuelle Thread die Objektsperre nicht sofort frei, d. h. der Thread im Zustand wait() wird dies tun Die Objektsperre muss nicht sofort aufgehoben werden, nachdem der Code im synchronisierten Codeblock ausgeführt wurde.

(2) muss auch in einer synchronisierten Methode oder einem synchronisierten Block aufgerufen werden Der Thread muss vor dem Aufruf der Sperre auch die Objektebene des Objekts ermitteln, andernfalls wird eine IllegalMonitorStateException ausgelöst. (3) Wenn notify() eine Benachrichtigung ausgibt, aber kein wait()-Thread vorhanden ist keine Wirkung.

4. notifyAll()

(1) kann dazu führen, dass alle „alle“ Threads in der Warteschlange auf dieselbe gemeinsam genutzte Ressource (d. h. dieselbe Sperre) warten ) beginnend mit Verlassen Sie den Wartezustand und wechseln Sie in den ausführbaren Zustand.

5,

6,

Vorgetäuschter Tod: „ Fake Death“ „Das Phänomen besteht tatsächlich darin, dass der Thread in den Wartezustand WAITING wechselt. Wenn alle Threads in den Zustand WAITING wechseln, führt das Programm keine Funktionen mehr aus und das gesamte Projekt befindet sich in einem gestoppten Zustand. Der Grund dafür ist: Im Fall mehrerer Produzenten und mehrerer Konsumenten kann beispielsweise der „Produzent“ den „Produzenten“ wecken, und der „Verbraucher“ weckt möglicherweise den „Verbraucher“, der wiederum den „Verbraucher“ weckt , wodurch der Thread weiterläuft und wartet. Wie kann dieses Problem gelöst werden? Ändern Sie einfach notify() in die Methode notifyAll(), das heißt, aktivieren Sie einfach die heterogenen Methoden zusammen.

7.

In Java ist Pipe Stream (pipeStream) ein spezieller Stream, der zur direkten Übertragung von Daten in verschiedenen Threads verwendet werden kann. Ein Thread sendet Daten an die Ausgabepipe und ein anderer Thread liest Daten aus der Eingabepipe. Durch die Verwendung von Pipes wird die Kommunikation zwischen verschiedenen Threads erreicht, ohne auf Dinge wie temporäre Dateien zurückgreifen zu müssen. Im JDK werden vier Klassen bereitgestellt, um die Kommunikation zwischen Threads zu ermöglichen, darunter Byteströme (PipedOutputStream, PipedInputStream) und Zeichenströme (PipedWriter, PipedReader).


public class Run {
 public static void main(String[] args) {
  try {
   WriteData writeData = new WriteData();
   ReadData readData = new ReadData();
   PipedOutputStream outputStream = new PipedOutputStream();
   PipedInputStream inputStream = new PipedInputStream();
   
   outputStream.connect(inputStream);//使两个Stream之间产生通信链接,这样才可以将数据进行输入输出

   ThreadRead threadRead = new ThreadRead(readData, inputStream);
   threadRead.start();
   Thread.sleep(1000);
   ThreadWrite threadWrite = new ThreadWrite(writeData, outputStream);
   threadWrite.start();
  } catch (IOException e) {
   e.printStackTrace();
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }
}
3. Verwendung der Join-Methode

1. In vielen Fällen erstellt und startet der Hauptthread einen Unterthread enden, bevor der Unterthread endet. Wenn der Hauptthread zu diesem Zeitpunkt beispielsweise warten möchte, bis der Unterthread seine Ausführung abgeschlossen hat, bevor er endet, verarbeitet der Unterthread ein Datenelement und der Hauptthread möchte den Wert in den Daten erhalten muss die Methode join() verwenden.

2. Die Funktion von join() besteht darin, auf die Zerstörung des Threads zu warten, wodurch der aktuelle Thread auf unbestimmte Zeit blockiert wird und darauf gewartet wird, dass der Thread von join() zuvor zerstört wird Den Code des aktuellen Threads weiterhin ausführen.

3. In ähnlicher Weise kann die Methode „join()“ durch die Methode „interrupt()“ unterbrochen werden und eine InterruptedException auslösen.

4. Was ist der Unterschied zwischen beitreten und synchronisiert?

(1) join() verwendet intern die Methode wait() zum Warten.

(2) Das synchronisierte Schlüsselwort verwendet das „Objektmonitor“-Prinzip als Synchronisation.

5. Was ist der Unterschied zwischen Join(long) und Sleep(long)?

(1) join(long) wird intern mithilfe der Methode wait(long) implementiert. Wenn die Methode wait(long) ausgeführt wird, wird die Sperre des aktuellen Threads aufgehoben und andere Threads können ebenfalls aufrufen Synchronisationsmethode in diesem Thread. Das heißt, nach dem Join (long) gibt der Thread die Sperre frei und muss mit anderen Threads um Sperrressourcen konkurrieren.

(2) Die Thread.sleep(long)-Methode hebt die Sperre nicht auf.

4. Verwendung der Klasse ThreadLocal

1. Variablenwerte können in öffentlicher Form geteilt werden statische Variablen. Alle Threads verwenden dieselbe öffentliche statische Variable. Wie kann dieses Problem gelöst werden, wenn jeder Thread seine eigenen gemeinsam genutzten Variablen haben soll? Die ThreadLocal-Klasse löst das Problem, dass jeder Thread seinen eigenen Wert bindet. Die ThreadLocal-Klasse kann mit einer Box verglichen werden, die globale Daten speichert.

2. Die ThreadLocal-Klasse ist isoliert, das heißt, jeder Thread kann die Daten seines eigenen Threads speichern, ohne sich gegenseitig zu beeinflussen, und die von ihm abgerufenen Daten sind auch die von ihm gespeicherten Daten Eigener Thread.

5. Verwendung der Klasse InheritableThreadLocal

1. Die InheritableThreadLocal-Klasse erbt von der ThreadLocal-Klasse, weist also die Merkmale der ThreadLocal-Klasse auf, ist jedoch eine spezielle ThreadLocal-Klasse. Ihre Besonderheit besteht darin, dass der InheritableThreadLocal-Variablenwert automatisch übergeben wird an alle untergeordneten Threads, normale ThreadLocal-Variablen jedoch nicht; außerdem kann durch Überschreiben der Methode childValue der Wert der Der untergeordnete Thread kann als übergeordneter Thread verwendet werden. Eine beliebige Funktion des Thread-Werts.

Bemerkungen:

(1) Was ist ein Unterthread?

enthalten in Thread thread = new Thread(new ThreadStart(delegate{
})); werden alle als untergeordnete Threads betrachtet. (Persönliches Verständnis)

(2) Was ist der Hauptthread?

Sowohl die Benutzeroberfläche als auch die Hauptfunktion sind der Hauptthread, mit Ausnahme von „Programme, die nicht im Thread enthalten sind“ kann als Hauptthread angesehen werden . (Persönliches Verständnis)

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Inter-Thread-Kommunikation im Java-Multithreading. 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