{"id":29104,"date":"2022-04-20T17:12:00","date_gmt":"2022-04-20T15:12:00","guid":{"rendered":"https:\/\/www.happycoders.eu\/?p=29104"},"modified":"2024-12-02T12:00:39","modified_gmt":"2024-12-02T11:00:39","slug":"java-queue-implementierungen","status":"publish","type":"post","link":"https:\/\/www.happycoders.eu\/de\/algorithmen\/java-queue-implementierungen\/","title":{"rendered":"Java Queue Implementierungen \u2013 Welche einsetzen?"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Dieser Artikel gibt einen \u00dcberblick \u00fcber alle im JDK verf\u00fcgbaren Queue-Implementierungen mitsamt ihrer Eigenschaften sowie eine Entscheidungshilfe, f\u00fcr welche Einsatzzwecke welche Implementierung am besten geeignet ist.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Der Klassenname in der folgenden Tabelle ist jeweils mit demjenigen Artikel der Tutorial-Serie verlinkt, in dem die jeweilige Queue-Implementierung mit all ihren Eigenschaften im Detail erkl\u00e4rt wird.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Eine Erkl\u00e4rung der Begriffe <em>blocking<\/em>, <em>non-blocking<\/em>, <em>fairness policy<\/em>, <em>bounded<\/em> und <em>unbounded<\/em> findest du im Artikel \u00fcber das <a href=\"\/de\/algorithmen\/java-blockingqueue\/\">BlockingQueue-Interface<\/a>.<\/p>\n\n\n\n<figure class=\"wp-block-table is-style-stripes less-line-height font-size-95\"><table><thead><tr><th>Klasse<\/th><th class=\"has-text-align-center\" data-align=\"center\">Basis<br>Daten-struktur<\/th><th class=\"has-text-align-center\" data-align=\"center\">Thread-<br>sicher?<\/th><th class=\"has-text-align-center\" data-align=\"center\">Blocking\/<br>Non-blocking<\/th><th class=\"has-text-align-center\" data-align=\"center\">Fairness<br>Policy<\/th><th class=\"has-text-align-center\" data-align=\"center\">Bounded\/<br>Unbounded<\/th><th class=\"has-text-align-center\" data-align=\"center\">Iterator Type<\/th><\/tr><\/thead><tbody><tr><td><a href=\"\/de\/algorithmen\/concurrentlinkedqueue-java\/\">ConcurrentLinkedQueue<\/a><\/td><td class=\"has-text-align-center\" data-align=\"center\">Verkettete Liste<\/td><td class=\"has-text-align-center\" data-align=\"center\">Ja<br><span style=\"font-size:90%\">(optimistisches Locking durch Compare-and-set)<\/span><\/td><td class=\"has-text-align-center\" data-align=\"center\">Non-blocking<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u2014<\/td><td class=\"has-text-align-center\" data-align=\"center\">Unbounded<\/td><td class=\"has-text-align-center\" data-align=\"center\">Weakly consistent\u00b9<\/td><\/tr><tr><td><a href=\"\/de\/algorithmen\/priorityqueue-java\/\">PriorityQueue<\/a><\/td><td class=\"has-text-align-center\" data-align=\"center\">Min-Heap<br><span style=\"font-size:90%\">(gespeichert in einem Array)<\/span><\/td><td class=\"has-text-align-center\" data-align=\"center\">Nein<\/td><td class=\"has-text-align-center\" data-align=\"center\">Non-blocking<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u2014<\/td><td class=\"has-text-align-center\" data-align=\"center\">Unbounded<\/td><td class=\"has-text-align-center\" data-align=\"center\">Fail-fast\u00b2<\/td><\/tr><tr><td><a href=\"\/de\/algorithmen\/linkedblockingqueue-java\/\">LinkedBlockingQueue<\/a><\/td><td class=\"has-text-align-center\" data-align=\"center\">Verkettete Liste<\/td><td class=\"has-text-align-center\" data-align=\"center\">Ja<br><span style=\"font-size:90%\">(pessimistisches Locking mit zwei Locks)<\/span><\/td><td class=\"has-text-align-center\" data-align=\"center\">Blocking<\/td><td class=\"has-text-align-center\" data-align=\"center\">Nicht verf\u00fcgbar<\/td><td class=\"has-text-align-center\" data-align=\"center\">Bounded<\/td><td class=\"has-text-align-center\" data-align=\"center\">Weakly consistent\u00b9<\/td><\/tr><tr><td><a href=\"\/de\/algorithmen\/arrayblockingqueue-java\/\">ArrayBlockingQueue<\/a><\/td><td class=\"has-text-align-center\" data-align=\"center\">Array<\/td><td class=\"has-text-align-center\" data-align=\"center\">Ja <br><span style=\"font-size:90%\">(pessimistisches Locking mit einem Lock)<\/span><\/td><td class=\"has-text-align-center\" data-align=\"center\">Blocking <\/td><td class=\"has-text-align-center\" data-align=\"center\">Optional<\/td><td class=\"has-text-align-center\" data-align=\"center\">Bounded<\/td><td class=\"has-text-align-center\" data-align=\"center\">Weakly consistent\u00b9<\/td><\/tr><tr><td><a href=\"\/de\/algorithmen\/priorityblockingqueue-java\/\">PriorityBlockingQueue<\/a><\/td><td class=\"has-text-align-center\" data-align=\"center\">Min-Heap<br><span style=\"font-size:90%\">(gespeichert in einem Array)<\/span><\/td><td class=\"has-text-align-center\" data-align=\"center\">Ja <br><span style=\"font-size:90%\">(pessimistisches Locking mit einem Lock)<\/span><\/td><td class=\"has-text-align-center\" data-align=\"center\">Blocking<br><span style=\"font-size:90%\">(nur dequeue)<\/span><\/td><td class=\"has-text-align-center\" data-align=\"center\">Nicht verf\u00fcgbar<\/td><td class=\"has-text-align-center\" data-align=\"center\">Unbounded<\/td><td class=\"has-text-align-center\" data-align=\"center\">Weakly consistent\u00b9<\/td><\/tr><tr><td><a href=\"\/de\/algorithmen\/delayqueue-java\/\">DelayQueue<\/a><\/td><td class=\"has-text-align-center\" data-align=\"center\">Priority Queue<\/td><td class=\"has-text-align-center\" data-align=\"center\">Ja <br><span style=\"font-size:90%\">(pessimistisches Locking mit einem Lock)<\/span><\/td><td class=\"has-text-align-center\" data-align=\"center\">Blocking<br><span style=\"font-size:90%\">(nur dequeue)<\/span><\/td><td class=\"has-text-align-center\" data-align=\"center\">Nicht verf\u00fcgbar<\/td><td class=\"has-text-align-center\" data-align=\"center\">Unbounded<\/td><td class=\"has-text-align-center\" data-align=\"center\">Weakly consistent\u00b9<\/td><\/tr><tr><td><a href=\"\/de\/algorithmen\/synchronousqueue-java\/\">SynchronousQueue<\/a><\/td><td class=\"has-text-align-center\" data-align=\"center\">Stack<br><span style=\"font-size:90%\">(impl. mit verketteter Liste)<\/span><\/td><td class=\"has-text-align-center\" data-align=\"center\">Ja<br><span style=\"font-size:90%\">(optimistisches Locking durch Compare-and-set)<\/span><\/td><td class=\"has-text-align-center\" data-align=\"center\">Blocking<\/td><td class=\"has-text-align-center\" data-align=\"center\">Optional<\/td><td class=\"has-text-align-center\" data-align=\"center\">Unbounded<\/td><td class=\"has-text-align-center\" data-align=\"center\">Der Iterator ist immer leer.<\/td><\/tr><tr><td><a href=\"\/de\/algorithmen\/linkedtransferqueue-java\/\">LinkedTransferQueue<\/a><\/td><td class=\"has-text-align-center\" data-align=\"center\">Verkettete Liste<\/td><td class=\"has-text-align-center\" data-align=\"center\">Ja<br><span style=\"font-size:90%\">(optimistisches Locking durch Compare-and-set)<\/span><\/td><td class=\"has-text-align-center\" data-align=\"center\">Blocking<br><span style=\"font-size:90%\">(nur transfer und dequeue)<\/span><\/td><td class=\"has-text-align-center\" data-align=\"center\">Nicht verf\u00fcgbar<\/td><td class=\"has-text-align-center\" data-align=\"center\">Unbounded<\/td><td class=\"has-text-align-center\" data-align=\"center\">Weakly consistent\u00b9<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"hc-footnote wp-block-paragraph\">\u00b9 Weakly consistent: Alle Elemente, die zum Zeitpunkt der Erzeugung des Interators in der Queue liegen, werden vom Iterator genau einmal durchlaufen. \u00c4nderungen, die danach erfolgen, k\u00f6nnen \u2013 m\u00fcssen aber nicht \u2013 durch den Iterator ber\u00fccksichtigt werden.<\/p>\n\n\n\n<p class=\"hc-footnote wp-block-paragraph\">\u00b2 Fail-fast: Der Iterator wirft eine <code>ConcurrentModificationException<\/code>, wenn w\u00e4hrend der Iteration Elemente in die Queue eingef\u00fcgt oder aus dieser entnommen werden.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"wann-solltest-du-welche-queue-implementierung-einsetzen\">Wann solltest du welche Queue-Implementierung einsetzen?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Anhand der Eigenschaften der Queue-Implementierungen, die in den jeweiligen Artikeln beschrieben und in der Tabelle oben zusammengefasst sind, kannst du die richtige Queue f\u00fcr jeden Einsatzzweck finden.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">F\u00fcr den tagt\u00e4glichen Gebrauch der allgemeinen Queue-Implementierungen mache ich folgende Empfehlungen:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"\/de\/algorithmen\/arraydeque-java\/\">ArrayDeque<\/a> f\u00fcr <strong>single-threaded<\/strong> Anwendungen.<\/li><li><code>ConcurrentLinkedQueue<\/code> als <strong>threadsichere, nicht blockierende<\/strong> und unbounded Queue.<\/li><li><code>ArrayBlockingQueue<\/code> als <strong>threadsichere, blockierende<\/strong>, bounded Queue, sofern du <strong>niedrige bis mittlere Contention<\/strong> zwischen Producer- und Consumer-Threads erwartest.<\/li><li><code>LinkedBlockingQueue<\/code> als <strong>threadsichere, blockierende<\/strong>, bounded Queue, wenn du <strong>hohe Contention<\/strong> zwischen Producer- und Consumer-Threads erwartest (am besten testen, welche Implementierung f\u00fcr deinen Use Case performanter ist).<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Hier das ganze noch einmal als Entscheidungsbaum:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img decoding=\"async\" width=\"1600\" height=\"696\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/java-queue-implementierungen.png\" alt=\"Entscheidungsbaum Java Queue-Implementierungen\" class=\"wp-image-29640\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/java-queue-implementierungen.png 1600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/java-queue-implementierungen-224x97.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/java-queue-implementierungen-336x146.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/java-queue-implementierungen-504x219.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/java-queue-implementierungen-672x292.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/java-queue-implementierungen-400x174.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/java-queue-implementierungen-600x261.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/java-queue-implementierungen-800x348.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/java-queue-implementierungen-944x411.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/java-queue-implementierungen-1200x522.png 1200w\" sizes=\"(max-width: 1600px) 100vw, 1600px\" \/><figcaption>Entscheidungsbaum Java Queue-Implementierungen<\/figcaption><\/figure>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"optimierte-mpmc-mpsc-spmc-und-spsc-queues\">Optimierte MPMC-, MPSC-, SPMC- und SPSC-Queues<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Alle vom JDK angebotenen threadsicheren Queue-Implementierungen k\u00f6nnen bedenkenlos in <em>multi-producer-multi-consumer<\/em>-Umgebungen eingesetzt werden. Das bedeutet, dass ein oder mehrere schreibende Threads sowie ein oder mehrere lesende Threads nebenl\u00e4ufig auf die JDK-Queues zugreifen k\u00f6nnen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Mit speziellen Mechanismen ist es m\u00f6glich Queues so zu optimieren, dass der Overhead f\u00fcr das Gew\u00e4hrleisten der Threadsicherheit minimiert wird, wenn es eine Beschr\u00e4nkung auf <em>einen<\/em> lesenden und\/oder <em>einen<\/em> schreibenden Thread gibt.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Dementsprechend unterscheidet man folgende vier F\u00e4lle:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Multi-producer-multi-consumer (MPMC)<\/li><li>Multi-producer-single-consumer (MPSC)<\/li><li>Single-producer-multi-consumer (SPMC)<\/li><li>Single-producer-single-consumer (SPSC)<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Die Open-Source-Bibliothek <a rel=\"noopener\" href=\"https:\/\/github.com\/JCTools\/JCTools\" target=\"_blank\">JCTools<\/a> bietet f\u00fcr alle vier F\u00e4lle hoch-optimierte Queue-Implementierungen.<\/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 class=\"wp-block-paragraph\">Dieser Artikel hat einen \u00dcberblick \u00fcber alle in Java verf\u00fcgbaren Queue-Implementierungen gegeben sowie eine Entscheidungshilfe, in welchen F\u00e4llen welche Queue einzusetzen ist.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In den n\u00e4chsten Teilen dieser Serie zeige ich dir, wie du Queues selbst implementieren kannst, beginnend mit der <a href=\"\/de\/algorithmen\/queue-implementieren-stack\/\">Implementierung mit einem Stack<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">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>Welche Queue-Implementierungen gibt es im JDK? Wie unterscheiden sie sich? In welchen F\u00e4llen sollte man welche Implementierung einsetzen?<\/p>\n","protected":false},"author":1,"featured_media":29394,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_seopress_titles_title":"","_seopress_titles_desc":"Welche Queue-Implementierungen gibt es im JDK? Wie unterscheiden sie sich? In welchen F\u00e4llen sollte man welche Implementierung einsetzen?","_seopress_robots_index":"","_seopress_robots_follow":"","_seopress_robots_imageindex":"","_seopress_robots_snippet":"","_seopress_robots_primary_cat":"none","_seopress_robots_breadcrumbs":"","_seopress_robots_freeze_modified_date":"","_seopress_robots_custom_modified_date":"","_seopress_robots_canonical":"","_seopress_social_fb_title":"","_seopress_social_fb_desc":"","_seopress_social_fb_img":"","_seopress_social_fb_img_attachment_id":0,"_seopress_social_fb_img_width":0,"_seopress_social_fb_img_height":0,"_seopress_social_twitter_title":"","_seopress_social_twitter_desc":"","_seopress_social_twitter_img":"","_seopress_social_twitter_img_attachment_id":0,"_seopress_social_twitter_img_width":0,"_seopress_social_twitter_img_height":0,"_seopress_redirections_value":"","_seopress_redirections_enabled":"","_seopress_redirections_enabled_regex":"","_seopress_redirections_logged_status":"both","_seopress_redirections_param":"","_seopress_redirections_type":301,"_seopress_analysis_target_kw":"queue-implementierung,queue-implementierungen,queue implementierung,queue implementierungen","_seopress_news_disabled":"","_seopress_video_disabled":"","_seopress_video":[],"_seopress_pro_schemas_manual":[{"_seopress_pro_rich_snippets_type":"none"}],"_seopress_pro_rich_snippets_disable_all":"","_seopress_pro_rich_snippets_disable":[],"_seopress_pro_schemas":[],"_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":4576,"_post_count":0,"footnotes":""},"categories":[127],"tags":[192],"class_list":["post-29104","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\/choice-2692575-1770x986c.jpg",1770,986,false],"thumbnail":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/choice-2692575-1770x986c.jpg",150,84,false],"medium":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/choice-2692575-1770x986c.jpg",300,167,false],"medium_large":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/choice-2692575-1770x986c.jpg",768,428,false],"large":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/choice-2692575-1770x986c.jpg",1024,570,false],"feature_thumb_224":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/choice-2692575-1770x986c-224x125.jpg",224,125,true],"feature_thumb_336":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/choice-2692575-1770x986c-336x187.jpg",336,187,true],"feature_thumb_504":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/choice-2692575-1770x986c-504x281.jpg",504,281,true],"feature_thumb_672":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/choice-2692575-1770x986c-672x374.jpg",672,374,true],"half_400":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/choice-2692575-1770x986c-400x223.jpg",400,223,true],"half_600":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/choice-2692575-1770x986c-600x334.jpg",600,334,true],"full_800":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/choice-2692575-1770x986c-800x446.jpg",800,446,true],"full_944":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/choice-2692575-1770x986c-944x526.jpg",944,526,true],"full_1200":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/choice-2692575-1770x986c-1200x668.jpg",1200,668,true],"wide_1180":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/choice-2692575-1770x986c-1180x490.jpg",1180,490,true],"wide_1770":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/choice-2692575-1770x986c-1770x735.jpg",1770,735,true],"1536x1536":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/choice-2692575-1770x986c.jpg",1536,856,false],"2048x2048":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/04\/choice-2692575-1770x986c.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":"Welche Queue-Implementierungen gibt es im JDK? Wie unterscheiden sie sich? In welchen F\u00e4llen sollte man welche Implementierung einsetzen?","public_identification_id":"38ff34ef24e64e9d942b00a341132be6","private_identification_id":"06701089adc7463aa406766c7d9c5710","_links":{"self":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/29104","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=29104"}],"version-history":[{"count":10,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/29104\/revisions"}],"predecessor-version":[{"id":42164,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/29104\/revisions\/42164"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/media\/29394"}],"wp:attachment":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/media?parent=29104"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/categories?post=29104"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/tags?post=29104"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}