Heim Java JavaErste Schritte Was ist eine Java-Warteschlange?

Was ist eine Java-Warteschlange?

Nov 14, 2019 am 10:56 AM
java 队列

Was ist eine Java-Warteschlange?

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):

Was ist eine Java-Warteschlange?

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:

Was ist eine Java-Warteschlange?

Was ist eine Java-Warteschlange?

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("生产者开始生产苹果###");
                        basket.produce();
                        System.out.println("生产者生产苹果完毕###");
                        System.out.println("篮子中的苹果数量:" + 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("篮子中的苹果数量:" + 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();
    }
}
Nach dem Login kopieren

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!

Erklärung dieser Website
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

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Perfekte Zahl in Java Perfekte Zahl in Java Aug 30, 2024 pm 04:28 PM

Leitfaden zur perfekten Zahl in Java. Hier besprechen wir die Definition, Wie prüft man die perfekte Zahl in Java?, Beispiele mit Code-Implementierung.

Weka in Java Weka in Java Aug 30, 2024 pm 04:28 PM

Leitfaden für Weka in Java. Hier besprechen wir die Einführung, die Verwendung von Weka Java, die Art der Plattform und die Vorteile anhand von Beispielen.

Smith-Nummer in Java Smith-Nummer in Java Aug 30, 2024 pm 04:28 PM

Leitfaden zur Smith-Zahl in Java. Hier besprechen wir die Definition: Wie überprüft man die Smith-Nummer in Java? Beispiel mit Code-Implementierung.

Fragen zum Java Spring-Interview Fragen zum Java Spring-Interview Aug 30, 2024 pm 04:29 PM

In diesem Artikel haben wir die am häufigsten gestellten Fragen zu Java Spring-Interviews mit ihren detaillierten Antworten zusammengestellt. Damit Sie das Interview knacken können.

Brechen oder aus Java 8 Stream foreach zurückkehren? Brechen oder aus Java 8 Stream foreach zurückkehren? Feb 07, 2025 pm 12:09 PM

Java 8 führt die Stream -API ein und bietet eine leistungsstarke und ausdrucksstarke Möglichkeit, Datensammlungen zu verarbeiten. Eine häufige Frage bei der Verwendung von Stream lautet jedoch: Wie kann man von einem Foreach -Betrieb brechen oder zurückkehren? Herkömmliche Schleifen ermöglichen eine frühzeitige Unterbrechung oder Rückkehr, aber die Stream's foreach -Methode unterstützt diese Methode nicht direkt. In diesem Artikel werden die Gründe erläutert und alternative Methoden zur Implementierung vorzeitiger Beendigung in Strahlverarbeitungssystemen erforscht. Weitere Lektüre: Java Stream API -Verbesserungen Stream foreach verstehen Die Foreach -Methode ist ein Terminalbetrieb, der einen Vorgang für jedes Element im Stream ausführt. Seine Designabsicht ist

Zeitstempel für Datum in Java Zeitstempel für Datum in Java Aug 30, 2024 pm 04:28 PM

Anleitung zum TimeStamp to Date in Java. Hier diskutieren wir auch die Einführung und wie man Zeitstempel in Java in ein Datum konvertiert, zusammen mit Beispielen.

Java -Programm, um das Kapselvolumen zu finden Java -Programm, um das Kapselvolumen zu finden Feb 07, 2025 am 11:37 AM

Kapseln sind dreidimensionale geometrische Figuren, die aus einem Zylinder und einer Hemisphäre an beiden Enden bestehen. Das Volumen der Kapsel kann berechnet werden, indem das Volumen des Zylinders und das Volumen der Hemisphäre an beiden Enden hinzugefügt werden. In diesem Tutorial wird erörtert, wie das Volumen einer bestimmten Kapsel in Java mit verschiedenen Methoden berechnet wird. Kapselvolumenformel Die Formel für das Kapselvolumen lautet wie folgt: Kapselvolumen = zylindrisches Volumenvolumen Zwei Hemisphäre Volumen In, R: Der Radius der Hemisphäre. H: Die Höhe des Zylinders (ohne die Hemisphäre). Beispiel 1 eingeben Radius = 5 Einheiten Höhe = 10 Einheiten Ausgabe Volumen = 1570,8 Kubikeinheiten erklären Berechnen Sie das Volumen mithilfe der Formel: Volumen = π × R2 × H (4

Wie führe ich Ihre erste Spring -Boot -Anwendung in der Spring Tool Suite aus? Wie führe ich Ihre erste Spring -Boot -Anwendung in der Spring Tool Suite aus? Feb 07, 2025 pm 12:11 PM

Spring Boot vereinfacht die Schaffung robuster, skalierbarer und produktionsbereiteter Java-Anwendungen, wodurch die Java-Entwicklung revolutioniert wird. Der Ansatz "Übereinkommen über Konfiguration", der dem Feder -Ökosystem inhärent ist, minimiert das manuelle Setup, Allo

See all articles