當前位置:編程學習大全網 - 源碼下載 - Java並發編程常用的類和集合?

Java並發編程常用的類和集合?

AtomicInteger

可以用原子方式更新int值。類AtomicBoolean、AtomicInteger、AtomicLong和AtomicReference的實例各自提供對相應類型單個變量的訪問和更新。java課程培訓機構認為基本的原理都是使用CAS操作:

booleancompareAndSet(expectedValue,updateValue);

如果此方法(在不同的類間參數類型也不同)當前保持expectedValue,則以原子方式將變量設置為updateValue,並在成功時報告true。

循環CAS,參考AtomicInteger中的實現:

publicfinalintgetAndIncrement(){for(;;){?intcurrent=get();?intnext=current+1;?if(compareAndSet(current,next))returncurrent;

}

}?publicfinalbooleancompareAndSet(intexpect,intupdate){returnunsafe.compareAndSwapInt(this,valueOffset,expect,update);

}

ABA問題

因為CAS需要在操作值的時候檢查下值有沒有發生變化,如果沒有發生變化則更新,但是如果壹個值原來是A,變成了B,又變成了A,那麽使用CAS進行檢查時會發現它的值沒有發生變化,但是實際上卻變化了。ABA問題的解決思路就是使用版本號。在變量前面追加上版本號,每次變量更新的時候把版本號加壹,那麽A-B-A就會變成1A-2B-3A。

從Java1.5開始JDK的atomic包裏提供了壹個類AtomicStampedReference來解決ABA問題。這個類的compareAndSet方法作用是首先檢查當前引用是否等於預期引用,並且當前標誌是否等於預期標誌,如果全部相等,則以原子方式將該引用和該標誌的值設置為給定的更新值。

ArrayBlockingQueue

壹個由數組支持的有界阻塞隊列。此隊列按FIFO(先進先出)原則對元素進行排序。隊列的頭部是在隊列中存在時間最長的元素。隊列的尾部是在隊列中存在時間最短的元素。新元素插入到隊列的尾部,隊列獲取操作則是從隊列頭部開始獲得元素。這是壹個典型的“有界緩存區”,固定大小的數組在其中保持生產者插入的元素和使用者提取的元素。壹旦創建了這樣的緩存區,就不能再增加其容量。試圖向已滿隊列中放入元素會導致操作受阻塞;試圖從空隊列中提取元素將導致類似阻塞。

此類支持對等待的生產者線程和使用者線程進行排序的可選公平策略。默認情況下,不保證是這種排序。然而,通過將公平性(fairness)設置為true而構造的隊列允許按照FIFO順序訪問線程。公平性通常會降低吞吐量,但也減少了可變性和避免了“不平衡性”。

LinkedBlockingQueue

壹個基於已鏈接節點的、範圍任意的blockingqueue。此隊列按FIFO(先進先出)排序元素。隊列的頭部是在隊列中時間最長的元素。隊列的尾部是在隊列中時間最短的元素。新元素插入到隊列的尾部,並且隊列獲取操作會獲得位於隊列頭部的元素。鏈接隊列的吞吐量通常要高於基於數組的隊列,但是在大多數並發應用程序中,其可預知的性能要低。

可選的容量範圍構造方法參數作為防止隊列過度擴展的壹種方法。如果未指定容量,則它等於Integer.MAX_VALUE。除非插入節點會使隊列超出容量,否則每次插入後會動態地創建鏈接節點。

如果構造壹個LinkedBlockingQueue對象,而沒有指定其容量大小,LinkedBlockingQueue會默認壹個類似無限大小的容量(Integer.MAX_VALUE),這樣的話,如果生產者的速度壹旦大於消費者的速度,也許還沒有等到隊列滿阻塞產生,系統內存就有可能已被消耗殆盡了。

  • 上一篇:隨機森林原理與Sklearn參數詳解
  • 下一篇:python網頁爬蟲如何獲取Network中的response?
  • copyright 2024編程學習大全網