Clojure Promise在原子图内

时间:2018-08-07 03:40:20

标签: multithreading clojure promise

我正在尝试跟踪对服务器的请求,并在数据准备就绪时执行一些操作。我有以下似乎有效的代码,但我想知道是否有更好的方法可以做到这一点-特别是我感到奇怪的是,在下面的将来,我在内部引用原子时反引用了一个Promise,该原子可能会改变状态。

(def requests (atom {:a (promise) :b (promise)}))
(future @(:b @requests) (println "b is ready"))
(swap! requests assoc :c (promise))
(deliver (:b @requests) 100)
>> b is ready

谢谢

2 个答案:

答案 0 :(得分:1)

Atoms旨在解决此问题:

  

内部,交换!读取当前值,将该函数应用于   并尝试进行比较并设置!因为另一个线程可能   在中间时间更改了该值,可能需要重试,   并在旋转循环中这样做。

因此,只要两个线程在映射中不使用相同的键(:a:b:c),您就可以放心。

答案 1 :(得分:1)

我用这种方法看到的主要问题是,您将这个诺言放在一个原子中,但是如果有人实际上将这个原子突变为包含一个不同的诺言,您的程序就会崩溃:观察者将等待一个没有人的诺言否则有参考。取而代之的是,我将promise放入需要通信的代码的两个部分共享的不可变结构中。

您可能会有点幻想,可以使用core.async通道而不是promise,但是如果您只需要传递单个值,那么promise就可以了。