Concurrency 在不牺牲安全并发性的情况下,分离选择原子内部的元素并对其进行更新。

Concurrency 在不牺牲安全并发性的情况下,分离选择原子内部的元素并对其进行更新。,concurrency,clojure,swap,Concurrency,Clojure,Swap,假设我有一个包含在atom中的数据结构,我想首先选择其中的一个元素,然后更新这个元素。我可以在一次交换中完成这两项操作!,这对于比赛条件和其他令人讨厌的事情来说是正确的,但是不允许太多的并发性。有更好的解决办法吗 在下面的示例中,代码速度大大降低,因为查找值会定期修改(每50ms一次),因此需要交换!回滚。 (swap! myAtom (fn [atom-state] (let [lookedUp (searchValIn atom-state)] ;This slows

假设我有一个包含在atom中的数据结构,我想首先选择其中的一个元素,然后更新这个元素。我可以在一次交换中完成这两项操作!,这对于比赛条件和其他令人讨厌的事情来说是正确的,但是不允许太多的并发性。有更好的解决办法吗

在下面的示例中,代码速度大大降低,因为查找值会定期修改(每50ms一次),因此需要交换!回滚。

(swap! myAtom
    (fn [atom-state]
        (let [lookedUp (searchValIn atom-state)] ;This slows down the code
            (if (*some condition*)
                lookedUp
                (modify lookedUp)))))

换句话说:我希望在不牺牲安全并发性的情况下,将选择元素和更新元素分开

据我所知,这是不可能的。为了保持数据视图的一致性,您需要在单个“事务”中执行查找和更新(在引号中,因为
transaction
term不适用于atom操作)。

您能告诉我们更多关于您希望执行更新的条件吗?鉴于atom变化如此频繁,lookedUp值很快就会失效。所以问题可能是:如果它失效了,你希望发生什么?是否要重新运行计算并重试?如果是这样,那么您的代码是最好的。但是,如果您希望在发现另一个线程更新atom使其无效时中止,那么可能会有更好的替代方案。