91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

ArrayList和LinkedList有什么區(qū)別?

jf_ro2CN3Fa ? 來(lái)源:芋道源碼 ? 作者:芋道源碼 ? 2022-11-17 10:14 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

來(lái)源:小姐姐味道
  • 延遲隊(duì)列
  • 關(guān)鍵代碼
  • 主要方法
  • 增加take方法的效率
  • End

ArrayList和LinkedList有什么區(qū)別?

這種侮辱人的問(wèn)題,默認(rèn)就把這兩者限定在了同一個(gè)場(chǎng)景之中,它甚至連八股文都算不上。

一旦你被問(wèn)到這種問(wèn)題,也證明面試基本上泡湯了--面試官已經(jīng)實(shí)在是找不到其他問(wèn)題與你交流了。

你Over了。

但當(dāng)我們細(xì)看一下LinkedList的class定義,就會(huì)發(fā)現(xiàn),它并不像是ArrayList的那樣具有純潔的列表精神。

publicclassArrayList<E>extendsAbstractList<E>
implementsList<E>,RandomAccess,Cloneable,java.io.Serializable

//VS

publicclassLinkedList<E>
extendsAbstractSequentialList<E>
implementsList<E>,Deque<E>,Cloneable,java.io.Serializable

LinkedList除了能夠當(dāng)作普通的列表,它還是一個(gè)Deque。雙向鏈表,聽(tīng)著就比較唬人,這就是一個(gè)既能當(dāng)做隊(duì)列、又能當(dāng)做棧的存在。

有了這種雙重Buff的疊加,LinkedList的應(yīng)用場(chǎng)景比ArrayList豐富的多。除了能做最簡(jiǎn)單的LRU緩存,LinkedList在刷題的時(shí)候也是充滿了正能量。

王者ConcurrentLinkedQueue,一個(gè)阻塞的雙向隊(duì)列,它的基本操作方法有:(3[基本]x2[異常與返回值]+4[阻塞加超時(shí)])x3[隊(duì)頭隊(duì)尾]=5x2x3=30,足足有30個(gè)方法??赐晟厦娴奈恼?,這30個(gè)方法可以很快手到擒來(lái)。

不過(guò)我們今天要聊的一個(gè)重點(diǎn),是使用Deque來(lái)實(shí)現(xiàn)更快的延遲隊(duì)列。

延遲隊(duì)列

如果你想要某些數(shù)據(jù)延遲一段時(shí)間再進(jìn)行處理,或者要再某段時(shí)間內(nèi)按照分組進(jìn)行一些計(jì)算,那延遲隊(duì)列無(wú)疑是非常合適的。

在Java的Concurrent包里,就靜悄悄的躺著DelayQueue。只要你的數(shù)據(jù)實(shí)現(xiàn)了Delayed接口,那么就可以放心大膽的把它們往里面塞。

可惜的是,DelayQueue的底層存儲(chǔ),使用的是PriorityQueue。

PriorityQueue是堆實(shí)現(xiàn)的,offer和poll數(shù)據(jù)的時(shí)間復(fù)雜度是O(logN)。這就意味著,當(dāng)DelayQueue中的數(shù)據(jù)比較多的時(shí)候,它的性能就會(huì)下降。

除了把數(shù)據(jù)分片,使用多個(gè)DelayQueue來(lái)完成工作,我們有沒(méi)有速度更快的方法?比如把PriorityQueue使用LinkedList來(lái)替換?

這要看場(chǎng)景。

如果你向DelayQueue中添加數(shù)據(jù),是與當(dāng)前添加的時(shí)間相關(guān)的,那完全可以使用LinkedList來(lái)替換PriorityQueue。

基于 Spring Boot + MyBatis Plus + Vue & Element 實(shí)現(xiàn)的后臺(tái)管理系統(tǒng) + 用戶小程序,支持 RBAC 動(dòng)態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能

  • 項(xiàng)目地址:https://github.com/YunaiV/ruoyi-vue-pro
  • 視頻教程:https://doc.iocoder.cn/video/

關(guān)鍵代碼

要了解DelayQueue的運(yùn)行原理,我們可以需要先看一下Delayed接口。任何想要存儲(chǔ)到DelayQueue中的數(shù)據(jù),都需要實(shí)現(xiàn)這個(gè)接口。

其中,getDelay就是用來(lái)判斷當(dāng)前數(shù)據(jù)是否超時(shí)的方法。而compareTo,則是PriorityQueue用來(lái)排序的,如果我們是按照當(dāng)前塞入數(shù)據(jù)的,則compareTo方法就不是必要的。

publiclonggetDelay(@NotNullTimeUnitunit){
returnMAX_CACHE_DUAL+this.enqueueTimeNs-System.nanoTime();
}
publicintcompareTo(@NotNullDelayedo){
longd=getDelay(TimeUnit.NANOSECONDS)-o.getDelay(TimeUnit.NANOSECONDS);
return(d==0)?0:(d0?-1:1);
}

按照以上的思路,我們把DelayQueue的代碼拷貝一份,僅保留關(guān)鍵代碼,如下。

publicclassLightweightDelayedQueue<EextendsDelayed>{
privatefinaltransientReentrantLocklock=newReentrantLock();
privatefinalLinkedListq=newLinkedList<>();
privatefinalConditionavailable=lock.newCondition();
privateThreadleader;

publicvoidput(Ee){
finalReentrantLocklock=this.lock;
lock.lock();
try{
q.offer(e);
if(q.peek()==e){
leader=null;
available.signal();
}
}finally{
lock.unlock();
}
}

publicEtake()throwsInterruptedException{
finalReentrantLocklock=this.lock;
lock.lockInterruptibly();
try{
for(;;){
Efirst=q.peek();
if(first==null)
available.await();
else{
longdelay=first.getDelay(NANOSECONDS);
if(delay<=?0L)
returnq.poll();
first=null;//don'tretainrefwhilewaiting
if(leader!=null)
available.await();
else{
ThreadthisThread=Thread.currentThread();
leader=thisThread;
try{
available.awaitNanos(delay);
}finally{
if(leader==thisThread)
leader=null;
}
}
}
}
}finally{
if(leader==null&&q.peek()!=null)
available.signal();
lock.unlock();
}
}

publicintsize(){
finalReentrantLocklock=this.lock;
lock.lock();
try{
returnq.size();
}finally{
lock.unlock();
}
}

publicintdrainTo(CollectionsuperE>c,intmaxElements){
Objects.requireNonNull(c);
if(c==this)
thrownewIllegalArgumentException();
if(maxElements<=?0)
return0;
finalReentrantLocklock=this.lock;
lock.lock();
try{
intn=0;
for(Efirst;
nnull
&&first.getDelay(NANOSECONDS)<=?0;){
c.add(first);//Inthisorder,incaseadd()throws.
q.poll();
++n;
}
returnn;
}finally{
lock.unlock();
}
}
}

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實(shí)現(xiàn)的后臺(tái)管理系統(tǒng) + 用戶小程序,支持 RBAC 動(dòng)態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能

  • 項(xiàng)目地址:https://github.com/YunaiV/yudao-cloud
  • 視頻教程:https://doc.iocoder.cn/video/

主要方法

輕量級(jí)的延遲隊(duì)列,如果一旦采用了LinkedList,那么它的入隊(duì)、出隊(duì)方法,就都變成了O(1)的時(shí)間復(fù)雜度。在延遲隊(duì)列中的數(shù)據(jù)增加時(shí),時(shí)間復(fù)雜度也能維持不變,可以說(shuō)是速度快的連兔子都追不上了。

一般,在java中,put和take方法,都是代表阻塞性方法。比如,take方法,我們可以將其安全的阻塞在某個(gè)線程上,而不用擔(dān)心太多的資源浪費(fèi)。

finalThreadthread=Thread.currentThread();
while(!this.close&&!thread.isInterrupted()){
Datadata=q.take();
}

這一切都是Condition辦到的,它和wait、notify的作用是一樣的。

當(dāng)我們通過(guò)put方法添加新的數(shù)據(jù)到隊(duì)列中,會(huì)通過(guò)signal方法,來(lái)通知等待的線程獲取數(shù)據(jù)。

相同的,如果take方法發(fā)現(xiàn)隊(duì)列中的數(shù)據(jù)為空,它將進(jìn)入等待狀態(tài)。如果有數(shù)據(jù),也并不是馬上把這些數(shù)據(jù)取出來(lái),因?yàn)閿?shù)據(jù)還沒(méi)到期。比如最老的數(shù)據(jù)還剩下5秒才到期,代碼也對(duì)這種情況進(jìn)行了處理,它會(huì)嘗試awaitNanos對(duì)應(yīng)的時(shí)間。

這樣,我們就可以使用這種簡(jiǎn)單的輪詢方式來(lái)實(shí)現(xiàn)延遲隊(duì)列,而不需要單獨(dú)的線程去檢測(cè)隊(duì)列中的數(shù)據(jù)。

增加take方法的效率

但是這樣還不夠。

當(dāng)數(shù)據(jù)量比較大的時(shí)候,隊(duì)列的數(shù)據(jù)可能有多條已經(jīng)到期。如果我們通過(guò)take方法來(lái)一條一條獲取的話,效率自然不如批量獲取高。

drainTo方法,可以一股腦的把到期的數(shù)據(jù)轉(zhuǎn)移到其他的集合中,但它并不是一個(gè)阻塞性的方法。

我們可以先使用take來(lái)阻塞線程,然后再批量取出所有數(shù)據(jù)。

下面代碼,會(huì)一次性獲取100條數(shù)據(jù)作為一個(gè)批量。

finalDatatakeItem=q.take();
finalListbuckets=newArrayList<>(100);
q.drainTo(buckets,99);
buckets.add(takeItem);

End

實(shí)際上,我們的某個(gè)業(yè)務(wù),當(dāng)采用LinkedList來(lái)替代PriorityQueue,并進(jìn)行批量操作后,CPU的使用直接降低了1/3。

Deque是xjjdog最喜歡的一個(gè)接口。每當(dāng)使用offerFirst、offerLast這樣精準(zhǔn)的API進(jìn)行操作,都會(huì)體驗(yàn)到多巴胺的樂(lè)趣。LinkedList作為它的兒子,自然擁有了這些所有的功能。

當(dāng)我們使用concurrent包里的基本API,對(duì)這些淳樸的工具進(jìn)行封裝,它們就會(huì)煥發(fā)出新的活力。



審核編輯 :李倩


聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 數(shù)據(jù)
    +關(guān)注

    關(guān)注

    8

    文章

    7342

    瀏覽量

    94910
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4973

    瀏覽量

    74155

原文標(biāo)題:當(dāng) LinkedList 不是列表時(shí),速度快的兔子都追不上!

文章出處:【微信號(hào):芋道源碼,微信公眾號(hào):芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    請(qǐng)問(wèn)TJA1028DT/0 和 TJA1028x/5/20 什么區(qū)別

    TJA1028DT/0 和 TJA1028x/5/20 什么區(qū)別?
    發(fā)表于 03-20 07:41

    頻率綜合器、頻率源、信號(hào)源什么區(qū)別?一文講透

    頻率綜合器、頻率源、信號(hào)源什么區(qū)別,簡(jiǎn)單來(lái)說(shuō)就是頻率源是“提供心跳”的——穩(wěn)定、精準(zhǔn),但功能單一, 頻率綜合器是“可變心跳”——在頻率源基礎(chǔ)上增加了可編程能力, 信號(hào)源是“完整樂(lè)隊(duì)”——包含頻率綜合器,還能調(diào)制、編碼、仿真各種復(fù)雜信號(hào)。
    的頭像 發(fā)表于 03-05 14:07 ?170次閱讀
    頻率綜合器、頻率源、信號(hào)源<b class='flag-5'>有</b><b class='flag-5'>什么區(qū)別</b>?一文講透

    行星減速機(jī)與齒輪減速機(jī)什么區(qū)別?

    行星減速機(jī)與齒輪減速機(jī)什么區(qū)別
    的頭像 發(fā)表于 01-04 16:30 ?1678次閱讀
    行星減速機(jī)與齒輪減速機(jī)<b class='flag-5'>有</b><b class='flag-5'>什么區(qū)別</b>?

    武漢芯源MCU和英飛凌MCU什么區(qū)別

    武漢芯源MCU和英飛凌MCU什么區(qū)別
    發(fā)表于 12-11 06:26

    MCU不同封裝都什么區(qū)別?

    目前MCU不同封裝都什么區(qū)別
    發(fā)表于 12-01 06:41

    請(qǐng)問(wèn)jtag和jlink什么區(qū)別?。?/a>

    jtag和jlink什么區(qū)別啊?
    發(fā)表于 11-28 06:46

    高壓探棒和高壓差分探頭什么區(qū)別?

    我們?cè)谑褂霉β史糯笃鞣糯笮盘?hào),或是需要檢測(cè)信號(hào)的時(shí)候,可能都會(huì)用到這樣一個(gè)測(cè)試測(cè)量設(shè)備,那就是高壓探棒和高壓差分探頭,那么你知道高壓探棒和高壓差分探頭什么區(qū)別嗎?一、高壓探棒和差分探頭的基本概念
    的頭像 發(fā)表于 11-19 08:38 ?568次閱讀
    高壓探棒和高壓差分探頭<b class='flag-5'>有</b><b class='flag-5'>什么區(qū)別</b>?

    ARM架構(gòu)與DSP什么區(qū)別?哪一個(gè)更好?

    ARM架構(gòu)與DSP什么區(qū)別?哪一個(gè)更好?
    發(fā)表于 11-19 06:14

    微波雷達(dá)和毫米波雷達(dá)什么區(qū)別

    微波雷達(dá)和毫米波雷達(dá)什么區(qū)別 前言:不知道大家有沒(méi)有發(fā)現(xiàn),各種雷達(dá)模塊的使用開(kāi)始逐漸加入各種智能家居產(chǎn)品了,像人來(lái)燈亮,人走燈滅這種雷達(dá)感應(yīng)的產(chǎn)品早幾年就開(kāi)始進(jìn)入市場(chǎng)了,還有各種感應(yīng)開(kāi)關(guān)等產(chǎn)品
    的頭像 發(fā)表于 10-30 16:56 ?2121次閱讀
    微波雷達(dá)和毫米波雷達(dá)<b class='flag-5'>有</b><b class='flag-5'>什么區(qū)別</b>

    CBB82電容和CBB81電容什么區(qū)別

    CBB81電容大家都不陌生,它屬于高壓諧振電容器,在很多高壓、高頻、大電流電路中,都能見(jiàn)到它的身影,還有一種電容器叫CBB82電容,兩者只有一字之差,什么區(qū)別呢?
    的頭像 發(fā)表于 09-15 14:53 ?1071次閱讀

    Re-Driver 和 Re-Timer 什么區(qū)別?

    Re-Driver 和 Re-Timer 什么區(qū)別
    發(fā)表于 08-21 06:14

    使用ICP編程工具進(jìn)行離線編程設(shè)置時(shí),啟用“使用密碼”什么區(qū)別

    使用ICP編程工具進(jìn)行離線編程設(shè)置時(shí),啟用“使用密碼”什么區(qū)別
    發(fā)表于 08-19 06:04

    請(qǐng)問(wèn)ST7701和ST7701S什么區(qū)別嗎?

    ST7701和ST7701S什么區(qū)別
    發(fā)表于 07-22 08:16

    sd-wan組網(wǎng)方案和woc設(shè)備有什么區(qū)別

    SD-WAN組網(wǎng)方案和WOC(廣域網(wǎng)優(yōu)化控制器)設(shè)備是解決企業(yè)廣域網(wǎng)(WAN)問(wèn)題的兩種不同技術(shù)路線,它們的目標(biāo)部分重疊(提升性能、降低成本),但核心原理、實(shí)現(xiàn)方式和側(cè)重點(diǎn)顯著區(qū)別,主機(jī)推薦小編為您整理發(fā)布sd-wan組網(wǎng)方案和woc設(shè)備有
    的頭像 發(fā)表于 06-03 11:21 ?1107次閱讀
    sd-wan組網(wǎng)方案和woc設(shè)備有<b class='flag-5'>什么區(qū)別</b>

    GD32與STM32什么區(qū)別

    電子發(fā)燒友網(wǎng)站提供《GD32與STM32什么區(qū)別.docx》資料免費(fèi)下載
    發(fā)表于 04-03 17:27 ?0次下載