18

我最近很喜欢看Google IO 关于 Go 并发模式的演讲

尽管 Go 的并发方法(groutines、通过通道的通信)明显不同于 Clojure(不变性、管理引用、STM),但在 Clojure 上下文中的某些情况下,Go 方法似乎仍然有用。

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

  • channel- 像对象一样阻塞,直到读写器在两端都可用
  • select可以在多个通道上等待结果的类似构造

PS对 Java 解决方案非常满意,因为它很容易从 Clojure 中使用

更新自从最初提出这个问题以来,Clojure 现在有了core.async,它提供了所有这些功能等等。

4

8 回答 8

5

您应该查看core.async。它是由 Rich Hickey 编写的实现 go 风格通道的库。

于 2014-09-26T01:47:29.070 回答
3

阻塞直到读写器两端都可用的类似通道的对象

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

如果我的假设是正确的,那么您可以有两种选择(在标准 Java 中)。

  1. 同步队列
  2. TransferQueue(虽然这也可以用作缓冲通道)

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

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

于 2012-07-03T15:27:35.507 回答
3

我最近编写了 go-lightly,这是一个支持使用 Go 并发结构进行编程的 Clojure 库,将一些 Clojure 习语放在这种并发编程风格上。

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

  1. 围棋套路
  2. 同步(阻塞)通道
  3. 有界的,主要是异步(非阻塞)通道
  4. select从多个通道读取下一条可用消息的运算符
  5. 通道读/写/选择的超时操作

go-lightly 库具有所有这些功能,构建在 Java 和 Clojure 中可用的功能之上。True Go 例程被多路复用到线程上,而不是在其整个生命周期内完全使用线程。在 go-lightly 中,我在 Clojure 未来宏之上构建了 go 例程,因此这是 JVM 上 Go 模型最薄弱的部分。

我尝试使用 lamina,但它缺少有界通道(在某些情况下您可能需要它,并且是 Go 缓冲通道模型的一部分),据我所知,在将消息放到渠道。这是 Go 并发模型的一个关键特性。

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

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

于 2013-01-30T04:12:00.413 回答
2

在不了解 Go 的情况下,看看 Lamina 是否符合您的要求https://github.com/ztellman/lamina

于 2012-07-02T18:43:02.397 回答
1

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

于 2013-06-13T07:55:46.423 回答
0

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

Erlang以轻量级低于 1000 字节的进程 而闻名。

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

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

于 2012-07-02T22:31:11.820 回答
0

akka演员~= goroutine+channel

于 2012-07-05T08:26:18.153 回答
0

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

JCSP 非常好……但是缺点仍然是 JVM 施加的限制,尤其是线程的高成本。在 Go 或 Occam 中,线程的数量可以达到数百万,但在 JVM 中则不然。

于 2012-12-18T22:21:02.457 回答