Java 中可用的协程库
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2846428/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Available Coroutine Libraries in Java
提问by JUST MY correct OPINION
I would like to do some stuff in Java that would be clearer if written using concurrent routines, but for which full-on threads are serious overkill. The answer, of course, is the use of coroutines, but there doesn't appear to be any coroutine support in the standard Java libraries and a quick Google on it brings up tantalising hints here or there, but nothing substantial.
我想在 Java 中做一些如果使用并发例程编写会更清晰的东西,但是对于这些完整的线程来说是严重的矫枉过正。答案当然是使用coroutines,但在标准 Java 库中似乎没有任何协程支持,并且在它上面的快速 Google 会在这里或那里提供诱人的提示,但没有什么实质性的。
Here's what I've found so far:
这是我迄今为止发现的:
- JSIMhas a coroutine class, but it looks pretty heavyweight and conflates, seemingly, with threads at points. The point of this is to reduce the complexity of full-on threading, not to add to it. Further I'm not sure that the class can be extracted from the library and used independently.
- Xalanhas a coroutine set class that does coroutine-like stuff, but again it's dubious if this can be meaningfully extracted from the overall library. It also looks like it's implemented as a tightly-controlled form of thread pool, not as actual coroutines.
- There's a Google Code projectwhich looks like what I'm after, but if anything it looks more
heavyweight than using threads would be. I'm basically nervous of something that requires software to
dynamically change the JVM bytecode at runtime to do its work. This looks like overkill and like
something that will cause more problems than coroutines would solve. Further it looks like it doesn't
implement the whole coroutine concept. By my glance-over it gives a
yieldfeature that just returns to the invoker. Proper coroutines allowyields to transfer control to any known coroutine directly. Basically this library, heavyweight and scary as it is, only gives you support for iterators, not fully-general coroutines. - The promisingly-named Coroutine for Javafails because it's a platform-specific (obviously using JNI) solution.
- JSIM有一个协程类,但它看起来非常重量级,并且似乎与线程混为一谈。这样做的目的是降低全线程的复杂性,而不是增加它。此外,我不确定该类是否可以从库中提取并独立使用。
- Xalan有一个协程集类,它可以做类似协程的东西,但是如果可以从整个库中有意义地提取它,这也是值得怀疑的。它看起来也像是作为一种严格控制的线程池形式来实现的,而不是作为实际的协程。
- 有一个Google Code 项目看起来像我所追求的那样,但如果有的话,它看起来比使用线程更重量级。我基本上对需要软件在运行时动态更改 JVM 字节码以完成其工作的事情感到紧张。这看起来有点矫枉过正,而且会导致比协程解决的问题更多的问题。此外,它似乎没有实现整个协程概念。通过我的一瞥,它提供了一个
yield返回给调用者的特性。适当的协程允许yields 将控制直接转移到任何已知的协程。基本上这个库,重量级和可怕的,只为你提供对迭代器的支持,而不是完全通用的协程。 - 有前途的Java 协程失败了,因为它是特定于平台的(显然使用 JNI)解决方案。
And that's about all I've found.
这就是我发现的全部内容。
I know about the native JVM support for coroutines in the Da Vinci Machine and I also know about the JNI continuations trickfor doing this. These are not really good solutions for me, however, as I would not necessarily have control over which VM or platform my code would run on. (Indeed any bytecode manipulation system would suffer similar problems -- it would be best were this pure Java if possible. Runtime bytecode manipulation would restrict me from using this on Android, for example.)
我了解达芬奇机器中对协程的原生 JVM 支持,我也了解用于执行此操作的JNI 延续技巧。然而,这些对我来说并不是很好的解决方案,因为我不一定能控制我的代码将在哪个虚拟机或平台上运行。(确实,任何字节码操作系统都会遇到类似的问题——如果可能的话,最好是纯 Java。例如,运行时字节码操作会限制我在 Android 上使用它。)
So does anybody have any pointers? Is this even possible? If not, will it be possible in Java 7?
所以有人有任何指示吗?这甚至可能吗?如果没有,在 Java 7 中有可能吗?
Edited to add:
编辑添加:
Just to ensure that confusion is contained, this is a relatedquestion to my other one, but not the same. This one is looking for an existingimplementation in a bid to avoid reinventing the wheel unnecessarily. The other one is a question relating to how one would go about implementing coroutines in Java should this question prove unanswerable. The intent is to keep different questions on different threads.
只是为了确保包含混淆,这是与我的另一个相关的问题,但不一样。这个人正在寻找一个现有的实现,以避免不必要地重新发明轮子。另一个是关于如果这个问题无法回答的话,如何在 Java 中实现协程的问题。目的是在不同的线程上保留不同的问题。
Further edited to add:
进一步编辑添加:
The answer is selected. Some commentary, however, is in order. The library pointed to is not a coroutine library, so it technically doesn't answer my question. That being said, however, it has two edges over the Google Code project linked to above:
该答案被选中。然而,一些评论是有序的。指向的库不是协程库,因此从技术上讲它不能回答我的问题。然而,话虽如此,它与上面链接的 Google Code 项目相比有两个优势:
- Both solutions use bytecode manipulation, but the selected library allows staticbytecode manipulation which renders it usable in Android and other non-compliant JVM stacks.
- The Google Code project doesn't do full coroutines. While the answer's library doesn't even do coroutines at all, it does something more important: it provides a good, foundational tool for rolling my own full-featured coroutines.
- 两种解决方案都使用字节码操作,但所选库允许静态字节码操作,这使其可用于 Android 和其他不兼容的 JVM 堆栈。
- Google Code 项目不执行完整的协程。虽然 answer 的库根本不做协程,但它做了一些更重要的事情:它提供了一个很好的基础工具来滚动我自己的全功能协程。
采纳答案by Guillaume
Javaflowis a continuation implementation, it will probably let you do that. It uses bytecode manipulation though.
Javaflow是一个延续实现,它可能会让你这样做。虽然它使用字节码操作。
Anyway, it feels like you're trying to do OOP with plain C. It's doable but it doesn't mean you should do it.
无论如何,感觉就像您正在尝试使用普通 C 语言进行 OOP。这是可行的,但并不意味着您应该这样做。
回答by Kresten Krab Thorup
The Kilimframework implements coroutines by using byte code rewriting. I've used it myself to implement light-weight processes in Erjang, and it is very stable and surprisingly fast for the amount of bytecode rewriting that goes on.
该奇勒姆框架实现协同程序使用字节代码重写。我自己用它在Erjang 中实现了轻量级进程,它非常稳定,并且对于正在进行的字节码重写量来说非常快。
Kilim's coroutines interact by using mailboxes, so I use the framework to model Erlang actors. But it can just as well be used to do coroutines in a shared memory model.
Kilim 的协程通过使用邮箱进行交互,因此我使用该框架对 Erlang 演员进行建模。但它也可以用于在共享内存模型中执行协程。
回答by rrmckinley
What do you think of this continuations library written by Matthias Mann? I have copied the pros and cons from the creator's web site to facilitate discussion. It is important to look at the tests in the source code to see beyond the one example on the web site.
你如何看待这个由 Matthias Mann 编写的延续库?我已经从创作者的网站上复制了利弊,以方便讨论。重要的是查看源代码中的测试以了解网站上的一个示例之外的内容。
http://www.matthiasmann.de/content/view/24/26/
http://www.matthiasmann.de/content/view/24/26/
Lets start with what you get:
让我们从你得到的开始:
- Write simple sequential code - you no longer need to create state machines by hand
- No Threads are created or needed - no multi thread synchronization issues
- No garbage creation from code execution
- Very small runtime overhead
- Only suspendable method calls are changed - all calls into your standard library (like java.util.* etc) are not affected at all.
- Full serialization support
- You can store the execution state of coroutines as part of your game state in your save game without any additional code. This of course requires that your classes and data types which you use in your coroutines are serializable. Full support for exception handling and finally blocks
- Offline preprocessing does not slow down you application load time Of course runtime instrumentation is also possible.
- Very small runtime library - less then 10 KByte (uncompressed JAR) BSD License
- 编写简单的顺序代码 - 您不再需要手动创建状态机
- 没有创建或需要线程 - 没有多线程同步问题
- 代码执行不会产生垃圾
- 非常小的运行时开销
- 只更改可挂起的方法调用 - 对标准库的所有调用(如 java.util.* 等)根本不受影响。
- 完整的序列化支持
- 您可以将协程的执行状态作为游戏状态的一部分存储在您的保存游戏中,而无需任何额外的代码。这当然要求您在协程中使用的类和数据类型是可序列化的。完全支持异常处理和 finally 块
- 离线预处理不会减慢您的应用程序加载时间 当然,运行时检测也是可能的。
- 非常小的运行时库 - 小于 10 KB(未压缩的 JAR)BSD 许可证
With all these great features - you may be asking for the drawbacks. Well there are of course a few drawbacks:
有了所有这些强大的功能 - 您可能会问缺点。那么当然有一些缺点:
- Constructors and static initializers can't be suspended
- Suspendable methods can't be synchronized or have synchronized blocks
- You need to download ASM3 library to run the instrumentation task
- You can't call suspendable method with reflection
- 不能挂起构造函数和静态初始值设定项
- 可挂起的方法不能同步或有同步块
- 您需要下载 ASM3 库来运行检测任务
- 你不能用反射调用可挂起的方法
The synchronization issue can be worked around by putting code which requires the use of synchronization into it's own method.
通过将需要使用同步的代码放入它自己的方法中,可以解决同步问题。
回答by Stephen C
Your requirements seem to be:
您的要求似乎是:
- lightweight - not based on Threads,
- no reliance on native code, and
- no use of bytecode modification.
- 轻量级 - 不基于线程,
- 不依赖本机代码,并且
- 不使用字节码修改。
I have a nasty feeling that these requirements have ruled out all sensible strategies for implementing coroutines in Java.
我有一种讨厌的感觉,这些要求已经排除了在 Java 中实现协程的所有明智策略。
回答by offbynull
If you're using Java, there are 2 options available as of late 2017:
如果您使用的是 Java,则截至 2017 年末有 2 个选项可用:
Both of these are based off of commons-javaflow -- they re-write your code at bytecode level to get things to work.
这两者都基于 commons-javaflow——它们在字节码级别重写您的代码以使事情正常工作。
I maintain Coroutines-- The up-sides are that it's fast, it supports all major build systems, and it supports serialization/versioning of your coroutines. The down-side is that the API has a few deviations from commons-javaflow.
我维护协程——优点是它很快,它支持所有主要的构建系统,并且它支持你的协程的序列化/版本控制。不利的一面是 API 与 commons-javaflow 有一些偏差。
Vsilaev maintains Tascalate-Javaflow-- I haven't used it so I can't speak on it, but it is maintained and from looking at the examples it's API aligns closer to that of commons-javaflow.
Vsilaev 维护着Tascalate-Javaflow——我没有使用过它所以我不能谈论它,但是它被维护并且从查看示例来看它的 API 更接近于 commons-javaflow 的 API。
There are also language features in Kotlin and Scala (and maybe other JVM-based languages) that let you use coroutines. But, before switching languages you should be aware that Kotlin, Scala, or whatever the JVM language du jour is today is not and will never be Java. Whatever it's doing in the background to make things work may not work when the next release of the JVM rolls around.
Kotlin 和 Scala(可能还有其他基于 JVM 的语言)中也有一些语言特性可以让您使用协程。但是,在转换语言之前,您应该意识到 Kotlin、Scala 或任何今天流行的 JVM 语言不是也永远不会是 Java。当 JVM 的下一个版本推出时,无论它在后台做什么来使事情工作可能都不起作用。
The folks who maintain the JDK at Oracle have a track record of using these third-party JVM languages as market research. If a high-level feature gets added to a third-party JVM language and it's popular enough, they'll incorporate it into Java. This is what's happening right now with coroutines. There's an OpenJDK project called Project Loomthat aims to add coroutines to the Java language.
在 Oracle 维护 JDK 的人有使用这些第三方 JVM 语言作为市场调查的记录。如果将高级功能添加到第三方 JVM 语言中并且它足够流行,他们就会将其合并到 Java 中。这就是协程现在正在发生的事情。有一个名为Project Loom的 OpenJDK 项目旨在为 Java 语言添加协程。
It's still early days for Project Loom. If you critically look through the proposal, it's a mess. I'm sure it'll stabilize as time goes on, but what we'll ultimately end up getting may be entirely different from what many of us are expecting.
Loom 项目还处于早期阶段。如果您批判性地查看提案,那将是一团糟。我相信随着时间的推移它会稳定下来,但我们最终得到的可能与我们许多人的预期完全不同。
To recap, your options are to either use one of the bytecode instrumentation toolkits or to switch languages. Project Loom is still in early days and there's a possibility that it may never actually get added to Java.
概括地说,您的选择是使用字节码检测工具包之一或切换语言。Project Loom 仍处于早期阶段,它可能永远不会真正添加到 Java 中。
回答by rrmckinley
the Play framework now provides continuations with Javaflow. Because Play provides so much convenience in other areas, you may want to start with it.
Play 框架现在提供 Javaflow 的延续。因为 Play 在其他方面提供了如此多的便利,您可能想从它开始。
http://www.playframework.org/documentation/1.2RC2/releasenotes-1.2#Continuations
http://www.playframework.org/documentation/1.2RC2/releasenotes-1.2#Continuations
回答by eso
There is a new coroutine framework library available for Java. It is implemented in pure Java, so there's no need for JNI or Java Agents running separately. It is open source and can be downloaded from GitHub:
有一个可用于 Java 的新协程框架库。它是用纯 Java 实现的,因此不需要单独运行 JNI 或 Java 代理。它是开源的,可以从 GitHub 下载:
https://github.com/esoco/coroutines
https://github.com/esoco/coroutines
An introduction to the framework can be found on Medium:
可以在 Medium 上找到该框架的介绍:
回答by Vadzim
Quasarimplements Go-like coroutinesand channels among other features using continuations.
Quasar使用延续实现了类似 Go 的协程和通道以及其他功能。
More details, benchmarks and links on Quasar in my another answer.
在我的另一个答案中有关 Quasar 的更多详细信息、基准和链接。

