成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

還不了解Java的五大BlockingQueue阻塞隊列源碼,看這篇文章就夠了

開發(fā) 前端
大家用過消息隊列(MessageQueue),就知道消息隊列作用是解耦、異步、削峰。同樣BlockingQueue?的作用也是這三種,區(qū)別是BlockingQueue?只作用于本機器,而消息隊列相當于分布式BlockingQueue。

引言

最近一個月一直在更新《解讀Java源碼專欄》,其中跟大家一起剖析了Java的常見的5種BlockingQueue(阻塞隊列),今天就盤點一下這幾種阻塞隊列的優(yōu)缺點、區(qū)別,以及應(yīng)用場景。

常見的BlockingQueue有以下5種,下面會詳細介紹。

  • ArrayBlockingQueue

基于數(shù)組實現(xiàn)的阻塞隊列,創(chuàng)建隊列時需指定容量大小,是有界隊列。

  • LinkedBlockingQueue

基于鏈表實現(xiàn)的阻塞隊列,默認是無界隊列,創(chuàng)建可以指定容量大小

  • SynchronousQueue

一種沒有緩沖的阻塞隊列,生產(chǎn)出的數(shù)據(jù)需要立刻被消費

  • PriorityBlockingQueue

實現(xiàn)了優(yōu)先級的阻塞隊列,可以按照元素大小排序,是無界隊列

  • DelayQueue

實現(xiàn)了延遲功能的阻塞隊列,基于PriorityQueue實現(xiàn)的,是無界隊列

BlockingQueue簡介

這幾種阻塞隊列都是實現(xiàn)了BlockingQueue接口,在日常開發(fā)中,我們好像很少用到BlockingQueue(阻塞隊列),BlockingQueue到底有什么作用?應(yīng)用場景是什么樣的?

如果使用過線程池或者閱讀過線程池源碼,就會知道線程池的核心功能都是基于BlockingQueue實現(xiàn)的。

大家用過消息隊列(MessageQueue),就知道消息隊列作用是解耦、異步、削峰。同樣BlockingQueue的作用也是這三種,區(qū)別是BlockingQueue只作用于本機器,而消息隊列相當于分布式BlockingQueue。

圖片

BlockingQueue作為阻塞隊列,主要應(yīng)用于生產(chǎn)者-消費者模式的場景,在并發(fā)多線程中尤其常用。

  1. 比如像線程池中的任務(wù)調(diào)度場景,提交任務(wù)和拉取并執(zhí)行任務(wù)。
  2. 生產(chǎn)者與消費者解耦的場景,生產(chǎn)者把數(shù)據(jù)放到隊列中,消費者從隊列中取數(shù)據(jù)進行消費。兩者進行解耦,不用感知對方的存在。
  3. 應(yīng)對突發(fā)流量的場景,業(yè)務(wù)高峰期突然來了很多請求,可以放到隊列中緩存起來,消費者以正常的頻率從隊列中拉取并消費數(shù)據(jù),起到削峰的作用。

BlockingQueue是個接口,定義了幾組放數(shù)據(jù)和取數(shù)據(jù)的方法,來滿足不同的場景。

操作

拋出異常

返回特定值

阻塞

阻塞一段時間

放數(shù)據(jù)

add()

offer()

put()

offer(e, time, unit)

取數(shù)據(jù)(同時刪除數(shù)據(jù))

remove()

poll()

take()

poll(time, unit)

取數(shù)據(jù)(不刪除)

element()

peek()

不支持

不支持

這四組方法的區(qū)別是:

  1. 當隊列滿的時候,再次添加數(shù)據(jù),add()會拋出異常,offer()會返回false,put()會一直阻塞,offer(e, time, unit)會阻塞指定時間,然后返回false。
  2. 當隊列為空的時候,再次取數(shù)據(jù),remove()會拋出異常,poll()會返回null,take()會一直阻塞,poll(time, unit)會阻塞指定時間,然后返回null。

ArrayBlockingQueue

  1. ArrayBlockingQueue底層基于數(shù)組實現(xiàn),采用循環(huán)數(shù)組,提升了數(shù)組的空間利用率。
  2. ArrayBlockingQueue初始化的時候,必須指定隊列長度,是有界的阻塞隊列,所以要預(yù)估好隊列長度,保證生產(chǎn)者和消費者速率相匹配。
  3. ArrayBlockingQueue的方法是線程安全的,使用ReentrantLock在操作前后加鎖來保證線程安全。

LinkedBlockingQueue

  1. LinkedBlockingQueue底層基于鏈表實現(xiàn),支持從頭部彈出數(shù)據(jù),從尾部添加數(shù)據(jù)。
  2. LinkedBlockingQueue初始化的時候,如果不指定隊列長度,默認長度是Integer最大值,相當于無界隊列,有內(nèi)存溢出風(fēng)險,建議初始化的時候指定隊列長度。
  3. LinkedBlockingQueue的方法是線程安全的,分別使用了讀寫兩把鎖,比ArrayBlockingQueue性能更好。

與ArrayBlockingQueue區(qū)別是:

  1. 底層結(jié)構(gòu)不同,ArrayBlockingQueue底層基于數(shù)組實現(xiàn),初始化的時候必須指定數(shù)組長度,無法擴容。LinkedBlockingQueue底層基于鏈表實現(xiàn),鏈表最大長度是Integer最大值。
  2. 占用內(nèi)存大小不同,ArrayBlockingQueue一旦初始化,數(shù)組長度就確定了,不會隨著元素增加而改變。LinkedBlockingQueue會隨著元素越多,鏈表越長,占用內(nèi)存越大。
  3. 性能不同,ArrayBlockingQueue的入隊和出隊共用一把鎖,并發(fā)較低。LinkedBlockingQueue入隊和出隊使用兩把獨立的鎖,并發(fā)情況下性能更高。
  4. 公平鎖選項,ArrayBlockingQueue初始化的時候,可以指定使用公平鎖或者非公平鎖,公平鎖模式下,可以按照線程等待的順序來操作隊列。LinkedBlockingQueue只支持非公平鎖。
  5. 適用場景不同,ArrayBlockingQueue適用于明確限制隊列大小的場景,防止生產(chǎn)速度大于消費速度的時候,造成內(nèi)存溢出、資源耗盡。LinkedBlockingQueue適用于業(yè)務(wù)高峰期可以自動擴展消費速度的場景。

SynchronousQueue

無論是ArrayBlockingQueue還是LinkedBlockingQueue都是起到緩沖隊列的作用,當消費者的消費速度跟不上時,任務(wù)就在隊列中堆積,需要等待消費者慢慢消費。

如果我們想要自己的任務(wù)快速執(zhí)行,不要積壓在隊列中,該怎么辦?這時候就可以使用SynchronousQueue了。

SynchronousQueue被稱為同步隊列,當生產(chǎn)者往隊列中放元素的時候,必須等待消費者把這個元素取走,否則一直阻塞。消費者取元素的時候,同理也必須等待生產(chǎn)者放隊列中放元素。

  1. SynchronousQueue底層有兩種實現(xiàn)方式,分別是基于棧實現(xiàn)非公平策略,以及基于隊列實現(xiàn)的公平策略。
  2. SynchronousQueue初始化的時候,可以指定使用公平策略還是非公平策略。
  3. SynchronousQueue不存儲元素,不適合作為緩存隊列使用。適用于生產(chǎn)者與消費者速度相匹配的場景,可減少任務(wù)執(zhí)行的等待時間。

PriorityBlockingQueue

由于PriorityQueue跟前幾個阻塞隊列不一樣,并沒有實現(xiàn)BlockingQueue接口,只是實現(xiàn)了Queue接口,所以PriorityQueue并不算阻塞隊列。Queue接口中定義了幾組放數(shù)據(jù)和取數(shù)據(jù)的方法,來滿足不同的場景。

  1. PriorityQueue實現(xiàn)了Queue接口,提供了兩組放數(shù)據(jù)和讀數(shù)據(jù)的方法,來滿足不同的場景。
  2. PriorityQueue底層基于數(shù)組實現(xiàn),實現(xiàn)了按照元素值大小排序的功能,內(nèi)部按照最小堆存儲,實現(xiàn)了高效的插入和刪除。
  3. PriorityQueue初始化的時候,可以指定數(shù)組長度和自定義比較器。
  4. PriorityQueue初始容量是11,當數(shù)組容量小于64,采用2倍擴容,否則采用1.5擴容。
  5. PriorityQueue每次都是從數(shù)組頭節(jié)點取元素,取之后需要調(diào)整最小堆。

DelayQueue

DelayQueue是一種本地延遲隊列,比如希望我們的任務(wù)在5秒后執(zhí)行,就可以使用DelayQueue實現(xiàn)。常見的使用場景有:

  • 訂單10分鐘內(nèi)未支付,就取消。
  • 緩存過期后,就刪除。
  • 消息的延遲發(fā)送等。
  1. DelayQueue底層采用組合的方式,復(fù)用PriorityQueue的按照延遲時間排序任務(wù)的功能,實現(xiàn)了延遲隊列。
  2. DelayQueue是線程安全的,內(nèi)部使用ReentrantLock加鎖。

總結(jié)

這5種阻塞隊列的特性各不相同,在使用的時候該怎么選擇呢?我做了一張圖,供大家參考。

圖片 圖片

責(zé)任編輯:武曉燕 來源: 一燈架構(gòu)
相關(guān)推薦

2021-11-10 07:47:48

Traefik邊緣網(wǎng)關(guān)

2019-09-25 09:17:43

物聯(lián)網(wǎng)技術(shù)信息安全

2017-03-30 22:41:55

虛擬化操作系統(tǒng)軟件

2019-10-30 09:25:58

NginxApache 服務(wù)器

2022-05-27 08:18:00

HashMapHash哈希表

2024-03-26 00:00:06

RedisZSet排行榜

2018-10-31 17:22:25

AI人工智能芯片

2019-10-31 09:48:53

MySQL數(shù)據(jù)庫事務(wù)

2018-08-17 09:14:43

餓了么容器演進

2024-02-28 08:59:47

2020-10-13 07:44:40

緩存雪崩 穿透

2022-08-26 05:22:21

RabbitMQ架構(gòu)

2017-12-12 12:53:09

2017-03-10 21:04:04

Android適配

2017-03-07 15:35:26

Android適配 界面

2021-04-09 10:03:12

大數(shù)據(jù)exactly-onc

2021-05-07 07:52:51

Java并發(fā)編程

2019-08-16 09:41:56

UDP協(xié)議TCP

2021-09-30 07:59:06

zookeeper一致性算法CAP

2019-07-10 15:15:23

JVM虛擬機Java
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 久久成人一区二区三区 | 国产区免费视频 | 国产综合久久久久久鬼色 | 三级在线观看 | 一区二区中文 | 小早川怜子xxxxaⅴ在线 | 成人h动漫精品一区二区器材 | 99re视频在线观看 | 精品av久久久久电影 | 欧美激情久久久 | 欧美激情一区二区三区 | 免费看a | 国产精品一区二区不卡 | 成年人在线观看 | 亚洲码欧美码一区二区三区 | 欧美日韩一区二区三区不卡视频 | 精品在线免费看 | 国产精品高潮呻吟久久aⅴ码 | 中文在线a在线 | 国产a视频| 91精品国产91久久久久久 | 四虎影院在线观看免费视频 | 亚洲国产一区二区三区 | 欧美一区二区三区大片 | 亚洲欧美日韩精品久久亚洲区 | 成人免费在线视频 | 3p视频在线观看 | 日日天天 | 欧美成人免费在线 | 中文字幕av亚洲精品一部二部 | 国产成人精品综合 | 亚洲电影成人 | 婷婷丁香综合网 | 一级黄色片美国 | 中文字幕一区二区三区不卡在线 | 欧美一区二区三区四区在线 | 精品久久国产老人久久综合 | 精品中文字幕在线观看 | 91精品国产91久久久 | 天天人人精品 | 中文字幕精品一区二区三区精品 |