天天看點

Akka筆記之Actor簡介

英文原文連結,譯文連結,原文作者:arun manivannan ,譯者:有孚

寫過多線程的人都不會否認,多線程應用的維護是件多麼困難和痛苦的事。我說的是維護,這是因為開始的時候還很簡單,一旦你看到性能得到提升就會歡呼雀躍。然而,當你發現很難從子任務的錯誤中恢複或者有些僵屍bug很難複現再或者你的分析器顯示你的線程在寫入一個共享狀态前大部分時間都浪費在阻塞上面的時候,痛苦降臨了。

我刻意沒提java的并發api,以及它裡面的集合類使得多線程程式設計變得多麼輕松簡單,因為我相信既然你們點進了這篇文章,那就說明你希望能更好地控制你的子任務,或者你就是不喜歡使用鎖以及同步塊,希望能有一種更高層次的抽象。

在本系列的akka筆記中,我們将通過一些簡單的akka例子來體驗下它的諸多特性。

akka中的actor遵循actor模型。

你可以把actor當作是人。這些人不會親自去和别人交談。他們隻通過郵件來交流。

我們來稍微解釋下這點。

假設有兩個人——一個聰明的老師和一個學生。學生每天早上都會發一封郵件給老師,而老師則會回複一句名言。

需要注意的地方:

1. 學生發送郵件。一旦發送成功,郵件不能再修改。這天然就具備了不可變性。

2. 老師會自己決定何時檢查郵箱。

3. 老師還會回複一封郵件。

4. 學生會自己決定何時檢查郵箱。

5. 學生不會一直等待回信(非阻塞的)。

這就可以總結出actor模型的一個基本特征——消息傳遞。

Akka筆記之Actor簡介

現在,想像一下3個聰明的老師和3個學生——每個學生都會向所有老師分别發送筆記。這會發生什麼?事實上沒有任何改變。每個人都有自己的郵箱。這裡有一點值得強調一下:

預設情況下,郵箱中的郵件是按它們到達的順序進行處理的。

本質上這就是一個concurrentlinkedqueue](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/concurrentlinkedqueue.html)。由于沒有人在等待郵件,這就是一個非阻塞的消息。(akka[内置包含許多種郵箱實作,包括有界的以及基于優先級的)。事實上,我們自己也能開發一個。

Akka筆記之Actor簡介

想像下這三個老師是不同系的——曆史,地理以及哲學。

曆史老師對過去的某個事件進行了評論,地理老師則發送了一個很有意思的地方,而哲學老師回複了一句名言。每個學生都分别給各個老師發送郵件并收到回信。學生并不關心郵件到底是系裡的哪個老師回複的。如果有一天有個老師生病了呢?系裡至少得有一個老師在處理郵件才行。這樣的話,系裡的另一位老師就會頂上這項工作。

Akka筆記之Actor簡介

1. 會有一個actor的池,每個actor會處理不同的事件。

2. actor做的事情可能會抛出異常。它自己無法從中恢複。這種情況下,需要再生成一個新的actor來頂替它。換句話說,這個新的actor會忽略剛才那條消息,繼續處理剩餘的消息。這些也被稱為指令(directive),後面我們會再講到它們。

我們假設下每個老師都會通過郵件來發送考試成績,如果學生這麼要求的話。類似的,actor也可能會處理多種類型的消息。

那如果學生不想收到多封郵件,而是一封該怎麼辦呢?

actor同樣可以完成這個。我們可以将老師進行分層。後面我們講到supervisor和future的時候會再回來講下這點。

應mohan的要求,我們把類比的實體和actor模型中的元件做一下映射。

Akka筆記之Actor簡介

學生和老師都是我們的actor。收件箱就是mailbox元件。請求和響應是不可修改的。它們都是不可變對象。最後,actor中的messagedispatcher元件會管理郵箱并将消息路由到對應的mailbox中。

說得夠多的了,我們來寫下代碼吧…

未完待續…