CodeGym /จาวาบล็อก /สุ่ม /Java Queue Interface และการใช้งาน
John Squirrels
ระดับ
San Francisco

Java Queue Interface และการใช้งาน

เผยแพร่ในกลุ่ม
ที่นี่เราจะหารือเกี่ยวกับอินเตอร์เฟส Java Queue คุณจะพบว่า โครงสร้างข้อมูล Queueคืออะไร วิธีการแสดงใน Java วิธีใดที่สำคัญที่สุดสำหรับคิวทั้งหมด นอกจากนี้ การนำ Queue ไปใช้ในภาษาจาวามีอะไรบ้าง หลังจากนั้น เราจะพิจารณาการใช้งานที่สำคัญที่สุดอย่างละเอียดยิ่งขึ้นและเรียนรู้ด้วยตัวอย่าง

โครงสร้างข้อมูลคิว

คิวเป็นโครงสร้างข้อมูลนามธรรมเชิงเส้นที่มีลำดับเฉพาะของการดำเนินการ - เข้าก่อนออกก่อน (FIFO) ซึ่งหมายความว่าคุณสามารถเพิ่มองค์ประกอบ (หรือจัดคิว ใส่ในคิว) ได้เฉพาะที่ส่วนท้ายของโครงสร้าง และนำองค์ประกอบ (ยกเลิกหรือลบออกจากคิว) จากจุดเริ่มต้นเท่านั้น คุณอาจนึกภาพโครงสร้างข้อมูล Queue ได้อย่างง่ายดาย เหมือนต่อคิวหรือต่อแถวลูกค้าจริงๆ ลูกค้าที่มาก่อนจะได้รับบริการก่อนเช่นกัน หากคุณมีคนต่อแถวสี่คนในแมคโดนัลด์หรือที่อื่น คนแรกที่เข้าแถวจะเป็นคนแรกที่ได้ร้าน ถ้าลูกค้าใหม่มา เขา/เธอจะเป็นลำดับที่ 5 ที่จะได้แฮมเบอร์เกอร์ Java Queue Interface และการใช้งาน - 1ดังนั้นในขณะที่ทำงานกับคิว องค์ประกอบใหม่จะถูกเพิ่มเข้าไปที่ส่วนท้าย และหากคุณต้องการรับองค์ประกอบ องค์ประกอบนั้นจะถูกนำจากจุดเริ่มต้น นี่คือหลักการสำคัญของงานโครงสร้างข้อมูลแบบคิวคลาสสิก

คิวใน Java

Queue ใน Java เป็นอินเทอร์เฟซ ตามเอกสารของ Oracle อินเตอร์เฟสคิวมีซูเปอร์อินเตอร์เฟส 2 อินเทอร์เฟซ 4 อินเทอร์เฟซที่แตกต่างกันซึ่งสืบทอดมาจากคิว และรายการคลาสที่น่าประทับใจอย่างยิ่ง

อินเทอร์เฟซขั้นสูง:

คอลเลกชัน<E>, Iterable<E>

อินเทอร์เฟซย่อยที่รู้จักทั้งหมด:

BlockingDeque<E>, BlockingQueue<E>, Deque<E>, TransferQueue<E>

คลาสการใช้งานที่รู้จักทั้งหมด:

AbstractQueue, ArrayBlockingQueue, ArrayDeque, ConcurrentLinkedDeque, ConcurrentLinkedQueue, DelayQueue, LinkedBlockingDeque, LinkedBlockingQueue, LinkedList, LinkedTransferQueue, PriorityBlockingQueue, PriorityQueue, SynchronousQueue

มันหมายความว่าอะไร? ก่อนอื่น Java Queue เป็นส่วนหนึ่งของ Collection Framework และใช้อินเทอร์เฟซ Collection ดังนั้นจึงรองรับทุกวิธีของส่วนต่อประสานการรวบรวม เช่น การแทรก การลบ และอื่นๆ Queue ใช้อินเทอร์เฟซ Iterable ซึ่งอนุญาตให้วัตถุเป็นเป้าหมายของคำสั่ง "for-each loop"

วิธีการคิว Java

Queue ประกาศจำนวนของวิธีการ เนื่องจากเมธอดของอินเทอร์เฟซควรแสดงในคลาสทั้งหมดที่ใช้ Queue วิธีการคิวที่สำคัญที่สุด Java:
  • Boolean offer() – แทรกองค์ประกอบใหม่ลงในคิวถ้าเป็นไปได้
  • Boolean add(E e) – แทรกองค์ประกอบใหม่ลงในคิวถ้าเป็นไปได้ คืนค่าจริงในกรณีที่สำเร็จ และโยน IllegalStateException หากไม่มีช่องว่าง
  • การสำรวจวัตถุ () - ดึงและลบองค์ประกอบออกจากส่วนหัวของ คืนค่า null หากคิวว่างเปล่า
  • วัตถุลบ () - ดึงและลบองค์ประกอบออกจากส่วนหัวของคิว
  • Object peek() – ดึงข้อมูล แต่ไม่ลบองค์ประกอบออกจากส่วนหัวของคิว คืนค่า null หากคิวว่างเปล่า
  • องค์ประกอบวัตถุ () - ดึงข้อมูล แต่ไม่ลบองค์ประกอบออกจากส่วนหัวของคิว

อินเทอร์เฟซย่อยของ Java Queue

อินเตอร์เฟส คิวได้รับการสืบทอดโดย 4 อินเตอร์เฟสย่อย – BlockingDeque<E>, BlockingQueue<E>, Deque<E>, TransferQueue <E> คุณอาจแบ่งพวกมันออกเป็น 3 กลุ่ม: Deques, Blocking Queues และ Transfer Queues โดย BlockingDeque เป็นของสองกลุ่มแรก มาดูกลุ่มเหล่านี้กัน

เดค

Deque หมายถึงD ouble - E nded Q ueue และรองรับการเพิ่มหรือลบจากส่วนท้ายของข้อมูลในรูปแบบคิว (เข้าก่อนออกก่อน/FIFO) หรือจากส่วนหัวเป็นโครงสร้างข้อมูลยอดนิยมอื่นที่เรียกว่าสแต็ก (สุดท้ายเข้า - ออกก่อน/LIFO) คลาสที่ใช้ Deque Interface: ArrayDeque, ConcurrentLinkedDeque, LinkedBlockingDeque, LinkedList

การบล็อกคิว

คิวการบล็อกคือคิวที่บล็อกเธรดในสองกรณี:
  • เธรดกำลังพยายามรับองค์ประกอบจากคิวว่าง
  • เธรดกำลังพยายามใส่องค์ประกอบในคิวเต็ม
เมื่อเธรดพยายามรับไอเท็มจากคิวว่าง เธรดจะรอจนกว่าเธรดอื่นจะใส่ไอเท็มลงในคิว ในทำนองเดียวกัน เมื่อเธรดพยายามใส่องค์ประกอบลงในคิวเต็ม เธรดจะรอจนกว่าเธรดอื่นจะนำองค์ประกอบออกจากคิวเพื่อให้ได้พื้นที่ว่างสำหรับองค์ประกอบ แน่นอน แนวคิดของ "คิวเต็ม" หมายความว่าคิวมีขนาดจำกัด ซึ่งมักจะระบุไว้ในตัวสร้าง คิวการบล็อกมาตรฐานประกอบด้วย LinkedBlockingQueue, SynchronousQueue และ ArrayBlockingQueue การใช้คลาสของ อินเทอร์เฟ ซ BlockingQueue : ArrayBlockingQueue, DelayQueue, LinkedBlockingDeque, LinkedBlockingQueue, LinkedTransferQueue, PriorityBlockingQueue, SynchronousQueue การปิดกั้นDequeเป็นอินเทอร์เฟซย่อยสำหรับ BlockingQueue BlockingDeque เช่น BlockingQueue เป็นคิวการบล็อก แต่เป็นแบบสองทิศทาง ดังนั้นจึงสืบทอดคุณสมบัติของส่วนต่อประสาน Deque มุ่งเน้นไปที่การดำเนินการแบบหลายเธรด ไม่อนุญาตให้มีองค์ประกอบเป็นศูนย์และความจุอาจถูกจำกัด การใช้งานอินเทอร์เฟซ BlockingDeque จะบล็อกการดำเนินการรับองค์ประกอบหากคิวว่าง และเพิ่มองค์ประกอบลงในคิวหากองค์ประกอบเต็ม

โอนคิว

อินเทอร์เฟซ TransferQueue ขยายอินเทอร์เฟซ BlockingQueue อย่างไรก็ตาม ไม่เหมือนกับการใช้คิวอินเทอร์เฟซ BlockingQueue ตรงที่เธรดสามารถบล็อกได้หากคิวว่าง (กำลังอ่าน) หรือหากคิวเต็ม (กำลังเขียน) คิวอินเทอร์เฟซ TransferQueue จะบล็อกสตรีมการเขียนจนกว่าสตรีมอื่นจะดึงองค์ประกอบ ใช้วิธีการโอนสำหรับสิ่งนี้ กล่าวอีกนัยหนึ่ง การใช้งาน BlockingQueue รับประกันว่าองค์ประกอบที่สร้างโดย Producer จะต้องอยู่ในคิว ในขณะที่การใช้งาน TransferQueue รับประกันว่าองค์ประกอบ Producer นั้น "ได้รับ" โดยผู้บริโภค มีการใช้งาน Java อย่างเป็นทางการเพียงรายการเดียวของอินเทอร์เฟซ TransferQueue นั่นคือ LinkedTransferQueue

การใช้งาน Java Queue

มีหลายคลาสที่ใช้อินเทอร์เฟซ Queue:
  • AbstractQueueตามเอกสาร Queue Java 8 คลาสนามธรรมนี้มีการใช้งานพื้นฐานของการดำเนินการคิวบางอย่าง ไม่อนุญาตให้ใช้องค์ประกอบที่เป็นค่าว่าง มีอีก 3 วิธีในการเพิ่ม ลบ และองค์ประกอบตาม Queue classic offer , pollและpeekตามลำดับ อย่างไรก็ตาม พวกเขาส่งข้อยกเว้นแทนที่จะระบุความล้มเหลวผ่านการคืนค่าเท็จหรือค่า null
  • ArrayBlockingQueue — คิวบล็อก FIFO ขนาดคงที่ที่สนับสนุนโดยอาร์เรย์
  • ArrayDeque — การใช้งานอาร์เรย์ที่ปรับขนาดได้ของอินเทอร์เฟซ Deque
  • ConcurrentLinkedDeque — deque ที่เกิดขึ้นพร้อมกันแบบไม่จำกัดโดยยึดตามโหนดที่เชื่อมโยง
  • ConcurrentLinkedQueue — คิวที่ปลอดภัยสำหรับเธรดที่ไม่มีขอบเขตตามโหนดที่เชื่อมโยง
  • DelayQueue — คิวการจัดตารางเวลาตามเวลาที่ได้รับการสนับสนุนโดยฮีป
  • LinkedBlockingDeque — การใช้งานพร้อมกันของอินเทอร์เฟซ Deque
  • LinkedBlockingQueue — คิวการปิดกั้น FIFO ที่เป็นทางเลือกซึ่งสนับสนุนโดยโหนดที่เชื่อมโยง
  • LinkedList — การนำรายการที่เชื่อมโยงเป็นสองเท่าของอินเทอร์เฟซ List และ Deque ใช้การดำเนินการรายการทางเลือกทั้งหมด และอนุญาตองค์ประกอบทั้งหมด (รวมถึง null)
  • LinkedTransferQueue — TransferQueue ที่ไม่มีขอบเขตตามโหนดที่เชื่อมโยง
  • PriorityBlockingQueue — คิวลำดับความสำคัญการบล็อกที่ไม่มีขอบเขตซึ่งสนับสนุนโดยฮีป
  • PriorityQueue — คิวลำดับความสำคัญตามโครงสร้างข้อมูลฮีป
  • SynchronousQueue — คิวบล็อกที่การดำเนินการแทรกแต่ละครั้งต้องรอการดำเนินการลบที่สอดคล้องกันโดยเธรดอื่น และในทางกลับกัน
การใช้งานที่ได้รับความนิยมมากที่สุด ได้แก่ LinkedList, ArrayBlockingQueue และ PriorityQueue ลองดูที่พวกเขาและทำตัวอย่างเพื่อความเข้าใจที่ดีขึ้น

รายการที่เชื่อมโยง

Class LinkedList ใน Java ใช้อินเทอร์เฟซ List และ Deque ดังนั้นจึงเป็นการรวมกันของ List และ Deque ซึ่งเป็นคิวแบบสองทางที่รองรับการเพิ่มและลบองค์ประกอบจากทั้งสองด้าน ใน Java LinkedList มีการเชื่อมโยงแบบทวีคูณ List: ทุกอิลิเมนต์ของ List เรียก Node และมีอ็อบเจกต์และการอ้างอิงไปยังออบเจ็กต์ที่อยู่ใกล้เคียงสองออบเจ็กต์ — รายการก่อนหน้าและรายการถัดไป Java Queue Interface และการใช้งาน - 2คุณอาจกล่าวได้ว่า LinkedList ไม่ค่อยมีประสิทธิภาพในแง่ของการใช้หน่วยความจำ นั่นเป็นความจริง แต่โครงสร้างข้อมูลนี้จะมีประโยชน์ในกรณีของการดำเนินการแทรกและลบ อย่างไรก็ตาม จะเกิดขึ้นก็ต่อเมื่อคุณใช้ตัววนซ้ำสำหรับสิ่งเหล่านี้ (ในกรณีนี้จะเกิดขึ้นในเวลาคงที่) การดำเนินการเข้าถึงโดยดัชนีดำเนินการโดยการค้นหาจากจุดเริ่มต้นของจุดสิ้นสุด (แล้วแต่ว่าระยะใดจะใกล้กว่า) ไปยังองค์ประกอบที่ต้องการ อย่างไรก็ตาม อย่าลืมเกี่ยวกับค่าใช้จ่ายเพิ่มเติมสำหรับการจัดเก็บข้อมูลอ้างอิงระหว่างองค์ประกอบต่างๆ ดังนั้น LinkedList จึงเป็นการใช้งานคิวที่ได้รับความนิยมมากที่สุดใน Java เป็นการใช้งาน List และ Deque และช่วยให้เราสร้างคิวแบบสองทิศทางที่ประกอบด้วยวัตถุใด ๆ รวมถึง null LinkedList คือชุดขององค์ประกอบต่างๆ
ข้อมูลเพิ่มเติมเกี่ยวกับ LinkedList: โครงสร้างข้อมูล Java ของ LinkedList

ตัวสร้างรายการที่เชื่อมโยง

LinkedList()ที่ไม่มีพารามิเตอร์ใช้เพื่อสร้างรายการว่าง LinkedList(Collection<? ขยาย E> c)มีไว้สำหรับสร้างรายการที่มีองค์ประกอบของคอลเล็กชันที่ระบุ ลำดับจะถูกส่งกลับโดยตัววนซ้ำของคอลเล็กชัน

วิธีการ LinkedList หลัก:

  • เพิ่ม (องค์ประกอบ E) ผนวกองค์ประกอบที่ระบุต่อท้ายรายการนี้
  • เพิ่ม (ดัชนี int องค์ประกอบ E) แทรกองค์ประกอบที่ดัชนีตำแหน่งที่ระบุ
  • รับ (ดัชนี int) ส่งกลับองค์ประกอบในตำแหน่งที่ระบุในรายการนี้
  • ลบ (ดัชนี int) ลบองค์ประกอบที่ดัชนีตำแหน่ง;
  • remove(Object o) ลบองค์ประกอบ ?o ที่เกิดขึ้นครั้งแรกออกจากรายการนี้หากมีอยู่
  • remove() ดึงและลบองค์ประกอบแรกของรายการ
  • addFirst(), addLast() เพิ่มองค์ประกอบที่จุดเริ่มต้น/จุดสิ้นสุดของรายการ
  • clear() ลบองค์ประกอบทั้งหมดออกจากรายการ
  • มี (วัตถุ o) คืนค่าจริงหากรายการมีองค์ประกอบ o
  • indexOf(Object o) ส่งคืนดัชนีของการเกิดขึ้นครั้งแรกขององค์ประกอบ o หรือ -1 หากไม่มีอยู่ในรายการ
  • set(int index, E element) แทนที่องค์ประกอบที่ตำแหน่งดัชนีด้วยองค์ประกอบ
  • size() ส่งกลับจำนวนขององค์ประกอบในรายการ
  • toArray() ส่งคืนอาร์เรย์ที่มีองค์ประกอบของรายการทั้งหมดตั้งแต่องค์ประกอบแรกจนถึงองค์ประกอบสุดท้าย
  • pop() ที่ดึงองค์ประกอบจากสแต็ก (แสดงโดยรายการ)
  • push(E e) ที่ผลักองค์ประกอบไปยังสแต็ก (แสดงโดยรายการนี้)
ตัวอย่าง Java Queue — LinkedList (การใส่และลบอิลิเมนต์ด้วยวิธีต่างๆ)

import java.util.*;
 
public class LinkedListTest {
 
       public static void main(String args[]){
 
           LinkedList<Integer> myLinkedList= new LinkedList<Integer>();
           myLinkedList.add(1);
           myLinkedList.add(2);
           myLinkedList.add(4);
           System.out.println("three added elements: " + myLinkedList);
           //put one element into the head, not to the tail:
           myLinkedList.push(5);
           System.out.println("The new element last in will be the first: " + myLinkedList);
           //add new element at the specified position:
           myLinkedList.add(4,3);
           //put one element into the head, not to the tail (same as push):
           myLinkedList.addFirst(6);
           System.out.println(myLinkedList);
           //now remove element no 2 (it is 1):
           myLinkedList.remove(2);
           System.out.println(myLinkedList);
           //now remove the head of the list
           myLinkedList.pop();
           System.out.println(myLinkedList);
           //remove with the other method
           myLinkedList.remove();
           System.out.println(myLinkedList);
           //and with one more
           myLinkedList.poll();
           System.out.println(myLinkedList);
       }
       }

คิวลำดับความสำคัญ

PriorityQueue ไม่ใช่คิวในความหมายทั่วไปของ FIFO องค์ประกอบของคิวลำดับความสำคัญจะเรียงลำดับตามลำดับธรรมชาติ หรือโดยตัวเปรียบเทียบที่จัดไว้ให้ในเวลาสร้างคิว ทั้งนี้ขึ้นอยู่กับตัวสร้างที่ใช้ อย่างไรก็ตาม มันไม่ใช่คำสั่งที่เหมือนอยู่ในโครงสร้างเชิงเส้น เช่น รายการ (จากใหญ่สุดไปหาเล็กสุดหรือกลับกัน) คิวลำดับความสำคัญขึ้นอยู่กับฮีปขั้นต่ำลำดับความสำคัญ ฮีปเป็นโครงสร้างข้อมูลแบบไบนารีทรี. ลำดับความสำคัญของผู้ปกครองแต่ละคนมีมากกว่าลำดับความสำคัญของบุตรหลาน ต้นไม้เรียกว่าเลขฐานสองสมบูรณ์ ถ้าผู้ปกครองแต่ละคนมีลูกไม่เกินสองคน และการเติมระดับจะเรียงจากบนลงล่าง (จากระดับเดียวกัน — จากซ้ายไปขวา) ฮีปไบนารีจัดระเบียบตัวเองใหม่ทุกครั้งที่มีการเพิ่มหรือลบองค์ประกอบใหม่ ในกรณีของ min-heap องค์ประกอบที่เล็กที่สุดจะไปที่รูทโดยไม่คำนึงถึงลำดับของการแทรก Priority Queue ขึ้นอยู่กับ min-heap นี้ ดังนั้นหากเรามี PriorityQueue เป็นจำนวนเต็ม องค์ประกอบแรกของมันจะมีค่าน้อยที่สุดในจำนวนเหล่านี้ หากคุณลบรูท ตัวที่เล็กที่สุดตัวถัดไปจะกลายเป็นรูท

วิธีการจัดคิวลำดับความสำคัญหลัก:

  • เพิ่มบูลีน (วัตถุ)แทรกองค์ประกอบที่ระบุในคิวลำดับความสำคัญ คืนค่าจริงในกรณีที่สำเร็จ ถ้าคิวเต็ม เมธอดจะส่งข้อยกเว้น
  • ข้อเสนอบูลีน (วัตถุ)แทรกองค์ประกอบที่ระบุลงในคิวลำดับความสำคัญนี้ หากคิวเต็ม เมธอดจะส่งกลับค่าเท็จ
  • บูลีนลบ (วัตถุ)ลบอินสแตนซ์เดียวขององค์ประกอบที่ระบุออกจากคิวนี้ หากมีอยู่
  • การสำรวจวัตถุ ()ดึงและลบส่วนหัวของคิวนี้ คืนค่า null หากคิวว่างเปล่า
  • void clear()ลบองค์ประกอบทั้งหมดออกจากลำดับความสำคัญ
  • องค์ประกอบวัตถุ ()ดึงส่วนหัวของคิวนี้โดยไม่ต้องลบออก ส่ง NoSuchElementException หากคิวว่างเปล่า
  • Object peek()ดึงส่วนหัวของคิวโดยไม่ต้องลบออก คืนค่า null หากคิวว่างเปล่า
  • บูลีนมี (Object o)คืนค่าจริงหากคิวมีองค์ประกอบ o
  • int size()ส่งคืนจำนวนองค์ประกอบในคิวนี้

ตัวอย่างของ PriorityQueue


import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
 
public class PriorityQueueExample {
   public static void main(String[] args) {
 
       Queue<Integer> queueL = new LinkedList<>();
       for (int i = 5; i > 0; i--) {
           queueL.add(i);
       }
       System.out.println("Print our LinkedList Queue (FIFO): " + queueL);
       Queue<Integer> priorityQueue = new PriorityQueue<>();
 
       for (int i = 5; i > 0; i--) {
       priorityQueue.offer(i);
       }
 
       System.out.println("PriorityQueue printing (by iterating, no elements removing): " + priorityQueue);
       System.out.println("Print PriorityQueue using poll() (by retrieval): " );
       while (!priorityQueue.isEmpty()) {
           System.out.println(priorityQueue.poll());
       }
}
}
Print our LinkedList Queue (FIFO): [5, 4, 3, 2, 1]
PriorityQueue printing (by iterating, no elements removing): [1, 2, 4, 5, 3]
Print our  PriorityQueue using poll() (by retrieval): 
1
2
3
4
5
สิ่งสำคัญคือต้องเข้าใจว่าคิวลำดับความสำคัญขึ้นอยู่กับฮีปแบบไบนารี ดังนั้นจึงไม่เก็บองค์ประกอบตามลำดับการเรียงเชิงเส้น ทุกวิถีทางจากรากถึงใบถูกสั่ง แต่วิธีที่แตกต่างจากรากนั้นไม่ได้ นั่นหมายความว่าคุณจะได้รับองค์ประกอบขั้นต่ำของคิวอย่างรวดเร็ว หากคุณลบส่วนหัวทุกครั้ง คุณจะพิมพ์โครงสร้างที่เรียงลำดับ

ArrayBlockingQueue

โครงสร้างข้อมูลภายในของ ArrayBlockingQueueขึ้นอยู่กับอาร์เรย์แบบวงกลมเพื่อจัดเก็บองค์ประกอบ เป็นคิวทั่วไป (FIFO) ในกรณีที่องค์ประกอบใหม่ถูกแทรกที่ส่วนท้ายของคิว และการดำเนินการแยกส่งคืนองค์ประกอบจากส่วนหัวของคิว เมื่อสร้างคิวแล้วจะไม่สามารถเปลี่ยนแปลงได้ ความพยายามที่จะแทรก (ใส่) องค์ประกอบลงในคิวเต็มนำไปสู่การบล็อกโฟลว์ การพยายามรับองค์ประกอบจากคิวว่างจะบล็อกเธรดด้วย ดังที่เราได้กล่าวไปแล้ว อาร์เรย์นี้เป็นวงกลม นั่นหมายความว่าองค์ประกอบแรกและองค์ประกอบสุดท้ายของอาร์เรย์ได้รับการปฏิบัติที่อยู่ติดกันทางตรรกะ คิวจะเลื่อนดัชนีขององค์ประกอบส่วนหัวและส่วนท้ายทุกครั้งที่คุณใส่องค์ประกอบลงในคิวหรือลบออกจากคิว หากดัชนีบางตัวเลื่อนองค์ประกอบสุดท้ายของอาร์เรย์ ดัชนีจะเริ่มต้นใหม่จาก 0 ดังนั้น คิวไม่จำเป็นต้องเลื่อนองค์ประกอบทั้งหมดในกรณีที่มีการถอดส่วนหัว (เหมือนในอาร์เรย์ปกติ) อย่างไรก็ตาม ในกรณีของการลบองค์ประกอบออกจากตรงกลาง (โดยใช้ Iterator.remove) องค์ประกอบจะถูกเลื่อน ArrayBlockingQueueสนับสนุนนโยบายความเป็นธรรมเพิ่มเติมด้วย พารามิเตอร์ ที่ยุติธรรมในตัวสร้างเพื่อสั่งงานกระแสการรอของผู้ผลิต (การแทรกองค์ประกอบ) และผู้บริโภค (การแยกองค์ประกอบ) ตามค่าเริ่มต้น คำสั่งซื้อจะไม่รับประกัน อย่างไรก็ตาม หากคิวถูกสร้างขึ้นด้วย "fair == true" การนำคลาส ArrayBlockingQueue ไปใช้จะให้การเข้าถึงเธรดตามลำดับ FIFO โดยทั่วไป Equity จะลดแบนด์วิดท์ แต่ยังลดความผันผวนและป้องกันไม่ให้ทรัพยากรหมด

ตัวสร้างคลาส ArrayBlockingQueue

  • ArrayBlockingQueue (ความจุ int)สร้างคิวของความจุคงที่และด้วยนโยบายการเข้าถึงเริ่มต้น
  • ArrayBlockingQueue (int capacity, boolean fair)สร้างคิวที่มีความจุคงที่และนโยบายการเข้าถึงที่ระบุ
  • ArrayBlockingQueue (ความจุ int, บูลีนยุติธรรม, คอลเลกชัน <? ขยาย E> c)สร้างคิวที่มีความจุคงที่ที่ระบุโดยนโยบายการเข้าถึงและรวมองค์ประกอบในคิว
เรามีตัวอย่าง BlockingQueueExample เราสร้างคิวของ ArrayBlockingQueue ด้วยความจุขององค์ประกอบเดียวและแฟล็กที่ยุติธรรม เธรดสองเธรดเริ่มต้นขึ้น อย่างแรกคือเธรดของผู้ผลิต จัดคิวข้อความจากอาร์เรย์ข้อความโดยใช้วิธีการพุท อันที่สอง Consumer เธรดอ่านองค์ประกอบจากคิวโดยใช้ วิธี takeและแสดงในคอนโซล ลำดับขององค์ประกอบเป็นธรรมชาติสำหรับคิว

import java.util.concurrent.*;
 
public class ArrayBlockingQueueExample {
 
   private BlockingQueue<Integer> blockingQueue;
   private final Integer[]  myArray = {1,2,3,4,5};
  
       public ArrayBlockingQueueExample ()
       { blockingQueue = new ArrayBlockingQueue<Integer>(1, true);
           (new Thread(new Producer())).start();
           (new Thread(new Consumer())).start();
       }
 
       class Producer implements Runnable
       {
           public void run() {
               try {
                   int counter = 0;
                   for (int i=0; i < myArray.length; i++) {
                       blockingQueue.put(myArray[i]);
                       if (counter++ < 2)
                           Thread.sleep(3000);
                   } blockingQueue.put(-1);
               }
               catch (InterruptedException e) {
                   System.err.println(e.getMessage());
               }
           }
       }
 
       class Consumer implements Runnable
       {
           public void run() {
               try {
                   Integer message = 0;
                   while (!((message = blockingQueue.take()).equals(-1)))
                       System.out.println(message);
               } catch (InterruptedException e) {
                   System.err.println(e.getMessage());
               }
           }
       }
 
       public static void main(String[] args) {
           new ArrayBlockingQueueExample();
       }
   }
เอาต์พุตคือคิวตามลำดับธรรมชาติ สององค์ประกอบแรกปรากฏขึ้นพร้อมกับความล่าช้า เพื่อเสริมสิ่งที่คุณได้เรียนรู้ เราขอแนะนำให้คุณดูบทเรียนวิดีโอจากหลักสูตร Java ของเรา

ข้อสรุป

  • Queue ใช้เพื่อแทรกองค์ประกอบที่ส่วนท้ายของคิวและลบออกจากจุดเริ่มต้นของคิว เป็นไปตามแนวคิด FIFO
  • Java Queue เป็นส่วนหนึ่งของ Collection Framework และใช้อินเทอร์เฟซ Collection ดังนั้นจึงรองรับทุกวิธีของส่วนต่อประสานการรวบรวม เช่น การแทรก การลบ และอื่นๆ
  • การใช้งาน Queue ที่ใช้บ่อยที่สุดคือ LinkedList, ArrayBlockingQueue และ PriorityQueue
  • องค์ประกอบของคิวลำดับความสำคัญจะเรียงลำดับตามลำดับธรรมชาติ หรือโดยตัวเปรียบเทียบที่มีให้ในเวลาสร้างคิว ขึ้นอยู่กับตัวสร้างที่ใช้
  • หากมีการดำเนินการที่เป็นค่าว่างบน BlockingQueue ค่า NullPointerException จะถูกส่งออกไป
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION