2015-04-16 21 views
2

我正在尋找Python的yield from或gevent的猴子補丁的Java/Akka等價物。放棄線程/ CPU,直到異步調用在Akka和Java中完成爲止?


更新

目前已在關於什麼是問題是問,所以讓我重申這個問題的commets一些困惑:

如果我有前途,我怎麼等待爲了未來在不阻塞線程的情況下進行競爭,並且在未來完成之前不返回給調用者?


比方說我們有方法塊:

public Object foo() { 
    Object result = someBlockingCall(); 
    return doSomeThingWithResult(result); 
} 

爲了使這個異步的,我們會通過SomeBlockingCall()回調:

public void foo() { 
    someAsyncCall(new Handler() { 
     public void onSuccess(Object result) { 
      message = doSomethingWithResult(result); 
      callerRef.tell(message, ActorRef.noSender()); 
     } 
    }); 
} 

的調用foo()現在返回在結果準備好之前,調用者不再獲得結果。我們必須通過傳遞消息將結果返回給調用者。要將同步代碼轉換爲異步Akka代碼,需要重新設計調用者。

我想要的是異步代碼,看起來像Python的Gevent等同步代碼。

我想寫:

public Object foo() { 
    Future future = someAsyncCall(); 

    // save stack frame, go back to the event loop and relinquish CPU 
    // so other events can use the thread, 
    // and come back when future is complete and restore stack frame 
    return yield(future); 
} 

這將允許我做我同步異步代碼無需重新設計。

這是可行嗎?

注: 的遊戲框架似乎fake thisasync()AsyncResult。但是這通常不起作用,因爲我必須編寫處理AsyncResult的代碼,它看起來像上面的回調處理程序。

+0

是的,只是使用'未來'? ['CompleteableFuture.runAsync'](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html#runAsync-java.lang.Runnable-)應該這樣做。 –

+0

使用'ExecutorCompletionService'。 –

+0

@Boris the Spider,不,將來會做的事情是讓事件處理程序移到調用者。這個問題沒有解決,因爲調用者在調用處理程序之前仍然存在無關的問題。整個問題是在這段時間內不會阻止。 – Jay

回答

3

我認爲試圖找回一個更直接的同步設計,雖然有效,但實際上是一個好意和好主意(例如參見here)。

Quasar有設施獲得同步/封鎖仍在高效異步從API的(見本blog post),看起來你在尋找什麼的API。

最根本的問題是的同步/阻塞風格本身是壞的(實際上是異步和同步的雙重風格和可以轉化爲彼此,見例如here),但不是阻止Java的重量級線程效率不高它不是一個抽象問題,而是一個實現問題,所以不是因爲實現效率低下而放棄更容易的線程抽象,而是我認爲它更適合您的代碼的未來嘗試尋找更高效的線程實現。

羅蘭暗示,類星體增加了輕量線程或纖維到JVM,這樣你就可以得到異步框架不放棄的線程抽象和定期勢在必行控制流結構(序列相同的性能,循環等。 )以該語言提供。

它還統一JVM/JDK的線程,它的纖維共同界面下,這樣他們就可以無縫互操作,並提供了java.util.concurrent這個統一的概念的移植。

在股(或纖維或常規線程)的頂部類星體還提供不折不扣的二郎式演員阻擋圍棋般的渠道數據流編程,這樣你就可以選擇並行編程最適合您的技能和需求的範式,而不是被迫成爲一個範例。

它還提供綁定流行和標準技術(作爲Comsat項目的一部分),這樣你就可以保存你的代碼資產因爲移植工作將是最小的(如果有的話)。出於同樣的原因,你也可以選擇退出輕鬆,你應該選擇。

目前類星體已經爲的Java 7和8Clojure的Pulsar項目下很快JetBrain's Kotlin約束力和。基於JVM字節碼工具,如果存在集成模塊,Quasar可以真正使用任何JVM語言,並提供構建附加模塊的工具。

1

您的問題的答案是「否」,這是非常多的設計。將方法寫入異步意味着返回Future作爲其結果,該方法本身不會執行計算,但會安排稍後提供結果。然後,您可以將此Future傳遞到進一步使用的正確位置,例如通過使用衆多組合器之一(如maprecover等)對其進行轉換。

等待Future的嚴格結果將不得不阻止當前的執行線程,無論您使用哪種技術。使用普通的JVM線程,您將阻止來自操作系統的真實線程,Quasar將阻止您的光纖,使用Akka將阻止您的Actor(*);阻塞意味着阻塞,沒有辦法繞過。


(*)在一個演員,你會在以後通過消息得到的結果,而直到這一點,你將不得不切換行爲,使得新進入的消息被藏匿,拒絕或下降,這取決於在你的用例上。

相關問題