Есть ли хорошая реализация продолжений в Java?
Если да, то каковы накладные расходы? JVM не был разработан с такими вещами, не так ли? Так идет ли это против зерна?
Есть ли хорошая реализация продолжений в 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 повторный запрос.
сопрограмма 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 имеет continuation поддержка. Далее обсуждается и несколько примеров на DZone.
Я не могу советовать об эффективности или иным образом, кроме как сказать, что команда Mortbay всегда кажется увлекательной по таким вопросам. Скорее всего, будет обсуждение компромиссов реализации где-то на сайте Jetty.
Если я понимаю это правильно, я предполагаю, что очевидная проблема заключается в том, чтобы развернуть стек с активными экземплярами закрытия. Я полагаю, что язык с лексической областью мог бы теоретически выяснить, что дочерний кадр может создать экземпляр замыкания, определить те промежуточные кадры, на которые ссылаются, а затем он может malloc эти кадры вместо того, чтобы просто нажимать их на стек.
В этом случае компилятор может malloc всех фреймов или всех родительских фреймов замыкания, ссылающихся на объект, не привязанный к глобальным объектам.
Я не думаю, что JVM ограничивает закрытие больше, чем реальную машину, просто они борются с общей парадигмой стека, и поэтому они обычно получают штраф.
Если вы не против неявных продолжений, Kilim - отличный вариант. Он работает, обрабатывая аннотированные методы и генерируя для вас продолжение в байтекоде. Очевидно, что это делает намного больше, поскольку это фреймворк, но если вы хотите (отличную) производительность потокобезопасных продолжений, стоит посмотреть.
Играть! framework version 1.2.x также имеет поддержку продолжений, интегрированную с асинхронными http файлами.
Обратите внимание, что Play 1.2.x продолжения работают только с встроенным сервером Netty.
В последнее время появился еще один сильный конкурент.
Quasar использует forked из реализации Маттиаса Манна java продолжения, чтобы обеспечить более высокие функции уровня, такие как легкие потоки, Erlang-like участники и Go-like сопрограммы и channels.
В блоке Quasar Blog есть много тестов и подробных представлений.
Существует также готовая к использованию интеграция с именем Comsat, целью которой является упрощение создания веб-сервисов, основанных на механизмах продолжения под капотом.
Quasar также предоставляет хороший API Kotlin, который был показан на недавнем веб-семинаре JetBrains Квазар: эффективные и элегантные волокна, каналы и актеры.
Все упомянутое является открытым исходным кодом и свободно используется.
Scala также работает на JVM. Поэтому это может быть актуально.
Что такое Scala продолжения и зачем их использовать?
Кроме того, Scala имеет несколько аналогичную функцию async/await:
Другая библиотека Матиаса Манна:
Начиная с Java 8, теперь существует класс CompletableFuture<T>
, который поддерживает продолжение и более функциональное/реактивное программирование подходы.
Рассмотрим следующий пример, где класс предлагает метод downloadAndResize
:
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
}
Использование вышеуказанного метода может выглядеть так:
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
});