Java中的延续
Java中是否有很好的连续实现?
如果是这样,那么开销是多少? JVM的设计并没有考虑到这些,对吧? 这种反对谷物的情况如何?
请参阅Apache Javaflow http://commons.apache.org/sandbox/javaflow/
这是Java正在积极开发的唯一延续包。 另一个,RIFE,我不确定它处于哪个状态。
Javaflow http://commons.apache.org/sandbox/javaflow/播放框架使用Javaflow http://blog.heroku.com/archives/2011/8/29/play/
RIFE http://www.artima.com/lejava/articles/continuations.html WebWork使用。
JauVM http://jauvm.blogspot.com/2005/07/so-what-does-it-do.html JVM中的JVM,实现尾调用/继续
Scala 2.8 http://www.scala-lang.org/node/2096
Cocoon http://cocoon.apache.org/2.1/userdocs/flow/continuations.html http://wiki.apache.org/cocoon/RhinoWithContinuations
Jetty http://docs.codehaus.org/display/JETTY/Continuations重试请求。
coroutines http://code.google.com/p/coroutines
jconts https://github.com/idubrov/jconts
jyield http://code.google.com/p/jyield
Kilim http://www.malhar.net/sriram/kilim/thread_of_ones_own.pdf
Jetty有持续支持。 DZone还有进一步的讨论和一些样本。
我不能就效率或其他方面提出建议,除了说Mortbay团队总是对这些问题表现出一定的看法。 很可能会在Jetty网站的某处讨论实施权衡。
如果我理解正确,我认为明显的问题涉及在活动闭包实例的情况下展开堆栈。 我认为一个具有词法范围的语言理论上可以弄清楚子帧可以创建一个闭包实例,识别那些被引用的中间帧,然后它可以对这些帧进行malloc而不是仅仅将它们推到堆栈上。
就此而言,编译器可以对引用非全局绑定对象的闭包的所有帧或所有父帧进行malloc。
概要
我不认为JVM限制闭包只不过是真正的机器,它只是他们对抗一般的堆栈范例,所以他们通常会受到惩罚。
如果你不介意隐式延续, Kilim是一个很好的选择。 它的工作原理是处理带注释的方法并为您生成字节码的延续。 显然它会做更多,因为它是一个框架,但是如果你想要线程安全延续的(优秀)性能,那么值得一看。
玩! 框架版本1.2.x也支持与异步http好东西集成的continuation 。
请注意, Play 1.2.x continuation仅适用于内置的Netty服务器 。
而Play 2.x仍然不支持延续 。
从Java 8开始,现在有一个CompletableFuture
类,它支持continuation和更多function/反应式编程方法。
请考虑以下示例,其中Class提供downloadAndResize
方法:
public CompletableFuture downloadAndResize(String imageUrl, int width, int height) { return CompletableFuture .supplyAsync(() -> downloadImage(imageUrl)) .thenApplyAsync(x -> resizeImage(x, width, height)); } private Image downloadImage(String url){ // TODO Download the image from the given url... } private Image resizeImage(Image source, int width, int height){ // TODO Resize the image to w / h }
使用上述方法可能如下所示:
CompletableFuture imagePromise = downloadAndResize("http://some/url", 300, 200); imagePromise.thenAccept(image -> { // Gets executed when the image task has successfully completed // do something with the image });
最近出现了另一个强劲的竞争对手。
Quasar使用Matthias Mann实现的java continuation来提供更高级别的function,如轻量级线程 ,类似Erlang的actor和类似Go的协同程序和通道 。
Quasar博客中有许多基准和详细的介绍。
还有一个名为Comsat的即用型集成,旨在帮助轻松构建基于延续机制的高性能Web服务。
Quasar还提供了一个很好的Kotlin API,在最近的JetBrains网络研讨会Quasar上展示:高效优雅的纤维,通道和演员 。
提到的一切都是开源的,可以免费使用。
另见http://blog.paralleluniverse.co/2015/08/07/scoped-continuations/
更新
Quasar的经验后来被用作Loom项目的基础,该项目的 目的是在Java 11之后的某个时候将持续支持直接引入JVM。
它现在正在积极开发中,并且已经有了一个有效的alpha 原型 。
还考虑一下Kotlin Coroutines 。
它是通过可能更高性能的CPS转换 ( 仍然是堆栈 )实现的,并且可以像ForkJoinPool或Quasar集成一样使用任何异步执行器 。
配有方便的导游 库 。
谨防一些工具和reflection陷阱。
Scala也在JVM上运行。 所以它可能是相关的。
什么是Scala延续以及为什么要使用它们?
另外Scala有一些类似的异步/等待function:
Matthias Mann的另一个图书馆: