併發集合類的那些事

一般來說:在map中concurrenthashmap在同步鎖問題上效率較高

http://www.iteye.com/topic/164644

軟件包 java.util.concurrent 的描述

 

在併發編程中很常用的實用工具類。此包包括了幾個小的、已標準化的可擴展框架,以及一些提供有用功能的類,沒有這些類,這些功能會很難實現或實現起來冗長乏味。下面簡要描述主要的組件。另請參閱locks atomic 包。

 

執行程序

 

接口。Executor 是一個簡單的標準化接口,用於定義類似於線程的自定義子系統,包括線程池、異步 IO 和輕量級任務框架。根據所使用的具體 Executor 類的不同,可能在新創建的線程中,現有的任務執行線程中,或者調用 execute()的線程中執行任務,並且可能順序或併發執行。ExecutorService提供了多個完整的異步任務執行框架。ExecutorService 管理任務的排隊和安排,並允許受控制的關閉。ScheduledExecutorService子接口及相關的接口添加了對延遲的和定期任務執行的支持。ExecutorService 提供了安排異步執行的方法,可執行由Callable 表示的任何函數,結果類似於RunnableFuture 返回函數的結果,允許確定執行是否完成,並提供取消執行的方法。RunnableFuture是擁有 run 方法的 Futurerun 方法執行時將設置其結果。

 

實現。ThreadPoolExecutorScheduledThreadPoolExecutor提供可調的、靈活的線程池。Executors 類提供大多數 Executor 的常見類型和配置的工廠方法,以及使用它們的幾種實用工具方法。其他基於Executor 的實用工具包括具體類 FutureTask,它提供 Future 的常見可擴展實現,以及 ExecutorCompletionService,它有助於協調對異步任務組的處理。

 

隊列

 

java.util.concurrent ConcurrentLinkedQueue類提供了高效的、可伸縮的、線程安全的非阻塞 FIFO 隊列。java.util.concurrent 中的五個實現都支持擴展的 BlockingQueue接口,該接口定義了 put take 的阻塞版本:LinkedBlockingQueueArrayBlockingQueueSynchronousQueuePriorityBlockingQueueDelayQueue。這些不同的類覆蓋了生產者-使用者、消息傳遞、並行任務執行和相關併發設計的大多數常見使用的上下文。BlockingDeque接口擴展 BlockingQueue,以支持 FIFO LIFO(基於堆棧)操作。LinkedBlockingDeque類提供一個實現。

 

計時

 

TimeUnit 類爲指定和控制基於超時的操作提供了多重粒度(包括納秒級)。該包中的大多數類除了包含不確定的等待之外,還包含基於超時的操作。在使用超時的所有情況中,超時指定了在表明已超時前該方法應該等待的最少時間。在超時發生後,實現會盡力檢測超時。但是,在檢測超時與超時之後再次實際執行線程之間可能要經過不確定的時間。接受超時期參數的所有方法將小於等於 0 的值視爲根本不會等待。要永遠等待,可以使用Long.MAX_VALUE 值。

 

同步器

 

四個類可協助實現常見的專用同步語句。Semaphore 是一個經典的併發工具。CountDownLatch是一個極其簡單但又極其常用的實用工具,用於在保持給定數目的信號、事件或條件前阻塞執行。CyclicBarrier是一個可重置的多路同步點,在某些並行編程風格中很有用。Exchanger 允許兩個線程在 collection 點交換對象,它在多流水線設計中是有用的。

 

併發 Collection

 

除隊列外,此包還提供了設計用於多線程上下文中的 Collection 實現:ConcurrentHashMapConcurrentSkipListMapConcurrentSkipListSetCopyOnWriteArrayListCopyOnWriteArraySet。當期望許多線程訪問一個給定 collection 時,ConcurrentHashMap 通常優於同步的HashMapConcurrentSkipListMap 通常優於同步的TreeMap。當期望的讀數和遍歷遠遠大於列表的更新數時,CopyOnWriteArrayList優於同步的 ArrayList

 

此包中與某些類一起使用的“Concurrent&rdquo前綴;是一種簡寫,表明與類似的同步類有所不同。例如,java.util.HashtableCollections.synchronizedMap(new HashMap()) 是同步的,但ConcurrentHashMap則是併發的。併發 collection 是線程安全的,但是不受單個排他鎖的管理。在ConcurrentHashMap 這一特定情況下,它可以安全地允許進行任意數目的併發讀取,以及數目可調的併發寫入。需要通過單個鎖不允許對 collection 的所有訪問時,同步類是很有用的,其代價是較差的可伸縮性。在期望多個線程訪問公共 collection 的其他情況中,通常併發版本要更好一些。當collection 是未共享的,或者僅保持其他鎖時 collection 是可訪問的情況下,非同步 collection 則要更好一些。

 

大多數併發 Collection 實現(包括大多數 Queue)與常規的 java.util 約定也不同,因爲它們的迭代器提供了弱一致的,而不是快速失敗的遍歷。弱一致的迭代器是線程安全的,但是在迭代時沒有必要凍結 collection,所以它不一定反映自迭代器創建以來的所有更新。

 

內存一致性屬性

 

Java Language Specification 第 17 定義了內存操作(如共享變量的讀寫)的 happen-before 關係。只有寫入操作 happen-before 讀取操作時,才保證一個線程寫入的結果對另一個線程的讀取是可視的。synchronizedvolatile 構造 happen-before 關係,Thread.start() Thread.join() 方法形成 happen-before 關係。尤其是:

 

  • 線程中的每個操作 happen-before 稍後按程序順序傳入的該線程中的每個操作。
  • 一個解除鎖監視器的(synchronized 阻塞或方法退出)happen-before 相同監視器的每個後續鎖(synchronized 阻塞或方法進入)。並且因爲 happen-before 關係是可傳遞的,所以解除鎖定之前的線程的所有操作 happen-before 鎖定該監視器的任何線程後續的所有操作。
  • 寫入 volatile 字段 happen-before 每個後續讀取相同字段。volatile 字段的讀取和寫入與進入和退出監視器具有相似的內存一致性效果,但 需要互斥鎖。
  • 在線程上調用 start happen-before 已啓動的線程中的任何線程。
  • 線程中的所有操作 happen-before 從該線程上的 join 成功返回的任何其他線程。

 

java.util.concurrent 中所有類的方法及其子包擴展了這些對更高級別同步的保證。尤其是:

 

  • 線程中將一個對象放入任何併發 collection 之前的操作 happen-before 從另一線程中的 collection 訪問或移除該元素的後續操作。
  • 線程中向 Executor 提交 Runnable 之前的操作 happen-before 其執行開始。同樣適用於向 ExecutorService 提交 Callables
  • 異步計算(由 Future 表示)所採取的操作 happen-before 通過另一線程中 Future.get() 獲取結果後續的操作。
  • 釋放同步儲存方法(如 Lock.unlockSemaphore.release CountDownLatch.countDown)之前的操作 happen-before 另一線程中相同同步儲存對象成功獲取方法(如 Lock.lockSemaphore.acquireCondition.await CountDownLatch.await)的後續操作。
  • 對於通過 Exchanger 成功交換對象的每個線程對,每個線程中 exchange() 之前的操作 happen-before 另一線程中對應 exchange() 後續的操作。
  • 調用 CyclicBarrier.await 之前的操作 happen-before屏障操作所執行的操作,屏障操作所執行的操作 happen-before 從另一線程中對應 await 成功返回的後續操作。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章