使用GPars實現JVM併發和Actors模型
開源專案Gpars是一個在JVM上可以方便且安全平行計算開源框架,GPars提供Actor模型,它比Java傳統基於記憶體多執行緒共享式併發要高效得多,Actors封裝一個個活動物件,他們之間通訊是透過非同步的不可變訊息進行的,不管actor內部擁有什麼狀態,它不能從actor外部訪問,除非發一個訊息給這個actor,然後透過這個訊息獲得其內部狀態。
因為actors處理呼叫訊息是非同步的,他們自己需要啟用活動,一種方式是就分配系統執行緒給一個活動的物件,這樣隨著系統擴充套件,你需要頻繁地分配所有可用的執行緒,所以,一般採取在actors之間共享執行緒,如果一個actor不工作,那麼就回收系統執行緒,不再佔用系統執行緒(banq:類似執行緒池threadPool?)
Actors模型確保處理actor之間處理訊息時不能超過1個執行緒,actor內部狀態就可以被安全地修改(單執行緒),這樣actor是明顯的執行緒安全型。
傳送訊息也有一種方法sendAndWait(),這將會堵塞呼叫者不做任何事,一直等待訊息回覆(類似同步系統)。
Actors分為無狀態Actors和有狀態Actors(banq:一般偏重行為動作的 可用作服務的類都有無狀態和有狀態之分)
無態Actors: DynamicDispatchActor 重複掃描接受的訊息,然後分發給actor中定義的onMessage()方法。
ReactiveActor 是允許更覺類似事件驅動EDA風格,如groovy如下,actor就可以直接將訊息作為引數執行:
Java程式碼有些瑣碎:
有態Actors就類似Scala中的actors:
Continuations延續:
狀態跨越多個Actor,需要在他們之間延續事務一致性,這稱為Continuations模型,因為JVM不直接支援Continuations,必須在Actor框架中進行模擬。
react 方法是一個執行緒環節中的最後執行方法,一旦到期執行完畢,actor將會把執行緒歸還給系統,同時,react方法是一種下一個訊息到達需要執行的程式碼(閉包),那麼在react將執行緒歸還給系統之間,透過這個閉包將狀態傳遞給下一個訊息,實現類似延續風格的設計。
為了讓actor歸還執行緒,在react方法中寫程式碼:
loop迴圈把狀態都遍歷出來用來傳遞給下一個訊息。
總之,GPars是遵循訊息正規化(message-passing paradigms)中的Communicating Sequential Processes (CSP)和 dataflow,能提供Actors如下功能:
Agents代理
Dataflow concurrency資料流併發
Communicating Sequential Processes CSP
Parallel collections並行收集
Fork/Join capabilitiesFork/Join能力
Composable asynchronous functions組合式非同步
因為actors處理呼叫訊息是非同步的,他們自己需要啟用活動,一種方式是就分配系統執行緒給一個活動的物件,這樣隨著系統擴充套件,你需要頻繁地分配所有可用的執行緒,所以,一般採取在actors之間共享執行緒,如果一個actor不工作,那麼就回收系統執行緒,不再佔用系統執行緒(banq:類似執行緒池threadPool?)
Actors模型確保處理actor之間處理訊息時不能超過1個執行緒,actor內部狀態就可以被安全地修改(單執行緒),這樣actor是明顯的執行緒安全型。
GPars 提供了actors的Java實現,並且提供適合Groovy和Java方便呼叫的API。Actors實現三個標準操作:發生訊息,接受訊息,建立新Actor。
下面是GPars程式碼:
final class MyCounterActor extends DynamicDispatchActor { private int counter = 0; void onMessage(String message) { log("Received a string"); counter += message.length(); } void onMessage(Integer message) { log("Received an integer"); counter += message; } void onMessage(Boolean message) { log("Received a boolean"); reply(counter); } } public class DecryptorTest { public static void main(String[] args) throws InterruptedException { //建立Actor Actor counter = new MyCounterActor().start(); //傳送訊息 counter.send("Hello"); System.out.println("Current value is: " + counter.sendAndWait(true)); counter.stop(); counter.join(); } } <p class="indent"> |
傳送訊息也有一種方法sendAndWait(),這將會堵塞呼叫者不做任何事,一直等待訊息回覆(類似同步系統)。
Actors分為無狀態Actors和有狀態Actors(banq:一般偏重行為動作的 可用作服務的類都有無狀態和有狀態之分)
無態Actors: DynamicDispatchActor 重複掃描接受的訊息,然後分發給actor中定義的onMessage()方法。
ReactiveActor 是允許更覺類似事件驅動EDA風格,如groovy如下,actor就可以直接將訊息作為引數執行:
final def doubler = reactor { 2 * it } println 'Double of 10 = ' + doubler.sendAndWait(10) <p class="indent"> |
Java程式碼有些瑣碎:
Closure handler = new ReactorMessagingRunnable<Integer, Integer>() { @[author]Override[/author] protected Integer doRun(final Integer value) { return value * 2; } }; final Actor doubler = reactor(handler); <p class="indent"> |
有態Actors就類似Scala中的actors:
def actor = actor { loop { log 'Waiting for a gift' react {gift -> if (myWife.likes gift) reply 'Thank you!' else { reply 'Try again, please' react {anotherGift -> if (myChildren.like gift) reply 'Thank you!' } } } } } <p class="indent"> |
Continuations延續:
狀態跨越多個Actor,需要在他們之間延續事務一致性,這稱為Continuations模型,因為JVM不直接支援Continuations,必須在Actor框架中進行模擬。
react 方法是一個執行緒環節中的最後執行方法,一旦到期執行完畢,actor將會把執行緒歸還給系統,同時,react方法是一種下一個訊息到達需要執行的程式碼(閉包),那麼在react將執行緒歸還給系統之間,透過這個閉包將狀態傳遞給下一個訊息,實現類似延續風格的設計。
為了讓actor歸還執行緒,在react方法中寫程式碼:
def myActor = Actors.actor { loop { react {msg1 -> ... react {msg2 -> ... } // Never reached } // Never reached } // Never reached } <p class="indent"> |
loop迴圈把狀態都遍歷出來用來傳遞給下一個訊息。
總之,GPars是遵循訊息正規化(message-passing paradigms)中的Communicating Sequential Processes (CSP)和 dataflow,能提供Actors如下功能:
Agents代理
Dataflow concurrency資料流併發
Communicating Sequential Processes CSP
Parallel collections並行收集
Fork/Join capabilitiesFork/Join能力
Composable asynchronous functions組合式非同步
JVM Concurrency and Actors with GPars
[該貼被banq於2011-04-27 15:56修改過]
[該貼被banq於2011-04-27 15:56修改過]
相關文章
- JVM併發程式設計模型覽JVM程式設計模型
- 高階併發:Akka Actors和JavaEE7的EJB比較Java
- 不要將Actors用於併發程式設計程式設計
- JVM 併發性: Java 和 Scala 併發性基礎JVMJava
- PHP下用Swoole實現Actor併發模型PHP模型
- JVM上的併發和Java記憶體模型之同步塊筆記JVMJava記憶體模型筆記
- 併發-1-併發模型模型
- 聊聊 ab 和 jmeter 的併發模型JMeter模型
- 使用socket+gevent實現協程併發
- 使用GCD實現和封裝分組併發網路請求GC封裝
- JVM 併發性: 使用 Akka 執行非同步操作JVM非同步
- 《七週七併發模型》作者Paul Butcher:用併發計算實現最大效率(圖靈訪談)模型圖靈
- 資料庫系統的併發控制的兩種實現模型資料庫模型
- JVM併發機制探討—記憶體模型、記憶體可見性和指令重排序JVM記憶體模型排序
- 高併發場景下JVM調優實踐之路JVM
- JVM掃盲-3:虛擬機器記憶體模型與高效併發JVM虛擬機記憶體模型
- 常用高併發網路執行緒模型效能優化實現-體驗百萬級高併發執行緒模型設計執行緒模型優化
- [英] 《七週七併發模型》作者Paul Butcher:用併發計算實現最大效率(圖靈訪談)模型圖靈
- 併發模型比較模型
- Python 併發模型Python模型
- Go - 使用 sync.WaitGroup 來實現併發操作GoAI
- 使用併發工具實現 RPC 呼叫流量控制RPC
- curl_multi實現併發
- 使用 Swift 實現歸併排序Swift排序
- 使用C#和MemoryCache元件實現輪流呼叫APIKey以提高併發能力C#元件API
- 使用Disruptor實現生產者和消費者模型模型
- 【JVM】模型JVM模型
- 學習 Go併發模型Go模型
- DSSM模型和tensorflow實現SSM模型
- Redis實現併發阻塞鎖方案Redis
- java併發之SynchronousQueue實現原理Java
- 在Go中如何實現併發Go
- Java 併發集合的實現原理Java
- Scala,基於JVM的併發語言JVM
- Go語言 | CSP併發模型與Goroutine的基本使用Go模型
- 【JVM盲點補漏系列】「併發程式設計的難題和挑戰」深入理解JMM及JVM記憶體模型知識體系JVM程式設計記憶體模型
- 使用 Airtest 實現多臺 IOS 真機的併發測試AIiOS
- Java併發和多執行緒4:使用通用同步工具CountDownLatch實現執行緒等待Java執行緒CountDownLatch