【问题标题】:Clojure how to get access to one field from two threads?Clojure 如何从两个线程访问一个字段?
【发布时间】:2015-10-09 16:18:36
【问题描述】:

无法理解 clojure 中的多线程。找不到真正的多线程示例。大多数带有 atom、refs、vars 的样本都是单线程的。所以,我有一个追求。两个线程访问一个字段,每个线程都可以更改它。我为此使用 atom ,所以代码是:

   (do
     (def field (atom "v0"))

     (defn f1 []
       (dotimes [i 100000]
         (if (= i 9999)
           (reset! field "v1"))))

     (defn f2 []
       (dotimes [i 100000]
         (if (= i 777)
           (reset! field "v2"))))

   (do
     (deref (future (Thread/sleep 10) (f1))
            0 f2)
     (prn @field)))

但没什么,字段的值是“v0”。如何使用每个线程中的循环并访问变量来制作正常的双线程示例???

【问题讨论】:

  • 我很高兴 clojure 中的所有多线程样本!!!!在我的代码末尾,我添加了 (deref (future (Thread/sleep 5000) (prn @field)) 0 (prn @field))
  • 这有助于显示“v1”,但如果我在重置之前放置(prn @field)!在 f1 中,我无法获得“v2”,这就是问题所在,我无法将 f2 中的 @field 更改为在 f1 中读取它
  • 试试这一章:braveclojure.com/concurrency 它对 clojure 的并发性做了一些很好的介绍。整本书也很不错

标签: multithreading loops clojure


【解决方案1】:

观看deref的文档:

clojure.core/deref
([ref] [ref timeout-ms timeout-val])

返回 ref 的 in-transaction-value,否则返回 最近提交的 ref 值。当应用于 var 时,代理 或原子,返回其当前状态。当应用于延迟时,力 如果还没有强迫的话。当应用于未来时,如果 计算未完成。当应用于 promise 时,将阻塞 直到交付价值。超时的变体可以是 用于阻塞引用(期货和承诺),并将返回 timeout-val 如果在 a 之前达到超时(以毫秒为单位) 值可用。另请参阅 - 实现了吗?

所以你的超时时间是 0,这意味着它将返回默认值 这是f2 - 一个函数值(不是函数调用),它显然没有被调用,所以不会发生reset!

  1. 如果你想要“v1”,你应该像这样取消引用:

    (deref (future (Thread/sleep 10) (f1)) 100 (f2))

  2. 如果你想要“v2”:

    (deref (future (Thread/sleep 10) (f1)) 0 (f2))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-17
    • 2013-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多