任何以前做過多線程的人都不會否認管理多線程程序是困難并且痛苦的。 我說管理是因為它開始很容易而且當你看到性能提升時會很興奮。但是,當你看到你沒法從子線程的錯誤中恢復 或者 這些僵尸bug很難重現 或者 當用性能剖析器時你發現你的線程在更新一個共享狀態時阻塞了很長時間時,那真的很痛苦。
我傾向于不說Java的并發API和集合把并發編程變的更輕松和容易了,因為如果你看到這,你肯定渴望對子線程任務有更多控制或者希望更簡單但又不愿意去寫一堆的鎖和同步代碼塊,而且希望對這種模式有更高層的抽象。
著這個Akka筆記里,我們會將Akka的例子過一遍并且看看這個工具箱里的各種特性。
什么是Actors
直接把Actors想象成人,人與人之間不直接說話,人們通過郵件來交流。
下面展開說。
1.消息 MESSAGING
想象有兩個人 - 一個有智慧的老師和一個學生。 學生每天早上發郵件給老師,老師則回復一條妙語。
要點:
- 學生發一個郵件。一旦發出,郵件不能被編輯。這叫做不可變性。
- 老師在任何他喜歡的時間檢查郵箱。
- 老師會發回一個郵件(也是不可變的)。
- 學生自由的檢查自己的郵箱。
- 學生不會等待回復(沒有阻塞)。
以上基本上解釋了Actor模型的最基本模塊 - 傳遞消息。
2. 并發 CONCURRENCY###!
現在,想象有三個老師和三個學生 -每個學生都給每位老師發郵件。那現在有什么事情發生了呢?沒啥變化。每個人都有他們自己的郵箱。有一點需要記一下:
默認規則是郵箱里的郵件是按照接收的順序來閱讀/處理
內部實現默認是用ConcurrentLinkedQueue。并且因為沒有人等待撿郵箱里的郵件,這是一個簡單的非阻塞消息。(有很多內置的郵箱,事實上我們甚至能自己實現一個)
3.故障轉移 FAILOVER
想象三個老師來自不同的系 - 歷史系,地理系和哲學系
歷史老師會對過去的事情進行回復,地理老師會發出一個有趣的地方,哲學老師回復一個格言。每個學生會給每個老師發郵件(消息)并且得到回復。學生并不關心是系里的哪個老師發的回復。如果某一天老師生病了呢?必須至少有一個系里的老師來處理這些郵件(消息)。這時,必須有另一個老師頂替上來處理郵件。
需要注意的:
- 需要有一個能做各種不同事情的Actor的后備池。
- 一個Actor有可能在處理消息時出現問題。他也不能進行自我恢復。這種情況發生時會有一個新的Actor被創建并且取代老的Actor。一個可選的做法是,Actor可以忽略那個有問題的消息并且直接處理其他還沒處理的消息。這種方式叫Directives,我們稍后再說。
4.多任務 MULTITASKING
我們假設老師還會在學生詢問的時候用郵件回復考試分數。同樣的,Actor可以處理多種類型(type)的消息。
5.串聯 CHAINING
如果學生希望拿到一個完整的將三份消息串在一起的郵件而不是三份郵件呢?
我們的Actor仍然可以這么做。我們可以把老師串成一個繼承的層次結構。當我們談到Supervisor和Future時我們還是回到這里。
現在讓我們用Actor模型來類推一下這個組件。
學生和老師就是我們的Actors。郵箱就是Mailbox組件。請求和回復都不能被更改。他們是不可變(immutable)對象。最后,Actor中的MessageDispatcher組件是用來管理郵箱并且把消息路由到目標郵箱。
這是我翻譯的文章,原文在http://rerun.me/2014/09/11/introducing-actors-akka-notes-part-1/
文章來自微信平臺「麥芽面包」,微信號「darkjune_think」。轉載請注明。
文章列表