java併發包源碼剖析 - 序章

    爲了更好地理解併發,因此決定對java的整個併發包進行源碼程度剖析。

    首先介紹一下整個併發包的大體情況。主要分爲三個包
    1.java.util.concurrent  包括一些規範化可擴展的框架,即Executors,Queues,Synchronizers,Concurrent Collections等
    2.java.util.concurrent.atomic  擴展了volatile變量,成員域,和數組元素的概念,同時也提供了原子條件更新操作(compareAndSet)

    3.java.util.concurrent.locks  提供了和內置的同步和監視器有區別的鎖和條件等待的接口和類的框架。

    這三個包都主要提供了一些在併發編程中常用的多用途類。本次先從java.util.concurrent.locks包開始,逐步剖析整個併發包的框架代碼。

java.util.concurrent.locks簡介

    提供了和內置的同步和監視器有區別的鎖和條件等待的接口和類框架。框架以更加繁瑣的語法爲代價,允許更加鎖和條件狀態的更加靈活性的運用。

    Lock接口支持不同語義(可重入,公平等)的鎖的原則,可以在非阻塞式結構的上下文(包括 hand-over-hand 和鎖重排算法)中使用這些規則。主要的實現是 ReentrantLock 。

    ReadWriteLock接口類似地定義了可以被讀時共享,寫時獨佔的鎖。只提供了一個實現,ReentrantReadWriteLock,因此它已經代表了大部分常規的用途。但是程序員可以根據需求創建自己的實現。

    Condition接口描述了可以與鎖關聯的條件變量。這些在用法與隱式監視器Object.wait很想死,但是提供了擴展性。舉例來說,不同的條件對象可以與單個鎖關聯。

    AbstractQueuedSynchronizer類爲定義鎖和其它依賴於隊列阻塞線程的同步器的一個有用的基類。AbstractQueuedLongSynchronizer提供類相同的用途,但是擴展支持到64位同步器狀態。同樣作爲擴展類,AbstractOwnableSynchronizer,是一個幫助記錄獲取獨佔同步器線程的類。LockSupport類提供類更加底層的有助於開發者實現自己定製鎖類的阻塞和非阻塞。

java.util.concurrent簡介

    juc包主要提供了併發編程中用途廣泛的類。juc包含類一些規格化可擴展的框架,同時包括一些需要繁瑣或者複雜實現的類。


Executors
    接口Executor是一個簡單的規範化定義了可定製的線程子系統,即線程池,異步I/O,還有輕量級任務框架。基於使用的具體Executor類,任務可能會執行在一個新建的線程,或者一個已經存在的專門執行任務的線程,又或者線程執行execute方法,另外還可能會順序地或者併發地執行任務。ExecutorService提供了一個更加完整的異步任務執行框架。一個ExecutorService管理任務進隊和任務調度,並且允許控制停止。ScheduledExecutorService實現了接口以提供延遲和週期性任務執行的支持。ExecutorServices提供方法去分類參數爲Callable的異步執行函數,還有包含結果的Runnable類似物。Future返回函數的結果,允許決定執行是否完成,並且提供一種辦法去取消執行。RunnableFuture是一個執行run方法並且在執行完成之後,設置執行結果的Future。
    實現。類ThreadPoolExecutor和ScheduledThreadPoolExecutor提供可調控,靈活的線程池。Executors類爲大多數一般類型和設置的Executors提供工廠方法,同時也有一些多功效的方法去使用它們。其它基於Executors的實用類,包括具體的FutureTask類,提供了通用可擴展的Futures實現,還有ExecutorCompletionService類,協助負責協調一組異步任務的執行。

Queues
    ConcurrentlinkedQueue類提供了高效率可擴展的線程安全非阻塞FIFO隊列。在juc包中的五個實現提供了BlockingQueue接口的擴展,該接口定義了put和take的阻塞版本,它們分別是:LinkedBlockingQueue,ArrayBlockingQueue,SynchronousQueue,PriorityBlockingQueue,和DelayQueue。這些不同的類包含了大部分諸如生產者-消費者,消息,並行任務,還有相關的同步設計等的通用使用上下文。

Timing
    TimeUnit類提供了多種的粒度(包括納秒)去指定和控制基於超時的操作。大部分在包中的類包括類基於從超時到無窮等待的操作。所有這些例子中,當使用了超時之後,超時指定了方法在假設它超時前的最小等待時間。實現裏盡了“最大努力”在當超時發生時,最快時刻的檢測。所有方法接受超時參數的都把小於或等於零的值意味着不需要等待。要無限等待,你可以用Long.MAX_VALUE值。

Synchronizers
    四個類輔助特殊用途的同步慣用語法。
    Semaphore是經典的併發工具。
    CountDownLatch是一個非常簡單同時也是非常通用的阻塞直至指定數量的信號,事件,或者狀態獲取的工具。
    CyclicBarrier是一個可以重置的多路同步點,在某些併發編程風格中有用。
    Exchanger允許兩條線程在相遇點交換對象,在某些管道設計中很有用。

Concurrent Collections
    除了隊列,本包提供了在多線程上下文中設計實現的集合:ConcurrentHashMap, ConcurrentSkipListMap, ConcurrentSkipListSet, CopyOnWriteArrayList, 還有CopyOnWriteArraySet。當多線程訪問一個集合時,ConcurrentHashMap通常比synchronized的HashMap更好,ConcurrentSkipListMap通常比synchronized的TreeMap更好,CopyOnWriteArrayList在預期內讀和遍歷次數大大超過列表更新的次數時,通常比synchronized的ArrayList更好。
    在本包內的某些類的名字前綴“Concurrent”是一種速記,表明了與類似的“synchronized”類的不同之處。例如,java.util.Hashtable和Collections.synchronizedMap(new HashMap())是同步的(synchronized)。但是ConcurrentHashMap是併發的(“concurrent”)。一個併發的集合是線程安全的,但是不是被一個單獨的獨佔鎖管理。對於ConcurrentHashMap來說,它安全地允許了任何數量的併發讀操作,同時和一個可調度數量的併發寫操作。“Synchronized”類在當你在需要通過一個單獨的鎖來避免所有併發訪問時會很有用,這是以更差的可伸縮性爲代價的前提下。在其它情況下,多線程期望訪問一個通常的集合時,“併發”版本通常會更加好。當集合是非共享的,或者只被獲取了其它鎖纔可以訪問的條件下,非同步的集合一般更加好。
    大部分併發集合的實現(包括大部分Queues)都提供了弱連續(weak consistent)的迭代,這是與通常的java.util規定的fast-fail迭代遍歷中不同的地方。一個弱連續的迭代是線程安全的,但是在迭代過程中不必要的凍結(freeze)了集合,所以它可能(也可能不會)反應從迭代器創建以來的更新。

Memory Consistency Properties
    JLS第17章裏定義了happens-before在內存讀寫共享變量操作的關係。只當在寫操作happens-before讀操作的時候,單條線程寫的結果是保證被另外一條讀操作的線程可見的。Synchronized和volatile關鍵字,另外還有Thread.start()和Thread.join()方法,可以組成happens-before關係。特別地:
    1、線程內每個動作對於稍後的程序順序中的每個動作可見。
    2、對一個監視器的解鎖happens-before於每一個後續對同一個監視器的加鎖。
    3、對volatile字段的寫入操作happens-before於每一個後續的同一個字段的讀操作。不過volatile不提供獨佔鎖互斥性。
    4、Thread.start()的調用會happens-before於啓動線程裏面的動作。
    5、Thread中的所有動作都happens-before於其他從Thread.join()中返回的線程。
    在juc包中所有的類和它的子包都擴展這些保證到更高層次的同步性。特別地:
    1、在添加對象進去任意的併發集合中之前的動作都對其它線程後續的訪問或元素從集合刪除的可見。
    2、在Runnable遞交給Executor之前在線程的所有動作都對執行開始的動作可見。類似地,Callables遞交給ExecutorService也使用。
    3、Future的異步計算動作對後續其它線程Future.get()方法調用可見。
    4、在“釋放”同步器方法,如Lock.unlock,Semaphore.release,還有CountDownLatch.countDown之前的動作對後續的在其它線程裏於相同的同步器的“獲取”方法,如Lock.lock,Semaphore.acquire,Condition.await,和CountDownLatch.await可見。
    5、對每對通過Exchanger成功交往對象的線程來說,在每條調用exchange()方法之前的動作都對另外一條線程的後續的當前exchange()方法可見。
    6、在CyclicBarrier.await調用之前的動作,對於後續柵欄動作的執行可見,並且在柵欄動作的執行對於後續另外線程的成功調用await方法可見。

    其中A表示抽象類(Abstract class),I表示接口(Interface)得出以下部分:

Executors
AbstractExecutorService(A)
Callable(I)
CompletionService(A)
Executor(I)
ExecutorCompletionService
Executors
ExecutorService(I)
ForkJoinPool
ForkJoinTask(I)
ForkJoinWorkerThread
Future(I)
FutureTask
RecursiveAction(A)
RecursiveTask(A)
RejectedExecutionHandler(A)
RunnableFuture(I)
RunnableScheduledFuture(I)
ScheduledExecutorService
ScheduledFuture(I)
ScheduledThreadPoolExecutor
ThreadFactory(I)
ThreadLocalRandom
ThreadPoolExecutor

Timing
TimeUnit

Queues
ArrayBlockingQueue
BlockingQueue(I)
ConcurrentLinkedQueue
Delayed(I)
DelayQueue
LinkedBlockingQueue
LinkedTransferQueue
PriorityBlockingQueue
SynchronousQueue
TransferQueue(I)

Deque
BlockingDeque(I)
ConcurrentLinkedDeque
LinkedBlockingDeque

Synchronizers
CountDownLatch
CyclicBarrier
Exchanger
Phaser
Semaphore

Concurrent Collections
ConcurrentHashMap
ConcurrentMap(I)
ConcurrentNavigableMap(I)
ConcurrentSkipListMap
ConcurrentSkipListSet
CopyOnWriteArrayList
CopyOnWriteArraySet

發佈了36 篇原創文章 · 獲贊 4 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章