multithreading - 与 Clojure 的线程同步

标签 multithreading clojure clojure-java-interop

我有一个练习:

  • 按顺序打印从 1 到 100 的所有正整数。

  • 使用 block 、信号量或其他类似机制(但避免休眠)协调两个线程,使两个线程的组合输出按数字顺序显示。

     Sample Output
        In thread one: The number is ‘1’
        In thread two: The number is ‘2’
        In thread one: The number is ‘3’
        In thread two: The number is ‘4’
    

该练习适用于 Ruby,但我想向我的类(class)展示 Clojure 可能是该任务的一个不错的选择。

我对任何语言的线程都没有任何经验,但我想使用类似的东西:

 (def thread_1 (future (swap! my-atom inc) ))
 (def thread_2 (future (swap! my-atom inc) ))

@thread_1 总是返回相同的值。有没有办法在 Clojure 中协调两个线程?

我找到了 example在 Java 中使用 ReentrantLock 和 Condition,现在我正在尝试将其转换为 Clojure。

最佳答案

如果线程的顺序很重要,并且如果您对非经典线程通信感到好奇,您可以使用 clojure.core.async 并使用“ channel ”。

(require '[clojure.core.async :as a])

(let [chan-one (a/chan 1)
      chan-two (a/chan 1)]
  (a/>!! chan-one 1)
  (doseq [[thread in out] [["one" chan-one chan-two]
                           ["two" chan-two chan-one]]]
    (a/go-loop []
      (when-let [n (a/<! in)]
        (if (> n 10)
          (do (a/close! in)
              (a/close! out))
          (do (prn (format "In thread %s: The number is `%s`" thread n))
              (a/>! out (inc n))
              (recur)))))))

输出是

"In thread one: The number is `1`"
"In thread two: The number is `2`"
"In thread one: The number is `3`"
"In thread two: The number is `4`"
"In thread one: The number is `5`"
"In thread two: The number is `6`"
"In thread one: The number is `7`"
"In thread two: The number is `8`"
"In thread one: The number is `9`"
"In thread two: The number is `10`"

这里有个问题是go-routines在线程池中执行,所以它们不是专用线程,如果你想使用真正的线程,你应该这样:

(require '[clojure.core.async :as a])

(let [chan-one (a/chan 1)
      chan-two (a/chan 1)]
  (a/>!! chan-one 1)
  (doseq [[thread in out] [["one" chan-one chan-two]
                           ["two" chan-two chan-one]]]
    (a/thread
      (loop []
        (when-let [n (a/<!! in)]
          (if (> n 10)
            (do (a/close! in)
                (a/close! out))
            (do (prn (format "In thread %s: The number is `%s`" thread n))
                (a/>!! out (inc n))
                (recur))))))))

关于multithreading - 与 Clojure 的线程同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52302690/

相关文章:

java - 为什么通常不推荐客户端锁定?

java - 如何使用java多线程将大文本文件分割成更小的 block

java - 如何测量分布式系统中的请求时间?

hadoop - Cascalog:启动uberjar并在hadoop上进行main

clojure gen 类可变参数构造函数

c# - Freeswitch 事件套接字库

java - 在原始数组上调用 amap 时 Clojure 失败

clojure - 如何使用 Clojure 的 Apache Commons Codec 库?

Clojure 注释和整数