簡單易懂的Java Queue入門教程!

哈嘍,各位小伙伴們,你們好呀,我是喵手。運營社區:C站/掘金/騰訊云;歡迎大家常來逛逛

??今天我要給大家分享一些自己日常學習到的一些知識點,并以文字的形式跟大家一起交流,互相學習,一個人雖可以走的更快,但一群人可以走的更遠。

??我是一名后端開發愛好者,工作日常接觸到最多的就是Java語言啦,所以我都盡量抽業余時間把自己所學到所會的,通過文章的形式進行輸出,希望以這種方式幫助到更多的初學者或者想入門的小伙伴們,同時也能對自己的技術進行沉淀,加以復盤,查缺補漏。

小伙伴們在批閱的過程中,如果覺得文章不錯,歡迎點贊、收藏、關注哦。三連即是對作者我寫作道路上最好的鼓勵與支持!

前言

??在軟件開發領域,隊列是一種非常重要的數據結構。它被廣泛應用于多線程、網絡通信、緩存、消息隊列等場景。Java語言提供了多種隊列實現,其中最常用的是Queue接口及其實現類。下面將詳細介紹Java中的Queue及其應用場景。

摘要

??本文將介紹Java中Queue接口及其實現類的概念、源代碼解析、應用場景案例、優缺點分析、類代碼方法介紹、測試用例等內容。原則上,讀者需要掌握Java基礎語法及數據結構相關知識。

Queue

簡介

??Queue是Java中的一種接口,它繼承自Collection接口,并添加了一些隊列相關的方法。Queue的實現類有多種,包括LinkedList、ArrayBlockingQueue、PriorityQueue、ConcurrentLinkedQueue等。下面簡要介紹一下各個實現類的特點:

  1. LinkedList

??LinkedList是Java中的一個雙向鏈表實現類。LinkedList實現了Deque接口,Deque又是Queue接口的子接口,因此LinkedList可以被視為Queue的一種實現。LinkedList的優點是插入、刪除操作效率高,但是隨機訪問效率低。

  1. ArrayBlockingQueue

??ArrayBlockingQueue是Java中的一個基于數組的有界阻塞隊列實現類。它的內部實現類似于一個環形數組,數組的長度是固定的。ArrayBlockingQueue具有先進先出的隊列特性,它支持多線程安全訪問,可以指定等待時間,當隊列滿或空時,線程將被阻塞。

  1. PriorityQueue

??PriorityQueue是Java中的一個帶優先級的隊列實現類。它的內部是一個堆結構,根據元素的排序規則進行排序,每次出隊時都會返回當前隊列中最小(或最大)的元素。PriorityQueue的特點是插入、刪除效率高,但是元素數量較大時遍歷效率不高。

  1. ConcurrentLinkedQueue

??ConcurrentLinkedQueue是Java中的一個基于鏈表的無界并發隊列實現類。ConcurrentLinkedQueue的特點是多線程安全,能夠高效地處理高并發場景。它不支持阻塞操作,而且不保證元素的排序。

源代碼解析

下面我們以ArrayBlockingQueue為例,簡單解析一下它的源代碼。

public class ArrayBlockingQueue<E> extends AbstractQueue<E>implements BlockingQueue<E>, java.io.Serializable {/** The queued items */final Object[] items;/** items index for next take, poll or remove */int takeIndex;/** items index for next put, offer, or add */int putIndex;/** Number of elements in the queue */int count;/** Main lock guarding all access */final ReentrantLock lock;/** Condition for waiting takes */private final Condition notEmpty;/** Condition for waiting puts */private final Condition notFull;// ...
}

??如上所示,ArrayBlockingQueue繼承了AbstractQueue類,并實現了BlockingQueue接口和Serializable接口。其內部使用了一個Object數組items用于存儲隊列中的元素,使用takeIndex和putIndex分別表示下一次取出元素和添加元素的位置,使用count表示隊列中當前元素個數,使用lock實現線程同步,使用notEmpty和notFull兩個Condition實現阻塞和喚醒操作。

如下是部分源碼截圖:

在這里插入圖片描述

應用場景案例

下面介紹一下Queue在實際開發中的應用場景:

  1. 消息隊列

    在分布式系統中,消息隊列是一種常用的通信方式。生產者向隊列中添加消息,消費者從隊列中取出消息進行處理。Java語言中提供的ActiveMQ和RabbitMQ等消息隊列服務均使用了隊列的相關技術。

  2. 線程池

    在Java中,線程池通常使用BlockingQueue來存儲待執行的任務。當線程池中的線程已經全部分配任務時,新的任務將會被阻塞,直到有線程可用為止。Java中的ThreadPoolExecutor就是使用了BlockingQueue來存儲待執行的任務。

  3. 緩存

??在Java中,緩存通常使用LinkedList或ConcurrentLinkedQueue來實現。緩存存儲的是最近訪問過的元素,當緩存已滿時,新的元素會將最舊的元素移除。

優缺點分析

Queue的優缺點分析如下:

  1. 優點

    Queue能夠高效地實現元素的插入、刪除以及元素的存儲。Queue還能夠在多線程場景中安全地實現元素的讀寫操作。

  2. 缺點

??在某些場景下,Queue可能會存在性能瓶頸。例如當Queue中元素數量較大時,遍歷操作效率較低,此時需要使用其他數據結構來優化性能。另外Queue中元素的順序是固定的,無法對元素的順序進行修改。

類代碼方法介紹

Queue接口中包含了很多常用的方法,下面介紹一下其中一些常用的方法:

  1. add(E e)

    將元素e添加到隊列尾部,如果隊列已滿,則拋出IllegalStateException異常。

  2. offer(E e)

    將元素e添加到隊列尾部,返回值表示添加操作是否成功。

  3. remove()

    移除隊列頭部的元素并返回該元素,如果隊列為空,則拋出NoSuchElementException異常。

  4. poll()

    移除隊列頭部的元素并返回該元素,如果隊列為空,則返回null。

  5. element()

    返回隊列頭部的元素,如果隊列為空,則拋出NoSuchElementException異常。

  6. peek()

    返回隊列頭部的元素,如果隊列為空,則返回null。

測試用例

下面給出ArrayBlockingQueue的測試用例:

測試代碼

package com.example.javase.collection;import java.util.concurrent.*;/*** @Author ms* @Date 2023-10-24 23:32*/
public class QueueTest {private static final int BUFFER_SIZE = 10;private static final int PRODUCER_COUNT = 5;private static final int CONSUMER_COUNT = 5;private static final int ITEM_COUNT = 1000;private static final ExecutorService pool = Executors.newCachedThreadPool();public static void main(String[] args) throws InterruptedException {ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<>(BUFFER_SIZE);for (int i = 0; i < PRODUCER_COUNT; i++) {pool.execute(new Producer(queue, ITEM_COUNT));}for (int i = 0; i < CONSUMER_COUNT; i++) {pool.execute(new Consumer(queue, ITEM_COUNT));}TimeUnit.SECONDS.sleep(60);pool.shutdown();}static class Producer implements Runnable {final BlockingQueue<Integer> queue;final int count;Producer(BlockingQueue<Integer> queue, int count) {this.queue = queue;this.count = count;}public void run() {try {for (int i = 0; i < count; i++) {queue.put(i);}} catch (InterruptedException e) {Thread.currentThread().interrupt();}}}static class Consumer implements Runnable {final BlockingQueue<Integer> queue;final int count;Consumer(BlockingQueue<Integer> queue, int count) {this.queue = queue;this.count = count;}public void run() {try {for (int i = 0; i < count; i++) {queue.take();}} catch (InterruptedException e) {Thread.currentThread().interrupt();}}}
}

??這段代碼實現了生產者-消費者模型,使用了Java內置的阻塞隊列ArrayBlockingQueue來作為共享的緩沖區。主要包含了三個部分:

  1. 定義了共享緩沖區的大小BUFFER_SIZE、生產者和消費者的數量PRODUCER_COUNT和CONSUMER_COUNT,以及需要生產和消費的數據ITEM_COUNT。

  2. 在main方法中,創建一個ArrayBlockingQueue實例,并分別創建PRODUCER_COUNT個生產者線程和CONSUMER_COUNT個消費者線程,然后分別啟動這些線程并等待60秒鐘后關閉線程池。

  3. Producer和Consumer類都實現了Runnable接口。在Producer的run方法中,不斷向隊列中添加數據,直到添加的次數達到ITEM_COUNT;在Consumer的run方法中,不斷從隊列中取出數據,直到取出的次數達到ITEM_COUNT。由于ArrayBlockingQueue是線程安全的,因此不需要做額外的同步處理。

??總的來說,這段代碼展示了如何使用Java內置的阻塞隊列來實現生產者-消費者模型,避免了手動實現同步和互斥的復雜性,提高了代碼的可讀性、可維護性和可復用性。

測試結果

??根據如上測試用例,本地測試結果如下,僅供參考,你們也可以自行修改測試用例或者添加更多的測試數據或測試方法,進行熟練學習以此加深理解。

在這里插入圖片描述

代碼分析

??根據如上測試用例,本地測試結果如下,僅供參考,你們也可以自行修改測試用例或者添加更多的測試數據或測試方法,進行熟練學習以此加深理解。
??該代碼是一個使用 ArrayBlockingQueue 實現的生產者-消費者模型的示例。包含一個主類 ArrayBlockingQueueTest 和兩個內部靜態類 Producer 和 Consumer。主類中創建一個 ArrayBlockingQueue,然后創建 PRODUCER_COUNTProducer 線程和 CONSUMER_COUNTConsumer 線程,并啟動它們。每個 Producer 線程向隊列中插入 ITEM_COUNT 個元素,每個 Consumer 線程從隊列中取出 ITEM_COUNT 個元素。當所有線程運行完畢后,程序將等待 60 秒鐘,然后關閉線程池。

??ProducerConsumer 類實現了 Runnable 接口,分別包含一個 BlockingQueue 對象和一個 count 變量。在 run() 方法中,Producer 線程將元素插入隊列中,Consumer 線程從隊列中取出元素。如果隊列已滿(對于 Producer)或者隊列為空(對于 Consumer),線程會進入阻塞狀態。如果線程被中斷,則中斷狀態會被設置并退出線程。

??該示例使用了線程池來管理并發任務,增加效率。使用 ArrayBlockingQueue 實現了并發訪問控制,保證了線程安全。

小結

??Queue是Java中的一個接口,它的實現類包括LinkedListArrayBlockingQueuePriorityQueueConcurrentLinkedQueue等。Queue常用于消息隊列、線程池、緩存等場景。在使用Queue時需要注意線程安全性和性能問題。

總結

??本文介紹了Java中Queue接口及其實現類的概念、源代碼解析、應用場景案例、優缺點分析、類代碼方法介紹、測試用例等內容。Queue是Java中常用的數據結構,能夠高效地實現元素的插入、刪除及存儲,在多線程場景中也能保障線程安全。常用的Queue實現類有LinkedList、ArrayBlockingQueue、PriorityQueue、ConcurrentLinkedQueue等,它們都具有各自的優缺點。Queue的應用場景包括消息隊列、線程池、緩存等。在使用Queue時需要注意性能問題和線程安全性。

… …

文末

好啦,以上就是我這期的全部內容,如果有任何疑問,歡迎下方留言哦,咱們下期見。

… …

學習不分先后,知識不分多少;事無巨細,當以虛心求教;三人行,必有我師焉!!!

wished for you successed !!!


??若喜歡我,就請關注我叭。

??若對您有用,就請點贊叭。

??若有疑問,就請評論留言告訴我叭。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/10667.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/10667.shtml
英文地址,請注明出處:http://en.pswp.cn/web/10667.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

如何建設智慧黨校

隨著信息技術的飛速展開&#xff0c;特別是近年移動互聯網技術&#xff0c;物聯網技術&#xff0c;人工智能技術&#xff0c;大數據數據的深入展開&#xff0c;我國快速的進入信息化社會&#xff0c;信息化對各行各業的改造越來越深入&#xff0c;任何職業&#xff0c;任何安排…

SSM【Spring SpringMVC Mybatis】—— Spring(一)

目錄 1、初識Spring 1.1 Spring簡介 1.2 搭建Spring框架步驟 1.3 Spring特性 1.5 bean標簽詳解 2、SpringIOC底層實現 2.1 BeanFactory與ApplicationContexet 2.2 圖解IOC類的結構 3、Spring依賴注入數值問題【重點】 3.1 字面量數值 3.2 CDATA區 3.3 外部已聲明be…

淺談ArrayList和LinkedList的區別

ArrayList和LinkedList在Java中都是常用的List接口的實現類&#xff0c;但它們之間存在一些顯著的區別。 實現方式&#xff1a; ArrayList&#xff1a;基于數組實現。內部使用一個動態數組來存儲元素&#xff0c;這意味著可以通過索引快速訪問元素&#xff0c;時間復雜度為O(1)…

算法學習筆記(Nim游戲)

N i m Nim Nim游戲 n n n堆物品&#xff0c;每堆有 a i a_i ai?個&#xff0c;每個玩家輪流取走任意一堆的任意個物品&#xff0c;但不能不取&#xff0c;取走最后一個物品的人獲勝。 N i m Nim Nim游戲是一種經典的公平組合游戲。現在對它進行分析。 首先定義兩個博弈中的狀…

【Chisel】chisel中怎么處理類似verilog的可變位寬和parameter

在 Chisel 中處理可變位寬和參數的方式與 Verilog 有一些不同&#xff0c;因為 Chisel 是建立在 Scala 語言之上的。以下是如何在 Chisel 中處理這些概念的方法&#xff1a; 參數化&#xff08;Parameters&#xff09; 在 Chisel 中&#xff0c;參數化是通過在模塊構造函數中定…

VUE使用餓了么的上傳組件時實現圖片預覽

創作靈感 最近在寫項目時&#xff0c;遇到了上傳頭像的需求&#xff0c;我使用的是element組件中的upload組件。但是在使用時&#xff0c;我需要實現預覽、手動上傳頭像等功能。然而在使用餓了么組件時&#xff0c;這些功能還是需要我們自己去手動實現的&#xff0c;在手動實現…

Linux makefile進度條

語法 在依賴方法前面加上就不會顯示這一行的命令 注意 1.make 會在當前目錄下找名為“makefile” 或者 “Makefile” 的文件 2.為了生成第一依賴文件&#xff0c;如果依賴文件列表有文件不存在&#xff0c;則會到下面的依賴關系中查找 3..PHONY修飾的依賴文件總是被執行的 …

Redis——RDB、AOF和混合持久化機制

Redis提供了三種持久化機制來確保數據的持久保存&#xff0c;分別是RDB&#xff08;Redis DataBase&#xff09;、AOF&#xff08;Append Only File&#xff09;和混合持久化。 RDB&#xff08;Redis DataBase&#xff09; RDB持久化機制是將Redis在內存中的數據保存到磁盤上的…

xss-lab 1-18關payload

Less-1 ?name<script>alert()</script> Less-2 "><script>alert()</script> "οnclick"alert() " οnfοcus"alert() " οnblur"alert() Less-3 οnfοcusalert() οnbluralert() οnfοcusjavascript:aler…

Spring AopUtils深度解析:從入門到精通的全方位指南

1. 概述 AopUtils是Spring框架中的一個工具類&#xff0c;主要用于處理AOP&#xff08;面向切面編程&#xff09;相關的操作。它提供了一系列靜態方法&#xff0c;幫助開發者更方便地處理AOP中的對象、代理以及通知&#xff08;Advice&#xff09;等。 2. 用途 AopUtils的主要…

操作系統原理與系統——實驗十三多道批處理作業調度(作業可移動)

關鍵代碼 #include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct data{int hour;//當前小時int min;//當前分鐘 }time; struct node{char name[20];//進程名time arrive;//到達就緒隊列時間int zx;//執行時間(預期時間)int size;int ta…

Polygon市值機器人

隨著區塊鏈技術的蓬勃發展和數字貨幣市場的日益繁榮&#xff0c;投資者們對于如何精準把握市場動態、實現資產穩健增長的需求愈發迫切。在這個背景下&#xff08;市值管理飛//機//aishutuyu&#xff09;&#xff0c;Polygon市值機器人應運而生&#xff0c;作為一款基于Polygon公…

LeetCode 第397場周賽個人題解

目錄 100296. 兩個字符串的排列差 原題鏈接 思路分析 AC代碼 100274. 從魔法師身上吸取的最大能量 原題鏈接 思路分析 AC代碼 100281. 矩陣中的最大得分 原題鏈接 思路分析 AC代碼 100312. 找出分數最低的排列 原題鏈接 思路分析 AC代碼 100296. 兩個字符串的排…

timerfd加epoll封裝定時器

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 1、用timerfd加epoll封裝定時器的優點2、代碼實現 1、用timerfd加epoll封裝定時器的優點 定時器為什么需要timerfd 在設計定時器時&#xff0c;我們首先想到的就是…

【SpringBoot】Redis Lua腳本實戰指南:簡單高效的構建分布式多命令原子操作、分布式鎖

文章目錄 一.Lua腳本1.Lua特性2.Lua優勢 二.Lua語法1.注釋2.變量3.數據類型&#xff1a;3.1.基本類型3.2.對象類型&#xff1a;表&#xff08;table&#xff09; 4.控制結構&#xff1a;4.1.條件語句: 使用if、else和elseif來實現條件分支。4.2.循環結構&#xff1a;Lua支持for…

Shell參數擴展形式學習筆記

Shell參數擴展形式學習筆記 文章目錄 Shell參數擴展形式學習筆記空值判斷處理 ${parameter:-word} ${parameter:word} ${parameter:?word} ${parameter:word}變量位置截取 ${parameter:offset} ${parameter:offset:length}變量匹配組合 ${!prefix*} ${!prefix} ${!name[]} ${!…

感知機和神經網絡

引入 什么是神經網絡&#xff1f; 我們今天學習的神經網絡&#xff0c;不是人或動物的神經網絡&#xff0c;但是又是模仿人和動物的神經網絡而定制的神經系統&#xff0c;特別是大腦和神經中樞&#xff0c;定制的系統是一種數學模型或計算機模型&#xff0c;神經網絡由大量的人…

圖像處理:圖像噪聲添加

文章目錄 前言一、高斯噪聲二、椒鹽噪聲三、泊松噪聲四、斑點噪聲五、指數噪聲六、均勻噪聲總結 前言 本文主要介紹幾種添加圖像噪聲的方法&#xff0c;用于數據增強等操作。 以下圖為例。 一、高斯噪聲 高斯噪聲就是給圖片添加一個服從高斯分布的噪聲&#xff0c;可以通過調…

vLLM初探

vLLM是伯克利大學LMSYS組織開源的大語言模型高速推理框架&#xff0c;旨在極大地提升實時場景下的語言模型服務的吞吐與內存使用效率。vLLM是一個快速且易于使用的庫&#xff0c;用于 LLM 推理和服務&#xff0c;可以和HuggingFace 無縫集成。vLLM利用了全新的注意力算法「Page…

Python+PySpark數據計算

1、map算子 對RDD內的元素進行逐個處理&#xff0c;并返回一個新的RDD&#xff0c;可以使用lambda以及鏈式編程&#xff0c;簡化代碼。 注意&#xff1a;再python中的lambda只能有行&#xff0c;如果有多行&#xff0c;要寫成外部函數&#xff1b;&#xff08;T&#xff09;-&…