女人自慰AV免费观看内涵网,日韩国产剧情在线观看网址,神马电影网特片网,最新一级电影欧美,在线观看亚洲欧美日韩,黄色视频在线播放免费观看,ABO涨奶期羡澄,第一导航fulione,美女主播操b

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

ArrayList和LinkedList有什么區別?

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

掃碼添加小助手

加入工程師交流群

來源:小姐姐味道
  • 延遲隊列
  • 關鍵代碼
  • 主要方法
  • 增加take方法的效率
  • End

ArrayList和LinkedList有什么區別?

這種侮辱人的問題,默認就把這兩者限定在了同一個場景之中,它甚至連八股文都算不上。

一旦你被問到這種問題,也證明面試基本上泡湯了--面試官已經實在是找不到其他問題與你交流了。

你Over了。

但當我們細看一下LinkedList的class定義,就會發現,它并不像是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除了能夠當作普通的列表,它還是一個Deque。雙向鏈表,聽著就比較唬人,這就是一個既能當做隊列、又能當做棧的存在。

有了這種雙重Buff的疊加,LinkedList的應用場景比ArrayList豐富的多。除了能做最簡單的LRU緩存,LinkedList在刷題的時候也是充滿了正能量。

王者ConcurrentLinkedQueue,一個阻塞的雙向隊列,它的基本操作方法有:(3[基本]x2[異常與返回值]+4[阻塞加超時])x3[隊頭隊尾]=5x2x3=30,足足有30個方法。看完上面的文章,這30個方法可以很快手到擒來。

不過我們今天要聊的一個重點,是使用Deque來實現更快的延遲隊列。

延遲隊列

如果你想要某些數據延遲一段時間再進行處理,或者要再某段時間內按照分組進行一些計算,那延遲隊列無疑是非常合適的。

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

可惜的是,DelayQueue的底層存儲,使用的是PriorityQueue。

PriorityQueue是堆實現的,offer和poll數據的時間復雜度是O(logN)。這就意味著,當DelayQueue中的數據比較多的時候,它的性能就會下降。

除了把數據分片,使用多個DelayQueue來完成工作,我們有沒有速度更快的方法?比如把PriorityQueue使用LinkedList來替換?

這要看場景。

如果你向DelayQueue中添加數據,是與當前添加的時間相關的,那完全可以使用LinkedList來替換PriorityQueue。

基于 Spring Boot + MyBatis Plus + Vue & Element 實現的后臺管理系統 + 用戶小程序,支持 RBAC 動態權限、多租戶、數據權限、工作流、三方登錄、支付、短信、商城等功能

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

關鍵代碼

要了解DelayQueue的運行原理,我們可以需要先看一下Delayed接口。任何想要存儲到DelayQueue中的數據,都需要實現這個接口。

其中,getDelay就是用來判斷當前數據是否超時的方法。而compareTo,則是PriorityQueue用來排序的,如果我們是按照當前塞入數據的,則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的代碼拷貝一份,僅保留關鍵代碼,如下。

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 實現的后臺管理系統 + 用戶小程序,支持 RBAC 動態權限、多租戶、數據權限、工作流、三方登錄、支付、短信、商城等功能

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

主要方法

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

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

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

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

當我們通過put方法添加新的數據到隊列中,會通過signal方法,來通知等待的線程獲取數據。

相同的,如果take方法發現隊列中的數據為空,它將進入等待狀態。如果有數據,也并不是馬上把這些數據取出來,因為數據還沒到期。比如最老的數據還剩下5秒才到期,代碼也對這種情況進行了處理,它會嘗試awaitNanos對應的時間。

這樣,我們就可以使用這種簡單的輪詢方式來實現延遲隊列,而不需要單獨的線程去檢測隊列中的數據。

增加take方法的效率

但是這樣還不夠。

當數據量比較大的時候,隊列的數據可能有多條已經到期。如果我們通過take方法來一條一條獲取的話,效率自然不如批量獲取高。

drainTo方法,可以一股腦的把到期的數據轉移到其他的集合中,但它并不是一個阻塞性的方法。

我們可以先使用take來阻塞線程,然后再批量取出所有數據。

下面代碼,會一次性獲取100條數據作為一個批量。

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

End

實際上,我們的某個業務,當采用LinkedList來替代PriorityQueue,并進行批量操作后,CPU的使用直接降低了1/3。

Deque是xjjdog最喜歡的一個接口。每當使用offerFirst、offerLast這樣精準的API進行操作,都會體驗到多巴胺的樂趣。LinkedList作為它的兒子,自然擁有了這些所有的功能。

當我們使用concurrent包里的基本API,對這些淳樸的工具進行封裝,它們就會煥發出新的活力。



審核編輯 :李倩


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 數據
    +關注

    關注

    8

    文章

    7256

    瀏覽量

    91820
  • 代碼
    +關注

    關注

    30

    文章

    4900

    瀏覽量

    70698

原文標題:當 LinkedList 不是列表時,速度快的兔子都追不上!

文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關注!文章轉載請注明出處。

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

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    GD32與STM32什么區別

    電子發燒友網站提供《GD32與STM32什么區別.docx》資料免費下載
    發表于 04-03 17:27 ?0次下載

    ATX主板和ITX主板什么區別?

    在計算機硬件領域,主板是承載計算機核心組件的關鍵部件,其類型多樣,性能也各有千秋。那么ATX主板和ITX主板什么區別呢,下面來介紹一下:
    的頭像 發表于 03-03 08:47 ?711次閱讀

    DLP中video模式與pattern模式什么區別?

    你好,請問,在DLP相關文檔中,提到video模式與 pattern模式,請問這兩種模式什么區別
    發表于 03-03 08:32

    私有云和公有云什么區別

    私有云和公有云在多個方面存在顯著的區別,以下是具體的比較,主機推薦小編為您整理發布私有云和公有云什么區別。
    的頭像 發表于 02-20 10:38 ?728次閱讀

    AIGC和AI什么區別

    AIGC是AI在內容生成領域的一個特定應用方向,AI的技術發展為AIGC提供了基礎和支撐。那么,AIGC和AI什么區別呢?下面,AI部落小編帶您詳細了解。
    的頭像 發表于 02-20 10:33 ?826次閱讀

    請問ADS8343和ADS8341什么區別

    請問ADS8343和ADS8341什么區別
    發表于 01-08 06:30

    LMP91200 VCM和VCMHI引腳什么區別?

    VCM和VCMHI引腳什么區別,是說如果傳感器是高阻態的需要接VCMHI 嗎?
    發表于 12-31 07:36

    DAC7742和DAC7741什么區別?

    DAC7742和DAC7741什么區別?
    發表于 11-22 08:31

    FCCSP與FCBGA都是倒裝有什么區別

    本文簡單介紹了倒裝芯片球柵陣列封裝與倒裝芯片級封裝的概念與區別。 FCCSP與FCBGA都是倒裝,怎么區分?什么區別?
    的頭像 發表于 11-16 11:48 ?4167次閱讀
    FCCSP與FCBGA都是倒裝有<b class='flag-5'>什么區別</b>

    美國多IP服務器和美國多服務器什么區別

    美國多IP服務器和美國多服務器什么區別 美國多IP服務器和美國多服務器在概念、功能以及應用場景上存在明顯的區別。主機推薦小編為您整理發布美國多IP服務器和美國多服務器
    的頭像 發表于 11-11 10:22 ?699次閱讀

    RTOS與Linux到底什么區別

    很多做嵌入式開發的小伙伴都存在這樣的疑惑:RTOS與Linux到底什么區別?
    的頭像 發表于 10-29 09:53 ?1276次閱讀

    請問TAS5611APHDR與TAS5611APHD什么區別

    TAS5611APHDR與TAS5611APHD什么區別?TAS5611APHDR是否可以應用到TAS5611A說明書上的電路圖嗎?AD mode與BD mode工作模式什么區別
    發表于 10-28 08:02

    域名、IP 地址、網址分別是什么?什么區別呢?

    域名、IP 地址和網址我們經常會聽到這三個名詞,尤其是當你想要開通一個網站的時候,但很多人對它們之間的區別并不十分清楚,那么域名、IP 地址、網址分別是什么?什么區別呢?接下來讓我來一一
    的頭像 發表于 09-18 11:13 ?1714次閱讀
    域名、IP 地址、網址分別是什么?<b class='flag-5'>有</b><b class='flag-5'>什么區別</b>呢?

    功放和運放到底是什么區別

    想請問一下功放和運放到底是什么區別,感覺只要接一個小負載,運放的輸出電流也可以很大???到底什么區別
    發表于 09-10 07:00

    請問VCA821和VCA824什么區別

    請問VCA821和VCA824什么區別?兩個芯片的概述基本都一樣,但是細看里面的資料會發現一些參數圖表好像是不一樣的。那到底怎么看,什么區別
    發表于 09-05 07:59