{"id":28820,"date":"2022-04-20T17:02:47","date_gmt":"2022-04-20T15:02:47","guid":{"rendered":"https:\/\/www.happycoders.eu\/?p=28820"},"modified":"2024-11-27T15:04:32","modified_gmt":"2024-11-27T14:04:32","slug":"java-blockingqueue","status":"publish","type":"post","link":"https:\/\/www.happycoders.eu\/de\/algorithmen\/java-blockingqueue\/","title":{"rendered":"BlockingQueue-Interface in Java (mit Beispiel)"},"content":{"rendered":"\n<p>In diesem Artikel lernst du das Interface <code>java.util.concurrent.BlockingQueue<\/code> kennen. <code>BlockingQueue<\/code> erweitert das im vorherigen Teil dieser Tutorial-Serie besprochene <a href=\"\/de\/algorithmen\/java-queue\/\">Queue-Interface<\/a> um Methoden zum blockierenden Zugriff auf Queues.<\/p>\n\n\n\n<p>Bevor wir kl\u00e4ren, was \"blockierender Zugriff\" bedeutet, m\u00fcssen wir zun\u00e4chst \u00fcber den Begriff \"bounded Queue\" sprechen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"was-ist-eine-bounded-queue\">Was ist eine bounded Queue?<\/h2>\n\n\n\n<p>Wenn eine Queue nur eine begrenzte Anzahl von Elementen aufnehmen kann, spricht man von einer \"bounded Queue\". Die maximale Anzahl von Elementen wird mit \"Kapazit\u00e4t\" (englisch \"capacity\") bezeichnet und beim Erzeugen der Queue einmalig festgelegt.<\/p>\n\n\n\n<p>Die folgende Code-Zeile bspw. erzeugt eine auf 100 Elemente begrenzte <code>ArrayBlockingQueue<\/code>: <\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">Queue&lt;Integer&gt; queue = <span class=\"hljs-keyword\">new<\/span> ArrayBlockingQueue&lt;&gt;(<span class=\"hljs-number\">100<\/span>);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Ist die Anzahl der Elemente in der Queue hingegen <em>nicht<\/em> begrenzt (bzw. nur durch den zur Verf\u00fcgung stehenden Speicher), spricht man von einer \"unbounded Queue\".<\/p>\n\n\n\n<p>(Dieselbe Definition gilt \u00fcbrigens f\u00fcr alle Datenstrukturen, z. B. auch f\u00fcr Stacks und Deques.)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"was-ist-eine-blockierende-queue\">Was ist eine blockierende Queue?<\/h2>\n\n\n\n<p>Bei den Queue-Operationen \"Enqueue\" und \"Dequeue\" k\u00f6nnen zwei Sonderf\u00e4lle auftreten:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Wir k\u00f6nnten versuchen ein Element in eine bounded Queue einzuf\u00fcgen, die ihre Kapazit\u00e4tsgrenze erreicht hat \u2013 oder anders gesagt: die voll ist.<\/li><li>Wir k\u00f6nnten versuchen ein Element aus einer leeren Queue zu entnehmen.<\/li><\/ul>\n\n\n\n<p>Eine <em>nicht<\/em> blockierende (\"non-blocking\") Queue liefert in solchen F\u00e4llen einen bestimmten R\u00fcckgabewert oder wirft eine Exception (s. <a href=\"\/de\/algorithmen\/java-queue\/#java-queue-methoden\">Abschnitt \"Queue-Methoden\" im Artikel \u00fcber Java-Queues<\/a>).<\/p>\n\n\n\n<p>Eine <em>blockierende<\/em> Queue hingegen bietet zus\u00e4tzliche Methoden, die darauf warten, dass die gew\u00fcnschte Operation ausgef\u00fchrt werden kann:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Enqueue-Methoden, die beim Einf\u00fcgen in eine volle bounded Queue warten, bis diese wieder freie Kapazit\u00e4ten hat (dazu muss ein ander Thread ein Element entnehmen).<\/li><li>Dequeue-Methoden, die beim Entnehmen eines Element aus einer leeren Queue darauf warten, dass diese nicht mehr leer ist (dazu muss ein anderer Thread ein Element einf\u00fcgen).<\/li><\/ul>\n\n\n\n<p>Diese zus\u00e4tzlichen Methoden sind im <code>BlockingQueue<\/code>-Interface definiert und werden im folgenden Kapitel erl\u00e4utert.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"fairness-policy\">Fairness Policy<\/h3>\n\n\n\n<p>Blockierende Methoden werden dabei nicht automatisch in der Reihenfolge bedient, in der sie aufgerufen wurden. Die Abarbeitung in Aufrufreihenfolge kann bei einigen Queue-Implementierungen durch eine optionale \"Fairness Policy\" aktiviert werden. Diese erh\u00f6ht allerdings den Overhead und verringert damit den Durchsatz der Queue massiv. In der Regel ist die Aktivierung der \"Fairness Policy\" nicht n\u00f6tig.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"blockingqueue-interface\">BlockingQueue Interface<\/h2>\n\n\n\n<p>Die blockierenden Enqueue- und Dequeue-Operationen gibt es in jeweils zwei Varianten. Die erste Variante wartet unbegrenzt lange. Die zweite Variante gibt nach Ablauf einer vorgegebenen Wartezeit auf und liefert <code>false<\/code> bzw. <code>null<\/code> zur\u00fcck.<\/p>\n\n\n\n<p>Die folgende Tabelle zeigt in den ersten zwei Spalten die nicht blockierenden Methoden, die <code>BlockingQueue<\/code> von <code>Queue<\/code> erbt (und die wir im <a href=\"\/de\/algorithmen\/java-queue\/#java-queue-methoden\">vorherigen Teil des Tutorials<\/a> besprochen haben). In der dritten und vierten Spalte findest du die hinzugekommenden, blockierenden Methoden:<\/p>\n\n\n\n<figure class=\"wp-block-table is-style-stripes\"><table><thead><tr><th style=\"border-bottom:none\"><\/th><th colspan=\"2\" style=\"text-align:center;border-bottom:none\">Nicht blockierend<br>(geerbt von <code>Queue<\/code>)<\/th><th colspan=\"2\" style=\"text-align:center;border-bottom:none\">Blockierend<br>(neu in <code>BlockingQueue<\/code>)<\/th><\/tr><tr><th><\/th><th>Exception<\/th><th>R\u00fcckgabewert<\/th><th>Blockiert<\/th><th>Blockiert<br>mit Timeout<\/th><\/tr><\/thead><tbody><tr><td>Element anh\u00e4ngen<br>(<em>enqueue<\/em>):<\/td><td><code>add(E e)<\/code><\/td><td><code>offer(E e)<\/code><\/td><td><code>put(E e)<\/code><\/td><td><code>offer(E e,<br>&nbsp; long timeout,<br>&nbsp; TimeUnit unit)<\/code><\/td><\/tr><tr><td>Element entnehmen<br>(<em>dequeue<\/em>):<\/td><td><code>remove()<\/code><\/td><td><code>poll()<\/code><\/td><td><code>take()<\/code><\/td><td><code>poll(<br>&nbsp; long timeout,<br>&nbsp; TimeUnit unit)<\/code><\/td><\/tr><tr><td>Element ansehen<br>(<em>examine<\/em>):<\/td><td><code>element()<\/code><\/td><td><code>peek()<\/code><\/td><td>\u2013<\/td><td>\u2013<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Der folgende Abschnitt beschreibt die <code>BlockingQueue<\/code>-Methoden im Einzelnen<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"blockingqueue-methoden\">BlockingQueue Methoden<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">BlockingQueue.put()<\/h4>\n\n\n\n<p>Die <code>put()<\/code>-Methode f\u00fcgt, sofern Platz vorhanden ist, ein Element in die Queue ein. Ist die Kapazit\u00e4tsgrenze der Queue hingegen erreicht, blockiert die Methode solange, bis Platz freigeworden ist.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">BlockingQueue.offer() mit Timeout<\/h4>\n\n\n\n<p>Auch die <code>offer()<\/code>-Methode f\u00fcgt ein Element ein, wenn in der Queue noch Platz ist. Andernfalls wartet die Methode die angegebene Zeit. Wird in dieser Zeit ein Platz frei, wird das Element eingef\u00fcgt und die Methode gibt <code>true<\/code> zur\u00fcck. L\u00e4uft die Wartezeit hingegen ab, ohne dass ein Platz freigeworden ist, gibt die Methode <code>false<\/code> zur\u00fcck.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">BlockingQueue.take()<\/h4>\n\n\n\n<p>Diese Methode entnimmt ein Element vom Kopf der Queue, sofern die Queue nicht leer ist. Bei einer leeren Queue blockiert <code>take()<\/code> solange, bis ein Element verf\u00fcgbar geworden ist und gibt dieses dann zur\u00fcck.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">BlockingQueue.poll() mit Timeout<\/h4>\n\n\n\n<p>Auch <code>poll()<\/code> entnimmt ein Element vom Kopf der Queue, wenn diese nicht leer ist. Ist die Queue hingegen leer, wartet die Methode die angegebene Zeit. Sofern in der Wartezeit ein Element verf\u00fcgbar wird, wird dieses entnommen und zur\u00fcckgegeben. L\u00e4uft die Wartezeit ergebnislos ab, gibt die Methode <code>null<\/code> zur\u00fcck.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"interruptedexception-bei-blockierenden-methoden\">InterruptedException bei blockierenden Methoden<\/h3>\n\n\n\n<p>Alle blockierenden Methoden werfen eine <code>InterruptedException<\/code>, wenn auf dem wartenden Thread die <code>interrupt()<\/code>-Methode aufgerufen wird. Mit <code>interrupt()<\/code> sollten wartende Threads abgebrochen werden, wenn das Warten nicht mehr n\u00f6tig ist.<\/p>\n\n\n\n<p>Dies ist z. B. beim Herunterfahren der Applikation der Fall. Dabei wird eventuell das Ereignis, auf das die blockierende Methode wartet, nicht mehr eintreten. Die Methode w\u00fcrde aber dennoch auf den Eintritt des Ereignisses warten und damit ein regul\u00e4res Herunterfahren der Applikation verhindern. Das Abbrechen der wartenden Threads mit <code>interrupt()<\/code> erm\u00f6glicht ein sauberes Herunterfahren.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"java-blockingqueue-beispiel\">Java BlockingQueue Beispiel<\/h2>\n\n\n\n<p>Der folgende Quellcode zeigt ein Beispiel, welches aufgrund der Nebenl\u00e4ufigkeit deutlich komplexer ausf\u00e4llt als das Beispiel mit einer nicht-blockierenden Queue (\u2192 <a href=\"https:\/\/github.com\/SvenWoltmann\/java-collections-guide\/blob\/main\/src\/main\/java\/eu\/happycoders\/demos\/queue\/BlockingQueueExample.java\" target=\"_blank\" rel=\"noopener\">Code in GitHub<\/a>):<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">BlockingQueueExample<\/span> <\/span>{\n  <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> <span class=\"hljs-keyword\">long<\/span> startTime = System.currentTimeMillis();\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">(String&#091;] args)<\/span> <span class=\"hljs-keyword\">throws<\/span> InterruptedException <\/span>{\n    BlockingQueue&lt;Integer&gt; queue = <span class=\"hljs-keyword\">new<\/span> LinkedBlockingQueue&lt;&gt;(<span class=\"hljs-number\">3<\/span>);\n    ScheduledExecutorService pool = Executors.newScheduledThreadPool(<span class=\"hljs-number\">10<\/span>);\n\n    <span class=\"hljs-comment\">\/\/ Start reading from the queue immediately, every 3 seconds<\/span>\n    <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> i = <span class=\"hljs-number\">0<\/span>; i &lt; <span class=\"hljs-number\">10<\/span>; i++) {\n      <span class=\"hljs-keyword\">int<\/span> delaySeconds = i * <span class=\"hljs-number\">3<\/span>;\n      pool.schedule(() -&gt; dequeue(queue), delaySeconds, TimeUnit.SECONDS);\n    }\n\n    <span class=\"hljs-comment\">\/\/ Start writing to the queue after 3.5 seconds (so there are already 2<\/span>\n    <span class=\"hljs-comment\">\/\/ threads waiting), every 1 seconds (so that the queue fills faster than<\/span>\n    <span class=\"hljs-comment\">\/\/ it's emptied, so that we see a full queue soon)<\/span>\n    <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> i = <span class=\"hljs-number\">0<\/span>; i &lt; <span class=\"hljs-number\">10<\/span>; i++) {\n      <span class=\"hljs-keyword\">int<\/span> element = i; <span class=\"hljs-comment\">\/\/ Assign to an effectively final variable<\/span>\n      <span class=\"hljs-keyword\">int<\/span> delayMillis = <span class=\"hljs-number\">3500<\/span> + i * <span class=\"hljs-number\">1000<\/span>;\n      pool.schedule(() -&gt; enqueue(queue, element), delayMillis, TimeUnit.MILLISECONDS);\n    }\n\n    pool.shutdown();\n    pool.awaitTermination(<span class=\"hljs-number\">1<\/span>, TimeUnit.MINUTES);\n  }\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">enqueue<\/span><span class=\"hljs-params\">(BlockingQueue&lt;Integer&gt; queue, <span class=\"hljs-keyword\">int<\/span> element)<\/span> <\/span>{\n    log(<span class=\"hljs-string\">\"Calling queue.put(%d) (queue = %s)...\"<\/span>, element, queue);\n    <span class=\"hljs-keyword\">try<\/span> {\n      queue.put(element);\n      log(<span class=\"hljs-string\">\"queue.put(%d) returned (queue = %s)\"<\/span>, element, queue);\n    } <span class=\"hljs-keyword\">catch<\/span> (InterruptedException e) {\n      Thread.currentThread().interrupt();\n    }\n  }\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">dequeue<\/span><span class=\"hljs-params\">(BlockingQueue&lt;Integer&gt; queue)<\/span> <\/span>{\n    log(<span class=\"hljs-string\">\"    Calling queue.take() (queue = %s)...\"<\/span>, queue);\n    <span class=\"hljs-keyword\">try<\/span> {\n      Integer element = queue.take();\n      log(<span class=\"hljs-string\">\"    queue.take() returned %d (queue = %s)\"<\/span>, element, queue);\n    } <span class=\"hljs-keyword\">catch<\/span> (InterruptedException e) {\n      Thread.currentThread().interrupt();\n    }\n  }\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">log<\/span><span class=\"hljs-params\">(String format, Object... args)<\/span> <\/span>{\n    System.out.printf(\n        Locale.US,\n        <span class=\"hljs-string\">\"&#091;%4.1fs] &#091;%-16s] %s%n\"<\/span>,\n        (System.currentTimeMillis() - startTime) \/ <span class=\"hljs-number\">1000.0<\/span>,\n        Thread.currentThread().getName(),\n        String.format(format, args));\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In diesem Beispiel erstellen wir eine blocking, bounded Queue mit der Kapazit\u00e4t 3 und schedulen jeweils zehn Enqueue- und zehn Dequeue-Operationen.<\/p>\n\n\n\n<p>Die Enqueue-Operationen beginnen sp\u00e4ter, so dass wir am Anfang blockierende Dequeue-Operationen sehen k\u00f6nnen. Au\u00dferdem erfolgen die Enqueue-Operationen in k\u00fcrzen Abst\u00e4nden, so dass die Kapazit\u00e4tsgrenze der Queue nach einer Weile erreicht ist und wir blockierende Enqueue-Operationen sehen k\u00f6nnen.<\/p>\n\n\n\n<p>Hier die Ausgabe des Programms:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"Klartext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">&#091; 0.0s] &#091;pool-1-thread-1 ]     Calling queue.take() (queue = &#091;])...\n&#091; 3.0s] &#091;pool-1-thread-3 ]     Calling queue.take() (queue = &#091;])...\n&#091; 3.5s] &#091;pool-1-thread-2 ] Calling queue.put(0) (queue = &#091;])...\n&#091; 3.5s] &#091;pool-1-thread-2 ] queue.put(0) returned (queue = &#091;])\n&#091; 3.5s] &#091;pool-1-thread-1 ]     queue.take() returned 0 (queue = &#091;])\n&#091; 4.5s] &#091;pool-1-thread-10] Calling queue.put(1) (queue = &#091;])...\n&#091; 4.5s] &#091;pool-1-thread-10] queue.put(1) returned (queue = &#091;])\n&#091; 4.5s] &#091;pool-1-thread-3 ]     queue.take() returned 1 (queue = &#091;])\n&#091; 5.5s] &#091;pool-1-thread-8 ] Calling queue.put(2) (queue = &#091;])...\n&#091; 5.5s] &#091;pool-1-thread-8 ] queue.put(2) returned (queue = &#091;2])\n&#091; 6.0s] &#091;pool-1-thread-9 ]     Calling queue.take() (queue = &#091;2])...\n&#091; 6.0s] &#091;pool-1-thread-9 ]     queue.take() returned 2 (queue = &#091;])\n&#091; 6.5s] &#091;pool-1-thread-5 ] Calling queue.put(3) (queue = &#091;])...\n&#091; 6.5s] &#091;pool-1-thread-5 ] queue.put(3) returned (queue = &#091;3])\n&#091; 7.5s] &#091;pool-1-thread-6 ] Calling queue.put(4) (queue = &#091;3])...\n&#091; 7.5s] &#091;pool-1-thread-6 ] queue.put(4) returned (queue = &#091;3, 4])\n&#091; 8.5s] &#091;pool-1-thread-7 ] Calling queue.put(5) (queue = &#091;3, 4])...\n&#091; 8.5s] &#091;pool-1-thread-7 ] queue.put(5) returned (queue = &#091;3, 4, 5])\n&#091; 9.0s] &#091;pool-1-thread-4 ]     Calling queue.take() (queue = &#091;3, 4, 5])...\n&#091; 9.0s] &#091;pool-1-thread-4 ]     queue.take() returned 3 (queue = &#091;4, 5])\n&#091; 9.5s] &#091;pool-1-thread-2 ] Calling queue.put(6) (queue = &#091;4, 5])...\n&#091; 9.5s] &#091;pool-1-thread-2 ] queue.put(6) returned (queue = &#091;4, 5, 6])\n&#091;10.5s] &#091;pool-1-thread-1 ] Calling queue.put(7) (queue = &#091;4, 5, 6])...\n&#091;11.5s] &#091;pool-1-thread-10] Calling queue.put(8) (queue = &#091;4, 5, 6])...\n&#091;12.0s] &#091;pool-1-thread-3 ]     Calling queue.take() (queue = &#091;4, 5, 6])...\n&#091;12.0s] &#091;pool-1-thread-3 ]     queue.take() returned 4 (queue = &#091;5, 6, 7])\n&#091;12.0s] &#091;pool-1-thread-1 ] queue.put(7) returned (queue = &#091;5, 6, 7])\n&#091;12.5s] &#091;pool-1-thread-8 ] Calling queue.put(9) (queue = &#091;5, 6, 7])...\n&#091;15.0s] &#091;pool-1-thread-9 ]     Calling queue.take() (queue = &#091;5, 6, 7])...\n&#091;15.0s] &#091;pool-1-thread-9 ]     queue.take() returned 5 (queue = &#091;6, 7, 8])\n&#091;15.0s] &#091;pool-1-thread-10] queue.put(8) returned (queue = &#091;6, 7, 8])\n&#091;18.0s] &#091;pool-1-thread-5 ]     Calling queue.take() (queue = &#091;6, 7, 8])...\n&#091;18.0s] &#091;pool-1-thread-5 ]     queue.take() returned 6 (queue = &#091;7, 8, 9])\n&#091;18.0s] &#091;pool-1-thread-8 ] queue.put(9) returned (queue = &#091;7, 8, 9])\n&#091;21.0s] &#091;pool-1-thread-6 ]     Calling queue.take() (queue = &#091;7, 8, 9])...\n&#091;21.0s] &#091;pool-1-thread-6 ]     queue.take() returned 7 (queue = &#091;8, 9])\n&#091;24.0s] &#091;pool-1-thread-7 ]     Calling queue.take() (queue = &#091;8, 9])...\n&#091;24.0s] &#091;pool-1-thread-7 ]     queue.take() returned 8 (queue = &#091;9])\n&#091;27.0s] &#091;pool-1-thread-4 ]     Calling queue.take() (queue = &#091;9])...\n&#091;27.0s] &#091;pool-1-thread-4 ]     queue.take() returned 9 (queue = &#091;])<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Klartext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Zu Beginn ist die Queue leer, so dass die ersten zwei Leseversuche (nach 0 und 3 s) blockieren.<\/p>\n\n\n\n<p>Nach 3,5 s (nachdem also zwei lesende Threads an der Queue warten) beginnt das Programm sek\u00fcndlich in die Queue zu schreiben. Man sieht in der Ausgabe sch\u00f6n, wie dabei jeweils ein lesender Thread fortgesetzt wird und das angeh\u00e4ngte Element sofort wieder entnimmt (bei 3,5 und 4,5 s).<\/p>\n\n\n\n<p>Da das Programm dreimal so schnell in die Queue schreibt wie es daraus liest, blockiert nach 10,5 s der Versuch eine 7 in die Queue zu schreiben, da diese mit den Elementen [4, 5, 6] ihre Kapazit\u00e4tsgrenze von 3 erreicht hat.<\/p>\n\n\n\n<p>Erst nachdem nach 12 s die 4 aus der Queue entnommen wurde, kann die 7 eingef\u00fcgt werden. F\u00fcr die 8 und die 9 sehen wir ein entsprechendes Verhalten.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"blockingqueue-implementierungen\">BlockingQueue Implementierungen<\/h2>\n\n\n\n<p>Im JDK gibt es f\u00fcnf Implementierungen des <code>BlockingQueue<\/code>-Interfaces mit jeweils spezifischen Eigenschaften. In dem folgenden UML-Klassendiagramm sind diese mitsamt ihrem Interface farbig hinterlegt:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full_800\"><img decoding=\"async\" width=\"800\" height=\"500\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/java-BlockingQueue-class-hierarchy-800x500.png\" alt=\"BlockingQueue Interface in der Klassenhierarchie\" class=\"wp-image-28995\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/java-BlockingQueue-class-hierarchy-800x500.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/java-BlockingQueue-class-hierarchy-224x140.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/java-BlockingQueue-class-hierarchy-336x210.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/java-BlockingQueue-class-hierarchy-504x315.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/java-BlockingQueue-class-hierarchy-672x420.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/java-BlockingQueue-class-hierarchy-400x250.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/java-BlockingQueue-class-hierarchy-600x375.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/java-BlockingQueue-class-hierarchy-944x590.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/java-BlockingQueue-class-hierarchy-1200x750.png 1200w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/java-BlockingQueue-class-hierarchy.png 1600w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption>BlockingQueue Interface in der Klassenhierarchie<\/figcaption><\/figure><\/div>\n\n\n\n<p>Die Implementierungen werden jeweils in separaten Teilen des Tutorials behandelt. Dort werden deren Eigenschaften vorgestellt und anhand dieser erl\u00e4utert, unter welchen Voraussetzungen die jeweilige Implementierung eingesetzt werden sollte. Folgende Links f\u00fchren zu den entsprechenden Artikeln:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"\/de\/algorithmen\/linkedblockingqueue-java\/\">LinkedBlockingQueue<\/a><\/li><li><a href=\"\/de\/algorithmen\/arrayblockingqueue-java\/\">ArrayBlockingQueue<\/a><\/li><li><a href=\"\/de\/algorithmen\/priorityblockingqueue-java\/\">PriorityBlockingQueue<\/a><\/li><li><a href=\"\/de\/algorithmen\/delayqueue-java\/\">DelayQueue<\/a><\/li><li><a href=\"\/de\/algorithmen\/synchronousqueue-java\/\">SynchronousQueue<\/a><\/li><\/ul>\n\n\n\n<p>Du gelangst zu diesen Artikeln auch jederzeit \u00fcber die Tutorial-Navigation am rechten Rand.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"zusammenfassung-und-ausblick\">Zusammenfassung und Ausblick<\/h2>\n\n\n\n<p>Dieser Artikel hat zun\u00e4chst die Unterschiede zwischen bounded\/unbounded und blocking\/non-blocking Queues erl\u00e4utert. Im Anschluss hast du das <code>BlockingQueue<\/code>-Interface und dessen Methoden <code>put()<\/code>, <code>offer()<\/code>, <code>take()<\/code> und <code>poll()<\/code> kennengelernt.<\/p>\n\n\n\n<p>In den folgenden Teilen dieser Serie werden wir alle <code>Queue<\/code>- und <code>BlockingQueue<\/code>-Implementierung und deren Eigenschaften genauer unter die Lupe nehmen.<\/p>\n\n\n\n<p>Wenn du noch Fragen hast, stelle sie gerne \u00fcber die Kommentar-Funktion. M\u00f6chtest du \u00fcber neue Tutorials und Artikel informiert werden? Dann <a href=\"#\" data-formkit-toggle=\"d8ee997126\">klicke hier<\/a>, um dich f\u00fcr den HappyCoders.eu-Newsletter anzumelden.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Wie benutzt man das BlockingQueue-Interface? Welche Methoden bietet es an? Was sind blocking \/ unblocking, bounded \/ unbounded Queues?<\/p>\n","protected":false},"author":1,"featured_media":29399,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_seopress_robots_primary_cat":"none","_seopress_titles_title":"","_seopress_titles_desc":"Wie benutzt man das BlockingQueue-Interface in Java? Welche Methoden bietet es? Was sind blocking, unblocking, bounded, unbounded Queues?","_seopress_robots_index":"","_uag_custom_page_level_css":"","_wp_convertkit_post_meta":{"form":"-1","landing_page":"","tag":"0","restrict_content":"0"},"_metis_text_type":"standard","_metis_text_length":13423,"_post_count":0,"footnotes":""},"categories":[127],"tags":[192],"class_list":["post-28820","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-algorithmen","tag-datenstrukturen-queue"],"uagb_featured_image_src":{"full":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/balance-6815204-1770x986-1.jpg",1770,986,false],"thumbnail":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/balance-6815204-1770x986-1.jpg",150,84,false],"medium":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/balance-6815204-1770x986-1.jpg",300,167,false],"medium_large":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/balance-6815204-1770x986-1.jpg",768,428,false],"large":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/balance-6815204-1770x986-1.jpg",1024,570,false],"feature_thumb_224":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/balance-6815204-1770x986-1-224x125.jpg",224,125,true],"feature_thumb_336":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/balance-6815204-1770x986-1-336x187.jpg",336,187,true],"feature_thumb_504":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/balance-6815204-1770x986-1-504x281.jpg",504,281,true],"feature_thumb_672":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/balance-6815204-1770x986-1-672x374.jpg",672,374,true],"half_400":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/balance-6815204-1770x986-1-400x223.jpg",400,223,true],"half_600":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/balance-6815204-1770x986-1-600x334.jpg",600,334,true],"full_800":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/balance-6815204-1770x986-1-800x446.jpg",800,446,true],"full_944":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/balance-6815204-1770x986-1-944x526.jpg",944,526,true],"full_1200":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/balance-6815204-1770x986-1-1200x668.jpg",1200,668,true],"wide_1180":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/balance-6815204-1770x986-1-1180x490.jpg",1180,490,true],"wide_1770":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/balance-6815204-1770x986-1-1770x735.jpg",1770,735,true],"1536x1536":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/balance-6815204-1770x986-1.jpg",1536,856,false],"2048x2048":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/balance-6815204-1770x986-1.jpg",1770,986,false]},"uagb_author_info":{"display_name":"Sven Woltmann","author_link":"https:\/\/www.happycoders.eu\/de\/author\/sven\/"},"uagb_comment_info":0,"uagb_excerpt":"Wie benutzt man das BlockingQueue-Interface? Welche Methoden bietet es an? Was sind blocking \/ unblocking, bounded \/ unbounded Queues?","public_identification_id":"4a00fdbad3784e7b80945b6fe93c1f8a","private_identification_id":"0fafd6beadfc46e39423ddb49d49b1b1","_links":{"self":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/28820","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/comments?post=28820"}],"version-history":[{"count":10,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/28820\/revisions"}],"predecessor-version":[{"id":41696,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/28820\/revisions\/41696"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/media\/29399"}],"wp:attachment":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/media?parent=28820"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/categories?post=28820"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/tags?post=28820"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}