gpt4 book ai didi

multithreading - 如何以线程安全的方式初始化atom?

转载 作者:行者123 更新时间:2023-12-03 13:17:06 24 4
gpt4 key购买 nike

假设我有一个原子:

(def my-atom (atom nil))

然后我按如下方式初始化它:

(defn init-atom [init-value]
(when (nil? @my-atom)
(reset! my-atom init-value)))

如果从不同线程同时调用init-atom,则可能会出现竞态条件。我正在寻找一种安全正确地初始化原子的方法。有什么吗?

更新:

实际上我正在初始化它,如下所示:

(defn init-atom [produce-init-fn]
(when (nil? @my-atom)
(reset! my-atom (produce-init-fn)])))

product-init-fn 可能包含副作用。

最佳答案

以下内容将确保原子仅初始化一次:

(defn init-atom [init-value]
(swap! my-atom #(when (nil? %) init-value)))

Atom 和 swap! 语义保证传递给 swap! 的函数将以原子方式执行。

如果你传递一个产生初始值的函数,那么它就不能作为交换!如果发生冲突事务,可能会多次调用该函数。然后您需要使用某种锁定,如其他答案中所示:

(let [o (Object.)]
(defn init-atom [init-value-fn]
(locking o
(swap! my-atom #(when (nil? %) (init-value-fn))))))
如果 my-atom 存在其他并发事务,

init-value-fn 仍可能被多次调用。

如果您需要支持延迟初始化,并且 init-value-fn 是预先已知的并且对于所有线程都相同,您可以将其包装到 delay 中,然后它只会被调用一次,其结果将被缓存并重用:

(def my-init-value (delay init-value-fn))

(defn init-atom []
(swap! my-atom #(when (nil? %) @my-init-value)))

关于multithreading - 如何以线程安全的方式初始化atom?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39020179/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com