AKKA文件(java)——術語,概念
本章我們試圖建立一個通用的術語列表,用來定義有關併發和分散式系統的堅實的基礎,而這也是akka的目標。請注意,在這些術語當中許多並沒有一致的定義。我們簡單的尋求在akka文件範圍內使用的工作定義。
併發與並行
併發與並行是相關的概念,但是也有很多細節上的差異。併發意味著兩個或更多的任務正在取得進展,即使它們不是同時執行的。例如,可以用時間片的方式實現這一點,每個任務在時間片內執行一小部分,並與其它任務的切片混合執行。並行的出現使任務實現了真正的同時執行。
非同步與同步
如果方法的呼叫者在方法返回或丟擲異常前不能有任何進展,這個方法呼叫就被認為是同步的。然而非同步呼叫允許呼叫者可以取得有限的進展,呼叫的方法完成時會通過其它機制(可能是註冊的回撥、Future物件或一條訊息)向呼叫者傳送訊號。
一個同步API可能使用阻塞方式實現,但這不是必須的。對於一個CPU密集型任務可能有類似的阻塞行為。一般情況下,非同步API是更好的選擇,因為它們確保任務可以取得進展。角色是天生非同步的,一個角色能夠在傳送一條訊息後不用等待實際的傳輸行為而繼續執行。
非阻塞與阻塞
我們談論的阻塞是指一個執行緒的延遲可以無限期延遲其它一些執行緒。一個不錯的例子是一個執行緒以互斥的方式獨佔一項資源。如果一個執行緒無限期的(比如不小心運行了一個無限迴圈)持有這項資源,而其它執行緒因等待該資源而無法繼續執行。與此相反,非阻塞意味著沒有執行緒可以無限期的延遲其它執行緒。
非阻塞操作比阻塞操作要優先選擇,當系統中包含阻塞操作時,系統整體的進度就不能得到一般性的保證。
死鎖、飢餓與活鎖
死鎖的出現是因為多個參與者同時互相等待對方到達某個特定狀態進而得以繼續,然而它們都因為其它參與者不能到達這個特定狀態(一個“第二十二條軍規”問題)而不能繼續,所有相關子系統都不能被中斷。死鎖與阻塞緊密相關,因為一個參與者執行緒有能夠無限期延遲其它執行緒的必要。
發生了死鎖時,沒有引數者可以繼續執行,而飢餓恰好與之相反,當有參與者可以執行時,可能會有一個或更多得不到執行機會。典型場景是一個簡單排程演算法問題挑選高優先順序任務。如果持續傳入足夠多的高優先順序任務,低優先順序任務永遠也不會執行。
活鎖類似死鎖,沒有參與者可以繼續執行。所不同的是,不是在等待其它參與者的進度,而是參與者自己不斷改變自己的狀態。一個示例場景是兩個參與者有兩個相同的可用資源。它們都試圖獲得資源,但是它們還會檢查是否有其它參與者也需要這個資源。當資源被其它參與者請求時,它們嘗試得到這個資源的其它例項。在不走運的時候,可能會發生兩個競爭者在兩個資源之間反彈,永遠也不佔有它們,一直遷就於其它參與者。
競態條件
我們說的競態條件是指有關一組事件的順序的假設可能會受外部不確定性因素的影響。競態條件經常發生在多執行緒擁有一個共享可變狀態,而執行緒交替操作引發的意外行為。雖然這是一種常見情況,共享狀態也不必出現競態條件。一個例子是,客戶端向伺服器傳送無序資料包(UDP資料報就是這樣的例子)P1,P2。資料包可能經由不同的網路路徑,伺服器可能先收到P2再收到P1。如果訊息不包含有關它們的傳送順序的資訊,伺服器就不能確定資料包的順序了。依賴於資料包的意義就可能引發競態條件。
注意
AKKA只保證在一對給定角色之間傳遞的訊息始終保持訊息傳遞的順序。見訊息傳遞的可靠性。
非阻塞擔保(進展狀況)
在前面的章節中,因為一些原因而不推薦阻塞,包括死鎖的危險,降低系統吞吐量。接下來的部分我們從不同程度上討論多種非阻塞屬性。
無等待
一個無等待的方法是指每次呼叫確保在有限步驟內結束。如果一個方法是有界無等待的,它的步數就有一個上限。
基於這個定義,無等待方法永遠不阻塞,因此也不會死鎖,因為每一部分都可以在有限步數以後繼續(當呼叫結束時),無等待方法也不會發生飢餓。
無鎖定
無鎖定屬性比無等待要弱。發生無鎖定的呼叫時,方法常常在有限步驟內完成。這一定義意味著無鎖定的呼叫不會發生死鎖。另一方面,確保一些方法在有限步內完成不足以確保所有呼叫最終都會完成。換句話說,元鎖定不足以確保不會發生飢餓。
無阻塞
無阻塞是本文討論的比無鎖定還要弱的保證。一個無阻塞的方法呼叫是指如果有一個隔離執行的時間點(其它執行緒不執行任何步驟,比如掛起),它在有限步數內結束。所有無鎖定的物件都是無阻塞的,但是反過來通常不成立。
樂觀併發控制(OCC)方法通常是無阻塞的。OCC的做法是,每一個參與者試圖操作共享物件,但是如果一個參與者探測到與其它參與者衝突,它就回滾所有個性,並按照某些排程策略再次嘗試。如果某個時間點上有且只有一個參與者在嘗試,操作就會成功。
推薦文獻
- 多處理器程式設計的藝術(The Art of Multiprocessor Programming),M. Herlihy與N Shavit, 2008. ISBN 978-0123705914
- Java併發程式設計實踐(Java Concurrency in Practice),B. Goetz, T. Peierls, J. Bowbeer, D. Holmes與D. Lea. 2006. ISBN 978-0321349606