java - 在 Akka 和 Java 中放弃线程/CPU 直到异步调用完成?

标签 java concurrency akka

我正在寻找相当于 Python 的 yield from 或 gevent 的猴子补丁的 Java/Akka。


更新

评论中对于问题所问的内容有些困惑,所以让我重申一下问题:

如果我有一个 future,我如何等待 future 竞争而不阻塞线程并且在 future 完成之前不返回调用者?


假设我们有阻止的方法:

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);
}

这将使我能够使我的同步代码异步,而无需重新设计。

这可能吗?

注意: Play框架似乎fake this使用 async()AsyncResult。但这通常不起作用,因为我必须编写处理 AsyncResult 的代码,它看起来像上面的回调处理程序。

最佳答案

我认为尝试找回一种更直接的同步设计,虽然是一种高效的设计,但实际上是一个良好的意图和一个好主意(例如,参见 here )。

Quasar具有从异步 API 中获取仍然高效的同步/阻塞 API 的功能(请参阅此 blog post ),这正是您正在寻找的内容。

根本问题不是同步/阻塞风格本身不好(实际上异步和同步是双重风格,可以相互转换,例如 here ),而是阻塞Java的重量级线程效率不高:这不是一个抽象问题,而是一个实现问题,所以不要仅仅因为实现效率低下而放弃更容易的线程抽象,我同意尝试寻找更高效的线程实现对您的代码的 future 更好。

正如 Roland 所暗示的,Quasar 向 JVM 添加了轻量级线程或纤程,因此您可以获得与异步框架相同的性能而无需放弃线程抽象和常规命令语言中可用的控制流结构(序列、循环等)。

它还将 JVM/JDK 的线程及其纤程统一在一个通用strand接口(interface)下,以便它们可以无缝地互操作,并提供 java.util 的移植.concurrent这个统一的概念。

在线束之上(纤维或常规线程)Quasar 还提供成熟的Erlang 风格的 actor阻塞类似 Go 的 channel 数据流编程,因此您可以选择最适合您的技能和需求的并发编程范例,而不必被迫采用其中一种。

它还提供流行和标准技术的绑定(bind)(作为 Comsat 项目的一部分),因此您可以保留您的代码 Assets ,因为移植工作将最小(如果有)。出于同样的原因,如果您选择的话,您也可以轻松选择退出

目前,Quasar 在 Pulsar 下绑定(bind)了 Java 7 和 8Clojure项目很快JetBrain's Kotlin 。基于 JVM 字节码工具,如果存在集成模块,Quasar 确实可以与任何 JVM 语言一起工作,并且它提供了构建其他模块的工具。

关于java - 在 Akka 和 Java 中放弃线程/CPU 直到异步调用完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29680718/

相关文章:

java - 如何模拟 shirosession?

Java ThreadPoolExecutor 在一段时间后停止工作

apache-camel - Akka Camel 多个消费者

scala - 在处理 Akka 中的下一条消息之前等待异步 Future 调用

scala - 在 Akka 中设置日志记录级别

java - JdbcTemplate.execute() 方法可以抛出的所有异常

Java 正则表达式模式查找空 HTML/XML 元素

java - 如何在 JAVA 中从 SOAP Web 服务请求、将 SOAP 响应转换为 XML 并将其与另一个 SOAP 响应进行比较

mysql - 从 JPA PESSIMISTIC 锁获取的数据库行的物理锁

unit-testing - init() 函数能否安全地启动 go 例程,包括 along 测试?