代码之家  ›  专栏  ›  技术社区  ›  JUST MY correct OPINION

Java中可用的协同程序库

  •  41
  • JUST MY correct OPINION  · 技术社区  · 16 年前

    我想在Java中做一些事情,如果使用并发例程编写的话会更清楚,但是对于那些满是线程的东西来说,它们是严重的过度。当然,答案是 coroutines 但是,标准Java库中似乎没有任何协同程序支持,它上的一个快速谷歌在这里或那里带来了诱人的提示,但没有实质性的提示。

    以下是迄今为止我发现的:

    • JSIM 有一个协程类,但它看起来相当重,似乎与 点处的螺纹。这一点的目的是减少全线程的复杂性,而不是增加 它。此外,我不确定该类是否可以从库中提取并独立使用。
    • Xalan 有一个类似coroutine的coroutine集合类,但同样值得怀疑的是 可以有意义地从整个库中提取。它看起来也被实现为 严格控制线程池的形式,而不是实际的协程。
    • 有一个 Google Code project 看起来像我在找什么,但如果有什么的话,看起来更像 比使用线程更重。我基本上对需要软件 在运行时动态更改JVM字节码以完成其工作。这看起来太过分了 会导致比协程解决更多问题的东西。更进一步,看起来没有 实现整个协同工作的概念。我看了一眼就知道 yield 刚刚返回的功能 致调用方。适当的协程允许 产量 s将控制权直接转移到任何已知的协程。 基本上,这个库虽然很重而且很可怕,但它只提供对迭代器的支持,而不是 全面的协同训练。
    • 同名的 Coroutine for Java 失败,因为它是特定于平台的(显然使用 JNI)溶液。

    这就是我所找到的一切。

    我知道在达芬奇机器中对协程的本地JVM支持,我也知道 JNI continuations trick 因为这样做。然而,对于我来说,这些并不是很好的解决方案,因为我不必控制代码将运行在哪个VM或平台上。(实际上,任何字节码操作系统都会遇到类似的问题——如果可能的话,最好是纯Java。例如,运行时字节码操作会限制我在Android上使用它。)

    有人有什么建议吗?这是可能的吗?如果不是,在Java 7中有可能吗?


    编辑添加:

    为了确保控制混乱,这是一个 相关的 问题到 my other one 但不一样。这个在找一个 现有的 为了避免不必要地重新发明轮子而实施。另一个是一个关于如何在Java中实现协同程序的问题,如果这个问题是无法回答的。目的是在不同的线程上保留不同的问题。


    进一步编辑以添加:

    这个 answer is selected . 然而,一些评论是正确的。所指的库不是协同程序库,所以从技术上讲它不能回答我的问题。不过,尽管如此,与上面链接的谷歌代码项目相比,它有两个优势:

    1. 这两种解决方案都使用字节码操作,但选定的库允许 静止的 字节码操作,使得它可以在Android和其他不兼容的JVM堆栈中使用。
    2. 谷歌代码项目并不能完成完整的协程。虽然答案库根本不做协同工作,但它做了一些更重要的事情:它提供了一个很好的、基础性的工具来滚动我自己的全功能协同工作。
    9 回复  |  直到 7 年前
        1
  •  12
  •   Guillaume    16 年前

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

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

        2
  •  10
  •   Kresten Krab Thorup    15 年前

    这个 Kilim 框架通过使用字节代码重写实现协程。我自己用它来实现 Erjang 它非常稳定,而且对于继续进行的大量字节码重写速度惊人。

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

        3
  •  9
  •   rrmckinley    15 年前

    你觉得马蒂亚斯·曼写的延续图书馆怎么样?我从创建者的网站上复制了利弊,以便于讨论。重要的是要查看源代码中的测试,以便在网站上看到一个以上的示例。

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

    让我们从你得到的开始:

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

    有了这些伟大的特点,你可能会问缺点。当然也有一些缺点:

    • 无法挂起构造函数和静态初始值设定项
    • 可挂起的方法不能同步或具有同步块
    • 您需要下载ASM3库来运行检测任务
    • 不能使用反射调用Suspendable方法

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

        4
  •  5
  •   Stephen C    16 年前

    你的要求似乎是:

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

    我有一种讨厌的感觉,这些要求排除了在Java中实现协同程序的所有明智的策略。

        5
  •  3
  •   offbynull    8 年前

    如果你使用Java,那么在2017年底有2个选项可用:

    这两种方法都是基于通用的javaflow——它们在字节码级别重新编写代码以使事情正常工作。

    我保持 协同程序 --它的优点是速度快,支持所有主要的构建系统,并且支持协程的序列化/版本控制。缺点是API与Commons Javaflow有一些偏差。

    vsilaev维护 流苏 --我没有使用它,所以我不能在上面说,但它是维护的,从示例来看,它的API与Commons Javaflow的API更接近。

    Kotlin和Scala(以及其他基于JVM的语言)中也有语言特性,允许您使用协程。但是,在切换语言之前,你应该意识到,Kotlin、Scala或Jum语言现在的任何一个都不是,也永远不会是Java。当JVM的下一个版本发布时,不管它在后台做什么都可能无法工作。

    在Oracle中维护JDK的人员有使用这些第三方JVM语言进行市场调查的记录。如果将高级特性添加到第三方JVM语言中,并且它很流行,它们会将其合并到Java中。这就是协同训练现在正在发生的事情。有一个名为OpenJDK的项目 Project Loom 其目的是向Java语言添加协同程序。

    对于项目织布机来说,现在还为时过早。如果你仔细看了一下这个建议,那就一团糟了。我相信随着时间的推移,它会稳定下来,但我们最终会得到的可能与我们许多人所期待的完全不同。

    简单地说,您的选择是使用一个字节码检测工具包,或者切换语言。项目织机仍处于早期阶段,有可能永远不会添加到Java中。

        6
  •  2
  •   rrmckinley    15 年前

    play框架现在提供了javaflow的延续。因为游戏在其他领域提供了如此多的便利,你可能想从它开始。

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

        7
  •  1
  •   eso    7 年前

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

    https://github.com/esoco/coroutines

    该框架的介绍可在以下介质中找到:

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

        8
  •  0
  •   Community Mohan Dere    9 年前

    Quasar 器具 Go-like coroutines 以及使用continuations的其他功能。

    更多关于类星体的细节、基准和链接 another answer .

        9
  •  -2
  •   Esko    16 年前

    我查了你链接的相关问题,在我的生活中,我真的不明白线程有什么坏处。在Java线程中,从来都不是本地线程,它们只是孤立的执行单元,依赖于上下文,如果它们是有益的,则可以运行为它们自己的本机线程,即将大的执行块拆分为自己的线程是聪明的,而仅由于少数开销而保持小的执行块更为明智。

    也就是说,Java/JDK本身并没有为高级程序员提供的协同程序。JDK7 无论什么时候出来 )会有所谓的 jsr166y 这是DougLea的fork/join框架。有关技术信息, check this PDF 李先生本人。实际上,fork/join添加了另一个( 有用! 在Java内部线程模型之上的粒度级别,这将帮助您实现您想要的。