Die Gewindekommunikation wird verwendet, um den koordinierten Betrieb von Threads zu gewährleisten. Im Allgemeinen muss bei der Thread -Synchronisation berücksichtigt werden.
1. traditionelle Fadenkommunikation
Normalerweise werden drei Methoden der ObjectLT -Klasse verwendet:
Diese drei Methoden müssen vom Synchronisationsmonitor -Objekt aufgerufen werden und sind in zwei Situationen unterteilt:
Bei Synchronisierungsmethoden, da der Synchronisationsmonitor dieses Objekt ist, können diese drei Methoden direkt aufgerufen werden.
Beispiele sind wie folgt:
öffentliche Klasse SyncMetHodhreadCommunication {statische Klasse DataWrap {int data = 0; boolesche Flagge = Falsch; public synchronisierte void addthreada () {if (flag) {try {wait (); } catch (interruptedException e) {e.printstacktrace (); }} Daten ++; System.out.println (Thread.currentThread (). GetName () + "" + data); Flag = wahr; benachrichtigen(); } public synchronisierte void addthreadb () {if (! flag) {try {wait (); } catch (interruptedException e) {e.printstacktrace (); }} Daten ++; System.out.println (Thread.currentThread (). GetName () + "" + data); Flag = Falsch; benachrichtigen(); }} statische Klasse Threada erweitert Thread {private DataWrap -Daten; public threada (datawrap datawrap) {this.data = datawrap; } @Override public void run () {für (int i = 0; i <10; i ++) {data.addthreada (); }}} statischer Klasse Thread erweitert Thread {private datawrap -Daten; public taunt (datawrap datawrap) {this.data = datawrap; } @Override public void run () {für (int i = 0; i <10; i ++) {data.addthreadb (); }}} public static void main (string [] args) {// Implementieren Sie zwei Threads, um Daten zu addieren. neuer Threada (DataWrap) .Start (); neuer Turnier (DataWrap) .Start (); }}Wenn Sie Codeblöcke synchronisieren, müssen Sie das Monitor -Objekt verwenden, um diese drei Methoden aufzurufen.
Beispiele sind wie folgt:
öffentliche Klasse SyncBlockThreadComminication {statische Klasse DataWrap {Boolean Flag; int Daten; } statische Klasse Threada erweitert Thread {datawrap datawrap; public threada (datawrap datawrap) {this.datawrap = datawrap; } @Override public void run () {für (int i = 0; i <10; i ++) {synchronized (datAwrap) {if (datawrap.flag) {try {datawrap.wait (); } catch (interruptedException e) {e.printstacktrace (); }} datawrap.data ++; System.out.println (getName () + "" + datawrap.data); datawrap.flag = true; datawrap.notify (); }}}}} statischer Klasse erweitert Thread {datawrap datawrap; public taunt (datawrap datawrap) {this.datawrap = datawrap; } @Override public void run () {für (int i = 0; i <10; i ++) {synchronized (datawrap) {if (! Datawrap.flag) {try {datawrap.wait (); } catch (interruptedException e) {e.printstacktrace (); }} datawrap.data ++; System.out.println (getName () + "" + datawrap.data); datawrap.flag = false; datawrap.notify (); }}}} public static void main (string [] args) {// Implementieren Sie zwei Threads, um Daten zu addieren. neuer Threada (DataWrap) .Start (); neuer Turnier (DataWrap) .Start (); }}2. Verwenden Sie die Bedingung, um die Kommunikation der Faden zu steuern
Bei Verwendung eines Sperrobjekts, um die Synchronisation sicherzustellen, wird ein Zustandsobjekt verwendet, um die Koordination sicherzustellen.
Beispiele sind wie folgt:
import Java.util.concurrent.locks.condition; import Java.util.concurrent {statische Klasse datawrap {int Data; Boolesche Flagge; Private Final Lock Lock = New Reentrantlock (); private endgültige Bedingung Zustand = lock.newCondition (); public void addthreada () {lock.lock (); try {if (flag) {try {condition.await (); } catch (interruptedException e) {e.printstacktrace (); }} Daten ++; System.out.println (Thread.currentThread (). GetName () + "" + data); Flag = wahr; Condition.Signal (); } endlich {lock.unlock (); }} public void addthreadb () {lock.lock (); try {if (! flag) {try {condition.await (); } catch (interruptedException e) {e.printstacktrace (); }} Daten ++; System.out.println (Thread.currentThread (). GetName () + "" + data); Flag = Falsch; Condition.Signal (); } endlich {lock.unlock (); }}} statische Klasse Threada erweitert Thread {datawrap datawrap; public threada (datawrap datawrap) {this.datawrap = datawrap; } @Override public void run () {für (int i = 0; i <10; i ++) {datawrap.addthreada (); }}} statischer Klasse ThreadB erweitert Thread {datawrap datawrap; public taunt (datawrap datawrap) {this.datawrap = datawrap; } @Override public void run () {für (int i = 0; i <10; i ++) {datawrap.addthreadb (); }}} public static void main (string [] args) {// Implementieren Sie zwei Threads, um Daten zu addieren. neuer Threada (DataWrap) .Start (); neuer Turnier (DataWrap) .Start (); }}Das Warten (), singal () und singalall () des Bedingungsobjekts entspricht den Methoden Wait (), benachrichtigen () und notifyAll ().
3.. Verwenden Sie die Blockierung der Warteschlangenblockierung, um die Fadenkommunikation zu steuern
Blockingqueue ist eine Untergrenze der Warteschlangenschnittstelle, die hauptsächlich für die Gewindekommunikation verwendet wird. Es hat eine Funktion: Wenn der Produzenten -Thread versucht, ein Element in das Blockingqueue zu legen, ist der Faden blockiert, wenn die Warteschlange voll ist. Wenn der Verbraucherfaden versucht, das Element aus dem Blockingqueue herauszuholen, ist der Faden blockiert, wenn die Warteschlange leer ist. Diese beiden Merkmale entsprechen zwei Methoden, die Blockierungen, Put (e e) und take () unterstützen
Beispiele sind wie folgt:
Import Java.util.Concurrent.ArrayBlockingQueue; Import Java.util.Concurrent } statische Klasse Threada erweitert Thread {private BlockingQueue <Datawrap> Blockingqueue; public threada (blockingQueue <Datawrap> blockingqueue, String name) {super (name); this.blockingqueue = blockingqueue; } @Override public void run () {für (int i = 0; i <100; i ++) {try {datawrap datAwrap = blockingQueue.take (); datawrap.data ++; System.out.println (getName () + "" + datawrap.data); Schlaf (1000); } catch (interruptedException e) {e.printstacktrace (); }}}}} statischer Klasse erweitert Thread {private Blockingqueue <DatAwrap> BlockingQueue; private datawrap datawrap; public taunt (blockingQueue <Datawrap> blockingqueue, datawrap datawrap, String -Name) {Super (Name); this.blockingqueue = blockingqueue; this.datawrap = datawrap; } @Override public void run () {für (int i = 0; i <100; i ++) {try {datawrap.data ++; System.out.println (getName () + "" + datawrap.data); Blockingqueue.put (DataWrap); Schlaf (1000); } catch (interruptedException e) {e.printstacktrace (); }}}} public static void main (String [] args) {/// Implementieren Sie zwei Threads, um Daten zu addieren. Datawrap datawrap = new DataWrap (); BlockingQueue <Datawrap> blockingqueue = new ArrayBlockingQueue <> (1); New Threada (Blockingqueue, "Verbraucher"). starten (); neuer Taste (Blockingqueue, DataWrap, "Produzent"). start (); }}Blockingqueue hat fünf Implementierungsklassen:
ArrayBlockingQueue Blockingqueue -Warteschlange basierend auf Array -Implementierung
Linked Blockingqueue Blockingqueue -Warteschlange basierend auf der verknüpften Liste
Die Elemente in PriorityBlockingQueue müssen die vergleichbare Schnittstelle implementieren, und die Reihenfolge der Elemente wird nach dem Komparator angepasst.
Synchronousqueue synchronisiert die Warteschlange und erfordert, dass Zugriffsvorgänge in der Warteschlange abwechselnd durchgeführt werden müssen.
DelayQueue -Sammlungselemente müssen die Verzögerungsschnittstelle implementieren, und die Elemente in der Warteschlange werden nach dem Rückgabewert der Delay Interface -Methode getDelay () sortiert.
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.