2010-02-22 49 views
11

我來自Java,在那裏我將Runnable s提交給由線程池支持的ExecutorService。 Java中非常清楚如何設置線程池的大小限制。如何限制在Scala中使用actor時的併發性?

我有興趣使用Scala actors,但我不清楚如何限制併發。

讓我們假設,我正在創建一個接受「作業」的Web服務。作業提交POST請求,並且我希望我的服務將作業排入隊列,然後立即返回202 Accepted - 即作業是異步處理的。

如果我使用actors來處理隊列中的作業,如何限制同時處理的作業數量?

我可以想到幾種不同的方法來解決這個問題;我想知道是否有社區最佳實踐,或者至少是一些在Scala世界中有點標準的明確建立的方法。

我想到的一種方法是擁有一個協調員角色,該角色可以管理作業隊列和作業處理角色;我想它可以使用一個簡單的int字段來跟蹤當前正在處理的作業數量。但是,我確信這種方法會出現一些亂七八糟的情況,比如確保跟蹤錯誤發生的時間以減少數量。這就是爲什麼我想知道Scala是否已經提供了一個更簡單或更封裝的方法。

順便說一句我試着問這個問題a while ago但我問得不好。

謝謝!

回答

5

您可以覆蓋系統屬性actors.maxPoolSizeactors.corePoolSize這限制了演員的線程池的大小,然後在作爲演員能夠處理池中扔更多的就業崗位。你爲什麼認爲你需要油門你的反應?

+1

非常有用,謝謝! 我不確定我會使用術語_throttle_,但無論哪種方式,有時需要約束同時「進程」的數量,因爲他們所做的工作是資源密集型的。 – 2010-02-22 21:15:10

+3

這種方法可能不會產生所需的結果。它將允許作業排隊等待JVM耗盡內存。限制參與者可以使用的線程數量將僅限制實際並行執行的作業數量。我之前製作工作的速度超過了演員的能力,因此產生了OOM錯誤,所以你必須小心。 – 2010-02-23 01:20:51

+2

我在想這種方法的一個缺點是它是全球性的。有時我需要運行不同級別的資源利用率的不同類型的流程 - 使用Java線程池,我可以輕鬆使用具有不同設置的不同池。對於'actors.maxPoolSize',我只能爲所有actor使用單個數字,因爲它們全部由同一個線程池支持,對吧? – 2010-02-23 02:47:43

3

這裏真的有兩個問題。

首先是保持演員使用的線程池在控制之下。這可以通過設置系統屬性actors.maxPoolSize來完成。

第二個是已經提交到池的任務數量的失控增長。您可能會也可能不會關心這個問題,但是完全有可能觸發失敗情況,例如內存不足錯誤,並且在某些情況下,通過太快地生成太多任務,可能會導致更微妙的問題。

每個工作線程維護一個任務的出列。出隊是作爲一個數組來實現的,工作線程將動態擴展到某個最大大小。在2.7。x隊列可以增長得相當大,我發現當與大量的併發線程結合時會引發內存不足錯誤。最大出隊大小小於2.8。出列隊列也可以填滿。

解決這個問題需要你控制你產生了多少任務,這可能意味着你已經概述了某種協調器。當啓動一種數據處理管道的參與者比管道中稍後的參與者快得多時,我遇到了這個問題。爲了控制這個過程,我通常會讓鏈中的演員在每條X消息的前面跟蹤鏈中的演員,並且在X消息之後停止鏈中的演員,並等待返回。你也可以用更集中的協調員來完成。

相關問題