本文介绍了种族条件和Clojure原子的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好:clojure"atom"的文档指出-

Hi guys: The Documentation for the clojure "atom" states that -

"Changes to atoms are always free of race conditions."

但是-竞争条件不仅根据更改来定义,而且还根据不同线程中的并行逻辑操作来定义.

However- a race condition is defined not just in terms of a change , but rather, in context of parallel logical operations in different threads.

我想知道-确保原子的变化始终没有竞争条件" 的意义是什么?在Java中,我们有原子原语,它们支持特定的某些线程安全操作(例如,AtomicInteger支持"getAndIncrement"操作).但是Clojure原子是不可知类型的,例如,我们可以调用:

I am wondering - what is the significance of the guarantee that "Changes to atoms are always free of race conditions" ? In java, we have atomic primitives, which support certain thread-safe operations which are specific (for example, the AtomicInteger supports a "getAndIncrement" operation). But Clojure atoms are type-agnostic, for example, we can invoke :

  (atom "Hi im a string")  Or
  (atom (.getClass Object))

atom方法的灵活性意味着Clojure在幕后并不聪明"地为原子提供特定于类型的原子/线程安全操作.

The flexibility of the atom method means that Clojure, under the hood, is not "smartly" providing type-specific atomic / thread-safe operations for atoms.

因此,我想问-原子方法到底对我们的对象做了什么(也就是说,它是否只是简单地同步了整个对象?)

Thus, I would ask -- what exactly is the atom method "doing" to our objects (i.e. is it simply synchronizing the whole object ?)

推荐答案

atom 实际上是一个原子存储位置,可以保证是线程安全的.

An atom is effectively an atomic storage location that is guaranteed to be thread safe.

原子类似于Java的原子数据类型(例如 AtomicReference ),但实际上功能更强大,因为原子允许您使用任意函数来更新原子.示例:

Atoms are similar to Java's atomic data types (like AtomicReference), but are actually somewhat more powerful since an atom allows you to use an arbitrary function to update the atom. Example:

(def a (atom "foo"))

(defn appender [x]
  "Higher order function that returns a function which appends a specific string"
  (fn [s] 
    (str s x)))

(swap! a (appender "bar"))
=> "foobar"

在上面的示例中,交换!操作具有原子性,即使我们传递给它的追加器操作可能是一个非常复杂的函数.实际上,原子允许您以原子方式使用任意更新操作(通常应坚持使用纯函数,因为在发生争用时有可能多次调用该函数).

In the above example, the swap! operation behaves atomically, even though the appender operation we are passing to it could potentially be a quite complex function. In effect, atoms allow you to use an arbitrary update operation in an atomic way (you should normally stick to pure functions since it is possible for the function to be called multiple times in the event of contention).

原子显然不能保证放入其中的对象的线程安全(例如,如果在其中放入未同步的Java ArrayList,那么对于并发使用仍然不安全).但是,如果您坚持使用Clojure的不可变数据类型,它们都是完全线程安全的,那么您会很好.

Atoms obviously don't guarantee thread safety of objects you put inside them (e.g. if you put an unsynchronised Java ArrayList inside, then it's still unsafe for concurrent usage). However if you stick to Clojure's immutable data types which are all completely thread safe then you will be good.

这篇关于种族条件和Clojure原子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-26 23:37