2010-12-04 102 views
5

假設我有一個演員只有一個字段。每100條消息中有99條讀取值,第100條更新值。在這種情況下,我想並行處理讀取。換句話說,我怎樣才能實現使用Actor的讀/寫鎖的性能?對於Scala標準演員或Akka,這是否實用?還是我缺少的演員:)演員:如何有效地處理讀取主要數據

更新的點:固定混亂的語言,對不起

+1

是不是所有給演員的消息都是隻讀的(不可變的)?參與者收到消息並根據消息的內容進行一些處理。如果需要,它會將消息發送給另一個參與者作爲處理的一部分。 – 2010-12-04 19:04:47

+0

是的,這些消息是不可變的。想象一下作爲一個參與者的計數器/增量器的常見例子:我想知道如果讀取當前值對於其他讀取操作可以是非阻塞的。 – 2010-12-04 19:11:08

回答

6

你很可能是失蹤者的地步。我假設你想要一個你發送查詢的演員,然後它發回一個響應。有相當多的機制涉及向演員發送消息,處理消息併發迴響應。實際生成的響應消息將作爲任務創建並提交給線程池。在消息隊列和線程池之間有多個需要鎖定或CAS操作的地方。通常重點是演員會根據該消息在單獨的線索中完成一些工作。

如果您只想讀取並很少寫入數據(例如遞增計數器或訪問映射中的值),那麼使用java.util.concurrent中的適當類會更好。

3

我假設你的意思是說所有的消息都是不可變的,幾乎所有的消息都不會改變actor的狀態。在這種情況下,演員可能不是設計的最佳選擇。參與者允許您管理任何可變狀態,就像處理單線程代碼一樣。

實際上,每個參與者都有一個郵箱,郵件發送到該郵箱,然後一次處理一個郵箱。在你的情況下,這將是相當浪費。正如所建議的那樣,使用java.util.concurrent中的內容將是最有效的。

2

演員的目的是串行處理的消息。這使得他們很容易理解:一次只能得到一條消息,因此可以在不考慮併發性的情況下修改參與者中的任何變量(只要他們沒有被其他人突變)。這是最有效的方法嗎?絕對不!但效率低下的代碼能夠正常工作幾乎總是優於高效代碼被破壞。爲了獲得處理速度,你所要求的是完全相反的:你想明確地考慮併發性(「我知道99%的訪問將是讀取,因此可以並行發生!」),以獲得處理速度。在這種情況下,您可能希望使用java.util.concurrent.locks.ReentrantReadWriteLock直接控制對可變變量的訪問(如果在java.util.concurrent.atomic._中找到的訪問類型對您不適用)。請記住,您現在已經承擔了正確鎖定的責任,並且要小心。