Java 中可用的协程库

发布于 2024-09-01 23:08:20 字数 2476 浏览 1 评论 0 原文

我想用 Java 做一些事情,如果使用并发例程编写的话会更清晰,但对于这些来说,完整的线程是严重的过度杀伤力。答案当然是使用 协程,但是有标准 Java 库中似乎没有任何协程支持,快速 Google 一下它就会在这里或那里带来诱人的提示,但没有什么实质性的。

这是我到目前为止发现的内容:

  • JSIM 有一个协程类,但它看起来相当重量级,并且似乎与 点处的螺纹。这样做的目的是降低全线程的复杂性,而不是增加 它。此外,我不确定该类是否可以从库中提取并独立使用。
  • Xalan 有一个协程集类,可以执行类似协程的操作,但如果这又是可疑的 可以从整个库中有意义地提取。它看起来也像是作为一个实现的 严格控制的线程池形式,而不是实际的协程。
  • 有一个 Google Code 项目,它看起来像我的我在追寻,但如果有什么不同的话,它看起来更 比使用线程更重量级。我基本上对需要软件才能完成的事情感到紧张 在运行时动态更改 JVM 字节码以完成其工作。这看起来有点矫枉过正 这会导致比协程解决的问题更多的问题。另外看起来好像没有 实现整个协程的概念。通过我的浏览,它提供了一个仅返回的 yield 功能 给调用者。适当的协程允许yield将控制直接转移到任何已知的协程。 基本上这个库,重量级和可怕,因为它是,只给你支持迭代器,而不是 完全通用的协程。
  • 充满希望的 Coroutine for Java 失败了,因为它特定于平台的(显然使用 JNI)解决方案。

这就是我所发现的全部内容。

我了解达芬奇机器中对协程的本机 JVM 支持,并且我还了解 JNI 延续技巧 用于执行此操作。然而,这些对我来说并不是真正好的解决方案,因为我不一定能够控制我的代码将在哪个虚拟机或平台上运行。 (事实上​​,任何字节码操作系统都会遇到类似的问题——如果可能的话,最好是纯 Java。例如,运行时字节码操作会限制我在 Android 上使用它。)

那么有人有任何指针吗?这可能吗?如果不能的话,Java 7 中可以吗?


编辑添加:

只是为了确保包含混乱,这是我的另一个,但不一样。这个人正在寻找一种现有实现,以避免不必要的重新发明轮子。另一个问题是如果这个问题无法回答,那么如何在 Java 中实现协程。目的是将不同的问题保留在不同的线程上。


进一步编辑添加:

答案已选择。然而,一些评论是合理的。指向的库不是协程库,因此从技术上讲它并不能回答我的问题。然而,话虽这么说,它比上面链接的 Google Code 项目有两个优势:

  1. 两种解决方案都使用字节码操作,但所选库允许静态字节码操作,这使得它可以在 Android 和其他非兼容的 JVM 堆栈。
  2. Google Code 项目不执行完整的协程。虽然答案的库根本不做协程,但它做了更重要的事情:它提供了一个很好的基础工具来滚动我自己的全功能协程。

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.

Here's what I've found so far:

  • JSIM has 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.
  • Xalan has 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 project which 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 yield feature that just returns
    to the invoker. Proper coroutines allow yields 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 Java fails because it's a platform-specific (obviously using
    JNI) solution.

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 trick for 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.)

So does anybody have any pointers? Is this even possible? If not, will it be possible in Java 7?


Edited to add:

Just to ensure that confusion is contained, this is a related question to my other one, but not the same. This one is looking for an existing implementation 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.


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:

  1. Both solutions use bytecode manipulation, but the selected library allows static bytecode manipulation which renders it usable in Android and other non-compliant JVM stacks.
  2. 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

时光病人 2024-09-08 23:08:20

Javaflow 是一个延续实现,它可能会让您做到这一点。但它使用字节码操作。

不管怎样,感觉就像你正在尝试用普通的 C 来做 OOP。这是可行的,但并不意味着你应该这样做。

Javaflow is a continuation implementation, it will probably let you do that. It uses bytecode manipulation though.

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.

烈酒灼喉 2024-09-08 23:08:20

Kilim 框架通过字节码重写的方式实现协程。我自己用它在 Erjang 中实现了轻量级流程,它非常稳定并且速度快得惊人进行的字节码重写量。

Kilim 的协程通过使用邮箱进行交互,因此我使用该框架来对 Erlang actor 进行建模。但它也可以用于在共享内存模型中执行协程。

The Kilim framework 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.

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.

傾城如夢未必闌珊 2024-09-08 23:08:20

您如何看待 Matthias Mann 编写的这个延续库?我从创建者的网站上复制了优点和缺点,以方便讨论。查看源代码中的测试以了解网站上的一个示例之外的内容非常重要。

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

让我们从您得到的开始:

  • 编写简单的顺序代码 - 您不再需要手动创建状态机
  • 不会创建或不需要线程 - 不会出现多线程同步问题
  • 代码执行不会产生垃圾
  • 非常小的运行时开销
  • 仅可挂起的方法调用已更改 - 对标准库(如 java.util.* 等)的所有调用根本不受影响。
  • 完整的序列化支持
  • 您可以将协程的执行状态作为游戏状态的一部分存储在保存游戏中,而无需任何额外的代码。当然,这要求您在协程中使用的类和数据类型是可序列化的。
    完全支持异常处理和最终阻止
  • 离线预处理不会减慢应用程序加载时间
    当然,运行时检测也是可能的。
  • 非常小的运行时库 - 不到 10 KByte(未压缩的 JAR)
    BSD 许可证

拥有所有这些出色的功能 - 您可能会问缺点。当然也有一些缺点:

  • 构造函数和静态初始化器无法挂起 可
  • 挂起的方法无法同步或具有同步块
  • 您需要下载 ASM3 库来运行检测任务
  • 您无法通过反射调用可挂起的

方法可以通过将需要使用同步的代码放入其自己的方法中来解决同步问题。

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.

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

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

The synchronization issue can be worked around by putting code which requires the use of synchronization into it's own method.

流心雨 2024-09-08 23:08:20

您的要求似乎是:

  • 轻量级 - 不基于线程,
  • 不依赖本机代码,并且
  • 不使用字节码修改。

我有一种不好的感觉,这些要求已经排除了在 Java 中实现协程的所有明智策略。

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.

小…红帽 2024-09-08 23:08:20

如果您使用 Java,截至 2017 年末有 2 个选项可用:

这两个都基于 commons-javaflow —— 它们以字节码重写您的代码使事情正常运转的水平。

我维护 协程 - 优点是速度快,支持所有主要构建系统,并且它支持协程的序列化/版本控制。缺点是该 API 与 commons-javaflow 存在一些偏差。

Vsilaev 维护 Tascalate-Javaflow -- 我没用过所以不会说话其上,但它得到了维护,并且从示例来看,它的 API 更接近 commons-javaflow。

Kotlin 和 Scala(也许还有其他基于 JVM 的语言)中也有允许您使用协程的语言功能。但是,在切换语言之前,您应该意识到 Kotlin、Scala 或当今流行的任何 JVM 语言不是也永远不会是 Java。当 JVM 的下一个版本发布时,无论它在后台做什么来使事情正常运行,都可能不起作用。

Oracle 维护 JDK 的人员拥有使用这些第三方 JVM 语言进行市场研究的记录。如果第三方 JVM 语言中添加了高级功能并且足够流行,他们就会将其合并到 Java 中。这就是协程目前正在发生的情况。有一个名为 Project Loom 的 OpenJDK 项目,旨在添加Java 语言的协程。

Loom 项目还处于早期阶段。如果你批判性地审视这个提案,就会发现它一团糟。我确信随着时间的推移它会稳定下来,但我们最终得到的可能与我们许多人的预期完全不同。

回顾一下,您的选择是使用字节码检测工具包之一或切换语言。 Loom 项目仍处于早期阶段,它可能永远不会真正添加到 Java 中。

If you're using Java, there are 2 options available as of late 2017:

Both of these are based off of commons-javaflow -- they re-write your code at bytecode level to get things to work.

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.

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.

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.

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 Loom that aims to add coroutines to the Java language.

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.

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.

最美不过初阳 2024-09-08 23:08:20

Play 框架现在提供了 Javaflow 的延续。由于 Play 在其他方面提供了很多便利,因此您可能想从它开始。

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

the Play framework now provides continuations with Javaflow. Because Play provides so much convenience in other areas, you may want to start with it.

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

如日中天 2024-09-08 23:08:20

Java 有一个新的协程框架库。它是用纯Java实现的,因此不需要单独运行JNI或Java代理。它是开源的,可以从 GitHub 下载:

https://github.com/esoco/coroutines

该框架的介绍可以在 Medium 上找到:

https://medium.com/@esocogmbh/65661a379c85

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:

https://github.com/esoco/coroutines

An introduction to the framework can be found on Medium:

https://medium.com/@esocogmbh/65661a379c85

本宫微胖 2024-09-08 23:08:20

Quasar 实现 类似 Go 的协程以及使用延续的其他功能中的通道。

有关 Quasar 的更多详细信息、基准测试和链接,请参阅我的另一个答案

Quasar implements Go-like coroutines and channels among other features using continuations.

More details, benchmarks and links on Quasar in my another answer.

佞臣 2024-09-08 23:08:20

有一种方法可以使用 Project Loom 中的非公共 API 来实现本机 Java 协程。
例如,这是我的 Java 协程库: https://github.com/Anamorphosee/loomoroutines

There’s a way to implement native Java coroutines using a non-public API from the Project Loom.
For example this is my library for Java coroutines: https://github.com/Anamorphosee/loomoroutines

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文