Доступные библиотеки Coroutine в Java

Я хотел бы сделать некоторые вещи на Java, которые были бы яснее, если бы были написаны с использованием параллельных подпрограмм, но для которых полные потоки серьезны. Ответ, конечно, заключается в использовании coroutines, но, похоже, в стандартных библиотеках Java нет поддержки корутинов, и быстрый Google на нем вызывает дразнящие намеки здесь или там, но ничего существенного.

вот что я нашел далеко:

  • JSIM имеет класс coroutine, но он выглядит довольно тяжелым и объединяет, по-видимому, с нити в точках. Дело в том, чтобы уменьшить сложность полной потоковой обработки, а не добавлять он. Кроме того, я не уверен, что класс можно извлечь из библиотеки и использовать независимо.
  • отключено есть набор класса сопрограмма сопрограмма, что делает-нравится, но опять же сомнительно, если это можно реально извлечено из общей библиотеки. Он также выглядит так, как будто он реализован как плотно контролируемой виде пула потоков, а не как фактическое сопрограммы.
  • здесь проект кода Google который выглядит так, как я после, но если что-нибудь это выглядит больше тяжеловес, чем использование потоков будет. Я в основном нервничаю из-за того, что требует программного обеспечения для динамическое изменение байт-кода JVM во время выполнения для выполнения его работы. Это выглядит как перебор и как что-то, что будет вызвать больше проблем, чем сопрограммы бы решить. Дальше похоже, что нет реализовать всю концепцию coroutine. По моему взгляду-над ним дает yield функция, которая просто возвращает к Invoker. Правильное сопрограммы позволяют yields для передачи управления любой известной корутины напрямую. В основном эта библиотека, тяжеловесная и страшная, как она есть, только дает вам поддержку итераторов, а не полностью общие сопрограммы.
  • С многообещающим названием Coroutine для Java не удается, потому что это специфичная для платформы (очевидно, используя Решение средой JNI).

и это все, что я нашел.

Я знаю о родной поддержке JVM для coroutines в машине да Винчи, и я также знаю о JNI продолжение трюк для этого. Однако это не очень хорошие решения для меня, поскольку я не обязательно буду контролировать, на какой виртуальной машине или платформе будет выполняться мой код. (Действительно, любая система манипулирования байт-кодом страдайте от подобных проблем - было бы лучше, если бы это была чистая Java, если это возможно. Например, манипуляция байт-кодом во время выполнения ограничила бы меня в использовании этого на Android.)

Так у кого-нибудь есть какие-нибудь советы? Это вообще возможно? Если нет, будет ли это возможно в Java 7?


редактировать, чтобы добавить:

просто чтобы убедиться, что путаница содержится, это по теме вопрос мой другой, но не тот же. Этот ищет существующей реализация в попытке избежать ненужного изобретения колеса. Другой вопрос касается того, как можно было бы реализовать сорутинги на Java, если бы этот вопрос оказался неразрешимым. Цель состоит в том, чтобы держать разные вопросы в разных потоках.


далее отредактировано, чтобы добавить:

на ответ выбран. Некоторые комментарии, однако, уместны. Библиотека указал на это не библиотека сопрограмма, так что технически это не ответ на мой вопрос. При этом, однако, у него есть два края над проектом кода Google, связанным с выше:

  1. оба решения используют манипуляции байт-кода, но некоторые библиотеки позволяет статический байт-код манипуляции, которая делает его пригодным для использования в Android и других несовместимых стеков JVM.
  2. код проекта Google не сделать полную сопрограммы. Пока ответ библиотека даже не делает coroutines вообще, она делает что-то более важное: она обеспечивает хороший, основополагающий инструмент для прокатки моих собственных полнофункциональных coroutines.

8 ответов


Javaflow является реализацией продолжения, это, вероятно, позволит вам сделать это. Однако он использует манипуляцию байт-кодом.

в любом случае, кажется, что вы пытаетесь сделать ООП с простым C. это выполнимо, но это не значит, что вы должны это сделать.


на килим framework реализует сопрограммы с помощью перезаписи байтового кода. Я сам использовал его для реализации легких процессов в Erjang, и он очень стабилен и удивительно быстр для количества перезаписи байт-кода, которая продолжается.

килим сопрограммы взаимодействуют с помощью почтовых ящиков, поэтому я использую основу для модели Эрланга актеров. Но он может также быть использован, чтобы сделать сопрограммы в модели общей памяти.


Что вы думаете об этой библиотеке продолжения, написанной Маттиасом Манном? Я скопировал плюсы и минусы с веб-сайта Создателя, чтобы облегчить обсуждение. Важно взглянуть на тесты в исходном коде, чтобы увидеть за одним примером на веб-сайте.

http://www.matthiasmann.de/content/view/24/26/

начнем с того, что вы получаете:

  • написать простой последовательный код - вам больше не нужно создавать государство машины вручную
  • никакие потоки не создаются или не нужны-нет проблем синхронизации нескольких потоков
  • нет создания мусора из выполнения кода
  • очень небольшие накладные расходы во время выполнения
  • изменяются только приостанавливаемые вызовы методов - все вызовы в стандартную библиотеку (например, java.утиль.* etc) не затронуты вообще.
  • полная поддержка сериализации
  • вы можете сохранить состояние выполнения coroutines как часть вашего состояния игры в сохранить игру без дополнительного кода. Конечно, это требует, что ваши классы и типы данных, которые вы используете в своей сопрограммы являются сериализуемыми. Полная поддержка обработки исключений и, наконец, блоков
  • автономная предварительная обработка не замедляет время загрузки приложения Конечно, инструментирование времени выполнения также возможно.
  • очень маленькая библиотека времени выполнения-менее 10 Кбайт (несжатая банка) Лицензия BSD

со всеми этими замечательными функциями - возможно, вы просите о недостатках. Ну есть конечно несколько недостатков:

  • конструкторы и статические инициализаторы не могут быть приостановлены
  • Suspendable методы не могут быть синхронизированы или синхронизированы блоки
  • вам нужно загрузить библиотеку ASM3 для запуска задачи инструментирования
  • вы не можете вызвать suspendable метод с отражением

проблема синхронизации может быть решена путем ввода кода, который требует использования синхронизации в собственном методе.


ваши требования, кажется:

  • легковес - не основанный на потоках,
  • не полагаться на собственный код и
  • нет использования модификации байт-кода.

У меня есть нехорошее ощущение, что эти требования исключают все разумные стратегии для реализации сопрограмм в Java.


Play framework теперь предоставляет продолжения с Javaflow. Поскольку игра обеспечивает так много удобства в других областях, вы можете начать с нее.

http://www.playframework.org/documentation/1.2RC2/releasenotes-1.2#Continuations


Если вы используете Java, есть 2 варианта, доступные в конце 2017:

оба они основаны на commons-javaflow - они переписывают ваш код на уровне байт-кода, чтобы заставить вещи работать.

Я Coroutines -- up-sides что оно быстро, оно поддерживает все главные системы строения, и оно поддерживает сериализацию / versioning ваш сопрограммы. Недостатком является то, что API имеет несколько отклонений от commons-javaflow.

Vsilaev поддерживает Tasclate-Javaflow -- Я не использовал его, поэтому я не могу говорить об этом, но он поддерживается и, глядя на примеры, он API выравнивается ближе к общему потоку javaflow.

есть также языковые функции в Kotlin и Scala (и, возможно, другие языки на основе JVM), которые позволяют использовать сорутинги. Но, перед переключением языков вы должны быть зная, что Котлин, Scala или любой другой язык JVM du jour сегодня не является и никогда не будет Java. Что бы он ни делал в фоновом режиме, чтобы заставить вещи работать, может не работать, когда следующий выпуск JVM катится.

люди, которые поддерживают JDK в Oracle, имеют послужной список использования этих сторонних языков JVM в качестве исследования рынка. Если функция высокого уровня добавляется к стороннему языку JVM и она достаточно популярна, они будут включать ее в Java. Это происходит прямо сейчас с coroutines. Существует проект OpenJDK под названием Проект Loom, который призван добавить сопрограммы в языке Java.

Это все еще ранние дни для проекта Loom. Если вы критически посмотрите на предложение, это беспорядок. Я уверен, что со временем он стабилизируется, но то, что мы в конечном итоге получим, может полностью отличаться от того, что многие из нас ожидают.

напомним, что вы можете использовать один из байткода измерительных инструментов или для переключения языков. Проект Loom все еще находится в начале, и есть вероятность, что он никогда не будет добавлен в Java.


Квазар осуществляет Go-как coroutines и каналы среди других особенностей используя продолжения.

Подробнее, бенчмарки и ссылки на квазар в my еще один ответ.


Я проверил связанный с этим вопрос, который вы связали, и за всю жизнь я не могу понять, что такого плохого в потоках. В потоках Java никогда не являются собственными потоками, они просто изолированные единицы выполнения, которые в зависимости от контекста могут работать как их собственный собственный поток, если это выгодно, то есть разделение больших блоков выполнения на собственные потоки умно, сохраняя маленькие только в нескольких, более разумно из-за накладных расходов.

тем не менее, Java/JDK не изначально есть ли coroutines, доступные для программистов высокого уровня-пока. JDK7 (всякий раз, когда это выходит) будет иметь то, что известно как jsr166y который является Fork / Join framework от Doug Lea. Для технической информации, проверьте этот PDF mr. Сам Леа. На практике Fork/Join добавляет еще один (полезно!) уровень детализации поверх внутренней потоковой модели Java, которая должна помочь вам достичь того, что вы хотите.