Queue ist eine spezielle lineare Tabelle, die dem Prinzip ?First in, first out“ folgt. In unserem t?glichen Gebrauch verwenden wir es oft, um gleichzeitig Daten zu manipulieren. Bei der gleichzeitigen Programmierung ist es manchmal notwendig, threadsichere Warteschlangen zu verwenden. Wenn Sie eine Thread-sichere Warteschlange implementieren m?chten, gibt es normalerweise zwei M?glichkeiten: Eine besteht darin, eine Blockierungswarteschlange zu verwenden, und die andere darin, eine Thread-Synchronisationssperre zu verwenden.
Was ist eine Blockierungswarteschlange?
Angenommen, es gibt eine B?ckerei, in der ein Kunde Brot isst und ein Koch Brot backt. Es sind nicht mehr als 2 Stück Brot im Korb. Nachdem der Koch den Teig beendet hat, legt er das Brot in den Korb und wenn die G?ste das Brot essen, nehmen sie es aus dem Korb, um sicherzustellen, dass es dort ist Ist das Brot im Korb, wenn die G?ste das Brot essen, oder ist der Korb nicht überfüllt, wenn der Koch das Brot backt? Zu diesem Zeitpunkt müssen wir das Konzept der Blockierungswarteschlange einführen, das wir oft als Produzenten-Konsumenten-Modell bezeichnen.
Eine blockierende Warteschlange ist eine Warteschlange, die zwei zus?tzliche Vorg?nge unterstützt. Diese beiden zus?tzlichen Vorg?nge unterstützen das Blockieren von Einfügungs- und Entfernungsmethoden.
(1) Blockierende Einfügungsmethode unterstützen: Das hei?t, wenn die Warteschlange voll ist, blockiert die Warteschlange den Thread, der Elemente einfügt, bis die Warteschlange nicht mehr voll ist.
(2) Unterstützt die Blockierungsentfernungsmethode: Dies bedeutet, dass der Thread, der das Element erh?lt, darauf wartet, dass die Warteschlange leer wird, wenn die Warteschlange leer ist. Blockierende Warteschlangen werden h?ufig in Produzenten- und Verbraucherszenarien verwendet. Der Produzent ist der Thread, der Elemente zur Warteschlange hinzufügt, und der Verbraucher ist der Thread, der Elemente aus der Warteschlange übernimmt. Eine Blockierungswarteschlange ist ein Container, der von Produzenten zum Speichern von Elementen und von Konsumenten zum Abrufen von Elementen verwendet wird.
Keine blockierenden Warteschlangen im System: PriorityQueue und ConcurrentLinkedQueue
Werfen wir einen Blick auf die Beziehung zwischen nicht blockierenden Warteschlangen (am Beispiel von PriorityQueue):
Die PriorityQueue-Klasse erbt von AbstractQueue und implementiert die Serializable-Schnittstelle. PriorityQueue verwaltet im Wesentlichen eine geordnete Liste und befindet sich im Java-Util-Paket. Das Wort Priority in der ersten H?lfte seines Namens bedeutet tats?chlich ?Priorit?t“. Der Warteschlange hinzugefügte Elemente werden entsprechend ihrer natürlichen Reihenfolge (über die java.util.Comparable-Implementierung) oder gem?? der an den Konstruktor übergebenen java.util.Comparator-Implementierung positioniert.
ConcurrentLinkedQueue ist eine threadsichere Warteschlange, die auf verknüpften Knoten basiert. Der gleichzeitige Zugriff erfordert keine Synchronisierung. Da Elemente zum Ende der Warteschlange hinzugefügt und aus dem Kopf entfernt werden, funktioniert der gemeinsame Zugriff von ConcurrentLinkedQueue auf eine gemeinsame Sammlung problemlos, ohne die Gr??e der Warteschlange zu kennen. Das Sammeln von Informationen über die Warteschlangengr??e ist langsam und erfordert das Durchlaufen der Warteschlange. ConcurrentLinkedQueue ist eine unbegrenzte Thread-sichere Warteschlange, die auf verknüpften Knoten basiert. Sie verwendet eine First-In-First-Out-Regel, um die Knoten zu sortieren. Es wird dem Ende der Warteschlange hinzugefügt. Wenn wir ein Element erhalten, wird das Element am Anfang der Warteschlange zurückgegeben.
Warteschlange, die die Blockierungsschnittstelle implementiert:
Die BlockingQueue-Schnittstelle und fünf Blockierungswarteschlangenklassen werden zu java.util.concurrent hinzugefügt. Es handelt sich im Wesentlichen um eine FIFO-Datenstruktur mit einer Besonderheit. Anstatt sofort Elemente zur Warteschlange hinzuzufügen oder daraus zu entfernen, blockiert der Thread, der die Operation ausführt, bis Platz oder ein Element verfügbar wird.
Die fünf Warteschlangen bieten verschiedene:
·ArrayBlockingQueue: Eine begrenzte Warteschlange, die von einem Array unterstützt wird.
·LinkedBlockingQueue: Eine optionale begrenzte Warteschlange, die durch verknüpfte Knoten unterstützt wird.
·PriorityBlockingQueue: Eine unbegrenzte Priorit?tswarteschlange, die durch einen Priorit?tsheap unterstützt wird.
·DelayQueue: Eine zeitbasierte Planungswarteschlange, die durch einen Priorit?tsheap unterstützt wird.
·SynchronousQueue: Ein einfacher Rendezvous-Mechanismus unter Verwendung der BlockingQueue-Schnittstelle.
Werfen wir einen Blick auf die Vererbungsbeziehung zwischen ArrayBlockingQueue und LinkedBlockingQueue:
Indem wir uns die Vererbungsbeziehung zwischen betrachten Wir wissen, dass die beiden Klassen auch von AbstractQueue erben und die Serializable-Schnittstelle implementieren. Der Unterschied besteht darin, dass sie auch die BlockingQueue-Schnittstelle implementieren.
Eine kurze Einführung zu einigen davon:
Die Standardgr??e von LinkedBlockingQueueLinkedBlockingQueue ist Integer.MAX_VALUE, was als zwischengespeicherte begrenzte Warteschlange verstanden werden kann. Es handelt sich um eine Warteschlange, die auf einer verknüpften Liste basiert (Wer zuerst rein, zuerst raus). Wenn der Produzent ein Datenelement in die Warteschlange stellt, wird es in der Warteschlange zwischengespeichert. Wenn der Warteschlangenpuffer die maximale Cache-Kapazit?t erreicht (LinkedBlockingQueue kann diesen Wert über den Konstruktor angeben), wird die Produzentenwarteschlange blockiert, bis der Verbraucher sie verbraucht Wenn ein Datenelement gel?scht wird, wird der Produzenten-Thread aktiviert und umgekehrt.
ArrayBlockingQueue muss beim Erstellen die Kapazit?t angeben, und Sie k?nnen ausw?hlen, ob Fairness erforderlich ist. Wenn der Fairness-Parameter auf true gesetzt ist, wird der Thread mit der l?ngsten Wartezeit zuerst verarbeitet (tats?chlich wird ReentrantLock auf gesetzt). wahr Diese Art von Fairness: Das hei?t, der Thread mit der l?ngsten Wartezeit wird zuerst ausgeführt. Im Allgemeinen kostet Fairness Leistung, also nutzen Sie sie nur, wenn Sie sie wirklich brauchen. Es handelt sich um eine Array-basierte blockierende Ringwarteschlange, die Elemente nach dem FIFO-Prinzip (First In First Out) sortiert.
PriorityBlockingQueue ist eine Priorit?tswarteschlange, keine First-In-First-Out-Warteschlange. Elemente werden in der Reihenfolge ihrer Priorit?t entfernt, und die Warteschlange hat keine Obergrenze (nach Betrachtung des Quellcodes ist PriorityBlockingQueue eine Neuverpackung von PriorityQueue, basierend auf der Heap-Datenstruktur, und PriorityQueue hat keine Kapazit?tsbeschr?nkung, genau wie ArrayList in Priorit?t Es wird nicht blockiert, wenn es in die Blockierungswarteschlange gestellt wird. Obwohl diese Warteschlange logisch unbegrenzt ist, kann der Versuch, einen Add-Vorgang auszuführen, einen OutOfMemoryError verursachen, weil die Ressourcen ersch?pft sind Das Element wird blockiert, daher ist sein Abrufvorgang blockiert. Darüber hinaus müssen die in die Warteschlange eingehenden Elemente über Vergleichsm?glichkeiten verfügen.
über ConcurrentLinkedQueue und LinkedBlockingQueue:
kann auch als Unterschied zwischen blockierender Warteschlange und nicht blockierender Warteschlange verstanden werden:
1. LinkedBlockingQueue verwendet a Der Sperrmechanismus verwendet ConcurrentLinkedQueue den CAS-Algorithmus, obwohl die zugrunde liegende Sperrenerfassung von LinkedBlockingQueue ebenfalls den CAS-Algorithmus verwendet.
2. In Bezug auf das Abrufen von Elementen unterstützt ConcurrentLinkedQueue das Blockieren zum Abrufen von Elementen nicht und LinkedBlockingQueue unterstützt die blockierende take()-Methode.
3. In Bezug auf die Leistung beim Einfügen von Elementen ist der Unterschied zwischen Sperren und Sperren im tats?chlichen Gebrauch viel schneller als bei LinkedBlockingQueue.
Produzenten-Konsumenten-Code:
Ich habe im Internet ein kleines Beispiel eines Produzenten-Konsumenten gesehen, das für das Verst?ndnis von Blockierungswarteschlangen sehr hilfreich ist. Der Code ist wie folgt folgt:
import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class BlockingQueueTest { public static class Basket { BlockingQueue<String> basket = new ArrayBlockingQueue<>(3); private void produce() throws InterruptedException { basket.put("蘋果"); } private void consume() throws InterruptedException { basket.take(); } private int getAppleNumber() { return basket.size(); } } private static void testBasket() { final Basket basket = new Basket(); class Producer implements Runnable { public void run() { try { while (true) { System.out.println("生產(chǎn)者開始生產(chǎn)蘋果###"); basket.produce(); System.out.println("生產(chǎn)者生產(chǎn)蘋果完畢###"); System.out.println("籃子中的蘋果數(shù)量:" + basket.getAppleNumber() + "個"); Thread.sleep(300); } } catch (InterruptedException e) {} } } class Consumer implements Runnable { public void run() { try { while (true) { System.out.println("消費者開始消費蘋果***"); basket.consume(); System.out.println("消費者消費蘋果完畢***"); System.out.println("籃子中的蘋果數(shù)量:" + basket.getAppleNumber() + "個"); Thread.sleep(1000); } } catch (InterruptedException e) {} } } ExecutorService service = Executors.newCachedThreadPool(); Producer producer = new Producer(); Consumer consumer = new Consumer(); service.submit(producer); service.submit(consumer); try { Thread.sleep(10000); } catch (InterruptedException e) {} service.shutdownNow(); } public static void main(String[] args) { BlockingQueueTest.testBasket(); } }
VieleJava-Schulungsvideos, alle auf der chinesischen PHP-Website, willkommen zum Online-Lernen!
Das obige ist der detaillierte Inhalt vonWas ist eine Java-Warteschlange?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Hei?e KI -Werkzeuge

Undress AI Tool
Ausziehbilder kostenlos

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Clothoff.io
KI-Kleiderentferner

Video Face Swap
Tauschen Sie Gesichter in jedem Video mühelos mit unserem v?llig kostenlosen KI-Gesichtstausch-Tool aus!

Hei?er Artikel

Hei?e Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Um JDBC -Transaktionen korrekt zu verarbeiten, müssen Sie zun?chst den automatischen Komiti -Modus ausschalten und dann mehrere Vorg?nge ausführen und schlie?lich entsprechend den Ergebnissen festlegen oder rollen. 1. Nennen Sie Conn.SetAutoCommit (False), um die Transaktion zu starten. 2. Führen Sie mehrere SQL -Operationen aus, z. B. einfügen und aktualisieren. 3. Rufen Sie Conn.Commit () an, wenn alle Vorg?nge erfolgreich sind, und rufen Sie Conn.Rollback () auf, wenn eine Ausnahme auftritt, um die Datenkonsistenz zu gew?hrleisten. Gleichzeitig sollten Try-with-Ressourcen verwendet werden, um Ressourcen zu verwalten, Ausnahmen ordnungsgem?? zu behandeln und Verbindungen zu schlie?en, um Verbindungsleckage zu vermeiden. Darüber hinaus wird empfohlen, Verbindungspools zu verwenden und Save -Punkte zu setzen, um teilweise Rollback zu erreichen und Transaktionen so kurz wie m?glich zu halten, um die Leistung zu verbessern.

Pre-Formancetartuptimemoryusage, QuarkusandmicronautleadduToCompile-Time-foringandgraalvSupport, WithQuarkusofttenperformLightBetterin serverloser Szenarien.2. Thyvelopecosystem,

HTTP-Protokoll Middleware in Go kann Anforderungsmethoden, Pfade, Client-IP und zeitaufw?ndiges Aufzeichnen aufzeichnen. 1. Verwenden Sie http.Handlerfunc, um den Prozessor zu wickeln, 2. Nehmen Sie die Startzeit und die Endzeit vor und nach dem Aufrufen als n?chstes auf. Der vollst?ndige Beispielcode wurde überprüft, um auszuführen und eignet sich zum Starten eines kleinen und mittelgro?en Projekts. Zu den Erweiterungsvorschl?gen geh?ren das Erfassen von Statuscodes, die Unterstützung von JSON -Protokollen und die Nachverfolgung von ID -IDs.

Die Müllsammlung von Java (GC) ist ein Mechanismus, der automatisch den Speicher verwaltet, der das Risiko eines Speicherlecks verringert, indem unerreichbare Objekte zurückgeführt werden. 1.GC beurteilt die Zug?nglichkeit des Objekts aus dem Stammobjekt (z. B. Stapelvariablen, aktive Threads, statische Felder usw.) und nicht erreichbare Objekte als Müll markiert. 2. Basierend auf dem markierten Algorithmus markieren Sie alle erreichbaren Objekte und l?schen Sie nicht markierte Objekte. 3.. Verfolgen Sie eine Generationskollektionsstrategie: Die neue Generation (Eden, S0, S1) führt h?ufig MollGC aus; Die ?lteren Menschen erzielen weniger, dauert jedoch l?nger, um MajorGC durchzuführen. MetaPace speichert Klassenmetadaten. 4. JVM bietet eine Vielzahl von GC -Ger?ten: SerialGC ist für kleine Anwendungen geeignet; ParallelgC verbessert den Durchsatz; CMS reduziert sich

Durch die Auswahl des richtigen HTMlinput -Typs kann die Datengenauigkeit verbessert, die Benutzererfahrung verbessert und die Benutzerfreundlichkeit verbessert werden. 1. W?hlen Sie die entsprechenden Eingabetypen gem?? dem Datentyp aus, z. B. Text, E -Mail, Tel, Nummer und Datum, die automatisch überprüft und an die Tastatur anpassen k?nnen. 2. Verwenden Sie HTML5, um neue Typen wie URL, Farbe, Reichweite und Suche hinzuzufügen, die eine intuitivere Interaktionsmethode bieten k?nnen. 3.. Verwenden Sie Platzhalter und erforderliche Attribute, um die Effizienz und Genauigkeit der Formulierung zu verbessern. Es sollte jedoch beachtet werden, dass der Platzhalter das Etikett nicht ersetzen kann.

GradleStheBetterChoiceFormostnewProjectsDuetoitSuperiorFlexibilit?t, Leistung und ModerntoolingSupport.1.GRADLE'SGROOVY/KOTLINDSLISMORECONCISEANDEIPRESSIVETHANMANMANBOSEXML.2.GRAGRECONCISEANDEPRPRESSIVETHANMAVENSVOSEXML.2.

Die klare Antwort auf diese Frage ist die Empfehlung, das Beobachtermuster mithilfe einer benutzerdefinierten Observer -Schnittstelle zu implementieren. 1. Obwohl Java beobachtbar und Beobachter liefert, ist erstere eine Klasse und wurde veraltet und fehlt Flexibilit?t. 2. Die moderne empfohlene Praxis besteht darin, eine funktionale Observer -Schnittstelle zu definieren, und das Subjekt beh?lt die Beobachterliste bei und benachrichtigt alle Beobachter, wenn sich der Zustand ?ndert. 3.. Es kann in Kombination mit Lambda -Ausdrücken verwendet werden, um die Einfachheit und Wartbarkeit des Codes zu verbessern. V. Daher sollten neue Projekte ein benutzerdefiniertes Observer-Schnittstellenschema annehmen, das Typen ist, einfach zu testen und sich auf moderne Java spezialisiert zu haben

Die Verwendung der OpenCSV -Bibliothek ist die beste Wahl zum Lesen von CSV -Dateien. Es kann komplexe Situationen bew?ltigen und mehrere Merkmale unterstützt. 2. Für einfache CSV-Dateien k?nnen Sie Javas integriertes BufferedReader in Kombination mit Split-Methode verwenden. 3. Wenn Sie eine flexiblere Formatsteuerung ben?tigen oder Apache -Komponenten verwendet haben, k?nnen Sie Apache CommonsCSV ausw?hlen. OpenCSV wird für die Einfachheit, Robustheit und die F?higkeit, CSV -Probleme in realen Szenarien zu l?sen, empfohlen.
