[{"data":1,"prerenderedAt":1416},["ShallowReactive",2],{"blog-\u002Fblog\u002Fjava-queue-deque-arraydeque-priorityqueue":3},{"id":4,"title":5,"body":6,"description":1402,"difficulty":1403,"extension":1404,"framework":1405,"frameworkSlug":99,"meta":1406,"navigation":133,"order":161,"path":1407,"qaPath":1408,"seo":1409,"stem":1410,"subtopic":1411,"topic":1412,"topicSlug":1413,"updated":1414,"__hash__":1415},"blog\u002Fblog\u002Fjava-queue-deque-arraydeque-priorityqueue.md","Java Queue & Deque — ArrayDeque, PriorityQueue & Producer-Consumer",{"type":7,"value":8,"toc":1390},"minimark",[9,14,64,68,94,240,258,262,303,394,417,421,481,553,579,583,603,646,671,675,709,844,864,868,896,1000,1027,1031,1063,1174,1214,1218,1251,1297,1309,1313,1386],[10,11,13],"h2",{"id":12},"queues-are-about-ends-not-indexing","Queues are about ends, not indexing",[15,16,17,18,22,23,27,28,31,32,35,36,38,39,42,43,46,47,50,51,55,56,59,60,63],"p",{},"A ",[19,20,21],"code",{},"List"," lets you reach any position; a ",[24,25,26],"strong",{},"queue"," deliberately gives that up. The whole\npoint of the ",[19,29,30],{},"Queue"," family is to constrain access to the ",[24,33,34],{},"ends"," of a collection so the\ndata structure underneath can be fast and the intent of your code is obvious. ",[19,37,30],{},"\nmodels ",[24,40,41],{},"FIFO"," (first-in, first-out): you add at the ",[24,44,45],{},"tail"," and take from the ",[24,48,49],{},"head",".\nBut \"queue\" is really a contract about ",[52,53,54],"em",{},"which element comes out next",", not a promise of\nFIFO — ",[19,57,58],{},"PriorityQueue"," hands you the smallest element, and a ",[19,61,62],{},"Deque"," used as a stack hands\nyou the most recent. This guide walks the interface hierarchy and the implementations that\nback it, with an eye on the design judgment interviewers actually probe.",[10,65,67],{"id":66},"the-two-method-families","The two method families",[15,69,70,71,73,74,77,78,81,82,85,86,89,90,93],{},"The single most important thing to internalize about ",[19,72,30],{}," is that every core operation\nships in ",[24,75,76],{},"two flavours",": one that ",[24,79,80],{},"throws"," on failure and one that returns a ",[24,83,84],{},"special\nvalue"," (",[19,87,88],{},"false"," or ",[19,91,92],{},"null","). This is not redundancy — it encodes intent. The throwing form\nsays \"failure here is a bug, surface it loudly.\" The returning form says \"emptiness or\nfullness is normal control flow I will check.\"",[95,96,101],"pre",{"className":97,"code":98,"language":99,"meta":100,"style":100},"language-java shiki shiki-themes github-light github-dark","Queue\u003CInteger> q = new ArrayDeque\u003C>();\n\nq.add(1);        \u002F\u002F throws IllegalStateException if a bounded queue is full\nq.offer(1);      \u002F\u002F returns false instead of throwing\n\nq.remove();      \u002F\u002F throws NoSuchElementException when empty\nq.poll();        \u002F\u002F returns null when empty\n\nq.element();     \u002F\u002F throws NoSuchElementException when empty\nq.peek();        \u002F\u002F returns null when empty\n","java","",[19,102,103,128,135,159,177,182,196,210,215,228],{"__ignoreMap":100},[104,105,108,112,116,119,122,125],"span",{"class":106,"line":107},"line",1,[104,109,111],{"class":110},"sVt8B","Queue\u003C",[104,113,115],{"class":114},"szBVR","Integer",[104,117,118],{"class":110},"> q ",[104,120,121],{"class":114},"=",[104,123,124],{"class":114}," new",[104,126,127],{"class":110}," ArrayDeque\u003C>();\n",[104,129,131],{"class":106,"line":130},2,[104,132,134],{"emptyLinePlaceholder":133},true,"\n",[104,136,138,141,145,148,152,155],{"class":106,"line":137},3,[104,139,140],{"class":110},"q.",[104,142,144],{"class":143},"sScJk","add",[104,146,147],{"class":110},"(",[104,149,151],{"class":150},"sj4cs","1",[104,153,154],{"class":110},");        ",[104,156,158],{"class":157},"sJ8bj","\u002F\u002F throws IllegalStateException if a bounded queue is full\n",[104,160,162,164,167,169,171,174],{"class":106,"line":161},4,[104,163,140],{"class":110},[104,165,166],{"class":143},"offer",[104,168,147],{"class":110},[104,170,151],{"class":150},[104,172,173],{"class":110},");      ",[104,175,176],{"class":157},"\u002F\u002F returns false instead of throwing\n",[104,178,180],{"class":106,"line":179},5,[104,181,134],{"emptyLinePlaceholder":133},[104,183,185,187,190,193],{"class":106,"line":184},6,[104,186,140],{"class":110},[104,188,189],{"class":143},"remove",[104,191,192],{"class":110},"();      ",[104,194,195],{"class":157},"\u002F\u002F throws NoSuchElementException when empty\n",[104,197,199,201,204,207],{"class":106,"line":198},7,[104,200,140],{"class":110},[104,202,203],{"class":143},"poll",[104,205,206],{"class":110},"();        ",[104,208,209],{"class":157},"\u002F\u002F returns null when empty\n",[104,211,213],{"class":106,"line":212},8,[104,214,134],{"emptyLinePlaceholder":133},[104,216,218,220,223,226],{"class":106,"line":217},9,[104,219,140],{"class":110},[104,221,222],{"class":143},"element",[104,224,225],{"class":110},"();     ",[104,227,195],{"class":157},[104,229,231,233,236,238],{"class":106,"line":230},10,[104,232,140],{"class":110},[104,234,235],{"class":143},"peek",[104,237,206],{"class":110},[104,239,209],{"class":157},[15,241,242,243,245,246,245,248,250,251,245,253,245,255,257],{},"Pick ",[19,244,166],{},"\u002F",[19,247,203],{},[19,249,235],{}," as your default for bounded or concurrent queues where running\nempty or full is expected. Reserve ",[19,252,144],{},[19,254,189],{},[19,256,222],{}," for the cases where an empty\nqueue genuinely means a programming error you want to crash on.",[10,259,261],{"id":260},"deque-both-ends-in-play","Deque: both ends in play",[15,263,264,267,268,270,271,274,275,278,279,282,283,245,286,289,290,245,293,289,296,245,299,302],{},[19,265,266],{},"Deque\u003CE>"," (\"double-ended queue\", said \"deck\") extends ",[19,269,30],{}," and lets you insert, remove,\nand examine at ",[24,272,273],{},"both"," the head and the tail. Each operation gains a ",[19,276,277],{},"First"," and a ",[19,280,281],{},"Last","\nvariant, and each of those keeps the throwing-vs-returning split — so the API doubles into a\ntidy grid: ",[19,284,285],{},"addFirst",[19,287,288],{},"offerFirst",", ",[19,291,292],{},"removeLast",[19,294,295],{},"pollLast",[19,297,298],{},"getFirst",[19,300,301],{},"peekFirst",", and so\non.",[95,304,306],{"className":97,"code":305,"language":99,"meta":100,"style":100},"Deque\u003CInteger> d = new ArrayDeque\u003C>();\nd.addFirst(1);     \u002F\u002F [1]\nd.addLast(2);      \u002F\u002F [1, 2]\nd.peekFirst();     \u002F\u002F 1   (returns null if empty)\nd.getLast();       \u002F\u002F 2   (throws if empty)\nd.pollFirst();     \u002F\u002F removes 1 -> [2]\n",[19,307,308,324,341,358,369,382],{"__ignoreMap":100},[104,309,310,313,315,318,320,322],{"class":106,"line":107},[104,311,312],{"class":110},"Deque\u003C",[104,314,115],{"class":114},[104,316,317],{"class":110},"> d ",[104,319,121],{"class":114},[104,321,124],{"class":114},[104,323,127],{"class":110},[104,325,326,329,331,333,335,338],{"class":106,"line":130},[104,327,328],{"class":110},"d.",[104,330,285],{"class":143},[104,332,147],{"class":110},[104,334,151],{"class":150},[104,336,337],{"class":110},");     ",[104,339,340],{"class":157},"\u002F\u002F [1]\n",[104,342,343,345,348,350,353,355],{"class":106,"line":137},[104,344,328],{"class":110},[104,346,347],{"class":143},"addLast",[104,349,147],{"class":110},[104,351,352],{"class":150},"2",[104,354,173],{"class":110},[104,356,357],{"class":157},"\u002F\u002F [1, 2]\n",[104,359,360,362,364,366],{"class":106,"line":161},[104,361,328],{"class":110},[104,363,301],{"class":143},[104,365,225],{"class":110},[104,367,368],{"class":157},"\u002F\u002F 1   (returns null if empty)\n",[104,370,371,373,376,379],{"class":106,"line":179},[104,372,328],{"class":110},[104,374,375],{"class":143},"getLast",[104,377,378],{"class":110},"();       ",[104,380,381],{"class":157},"\u002F\u002F 2   (throws if empty)\n",[104,383,384,386,389,391],{"class":106,"line":184},[104,385,328],{"class":110},[104,387,388],{"class":143},"pollFirst",[104,390,225],{"class":110},[104,392,393],{"class":157},"\u002F\u002F removes 1 -> [2]\n",[15,395,396,397,400,401,403,404,407,408,410,411,413,414,416],{},"Because ",[24,398,399],{},"both ends are O(1)",", a ",[19,402,62],{}," is the one structure that can serve as ",[52,405,406],{},"either"," a\nFIFO queue or a LIFO stack. The inherited plain-",[19,409,30],{}," methods simply map insertion to the\n",[24,412,45],{}," and removal to the ",[24,415,49],{},", giving you FIFO for free.",[10,418,420],{"id":419},"deque-as-a-stack-and-goodbye-legacy-stack","Deque as a stack — and goodbye, legacy Stack",[15,422,423,425,426,289,429,432,433,435,436,438,439,441,442,289,444,441,446,289,449,441,451,453,454,457,458,461,462,465,466,469,470,472,473,476,477,480],{},[19,424,62],{}," also exposes ",[19,427,428],{},"push",[19,430,431],{},"pop",", and ",[19,434,235],{},", which all operate on the ",[24,437,49],{}," as a LIFO\nstack: ",[19,440,428],{}," is ",[19,443,285],{},[19,445,431],{},[19,447,448],{},"removeFirst",[19,450,235],{},[19,452,301],{},". This is the\n",[24,455,456],{},"recommended modern stack",", and the reason is worth knowing. The old ",[19,459,460],{},"java.util.Stack","\nextends ",[19,463,464],{},"Vector",", which makes every operation ",[24,467,468],{},"synchronized"," (slow, and pointless single\n-threaded) and — worse — leaks ",[19,471,464],{},"'s index methods, so callers can ",[19,474,475],{},"get(i)"," or insert\ninto the middle, shattering the stack abstraction. It even iterates ",[24,478,479],{},"bottom-to-top",", the\nopposite of pop order.",[95,482,484],{"className":97,"code":483,"language":99,"meta":100,"style":100},"Deque\u003CInteger> stack = new ArrayDeque\u003C>();\nstack.push(1);     \u002F\u002F [1]\nstack.push(2);     \u002F\u002F [2, 1]  — head is the top\nstack.peek();      \u002F\u002F 2\nstack.pop();       \u002F\u002F 2 -> [1]   (push\u002Fpop\u002Fpeek THROW on empty)\n",[19,485,486,501,516,531,542],{"__ignoreMap":100},[104,487,488,490,492,495,497,499],{"class":106,"line":107},[104,489,312],{"class":110},[104,491,115],{"class":114},[104,493,494],{"class":110},"> stack ",[104,496,121],{"class":114},[104,498,124],{"class":114},[104,500,127],{"class":110},[104,502,503,506,508,510,512,514],{"class":106,"line":130},[104,504,505],{"class":110},"stack.",[104,507,428],{"class":143},[104,509,147],{"class":110},[104,511,151],{"class":150},[104,513,337],{"class":110},[104,515,340],{"class":157},[104,517,518,520,522,524,526,528],{"class":106,"line":137},[104,519,505],{"class":110},[104,521,428],{"class":143},[104,523,147],{"class":110},[104,525,352],{"class":150},[104,527,337],{"class":110},[104,529,530],{"class":157},"\u002F\u002F [2, 1]  — head is the top\n",[104,532,533,535,537,539],{"class":106,"line":161},[104,534,505],{"class":110},[104,536,235],{"class":143},[104,538,192],{"class":110},[104,540,541],{"class":157},"\u002F\u002F 2\n",[104,543,544,546,548,550],{"class":106,"line":179},[104,545,505],{"class":110},[104,547,431],{"class":143},[104,549,378],{"class":110},[104,551,552],{"class":157},"\u002F\u002F 2 -> [1]   (push\u002Fpop\u002Fpeek THROW on empty)\n",[15,554,555,558,559,245,561,563,564,563,567,570,571,245,573,575,576,578],{},[19,556,557],{},"ArrayDeque"," as a stack is unsynchronized, tight-contracted, and iterates in the right\norder. One subtlety: the stack-named ",[19,560,431],{},[19,562,235],{}," ",[24,565,566],{},"throw",[19,568,569],{},"NoSuchElementException"," on an\nempty deque, unlike ",[19,572,388],{},[19,574,301],{},", which return ",[19,577,92],{},".",[10,580,582],{"id":581},"arraydeque-vs-linkedlist","ArrayDeque vs LinkedList",[15,584,585,586,588,589,591,592,595,596,441,599,602],{},"Both implement ",[19,587,62],{},", but the storage underneath drives the choice. ",[19,590,557],{}," is a\nresizable ",[24,593,594],{},"circular array"," — contiguous memory, excellent cache locality, no per-element\nnode object. ",[19,597,598],{},"LinkedList",[24,600,601],{},"doubly-linked nodes",", each costing an object plus two\npointers, scattered across the heap.",[95,604,606],{"className":97,"code":605,"language":99,"meta":100,"style":100},"Deque\u003CInteger> fast = new ArrayDeque\u003C>();    \u002F\u002F prefer this for queue\u002Fstack\u002Fdeque use\nDeque\u003CInteger> list = new LinkedList\u003C>();     \u002F\u002F only when you also need List behaviour\n",[19,607,608,627],{"__ignoreMap":100},[104,609,610,612,614,617,619,621,624],{"class":106,"line":107},[104,611,312],{"class":110},[104,613,115],{"class":114},[104,615,616],{"class":110},"> fast ",[104,618,121],{"class":114},[104,620,124],{"class":114},[104,622,623],{"class":110}," ArrayDeque\u003C>();    ",[104,625,626],{"class":157},"\u002F\u002F prefer this for queue\u002Fstack\u002Fdeque use\n",[104,628,629,631,633,636,638,640,643],{"class":106,"line":130},[104,630,312],{"class":110},[104,632,115],{"class":114},[104,634,635],{"class":110},"> list ",[104,637,121],{"class":114},[104,639,124],{"class":114},[104,641,642],{"class":110}," LinkedList\u003C>();     ",[104,644,645],{"class":157},"\u002F\u002F only when you also need List behaviour\n",[15,647,648,649,654,655,657,658,660,661,664,665,667,668,670],{},"For pure queue, stack, or deque work, ",[24,650,651,653],{},[19,652,557],{}," wins"," on speed and memory. Reach for\n",[19,656,598],{}," only when you genuinely need ",[19,659,21],{}," operations (indexing, ",[19,662,663],{},"ListIterator",") on\nthe same object, or — the rare case — you must store ",[19,666,92],{},", which ",[19,669,557],{}," forbids.",[10,672,674],{"id":673},"priorityqueue-a-heap-not-a-line","PriorityQueue: a heap, not a line",[15,676,677,679,680,683,684,687,688,690,691,693,694,697,698,700,701,704,705,708],{},[19,678,58],{}," breaks the FIFO assumption: its ",[24,681,682],{},"head is always the smallest element"," by\nthe ordering, not the oldest. It is backed by a ",[24,685,686],{},"binary heap",", so ",[19,689,166],{}," and ",[19,692,203],{}," run\nin ",[24,695,696],{},"O(log n)"," while ",[19,699,235],{}," is O(1). Ordering comes either from the elements' natural\n",[19,702,703],{},"Comparable"," order or from a ",[19,706,707],{},"Comparator"," you pass at construction.",[95,710,712],{"className":97,"code":711,"language":99,"meta":100,"style":100},"\u002F\u002F default: min-heap by natural order\nPriorityQueue\u003CInteger> min = new PriorityQueue\u003C>();\nmin.offer(5); min.offer(1); min.offer(3);\nmin.poll();    \u002F\u002F 1 — smallest first\n\n\u002F\u002F max-heap, and ordering by a field\nPriorityQueue\u003CInteger> max = new PriorityQueue\u003C>(Comparator.reverseOrder());\nPriorityQueue\u003CTask> byPriority =\n    new PriorityQueue\u003C>(Comparator.comparingInt(Task::priority));\n",[19,713,714,719,736,769,781,785,790,812,825],{"__ignoreMap":100},[104,715,716],{"class":106,"line":107},[104,717,718],{"class":157},"\u002F\u002F default: min-heap by natural order\n",[104,720,721,724,726,729,731,733],{"class":106,"line":130},[104,722,723],{"class":110},"PriorityQueue\u003C",[104,725,115],{"class":114},[104,727,728],{"class":110},"> min ",[104,730,121],{"class":114},[104,732,124],{"class":114},[104,734,735],{"class":110}," PriorityQueue\u003C>();\n",[104,737,738,741,743,745,748,751,753,755,757,759,761,763,766],{"class":106,"line":137},[104,739,740],{"class":110},"min.",[104,742,166],{"class":143},[104,744,147],{"class":110},[104,746,747],{"class":150},"5",[104,749,750],{"class":110},"); min.",[104,752,166],{"class":143},[104,754,147],{"class":110},[104,756,151],{"class":150},[104,758,750],{"class":110},[104,760,166],{"class":143},[104,762,147],{"class":110},[104,764,765],{"class":150},"3",[104,767,768],{"class":110},");\n",[104,770,771,773,775,778],{"class":106,"line":161},[104,772,740],{"class":110},[104,774,203],{"class":143},[104,776,777],{"class":110},"();    ",[104,779,780],{"class":157},"\u002F\u002F 1 — smallest first\n",[104,782,783],{"class":106,"line":179},[104,784,134],{"emptyLinePlaceholder":133},[104,786,787],{"class":106,"line":184},[104,788,789],{"class":157},"\u002F\u002F max-heap, and ordering by a field\n",[104,791,792,794,796,799,801,803,806,809],{"class":106,"line":198},[104,793,723],{"class":110},[104,795,115],{"class":114},[104,797,798],{"class":110},"> max ",[104,800,121],{"class":114},[104,802,124],{"class":114},[104,804,805],{"class":110}," PriorityQueue\u003C>(Comparator.",[104,807,808],{"class":143},"reverseOrder",[104,810,811],{"class":110},"());\n",[104,813,814,816,819,822],{"class":106,"line":212},[104,815,723],{"class":110},[104,817,818],{"class":114},"Task",[104,820,821],{"class":110},"> byPriority ",[104,823,824],{"class":114},"=\n",[104,826,827,830,832,835,838,841],{"class":106,"line":217},[104,828,829],{"class":114},"    new",[104,831,805],{"class":110},[104,833,834],{"class":143},"comparingInt",[104,836,837],{"class":110},"(Task",[104,839,840],{"class":114},"::",[104,842,843],{"class":110},"priority));\n",[15,845,846,847,850,851,853,854,856,857,860,861,863],{},"The comparator is ",[24,848,849],{},"fixed at construction",". For your own objects, supplying a ",[19,852,707],{},"\nor implementing ",[19,855,703],{}," is mandatory — without an ordering the heap can't decide its\nhead and throws ",[19,858,859],{},"ClassCastException"," on the first ",[19,862,166],{},". Building a heap from a known\ncollection (the constructor taking one) is O(n), cheaper than n separate inserts.",[10,865,867],{"id":866},"the-priorityqueue-iteration-trap","The PriorityQueue iteration trap",[15,869,870,871,877,878,881,882,885,886,889,890,895],{},"Here is the classic interview surprise: ",[24,872,873,874,876],{},"iterating a ",[19,875,58],{}," does not yield sorted\norder."," Its iterator and ",[19,879,880],{},"toString"," walk the ",[24,883,884],{},"internal heap array",", which is only\n",[52,887,888],{},"partially"," ordered — the heap invariant guarantees a parent precedes its children, nothing\nmore. Only ",[24,891,892,893],{},"draining via ",[19,894,203],{}," produces priority order.",[95,897,899],{"className":97,"code":898,"language":99,"meta":100,"style":100},"PriorityQueue\u003CInteger> pq = new PriorityQueue\u003C>(List.of(5, 1, 3, 2, 4));\nSystem.out.println(pq);              \u002F\u002F e.g. [1, 2, 3, 5, 4] — NOT sorted\n\nwhile (!pq.isEmpty())\n    System.out.print(pq.poll());     \u002F\u002F 12345 — sorted, by emptying\n",[19,900,901,944,958,962,981],{"__ignoreMap":100},[104,902,903,905,907,910,912,914,917,920,922,924,926,928,930,932,934,936,938,941],{"class":106,"line":107},[104,904,723],{"class":110},[104,906,115],{"class":114},[104,908,909],{"class":110},"> pq ",[104,911,121],{"class":114},[104,913,124],{"class":114},[104,915,916],{"class":110}," PriorityQueue\u003C>(List.",[104,918,919],{"class":143},"of",[104,921,147],{"class":110},[104,923,747],{"class":150},[104,925,289],{"class":110},[104,927,151],{"class":150},[104,929,289],{"class":110},[104,931,765],{"class":150},[104,933,289],{"class":110},[104,935,352],{"class":150},[104,937,289],{"class":110},[104,939,940],{"class":150},"4",[104,942,943],{"class":110},"));\n",[104,945,946,949,952,955],{"class":106,"line":130},[104,947,948],{"class":110},"System.out.",[104,950,951],{"class":143},"println",[104,953,954],{"class":110},"(pq);              ",[104,956,957],{"class":157},"\u002F\u002F e.g. [1, 2, 3, 5, 4] — NOT sorted\n",[104,959,960],{"class":106,"line":137},[104,961,134],{"emptyLinePlaceholder":133},[104,963,964,967,969,972,975,978],{"class":106,"line":161},[104,965,966],{"class":114},"while",[104,968,85],{"class":110},[104,970,971],{"class":114},"!",[104,973,974],{"class":110},"pq.",[104,976,977],{"class":143},"isEmpty",[104,979,980],{"class":110},"())\n",[104,982,983,986,989,992,994,997],{"class":106,"line":179},[104,984,985],{"class":110},"    System.out.",[104,987,988],{"class":143},"print",[104,990,991],{"class":110},"(pq.",[104,993,203],{"class":143},[104,995,996],{"class":110},"());     ",[104,998,999],{"class":157},"\u002F\u002F 12345 — sorted, by emptying\n",[15,1001,1002,1003,1006,1007,245,1009,1011,1012,1014,1015,1018,1019,1022,1023,1026],{},"If you need a sorted snapshot without destroying the queue, copy into a list and ",[19,1004,1005],{},"sort"," it.\nRemember the heap's complexity profile too: ",[19,1008,166],{},[19,1010,203],{}," are O(log n) and ",[19,1013,235],{}," is O(1),\nbut ",[19,1016,1017],{},"contains"," and arbitrary ",[19,1020,1021],{},"remove(Object)"," are ",[24,1024,1025],{},"O(n)"," linear scans — heaps are great at\n\"give me the minimum,\" weak at \"find this element.\"",[10,1028,1030],{"id":1029},"blockingqueue-and-producer-consumer","BlockingQueue and producer-consumer",[15,1032,1033,1034,1037,1038,1041,1042,1045,1046,1049,1050,1053,1054,1057,1058,245,1060,578],{},"When threads share a queue, the ",[19,1035,1036],{},"BlockingQueue\u003CE>"," interface in ",[19,1039,1040],{},"java.util.concurrent"," adds\noperations that ",[24,1043,1044],{},"wait"," instead of failing: ",[19,1047,1048],{},"put(e)"," blocks while the queue is full, and\n",[19,1051,1052],{},"take()"," blocks while it is empty. That is the entire foundation of the ",[24,1055,1056],{},"producer-consumer","\npattern — the queue owns the locking and the waiting, so neither side touches ",[19,1059,1044],{},[19,1061,1062],{},"notify",[95,1064,1066],{"className":97,"code":1065,"language":99,"meta":100,"style":100},"BlockingQueue\u003CInteger> q = new ArrayBlockingQueue\u003C>(10);   \u002F\u002F bounded -> back-pressure\n\nRunnable producer = () -> { while (true) q.put(produce()); };   \u002F\u002F blocks if full\nRunnable consumer = () -> { while (true) consume(q.take()); };  \u002F\u002F blocks if empty\n",[19,1067,1068,1093,1097,1137],{"__ignoreMap":100},[104,1069,1070,1073,1075,1077,1079,1081,1084,1087,1090],{"class":106,"line":107},[104,1071,1072],{"class":110},"BlockingQueue\u003C",[104,1074,115],{"class":114},[104,1076,118],{"class":110},[104,1078,121],{"class":114},[104,1080,124],{"class":114},[104,1082,1083],{"class":110}," ArrayBlockingQueue\u003C>(",[104,1085,1086],{"class":150},"10",[104,1088,1089],{"class":110},");   ",[104,1091,1092],{"class":157},"\u002F\u002F bounded -> back-pressure\n",[104,1094,1095],{"class":106,"line":130},[104,1096,134],{"emptyLinePlaceholder":133},[104,1098,1099,1102,1104,1107,1110,1113,1115,1117,1120,1123,1126,1128,1131,1134],{"class":106,"line":137},[104,1100,1101],{"class":110},"Runnable producer ",[104,1103,121],{"class":114},[104,1105,1106],{"class":110}," () ",[104,1108,1109],{"class":114},"->",[104,1111,1112],{"class":110}," { ",[104,1114,966],{"class":114},[104,1116,85],{"class":110},[104,1118,1119],{"class":150},"true",[104,1121,1122],{"class":110},") q.",[104,1124,1125],{"class":143},"put",[104,1127,147],{"class":110},[104,1129,1130],{"class":143},"produce",[104,1132,1133],{"class":110},"()); };   ",[104,1135,1136],{"class":157},"\u002F\u002F blocks if full\n",[104,1138,1139,1142,1144,1146,1148,1150,1152,1154,1156,1159,1162,1165,1168,1171],{"class":106,"line":161},[104,1140,1141],{"class":110},"Runnable consumer ",[104,1143,121],{"class":114},[104,1145,1106],{"class":110},[104,1147,1109],{"class":114},[104,1149,1112],{"class":110},[104,1151,966],{"class":114},[104,1153,85],{"class":110},[104,1155,1119],{"class":150},[104,1157,1158],{"class":110},") ",[104,1160,1161],{"class":143},"consume",[104,1163,1164],{"class":110},"(q.",[104,1166,1167],{"class":143},"take",[104,1169,1170],{"class":110},"()); };  ",[104,1172,1173],{"class":157},"\u002F\u002F blocks if empty\n",[15,1175,17,1176,1179,1180,1183,1184,1187,1188,1191,1192,1195,1196,1199,1200,1203,1204,1207,1208,1210,1211,1213],{},[24,1177,1178],{},"bounded"," queue gives ",[24,1181,1182],{},"back-pressure",": if consumers fall behind, the queue fills and\nproducers naturally throttle rather than exhausting memory. ",[19,1185,1186],{},"ArrayBlockingQueue"," (bounded,\nsingle lock) and ",[19,1189,1190],{},"LinkedBlockingQueue"," (separate put\u002Ftake locks, higher throughput) are the\nworkhorses; ",[19,1193,1194],{},"SynchronousQueue"," (zero capacity, direct hand-off) and ",[19,1197,1198],{},"PriorityBlockingQueue","\nround out the set. When threads should drain available work but ",[24,1201,1202],{},"never"," wait, a non\n-blocking ",[19,1205,1206],{},"ConcurrentLinkedQueue"," (lock-free CAS, ",[19,1209,203],{}," returns ",[19,1212,92],{}," immediately) fits\nbetter.",[10,1215,1217],{"id":1216},"the-no-nulls-rule","The no-nulls rule",[15,1219,1220,1221,289,1223,289,1225,1227,1228,1233,1234,1236,1237,1240,1241,1243,1244,1247,1248,1250],{},"Almost every queue — ",[19,1222,557],{},[19,1224,58],{},[19,1226,1206],{},", the blocking\nqueues — ",[24,1229,1230,1231],{},"rejects ",[19,1232,92],{},", and the reason ties the whole family together. ",[19,1235,92],{}," is the\n",[24,1238,1239],{},"sentinel"," the returning method family uses to mean \"the queue is empty.\" If a real ",[19,1242,92],{},"\nelement were allowed, ",[19,1245,1246],{},"poll() == null"," would be ambiguous: empty queue, or a head that\nhappens to be ",[19,1249,92],{},"?",[95,1252,1254],{"className":97,"code":1253,"language":99,"meta":100,"style":100},"Queue\u003CString> q = new ArrayDeque\u003C>();\nq.offer(null);   \u002F\u002F NullPointerException — by design\nq.poll();        \u002F\u002F null can therefore ONLY ever mean \"empty\"\n",[19,1255,1256,1271,1286],{"__ignoreMap":100},[104,1257,1258,1260,1263,1265,1267,1269],{"class":106,"line":107},[104,1259,111],{"class":110},[104,1261,1262],{"class":114},"String",[104,1264,118],{"class":110},[104,1266,121],{"class":114},[104,1268,124],{"class":114},[104,1270,127],{"class":110},[104,1272,1273,1275,1277,1279,1281,1283],{"class":106,"line":130},[104,1274,140],{"class":110},[104,1276,166],{"class":143},[104,1278,147],{"class":110},[104,1280,92],{"class":150},[104,1282,1089],{"class":110},[104,1284,1285],{"class":157},"\u002F\u002F NullPointerException — by design\n",[104,1287,1288,1290,1292,1294],{"class":106,"line":137},[104,1289,140],{"class":110},[104,1291,203],{"class":143},[104,1293,206],{"class":110},[104,1295,1296],{"class":157},"\u002F\u002F null can therefore ONLY ever mean \"empty\"\n",[15,1298,1299,1300,1302,1303,1305,1306,1308],{},"The lone holdout is ",[19,1301,598],{},", which predates the ",[19,1304,30],{}," interface and permits ",[19,1307,92],{}," —\none more reason not to use it as a queue.",[10,1310,1312],{"id":1311},"recap","Recap",[15,1314,1315,1317,1318,1320,1321,1324,1325,245,1327,245,1329,1331,1332,245,1334,245,1336,1338,1339,1341,1342,245,1344,400,1346,1349,1350,1353,1354,1358,1359,1361,1362,1364,1365,1367,1368,245,1370,1372,1373,1378,1379,1382,1383,1385],{},[19,1316,30],{}," constrains access to the ",[24,1319,34],{}," so implementations stay fast and intent stays\nclear. Master the ",[24,1322,1323],{},"two method families"," — throwing ",[19,1326,144],{},[19,1328,189],{},[19,1330,222],{}," for \"this is a\nbug\" versus returning ",[19,1333,166],{},[19,1335,203],{},[19,1337,235],{}," for expected emptiness. ",[19,1340,62],{}," doubles that into\nboth-ends access, giving you a FIFO queue or, via ",[19,1343,428],{},[19,1345,431],{},[24,1347,1348],{},"fast LIFO stack"," that\nretires the synchronized, leaky legacy ",[19,1351,1352],{},"Stack",". Prefer ",[24,1355,1356],{},[19,1357,557],{}," over ",[19,1360,598],{},"\nfor raw queue\u002Fstack\u002Fdeque work thanks to its contiguous backing array. ",[19,1363,58],{}," is a\n",[24,1366,686],{}," ordered by ",[19,1369,703],{},[19,1371,707],{},", with the famous \"iteration isn't\nsorted\" trap. For concurrency, ",[24,1374,1375],{},[19,1376,1377],{},"BlockingQueue"," powers producer-consumer with\nback-pressure. And the ",[24,1380,1381],{},"no-nulls"," rule across the family exists to keep ",[19,1384,92],{}," meaning\nexactly one thing: empty.",[1387,1388,1389],"style",{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":100,"searchDepth":130,"depth":130,"links":1391},[1392,1393,1394,1395,1396,1397,1398,1399,1400,1401],{"id":12,"depth":130,"text":13},{"id":66,"depth":130,"text":67},{"id":260,"depth":130,"text":261},{"id":419,"depth":130,"text":420},{"id":581,"depth":130,"text":582},{"id":673,"depth":130,"text":674},{"id":866,"depth":130,"text":867},{"id":1029,"depth":130,"text":1030},{"id":1216,"depth":130,"text":1217},{"id":1311,"depth":130,"text":1312},"A deep guide to Java's Queue and Deque interfaces — the throwing vs returning method families, ArrayDeque as a fast stack, PriorityQueue heap ordering, and BlockingQueue producer-consumer patterns.","medium","md","Java",{},"\u002Fblog\u002Fjava-queue-deque-arraydeque-priorityqueue","\u002Fjava\u002Fcollections\u002Fqueue-deque",{"title":5,"description":1402},"blog\u002Fjava-queue-deque-arraydeque-priorityqueue","Queue & Deque","Collections","collections","2026-06-20","CSpGS2XAAZqc9hgM2r6kwbQp3AQlmDLgYmF1wBUnChU",1782244090938]