Dieser Artikel spricht hauptsächlich über die Sammlungen, die mit der Parallelität verbunden sind. Für gewöhnliche Sammlungen finden Sie auf [Java Collection Overview].
1. Was ist Blockingqueue
Blockingqueue ist eine blockierende Warteschlange. Aus dem Wort Blockierung ist ersichtlich, dass der Zugriff auf eine blockierende Warteschlange in einigen Fällen zu einer Blockade führen kann. Es gibt zwei blockierte Hauptfälle:
1. Wenn die Warteschlange voll ist, wird sie aufgenommen.
2. Wenn die Warteschlange leer ist, wird sie aus der Warteschlange heraus sein.
Wenn ein Thread versucht, sich eine bereits vollständige Warteschlange zu stellen, wird er blockiert, es sei denn, ein anderer Thread führt die Warteschlange vor. In ähnlicher Weise wird ein Thread versucht, eine leere Warteschlange vorzustellen, es wird blockiert, es sei denn, ein anderer Thread hat die Warteschlange.
In Java befindet sich die Blockingqueue -Schnittstelle im java.util.concurrent -Paket (bereitgestellt in der Java 5 -Version). Aus den oben eingeführten Merkmalen der oben eingeführten Blockierungswarteschlange ist ersichtlich, dass die blockierende Warteschlange mit einer Gewinde ist.
2. So verwenden Sie Blockingqueue
Blockierende Warteschlangen werden hauptsächlich in Produzenten-/Verbraucherszenarien verwendet. Das folgende Bild zeigt eine Thread -Produktion und ein Thread -Verbrauchszenario:
Der für die Produktion verantwortliche Faden erstellt kontinuierlich neue Objekte und fügt sie in die blockierende Warteschlange ein, bis die Obergrenze dieser Warteschlange erreicht ist. Nachdem die Warteschlange ihre Obergrenze erreicht hat, wird der Produktionsfaden blockiert, bis der verbrauchte Faden die Warteschlange konsumiert. In ähnlicher Weise konsumiert der für den Verbrauch verantwortliche Thread ständig Objekte aus der Warteschlange, bis die Warteschlange leer ist. Wenn die Warteschlange leer ist, wird der Verbrauchsfaden blockiert, es sei denn, ein neues Objekt in der Warteschlange wird eingefügt.
3.. Methoden in der Blockingqueue -Schnittstelle
Es gibt vier Methodensätze zum Blockieren von Warteschlangen, um insert , remove und examine durchzuführen. Wenn die Operationen, die jedem Satz von Methoden entsprechen, nicht sofort ausgeführt werden können, werden unterschiedliche Reaktionen vorliegen. In der folgenden Tabelle werden diese Methoden auf klassifizierte Weise aufgeführt:
| - - | Wirft Ausnahme aus | Besonderer Wert | Blöcke | Machen aus |
|---|---|---|---|---|
| Einfügen | (o) hinzufügen | Angebot (o) | (o) setzen | Angebot (o, Zeitüberschreitung, Zeiteinheit) |
| Entfernen | entfernen (o) | Umfrage() | nehmen() | Umfrage (Auszeit, Zeiteinheit) |
| Prüfen | Element() | spähen() |
Die entsprechenden Eigenschaften dieser vier Methodensätze sind:
1. ThrowSexception: Wenn die Operation nicht sofort durchgeführt werden kann, wird eine Ausnahme ausgelöst.
2. SpecialValue: Wenn die Operation nicht sofort durchgeführt werden kann, wird ein besonderer Wert zurückgegeben, normalerweise wahr oder falsch
3. Blöcke: Wenn der Vorgang nicht sofort durchgeführt werden kann, wird der Vorgang blockiert
4. Zeitpunkt: Wenn der Vorgang nicht sofort durchgeführt werden kann, wird der Vorgang zum angegebenen Zeitpunkt blockiert. Wenn die angegebene Zeit nicht ausgeführt wird, wird ein besonderer Wert zurückgegeben, der normalerweise wahr oder falsch ist.
Es ist zu beachten, dass wir null nicht in das Blockingqueue einfügen können, sonst wird NullPointerException gemeldet.
4. Blockingqueue -Implementierungsklasse
Blockingqueue ist nur eine Schnittstelle im Paket java.util.concurrent . Wenn wir es speziell verwenden, verwenden wir seine Implementierungsklassen. Natürlich befinden sich diese Implementierungsklassen auch im Paket java.util.concurrent . In Java 6 sind Blockingqueue -Implementierungsklassen hauptsächlich wie folgt:
1. ArrayBlockingqueue
2. Delayqueue
3.. Linked Blockingqueue
4. Prioritätsblocker
5. Synchronousqueue
Im Folgenden werden wir diese Implementierungsklassen separat vorstellen.
4.1 ArrayBlockingqueue
ArrayBlockingQueue ist eine begrenzte Blockierungswarteschlange, und seine interne Implementierung ist ein Array. Die Bedeutung der Grenze bedeutet, dass seine Kapazität begrenzt ist, wir müssen ihre Kapazitätsgröße bei der Initialisierung angeben, und die Kapazitätsgröße kann nicht geändert werden, sobald sie angegeben ist.
ArrayBlockingQueue speichert Daten in erstmals erstmals. Das neu eingefügte Objekt ist der Schwanz und das neu bewegte Objekt ist der Kopf. Hier ist ein Beispiel für die Initialisierung und Verwendung von ArrayBlockingQueue:
Blockingqueue -Warteschlange = NeuarrayBlockingClockingQueue (1024); Queue.put ("1"); Object Object = Queue.Take ();4.2 Verzögerung
Was Delayqueue -Blöcke sind seine internen Elemente. Die Elemente in Delayqueue müssen die Schnittstelle java.util.concurrent.Delayed implementieren. Die Definition dieser Schnittstelle ist sehr einfach:
Die öffentliche Schnittstelle verzögert erweitert vergleichbar <verzögert> {Long getDelay (Zeiteinheit);} Der Rückgabewert getDelay() -Methode ist die Haltezeit, bevor das Warteschlangenelement veröffentlicht wird. Wenn 0 oder ein负值zurückgegeben wird, bedeutet dies, dass das Element abgelaufen ist und freigegeben werden muss. Zu diesem Zeitpunkt veröffentlicht DelyedQueue dieses Objekt über seine take() -Methode.
Wie aus der obigen Definition verzögerter Schnittstelle ersichtlich ist, erbt es auch die Comparable Schnittstelle. Dies liegt daran, dass die Elemente im DelyedQueue sortiert werden müssen. Im Allgemeinen klären wir nach Priorität der Ablaufzeit der Elemente.
Beispiel 1: Geben Sie eine Ablaufzeit für ein Objekt an
Erstens definieren wir ein Element, das die verzögerte Schnittstelle implementieren muss
Public Class DelyedElement implementiert verzögert {privat lang abgelaufen; private lange Verzögerung; privater Zeichenfolge Name; DelayedElement (String ElementName, Long Delay) {this. name = elementname; Das. Verzögerung = Verzögerung; abgelaufen = (Delay + System. CurrentTimemillis ()); } @Override public int vergleicheto (verzögert o) {DelayedElement Cached = (DelayedElement) o; return cached.getExpired ()> abgelaufen? 1: -1; } @Override public Long getDelay (Zeitunit -Einheit) {return (abgelaufen - System. CurrentTimemillis ()); } @Override public String toString () {return "DelayedElement [Delay =" + Delay + ", name =" + name + "]"; } public long getexpired () {return abgelaufen; }}Setzen Sie die Ablaufzeit dieses Elements auf 3S
öffentliche Klasse DelayQueueExample {public static void main (String [] args) löst unterbrochene Ausnahme aus {DelayQueue <vertastung> queue = new DelayQueue <> (); DelayedElement ele = neuer Verzögerung ("Cache 3 Sekunden", 3000); queue.put (ele); System. out.println (queue.take ()); }}Führen Sie diese Hauptfunktion aus und wir können feststellen, dass wir 3 Sekunden warten müssen, bevor wir dieses Objekt drucken.
Tatsächlich gibt es viele Anwendungsszenarien für DelayQueue, wie zeitgesteuerte Schließungsverbindungen, Cache -Objekte, Zeitüberschreitungsverarbeitung und andere Szenarien. Nehmen wir die Schülerprüfung als Beispiel, damit jeder die Verwendung von Delayqueue tiefer verstehen kann.
Beispiel 2: Behandeln Sie alle Schüler in der Prüfung als Delyqueue, wer die Fragen zuerst beendet, gibt sie zuerst frei
Zunächst konstruieren wir ein Studentenobjekt
Studenten im öffentlichen Klassen implementiert runnable, verzögert {privater String -Name; // Private lange Kosten nennen; // Zeit für die Testfragen privat lang fertige Zeit; // Zeit für den Abschluss öffentlicher Schüler (Zeichenfolge Name, lange Kostenzeit) {this. Name = Name; Das. Kostenzeit = Kostenzeit; fersetime = costime + System. CurrentTimemillis (); } @Override public void run () {System. out.println (Name + "Senden Sie das Papier, Zeit" + KostenTime /1000); } @Override public Long getDelay (Zeitunit -Einheit) {return (ferdeTime - System. CurrentTimemillis ()); } @Override public int vergleicheto (verzögert o) {Student Other = (Student) o; Rückgabekostenzeit> = andere. Kostenzeit? 1: -1; }}Erstellen Sie dann ein Lehrerobjekt, um die Prüfung an die Schüler zu bringen
öffentlicher Klassenlehrer {statische endgültige int student_size = 30; public static void main (String [] args) löst unterbrochene Ausnahme {random r = new random () aus; // Denken Sie an alle Schüler als Verzögerung von Warteschlangen DelyQueue <Student> student = new DelayQueue <Student> (); // Erstellen Sie einen Thread -Pool, damit die Schüler "ihre Hausaufgaben machen" -Edutorservice exec = Executors.NewFixedThreadpool (Student_Size); für (int i = 0; i <student_size; i ++) {// Initialisieren Sie den Namen und die Zeit des Schülers, um die Teststudenten zu machen. } // den Test wob } exec.shutdown (); }}Schauen wir uns die laufenden Ergebnisse an:
Student 2 Senden Sie das Papier, 3
Student 1 Überlieferung in Papieren, 5 nehmen 5
Student 5 Senden Sie das Papier, 7
Student 4 Senden Sie das Papier, nehmen Sie 8
Student 3 Senden Sie das Papier, 11
Durch die laufenden Ergebnisse können wir feststellen, dass jeder Schüler das Papier nach der angegebenen Startzeit " abhängig von der Methode getDelay () )" übermittelt ", und das Papier wird zuerst eingereicht ( abhängig von der Vergleiche () -Methode).
Wenn Sie sich den Quellcode ansehen, können Sie feststellen, dass die interne Implementierung von DelayQueue PriorityQueue und ein Schloss verwendet:
4.3 Linked Blockingqueue
Die Konfiguration der LinkedBlocking -Blockierungswarteschlangegröße ist optional. Wenn wir beim Initialisieren eine Größe angeben, ist sie begrenzt und wenn nicht angegeben, ist sie begrenzt. Es soll grenzenlos sein, aber in der Tat ist die Standardgröße Integer.MAX_VALUE -Kapazität. Die interne Implementierung ist eine verknüpfte Liste.
Wie ArrayBlockingQueue speichert LinkedBlockingQueue auch Daten zuerst in die erste Weise. Das neu eingefügte Objekt ist der Schwanz und das neu bewegte Objekt ist der Kopf. Hier ist ein Beispiel für das Initialisieren und Erstellen von LinkedBlocking -Verfahren:
BlockingQueue <String> unbegrenzt = new LinkedBlockingQueue <String> (); BlockingQueue <String> boded = new LinkedBlockingQueue <string> (1024); begrenzt.put ("value"); String value = bodened.take ();4.4 Prioritätsblocker
PriorityBlockingQueue ist eine Warteschlange ohne Grenzen, und ihre Sortierregeln entsprechen java.util.PriorityQueue . Es ist zu beachten, dass Null -Objekte in Prioritätsblockierung eingefügt werden dürfen.
Alle in Prioritätsblockierung eingefügten Objekte müssen die Schnittstelle java.lang.Comparable implementieren, und die Vorrangs -Sortierregeln der Warteschlange werden gemäß unserer Implementierung dieser Schnittstelle definiert.
Darüber hinaus können wir einen Iterator von PriorityBlockingQueue erhalten, aber dieser Iterator garantiert keine Iteration in Prioritätsreihenfolge.
Lassen Sie uns ein Beispiel geben, um zu veranschaulichen. Zunächst definieren wir einen Objekttyp, der die vergleichbare Schnittstelle implementieren muss:
Prioritätsprioritätsträger implementiert vergleichbar <priorityElement> {private int priority; // Prioritätsprioritätsfunktion (int Priorität) {// Priorität initialisieren. 1 : -1;}public int getPriority() { return priority;}public void setPriority(int priority) { this.priority = priority;}@Overridepublic String toString() { return "PriorityElement [priority=" + priority + "]";}}Dann setzen wir zufällig Priorität für die Warteschlange
Prioritätsblocker im Public Class {public static void main (String [] args) löscht InterruptedException aus {PriorityBlockingQueue <PriorityElement> queue = new PriorityBlockingCocingQueue <> (); für (int i = 0; i <5; i ++) {Random Random = new random (); PriorityElement ele = neue Prioritätselement (random.Nextint (10)); queue.put (ele); } while (! queue.isempty ()) {System.out.println (queue.take ()); }}}Schauen Sie sich die laufenden Ergebnisse an:
PriorityElement [Priorität = 3]
PriorityElement [Priorität = 4]
PriorityElement [Priorität = 5]
PriorityElement [Priorität = 8]
PriorityElement [Priorität = 9]
4.5 Synchronousqueue
In der Synchronousqueue -Warteschlange ist nur ein Element erlaubt. Wenn ein Thread ein Element einfügt, wird er blockiert, es sei denn, das Element wird von einem anderen Thread verbraucht.
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.