跳至主要内容
版本:0.7.4

Actor 模式

Actor 模式是併發編程的一種模型。透過這種編程模型編寫的應用程式可以很好處理一些系統性的併發問題。這裡所提到的併發問題是指計算機對同一數據進行邏輯處理時,可能由於存在同時發起多個的請求導致數據出現不正確的問題。這是在進行多線程編程時一定會遇到的問題。舉例而言,假如在不加同步鎖的情況下,使用 100 個線程併發對內存中的一個int變量執行++操作。這樣的話最終這個變量的結果往往小於 100。此處 Actor 模式是如何避免此問題的。

首先,為了便於理解,讀者在此處可以將 Actor 認為是一個物件。在面向对象的语言(Java、C#等)当中,可以认为 Actor 就是通过 new 关键词创建出来的对象。不過這個物件有一些特別的特性:

擁有屬於自身的狀態。物件都可以擁有自身的屬性,這是物件導向語言基本都具備的功能。在 Actor 模式中,这些属性都被统称为 Actor 的状态(State) 。Actor 的狀態由 Actor 自身進行維護。

這就強調了兩點:

第一、Actor 的狀態只能由自身進行改變,若要從外部改變 Actor 的狀態,只能通過調用 Actor 才能改變。

更新Actor狀態

第二、Actor 的狀態只在 Actor 內部進行維護,不與當前 Actor 之外的任何對象共享。這裏說的不共享也是強調其不能通過外部某個屬性的改變而導致 Actor 內部狀態的變化。這點主要是為了區別於一些具備“物件導向”語言特性的編程語言而言的。例如:在 C#的 class 的 public 属性,假如是引用类型,那么在外部获得这个 class 之后是可以改变 class 中的属性的。但是這在 Actor 模式當中是不被允許的。

共享Actor狀態

不過從 Actor 內部讀取數據到外部,這仍然是允許的。

讀取Actor狀態

單線程。Actor 通常同一時間只能接受一個呼叫(做一件事)。這裏所述的線程不完全是指電腦領域中的線程,是為了凸顯“Actor 同一時間只能處理一個請求的特性”而使用的詞語。假如當前 Actor 正在接受一個呼叫,那麼剩餘的呼叫都會阻塞,直到呼叫結束,下一個請求才允許被進入。這其實類似於一個同步鎖的機制。透過這種機制就避免了對 Actor 內部狀態進行修改時,存在併發問題的可能性。具体一点说明:如果使用 100 个线程对一个 Actor 进行并发调用,让 Actor 对状态中的一个 int 变量进行 ++ 操作。最終這個狀態的數值一定是 100。

併發執行Actor

不過單線程也不是絕對的,在不存在併發問題的請求情況下,允許併發處理。例如讀取 Actor 中的狀態,這通常不會有併發問題,那麼此時就允許進行併發操作。

併發讀取Actor