相当于Clojure / Java中的Goroutines

时间:2012-07-02 18:14:00

标签: java concurrency clojure go goroutine

我最近很高兴看到Google IO talk on Go Concurrency patterns

虽然Go的并发方法(沟通,通道上的沟通)明显不同于Clojure(不变性,管理参考,STM),但似乎Go方法在Clojure上下文中的某些情况下仍然有用。

对于Go的并发原语(可能是库),Clojure或Java中有直接的等价物,特别是:

  • channel - 类似于阻止读者和作者在两端都可用的对象
  • 类似select的构造,可以在多个渠道上等待结果

P.S。非常满意Java解决方案,因为它很容易在Clojure中使用

更新由于问题最初被问到,Clojure现在有core.async,它提供了所有这些功能以及更多功能。

8 个答案:

答案 0 :(得分:4)

你应该看看core.async。这是一个由Rich Hickey编写的库,它实现了go style渠道。

答案 1 :(得分:3)

  

类似频道的对象,直到读者和作者才会阻止   两端都有。

这有点令人困惑。你的意思是“直到,如果写作,读者可用,或者,如果阅读,作家可用”?我代表的是线程而不是构造,一个构造不能只阻塞线程。 (为避免混淆,构造将指示线程阻塞)。

如果我的假设是正确的,你可以有两种选择(标准Java)。

  1. SynchronousQueue
  2. TransferQueue(虽然这也可以用作缓冲通道)
  3.   

    类似select的构造,可以在多个通道上等待结果

    据我所知,没有任何真正的select类似构造。您可以拥有的最近的是ExecutorCompletionService,它将在提交的下一个可用任务完成时返回。

答案 2 :(得分:3)

我最近编写了go-lightly,这是一个Clojure库,支持使用Go并发构造进行编程,并在该并发编程风格上添加了一些Clojure习语。

Go并发编程的核心结构是:

  1. Go例程
  2. 同步(阻止)频道
  3. 有界,主要是异步(非阻塞)频道
  4. 一个select运算符,用于读取多个通道中的下一个可用消息
  5. 频道读/写/选择的超时操作
  6. go-lightly库具有所有这些功能,基于Java和Clojure提供的功能。 True Go例程被多路复用到线程上,而不是在完整生命周期内完全使用线程。在Go-lightly中,我在Clojure future宏的基础上构建了例程,因此这是JVM上Go模型中最薄弱的部分。

    我尝试使用lamina,但它缺少有界通道(在某些情况下你可能想要它并且是Go缓冲通道模型的一部分)并且据我所知,在放置时没有办法让生产者阻塞消息到频道上。这是Go并发模型的一个重要特征。

    我在git repo中使用了go-lightly库包含了一些例子。大多数是基于Rob Pike过去两年在谈判中提出的例子。

    在JCSP之上构建一个Clojure库会很有趣,但我还没有研究过。

答案 3 :(得分:2)

在不了解Go的情况下,请查看Lamina以了解它是否适​​合您所寻找的https://github.com/ztellman/lamina

答案 4 :(得分:1)

您可能需要查看Quasar/Pulsar。这是非常新的,但它正是你正在寻找的。

答案 5 :(得分:0)

看看Joxa。它是一种类似Clojure的Lisp方言,目标是Erlang虚拟机。

并且Erlang以轻量级的1000字节进程而闻名。

Erjang也有些相关,您可能会感兴趣。它是在JVM之上的Erlang虚拟机的实现。

所以理论上你可以将Joxa编译成BEAM然后仍然在JVM上运行它。不是我会推荐它: - )。

答案 6 :(得分:0)

akka actor〜= goroutine + channel

答案 7 :(得分:0)

我强烈推荐JCSP,基于Occam /晶片机算法。使用正式方法和形式证明器算法检查了此API实现的关键部分的正确性,因此尽可能可靠(Alternative类是这方面的主要成就)。

JCSP非常好......但是缺点仍然是JVM施加的限制,特别是线程的高成本。在Go或Occam中,线程可以以数百万计,但在JVM上则不是这样。