Is there a good implementation of continuations in Java?
If so, what is the overhead like? The JVM wasn't designed with these sort of things in mind, right? So is this kind of going against the grain?
Is there a good implementation of continuations in Java?
If so, what is the overhead like? The JVM wasn't designed with these sort of things in mind, right? So is this kind of going against the grain?
See Apache Javaflow http://commons.apache.org/sandbox/javaflow/
It's the only continuation package for java that's actively under development. The other one, RIFE, I'm not sure which state it's in.
Javaflow http://commons.apache.org/sandbox/javaflow/ Play framework use Javaflow http://blog.heroku.com/archives/2011/8/29/play/
RIFE http://www.artima.com/lejava/articles/continuations.html WebWork use.
JauVM http://jauvm.blogspot.com/2005/07/so-what-does-it-do.html JVM in JVM, implements tail call / continuation
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 retry request.
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 has continuation support. There is further discussion and some samples at DZone.
I can't advise on the efficiencies or otherwise, other than to say that the Mortbay team always appear concious of such issues. There will most likely be a discussion of implementation trade-offs somewhere on the Jetty site.
Since Java 8, there is now a CompletableFuture<T>
class which supports continuations and more functional / reactive programming approaches.
Consider the following example, where a Class offers a downloadAndResize
method:
public CompletableFuture<Image> 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
}
Usage of the above method could look like:
CompletableFuture<Image> imagePromise = downloadAndResize("http://some/url", 300, 200);
imagePromise.thenAccept(image -> {
// Gets executed when the image task has successfully completed
// do something with the image
});
CompletableFuture
is just one of possible ways to nicely wrap and use them. –
Lavery If I understand this correctly, I suppose the obvious problem involves unwinding the stack with closure instances active. I suppose a language with lexical scope could in theory figure out that a child frame may create a closure instance, identify those intermediate frames that are referenced, and then it could malloc those frames instead of just pushing them on the stack.
For that matter, a compiler could malloc all frames or all parent frames of a closure referencing a non-globally-bound object.
I don't think the JVM restricts closures any more than a real machine, it's just that they fight the general stack paradigm and so they usually get punted.
If you don't mind implicit continuations, Kilim is a great option. It works by processing annotated methods and generating the continuations in bytecode for you. Obviously it does a lot more since it's a framework, but if you want the (excellent) performance of thread-safe continuations, it's worth a look.
Play! framework version 1.2.x also has support for continuations integrated with async http goodies.
Note that Play 1.2.x continuations only work with the inbuilt Netty server.
Another strong competitior has appeared recently.
Quasar uses forked from Matthias Mann's implementation of java continuations to provide higher level features like lightweight threads, Erlang-like actors and Go-like coroutines and channels.
There are many benchmarks and detailed introductions in the Quasar Blog.
There is also ready-to-use integration named Comsat aimed to help easily building performant web services based on continuations machinery under the hood.
Quasar also provides a nice Kotlin API that was featured on recent JetBrains webinar Quasar: Efficient and Elegant Fibers, Channels and Actors.
Everything mentioned is open-source and free to use.
See also http://blog.paralleluniverse.co/2015/08/07/scoped-continuations/
Update
Quasar's experience was later used as foundation for the Loom Project which aims to bring continuations support directly into JVM sometime past Java 11.
It's under active development now and already has a working alpha prototype.
Consider also Kotlin Coroutines.
It's implemented via potentially more performant CPS transformations (still stackful) and can use any async executor under the hood like ForkJoinPool or Quasar integration.
Comes with handy guided library.
Beware of some tooling and reflection pitfalls.
Scala also runs on JVM. So it might be relevant.
What are Scala continuations and why use them?
In addition Scala has somewhat similar async/await feature:
Another library by Matthias Mann:
© 2022 - 2024 — McMap. All rights reserved.